Search in sources :

Example 1 with KNXFormatException

use of tuwien.auto.calimero.exception.KNXFormatException in project openhab1-addons by openhab.

the class KNXGenericBindingProvider method parseBindingConfigString.

/**
     * This is the main method that takes care of parsing a binding configuration
     * string for a given item. It returns a collection of {@link BindingConfig}
     * instances, which hold all relevant data about the binding to KNX of an item.
     * 
     * @param item the item for which the binding configuration string is provided
     * @param bindingConfig a string which holds the binding information
     * @return a knx binding config, a collection of {@link KNXBindingConfigItem}
     *         instances, which hold all relevant data about the binding
     * @throws BindingConfigParseException if the configuration string has no valid syntax
     */
protected KNXBindingConfig parseBindingConfigString(Item item, String bindingConfig) throws BindingConfigParseException {
    KNXBindingConfig config = new KNXBindingConfig();
    String[] datapointConfigs = bindingConfig.trim().split(",");
    // we can have one datapoint per accepted command type of this item
    for (int i = 0; i < datapointConfigs.length; i++) {
        try {
            String datapointConfig = datapointConfigs[i].trim();
            KNXBindingConfigItem configItem = new KNXBindingConfigItem();
            configItem.itemName = item.getName();
            if (datapointConfig.split("<").length > 2) {
                throw new BindingConfigParseException("Only one readable GA allowed.");
            }
            String[] dataPoints = datapointConfig.split("\\+");
            for (int j = 0; j < dataPoints.length; ++j) {
                String dataPoint = dataPoints[j].trim();
                // Just skip it, it will be handle in the next iteration.
                if (dataPoint.isEmpty()) {
                    continue;
                }
                boolean isReadable = false;
                int autoRefreshTimeInSecs = 0;
                // check for the readable flag
                if (dataPoint.startsWith("<")) {
                    isReadable = true;
                    dataPoint = dataPoint.substring(1);
                    // check for the auto refresh parameter
                    if (dataPoint.startsWith("(")) {
                        int endIndex = dataPoint.indexOf(")");
                        if (endIndex > -1) {
                            dataPoint = dataPoint.substring(1);
                            if (endIndex > 1) {
                                try {
                                    autoRefreshTimeInSecs = Integer.parseInt(dataPoint.substring(0, endIndex - 1));
                                    dataPoint = dataPoint.substring(endIndex);
                                    if (autoRefreshTimeInSecs == 0) {
                                        throw new BindingConfigParseException("Autorefresh time cannot be 0.");
                                    }
                                } catch (NumberFormatException nfe) {
                                    throw new BindingConfigParseException("Autorefresh time must be a number, but was '" + dataPoint.substring(1, endIndex) + "'.");
                                }
                            } else {
                                throw new BindingConfigParseException("Autorefresh time parameter: missing time. Empty brackets are not allowed.");
                            }
                        } else {
                            throw new BindingConfigParseException("Closing ')' missing on autorefresh time parameter.");
                        }
                    }
                }
                // find the DPT for this entry
                String[] segments = dataPoint.split(":");
                Class<? extends Type> typeClass = null;
                String dptID = null;
                if (segments.length == 1) {
                    //DatapointID NOT specified in binding config, so try to guess it
                    typeClass = item.getAcceptedCommandTypes().size() > 0 ? item.getAcceptedCommandTypes().get(i) : item.getAcceptedDataTypes().size() > 1 ? item.getAcceptedDataTypes().get(i) : item.getAcceptedDataTypes().get(0);
                    dptID = getDefaultDPTId(typeClass);
                } else {
                    //DatapointID specified in binding config, so use it
                    dptID = segments[0];
                }
                if (dptID == null || dptID.trim().isEmpty()) {
                    throw new BindingConfigParseException("No DPT could be determined for the type '" + typeClass.getSimpleName() + "'.");
                }
                // check if this DPT is supported
                if (KNXCoreTypeMapper.toTypeClass(dptID) == null) {
                    throw new BindingConfigParseException("DPT " + dptID + " is not supported by the KNX binding.");
                }
                String ga = (segments.length == 1) ? segments[0].trim() : segments[1].trim();
                // determine start/stop behavior
                Boolean startStopBehavior = Boolean.FALSE;
                if (ga.endsWith(START_STOP_MARKER_SUFFIX)) {
                    startStopBehavior = Boolean.TRUE;
                    ga = ga.substring(0, ga.length() - START_STOP_MARKER_SUFFIX.length());
                }
                // create group address and datapoint
                GroupAddress groupAddress = new GroupAddress(ga);
                configItem.startStopMap.put(groupAddress, startStopBehavior);
                Datapoint dp;
                if (j != 0 || item.getAcceptedCommandTypes().size() == 0) {
                    dp = new StateDP(groupAddress, item.getName(), 0, dptID);
                } else {
                    dp = new CommandDP(groupAddress, item.getName(), 0, dptID);
                }
                // assign datapoint to configuration item
                if (configItem.mainDataPoint == null) {
                    configItem.mainDataPoint = dp;
                }
                if (isReadable) {
                    configItem.readableDataPoint = dp;
                    if (autoRefreshTimeInSecs > 0) {
                        configItem.autoRefreshInSecs = autoRefreshTimeInSecs;
                    }
                }
                if (!configItem.allDataPoints.contains(dp)) {
                    configItem.allDataPoints.add(dp);
                } else {
                    throw new BindingConfigParseException("Datapoint '" + dp.getDPT() + "' already exists for item '" + item.getName() + "'.");
                }
            }
            config.add(configItem);
        } catch (IndexOutOfBoundsException e) {
            throw new BindingConfigParseException("No more than " + i + " datapoint definitions are allowed for this item.");
        } catch (KNXFormatException e) {
            throw new BindingConfigParseException(e.getMessage());
        }
    }
    return config;
}
Also used : CommandDP(tuwien.auto.calimero.datapoint.CommandDP) Datapoint(tuwien.auto.calimero.datapoint.Datapoint) Datapoint(tuwien.auto.calimero.datapoint.Datapoint) BindingConfigParseException(org.openhab.model.item.binding.BindingConfigParseException) StateDP(tuwien.auto.calimero.datapoint.StateDP) GroupAddress(tuwien.auto.calimero.GroupAddress) KNXFormatException(tuwien.auto.calimero.exception.KNXFormatException)

Example 2 with KNXFormatException

use of tuwien.auto.calimero.exception.KNXFormatException in project openhab1-addons by openhab.

the class KNXCoreTypeMapper method toType.

/*
     * (non-Javadoc)
     *
     * @see org.openhab.binding.knx.config.KNXTypeMapper#toType(tuwien.auto.calimero.datapoint.Datapoint, byte[])
     */
@Override
public Type toType(Datapoint datapoint, byte[] data) {
    try {
        DPTXlator translator = TranslatorTypes.createTranslator(datapoint.getMainNumber(), datapoint.getDPT());
        translator.setData(data);
        String value = translator.getValue();
        String id = translator.getType().getID();
        logger.trace("toType datapoint DPT = " + datapoint.getDPT());
        int mainNumber = getMainNumber(id);
        if (mainNumber == -1) {
            logger.debug("toType: couldn't identify mainnumber in dptID: {}.", id);
            return null;
        }
        int subNumber = getSubNumber(id);
        if (subNumber == -1) {
            logger.debug("toType: couldn't identify sub number in dptID: {}.", id);
            return null;
        }
        /*
             * Following code section deals with specific mapping of values from KNX to openHAB types were the String
             * received from the DPTXlator is not sufficient to set the openHAB type or has bugs
             */
        switch(mainNumber) {
            case 1:
                DPTXlatorBoolean translatorBoolean = (DPTXlatorBoolean) translator;
                switch(subNumber) {
                    case 8:
                        return translatorBoolean.getValueBoolean() ? UpDownType.DOWN : UpDownType.UP;
                    case 9:
                        return translatorBoolean.getValueBoolean() ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
                    case 10:
                        return translatorBoolean.getValueBoolean() ? StopMoveType.MOVE : StopMoveType.STOP;
                    case 19:
                        return translatorBoolean.getValueBoolean() ? OpenClosedType.OPEN : OpenClosedType.CLOSED;
                    case 22:
                        return DecimalType.valueOf(translatorBoolean.getValueBoolean() ? "1" : "0");
                    default:
                        return translatorBoolean.getValueBoolean() ? OnOffType.ON : OnOffType.OFF;
                }
            case 2:
                DPTXlator1BitControlled translator1BitControlled = (DPTXlator1BitControlled) translator;
                int decValue = (translator1BitControlled.getControlBit() ? 2 : 0) + (translator1BitControlled.getValueBit() ? 1 : 0);
                return new DecimalType(decValue);
            case 3:
                DPTXlator3BitControlled translator3BitControlled = (DPTXlator3BitControlled) translator;
                if (translator3BitControlled.getStepCode() == 0) {
                    /*
                         * there is no STOP for a IncreaseDecreaseType, so we are just using an INCREASE.
                         * It is up to the binding to recognize that a start/stop-dimming is in progress and
                         * stop the dimming accordingly.
                         */
                    logger.debug("toType: KNX DPT_Control_Dimming: break received.");
                    return IncreaseDecreaseType.INCREASE;
                }
                switch(subNumber) {
                    case 7:
                        return translator3BitControlled.getControlBit() ? IncreaseDecreaseType.INCREASE : IncreaseDecreaseType.DECREASE;
                    case 8:
                        return translator3BitControlled.getControlBit() ? UpDownType.DOWN : UpDownType.UP;
                }
            case 14:
                /*
                     * FIXME: Workaround for a bug in Calimero / Openhab DPTXlator4ByteFloat.makeString(): is using a
                     * locale when
                     * translating a Float to String. It could happen the a ',' is used as separator, such as
                     * 3,14159E20.
                     * Openhab's DecimalType expects this to be in US format and expects '.': 3.14159E20.
                     * There is no issue with DPTXlator2ByteFloat since calimero is using a non-localized translation
                     * there.
                     */
                DPTXlator4ByteFloat translator4ByteFloat = (DPTXlator4ByteFloat) translator;
                Float f = translator4ByteFloat.getValueFloat();
                if (Math.abs(f) < 100000) {
                    value = String.valueOf(f);
                } else {
                    NumberFormat dcf = NumberFormat.getInstance(Locale.US);
                    if (dcf instanceof DecimalFormat) {
                        ((DecimalFormat) dcf).applyPattern("0.#####E0");
                    }
                    value = dcf.format(f);
                }
                break;
            case 18:
                DPTXlatorSceneControl translatorSceneControl = (DPTXlatorSceneControl) translator;
                int decimalValue = translatorSceneControl.getSceneNumber();
                if (value.startsWith("learn")) {
                    decimalValue += 0x80;
                }
                value = String.valueOf(decimalValue);
                break;
            case 19:
                DPTXlatorDateTime translatorDateTime = (DPTXlatorDateTime) translator;
                if (translatorDateTime.isFaultyClock()) {
                    // Not supported: faulty clock
                    logger.debug("toType: KNX clock msg ignored: clock faulty bit set, which is not supported");
                    return null;
                } else if (!translatorDateTime.isValidField(DPTXlatorDateTime.YEAR) && translatorDateTime.isValidField(DPTXlatorDateTime.DATE)) {
                    // Not supported: "/1/1" (month and day without year)
                    logger.debug("toType: KNX clock msg ignored: no year, but day and month, which is not supported");
                    return null;
                } else if (translatorDateTime.isValidField(DPTXlatorDateTime.YEAR) && !translatorDateTime.isValidField(DPTXlatorDateTime.DATE)) {
                    // Not supported: "1900" (year without month and day)
                    logger.debug("toType: KNX clock msg ignored: no day and month, but year, which is not supported");
                    return null;
                } else if (!translatorDateTime.isValidField(DPTXlatorDateTime.YEAR) && !translatorDateTime.isValidField(DPTXlatorDateTime.DATE) && !translatorDateTime.isValidField(DPTXlatorDateTime.TIME)) {
                    // Not supported: No year, no date and no time
                    logger.debug("toType: KNX clock msg ignored: no day and month or year, which is not supported");
                    return null;
                }
                Calendar cal = Calendar.getInstance();
                if (translatorDateTime.isValidField(DPTXlatorDateTime.YEAR) && !translatorDateTime.isValidField(DPTXlatorDateTime.TIME)) {
                    // Pure date format, no time information
                    cal.setTimeInMillis(translatorDateTime.getValueMilliseconds());
                    value = new SimpleDateFormat(DateTimeType.DATE_PATTERN).format(cal.getTime());
                    return DateTimeType.valueOf(value);
                } else if (!translatorDateTime.isValidField(DPTXlatorDateTime.YEAR) && translatorDateTime.isValidField(DPTXlatorDateTime.TIME)) {
                    // Pure time format, no date information
                    cal.clear();
                    cal.set(Calendar.HOUR_OF_DAY, translatorDateTime.getHour());
                    cal.set(Calendar.MINUTE, translatorDateTime.getMinute());
                    cal.set(Calendar.SECOND, translatorDateTime.getSecond());
                    value = new SimpleDateFormat(DateTimeType.DATE_PATTERN).format(cal.getTime());
                    return DateTimeType.valueOf(value);
                } else if (translatorDateTime.isValidField(DPTXlatorDateTime.YEAR) && translatorDateTime.isValidField(DPTXlatorDateTime.TIME)) {
                    // Date format and time information
                    cal.setTimeInMillis(translatorDateTime.getValueMilliseconds());
                    value = new SimpleDateFormat(DateTimeType.DATE_PATTERN).format(cal.getTime());
                    return DateTimeType.valueOf(value);
                }
                break;
        }
        Class<? extends Type> typeClass = toTypeClass(id);
        if (typeClass == null) {
            return null;
        }
        if (typeClass.equals(PercentType.class)) {
            return PercentType.valueOf(value.split(" ")[0]);
        }
        if (typeClass.equals(DecimalType.class)) {
            return DecimalType.valueOf(value.split(" ")[0]);
        }
        if (typeClass.equals(StringType.class)) {
            return StringType.valueOf(value);
        }
        if (typeClass.equals(DateTimeType.class)) {
            String date = formatDateTime(value, datapoint.getDPT());
            if ((date == null) || (date.isEmpty())) {
                logger.debug("toType: KNX clock msg ignored: date object null or empty {}.", date);
                return null;
            } else {
                return DateTimeType.valueOf(date);
            }
        }
        if (typeClass.equals(HSBType.class)) {
            // value has format of "r:<red value> g:<green value> b:<blue value>"
            int r = Integer.parseInt(value.split(" ")[0].split(":")[1]);
            int g = Integer.parseInt(value.split(" ")[1].split(":")[1]);
            int b = Integer.parseInt(value.split(" ")[2].split(":")[1]);
            Color color = new Color(r, g, b);
            return new HSBType(color);
        }
    } catch (KNXFormatException kfe) {
        logger.info("Translator couldn't parse data for datapoint type '{}' (KNXFormatException).", datapoint.getDPT());
    } catch (KNXIllegalArgumentException kiae) {
        logger.info("Translator couldn't parse data for datapoint type '{}' (KNXIllegalArgumentException).", datapoint.getDPT());
    } catch (KNXException e) {
        logger.warn("Failed creating a translator for datapoint type '{}'.", datapoint.getDPT(), e);
    }
    return null;
}
Also used : KNXException(tuwien.auto.calimero.exception.KNXException) DPTXlatorDateTime(tuwien.auto.calimero.dptxlator.DPTXlatorDateTime) KNXIllegalArgumentException(tuwien.auto.calimero.exception.KNXIllegalArgumentException) DecimalFormat(java.text.DecimalFormat) Calendar(java.util.Calendar) Color(java.awt.Color) DPTXlatorString(tuwien.auto.calimero.dptxlator.DPTXlatorString) Datapoint(tuwien.auto.calimero.datapoint.Datapoint) DPTXlatorBoolean(tuwien.auto.calimero.dptxlator.DPTXlatorBoolean) DPTXlator2ByteFloat(tuwien.auto.calimero.dptxlator.DPTXlator2ByteFloat) DPTXlator4ByteFloat(tuwien.auto.calimero.dptxlator.DPTXlator4ByteFloat) DPTXlatorSceneControl(tuwien.auto.calimero.dptxlator.DPTXlatorSceneControl) DPTXlator(tuwien.auto.calimero.dptxlator.DPTXlator) DecimalType(org.openhab.core.library.types.DecimalType) DPTXlator3BitControlled(tuwien.auto.calimero.dptxlator.DPTXlator3BitControlled) DPTXlator4ByteFloat(tuwien.auto.calimero.dptxlator.DPTXlator4ByteFloat) KNXFormatException(tuwien.auto.calimero.exception.KNXFormatException) DPTXlator1BitControlled(tuwien.auto.calimero.dptxlator.DPTXlator1BitControlled) SimpleDateFormat(java.text.SimpleDateFormat) HSBType(org.openhab.core.library.types.HSBType) NumberFormat(java.text.NumberFormat)

Example 3 with KNXFormatException

use of tuwien.auto.calimero.exception.KNXFormatException in project openhab1-addons by openhab.

the class KNXBindingDatapointReaderTask method readFromKNXBus.

private void readFromKNXBus(Datapoint datapoint) throws InterruptedException {
    try {
        ProcessCommunicator pc = KNXConnection.getCommunicator();
        if (pc != null) {
            sLogger.debug("Autorefresh: Sending read request to KNX for item '{}' DPT '{}'", datapoint.getName(), datapoint.getDPT());
            pc.read(datapoint);
        } else {
            sLogger.debug("Autorefresh: Couldn't sent read request to KNX for item '{}'. Connection to KNX bus not (yet) established.", datapoint.getName());
        }
    } catch (KNXFormatException e) {
        sLogger.warn("Autorefresh: Cannot read value for item '{}' from KNX bus: {}: invalid format", datapoint.getName(), e.getMessage());
    } catch (KNXInvalidResponseException e) {
        sLogger.warn("Autorefresh: Cannot read value for item '{}' from KNX bus: {}: invalid response", datapoint.getName(), e.getMessage());
    } catch (KNXTimeoutException e) {
        sLogger.warn("Autorefresh: Cannot read value for item '{}' from KNX bus: {}: timeout", datapoint.getName(), e.getMessage());
        addToReadQueue(datapoint);
    } catch (KNXLinkClosedException e) {
        sLogger.warn("Autorefresh: Cannot read value for item '{}' from KNX bus: {}: link closed", datapoint.getName(), e.getMessage());
    } catch (KNXException e) {
        sLogger.warn("Autorefresh: Cannot read value for item '{}' from KNX bus: {}", datapoint.getName(), e.getMessage());
    } catch (KNXIllegalArgumentException e) {
        sLogger.warn("Autorefresh: Error sending KNX read request for '{}': {}", datapoint.getName(), e.getMessage());
    }
}
Also used : KNXInvalidResponseException(tuwien.auto.calimero.exception.KNXInvalidResponseException) KNXTimeoutException(tuwien.auto.calimero.exception.KNXTimeoutException) KNXException(tuwien.auto.calimero.exception.KNXException) KNXLinkClosedException(tuwien.auto.calimero.link.KNXLinkClosedException) KNXIllegalArgumentException(tuwien.auto.calimero.exception.KNXIllegalArgumentException) KNXFormatException(tuwien.auto.calimero.exception.KNXFormatException) ProcessCommunicator(tuwien.auto.calimero.process.ProcessCommunicator)

Aggregations

KNXFormatException (tuwien.auto.calimero.exception.KNXFormatException)3 Datapoint (tuwien.auto.calimero.datapoint.Datapoint)2 KNXException (tuwien.auto.calimero.exception.KNXException)2 KNXIllegalArgumentException (tuwien.auto.calimero.exception.KNXIllegalArgumentException)2 Color (java.awt.Color)1 DecimalFormat (java.text.DecimalFormat)1 NumberFormat (java.text.NumberFormat)1 SimpleDateFormat (java.text.SimpleDateFormat)1 Calendar (java.util.Calendar)1 DecimalType (org.openhab.core.library.types.DecimalType)1 HSBType (org.openhab.core.library.types.HSBType)1 BindingConfigParseException (org.openhab.model.item.binding.BindingConfigParseException)1 GroupAddress (tuwien.auto.calimero.GroupAddress)1 CommandDP (tuwien.auto.calimero.datapoint.CommandDP)1 StateDP (tuwien.auto.calimero.datapoint.StateDP)1 DPTXlator (tuwien.auto.calimero.dptxlator.DPTXlator)1 DPTXlator1BitControlled (tuwien.auto.calimero.dptxlator.DPTXlator1BitControlled)1 DPTXlator2ByteFloat (tuwien.auto.calimero.dptxlator.DPTXlator2ByteFloat)1 DPTXlator3BitControlled (tuwien.auto.calimero.dptxlator.DPTXlator3BitControlled)1 DPTXlator4ByteFloat (tuwien.auto.calimero.dptxlator.DPTXlator4ByteFloat)1