Search in sources :

Example 1 with TelegramConfiguration

use of org.openhab.binding.ebus.internal.configuration.TelegramConfiguration in project openhab1-addons by openhab.

the class EBusConfigurationProvider method getCommandById.

/**
     * Return all configurations by command id and class
     * 
     * @param commandId The command id
     * @return All matching configurations
     */
public TelegramConfiguration getCommandById(String commandId) {
    String[] idElements = StringUtils.split(commandId, ".");
    String commandClass = null;
    commandId = null;
    if (idElements.length > 1) {
        commandClass = idElements[0];
        commandId = idElements[1];
    }
    for (TelegramConfiguration entry : telegramRegistry) {
        if (StringUtils.equals(entry.getId(), commandId) && StringUtils.equals(entry.getClazz(), commandClass)) {
            return entry;
        }
    }
    return null;
}
Also used : TelegramConfiguration(org.openhab.binding.ebus.internal.configuration.TelegramConfiguration)

Example 2 with TelegramConfiguration

use of org.openhab.binding.ebus.internal.configuration.TelegramConfiguration in project openhab1-addons by openhab.

the class EBusConfigurationProvider method getCommandsByFilter.

/**
     * Return all configuration which filter match the bufferString paramter
     * 
     * @param bufferString The byte string to check against all loaded filters
     * @return All configurations with matching filter
     */
public List<TelegramConfiguration> getCommandsByFilter(String bufferString) {
    final List<TelegramConfiguration> matchedTelegramRegistry = new ArrayList<TelegramConfiguration>();
    /** select matching telegram registry entries */
    for (TelegramConfiguration registryEntry : telegramRegistry) {
        Pattern pattern = registryEntry.getFilterPattern();
        Matcher matcher = pattern.matcher(bufferString);
        if (matcher.matches()) {
            matchedTelegramRegistry.add(registryEntry);
        }
    }
    return matchedTelegramRegistry;
}
Also used : Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) ArrayList(java.util.ArrayList) TelegramConfiguration(org.openhab.binding.ebus.internal.configuration.TelegramConfiguration)

Example 3 with TelegramConfiguration

use of org.openhab.binding.ebus.internal.configuration.TelegramConfiguration in project openhab1-addons by openhab.

the class EBusTelegramParser method parse.

/**
     * Parses a valid eBus telegram and returns a map with key/values based on
     * configuration registry.
     * 
     * @param telegram The eBus telegram
     * @return A Map with parsed key/values
     */
public Map<String, Object> parse(EBusTelegram telegram) {
    // Check if a configuration provider is set
    if (configurationProvider == null) {
        logger.error("Configuration not loaded, can't parse telegram!");
        return null;
    }
    // Secure null check
    if (telegram == null) {
        return null;
    }
    // All parsed values
    final Map<String, Object> valueRegistry = new HashMap<String, Object>();
    // All parsed values with short keys, used for script evaluation
    final Map<String, Object> valueRegistryShortKeys = new HashMap<String, Object>();
    // Get as byte buffer
    final ByteBuffer byteBuffer = telegram.getBuffer();
    // Get hex string for debugging
    final String bufferString = EBusUtils.toHexDumpString(byteBuffer).toString();
    // queries the configuration provider for matching registry entries
    final List<TelegramConfiguration> matchedTelegramRegistry = configurationProvider.getCommandsByFilter(bufferString);
    loggerAnalyses.debug(bufferString);
    // No registry entries found, so this is a unknown telegram
    if (matchedTelegramRegistry.isEmpty()) {
        if (debugWriter != null && (debugWriteMode.contains("unknown") || debugWriteMode.contains("all"))) {
            debugWriter.writeTelegram(telegram, "<unknown>");
        }
        loggerAnalyses.debug("  >>> Unknown ----------------------------------------");
        if (loggerBrutforce.isTraceEnabled()) {
            loggerBrutforce.trace(bufferString);
            bruteforceEBusTelegram(telegram);
        }
        return null;
    }
    // loop thru all matching telegrams from registry
    for (TelegramConfiguration registryEntry : matchedTelegramRegistry) {
        int debugLevel = 0;
        // get id and class key if used
        String idKey = StringUtils.defaultString(registryEntry.getId());
        String classKey = StringUtils.defaultString(registryEntry.getClazz());
        // load debug level for this configuration entry if available
        if (registryEntry.getDebug() != null) {
            debugLevel = registryEntry.getDebug();
            if (debugWriter != null && debugWriteMode.contains("debug")) {
                debugWriter.writeTelegram(telegram, "DEBUG:" + registryEntry.getComment());
            }
        }
        if (debugWriter != null && debugWriteMode.equals("all")) {
            debugWriter.writeTelegram(telegram, registryEntry.getComment());
        }
        // get values block of configuration
        Map<String, TelegramValue> values = registryEntry.getValues();
        // debug
        loggerAnalyses.debug("  >>> {}", StringUtils.defaultIfEmpty(registryEntry.getComment(), "<No comment available>"));
        TelegramValue settings = null;
        // loop over all entries
        for (Entry<String, TelegramValue> entry : values.entrySet()) {
            String uniqueKey = (classKey != "" ? classKey + "." : "") + (idKey != "" ? idKey + "." : "") + entry.getKey();
            settings = entry.getValue();
            // Extract the value from byte buffer
            Object value = getValue(byteBuffer, entry.getValue());
            if (value == null) {
                // its okay if the value is null, maybe out of range min/max or replace value found
                logger.trace("Returned value is null, skip ...");
                continue;
            }
            // If compiled script available for this key, execute it now
            if (settings.getCsript() != null) {
                try {
                    // Add global variables thisValue and keyName to JavaScript context
                    HashMap<String, Object> bindings = new HashMap<String, Object>();
                    // short key
                    bindings.put(entry.getKey(), value);
                    // full key
                    bindings.put(uniqueKey, value);
                    // alias thisValue
                    bindings.put("thisValue", value);
                    // Evaluates script
                    value = evaluateScript(entry, bindings);
                } catch (ScriptException e) {
                    logger.error("Error on evaluating JavaScript!", e);
                    break;
                }
            }
            // debug
            String label = StringUtils.defaultString(settings.getLabel());
            String format = String.format("%-35s%-10s%s", uniqueKey, value, label);
            String alias = null;
            if (settings.getMapping() != null) {
                Map<String, String> mapping = settings.getMapping();
                alias = mapping.get(value.toString());
            }
            if (debugLevel >= 2) {
                loggerAnalyses.debug("    >>> " + format);
                if (alias != null) {
                    loggerAnalyses.debug("      >>> " + alias);
                }
            } else {
                loggerAnalyses.trace("    >>> " + format);
                if (alias != null) {
                    loggerAnalyses.trace("      >>> " + alias);
                }
            }
            // Add result to registry
            valueRegistry.put(uniqueKey, value);
            // Add result to temp. short key registry, used for scripts
            valueRegistryShortKeys.put(entry.getKey(), value);
            // also use class.id as key as shortcut if we have only one value
            if (values.size() == 1) {
                if (!StringUtils.isEmpty(classKey) && !StringUtils.isEmpty(idKey)) {
                    uniqueKey = classKey + "." + idKey;
                    valueRegistry.put(uniqueKey, value);
                }
            }
        }
        // computes values available? if not exit here
        if (registryEntry.getComputedValues() == null) {
            continue;
        }
        // post execute the computes_values block
        Map<String, TelegramValue> cvalues = registryEntry.getComputedValues();
        for (Entry<String, TelegramValue> entry : cvalues.entrySet()) {
            String uniqueKey = (classKey != "" ? classKey + "." : "") + (idKey != "" ? idKey + "." : "") + entry.getKey();
            // Add all values to script scope
            HashMap<String, Object> bindings = new HashMap<String, Object>();
            bindings.putAll(valueRegistryShortKeys);
            bindings.putAll(valueRegistry);
            Object value;
            try {
                // Evaluates script
                value = evaluateScript(entry, bindings);
                // Add result to registry
                valueRegistry.put(uniqueKey, value);
                if (debugLevel >= 2) {
                    String label = StringUtils.defaultString(settings.getLabel());
                    String format = String.format("%-35s%-10s%s", uniqueKey, value, label);
                    loggerAnalyses.debug("    >>> " + format);
                }
            } catch (ScriptException e) {
                logger.error("Error on evaluating JavaScript!", e);
            }
        }
    }
    return valueRegistry;
}
Also used : HashMap(java.util.HashMap) ByteBuffer(java.nio.ByteBuffer) TelegramValue(org.openhab.binding.ebus.internal.configuration.TelegramValue) ScriptException(javax.script.ScriptException) TelegramConfiguration(org.openhab.binding.ebus.internal.configuration.TelegramConfiguration)

Example 4 with TelegramConfiguration

use of org.openhab.binding.ebus.internal.configuration.TelegramConfiguration in project openhab1-addons by openhab.

the class EBusCommandProcessor method composeEBusTelegram.

/**
     * @param commandId
     * @param commandClass
     * @param dst
     * @param src
     * @param values
     * @return
     */
private byte[] composeEBusTelegram(String commandId, Byte dst, Byte src, Map<String, Object> values) {
    if (configurationProvider == null || configurationProvider.isEmpty()) {
        logger.debug("eBUS configuration provider not ready, can't get send data yet.");
        return null;
    }
    byte[] buffer = null;
    TelegramConfiguration commandCfg = configurationProvider.getCommandById(commandId);
    if (commandCfg != null) {
        if (dst == null && StringUtils.isNotEmpty(commandCfg.getDst())) {
            dst = EBusUtils.toByte(commandCfg.getDst());
        }
        if (dst == null) {
            logger.error("Unable to send command, destination address is missing. Set \"dst\" in item.cfg ...");
            return null;
        }
        byte[] bytesData = EBusUtils.toByteArray(commandCfg.getData());
        byte[] bytesCmd = EBusUtils.toByteArray(commandCfg.getCommand());
        if (values == null || values.isEmpty()) {
            logger.trace("No setter-values for eBUS telegram, used default data ...");
            buffer = new byte[bytesData.length + 6];
            buffer[0] = src;
            buffer[1] = dst;
            buffer[4] = (byte) bytesData.length;
            System.arraycopy(bytesCmd, 0, buffer, 2, bytesCmd.length);
            System.arraycopy(bytesData, 0, buffer, 5, bytesData.length);
            return buffer;
        }
        Map<String, TelegramValue> valuesConfig = commandCfg.getValues();
        if (valuesConfig == null || valuesConfig.isEmpty()) {
            logger.warn("No values configurated in json cfg ...");
            return null;
        }
        for (Entry<String, Object> entry : values.entrySet()) {
            TelegramValue valueEntry = valuesConfig.get(entry.getKey());
            if (valueEntry == null) {
                logger.warn("Unable to set value key \"{}\" in command \"{}.{}\", can't compose telegram ...", entry.getKey(), commandId);
                return null;
            }
            String type = valueEntry.getType();
            int pos = valueEntry.getPos() - 1;
            BigDecimal value = NumberUtils.toBigDecimal(entry.getValue());
            if (valueEntry.getMax() != null && value.compareTo(valueEntry.getMax()) == 1) {
                throw new RuntimeException("Value larger than allowed!");
            }
            if (valueEntry.getMin() != null && value.compareTo(valueEntry.getMin()) == -1) {
                throw new RuntimeException("Value smaller than allowed!");
            }
            if (value != null && valueEntry.getFactor() != null) {
                value = value.divide(valueEntry.getFactor());
            }
            byte[] encode = EBusCodecUtils.encode(type, value);
            if (encode.length == 0) {
                logger.warn("eBUS codec encoder returns empty buffer ...");
                return null;
            }
            // add computed single value to data buffer
            System.arraycopy(encode, 0, bytesData, pos - 5, encode.length);
        }
        for (Entry<String, TelegramValue> value : valuesConfig.entrySet()) {
            // check if the special value type for kromsch�der/wolf crc is availabel
            if (StringUtils.equals(value.getValue().getType(), "crc-kw")) {
                byte b = 0;
                int pos = value.getValue().getPos() - 6;
                for (int i = 0; i < bytesData.length; i++) {
                    // exclude crc pos
                    if (i != pos) {
                        b = EBusUtils.crc8(bytesData[i], b, (byte) 0x5C);
                    }
                }
                // set crc to specified position
                bytesData[pos] = b;
            }
        }
        bytesData = EBusUtils.encodeEBusData(bytesData);
        buffer = new byte[bytesData.length + 6];
        buffer[0] = src;
        buffer[1] = dst;
        buffer[4] = (byte) bytesData.length;
        System.arraycopy(bytesCmd, 0, buffer, 2, bytesCmd.length);
        System.arraycopy(bytesData, 0, buffer, 5, bytesData.length);
        return buffer;
    }
    return null;
}
Also used : TelegramConfiguration(org.openhab.binding.ebus.internal.configuration.TelegramConfiguration) TelegramValue(org.openhab.binding.ebus.internal.configuration.TelegramValue) BigDecimal(java.math.BigDecimal)

Example 5 with TelegramConfiguration

use of org.openhab.binding.ebus.internal.configuration.TelegramConfiguration in project openhab1-addons by openhab.

the class EBusConfigurationProvider method loadConfigurationFile.

/**
     * Loads a JSON configuration file by url
     * 
     * @param url The url to a configuration file
     * @throws IOException Unable to read configuration file
     * @throws ParseException A invalid json file
     */
public void loadConfigurationFile(URL url) throws IOException {
    // can reuse, share globally
    final ObjectMapper mapper = new ObjectMapper();
    final InputStream inputStream = url.openConnection().getInputStream();
    final List<TelegramConfiguration> loadedTelegramRegistry = mapper.readValue(inputStream, new TypeReference<List<TelegramConfiguration>>() {
    });
    for (Iterator<TelegramConfiguration> iterator = loadedTelegramRegistry.iterator(); iterator.hasNext(); ) {
        TelegramConfiguration object = iterator.next();
        transformDataTypes(object);
        // check if this filter pattern is already loaded
        String filter = object.getFilterPattern().toString();
        String fileComment = StringUtils.substringAfterLast(url.getFile(), "/") + " >>> " + object.getComment();
        if (loadedFilters.containsKey(filter)) {
            logger.info("Identical filter already loaded ... {} AND {}", loadedFilters.get(filter), fileComment);
        } else {
            loadedFilters.put(filter, fileComment);
        }
    }
    if (loadedTelegramRegistry != null && !loadedTelegramRegistry.isEmpty()) {
        telegramRegistry.addAll(loadedTelegramRegistry);
    }
}
Also used : InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) List(java.util.List) ObjectMapper(org.codehaus.jackson.map.ObjectMapper) TelegramConfiguration(org.openhab.binding.ebus.internal.configuration.TelegramConfiguration)

Aggregations

TelegramConfiguration (org.openhab.binding.ebus.internal.configuration.TelegramConfiguration)5 ArrayList (java.util.ArrayList)2 TelegramValue (org.openhab.binding.ebus.internal.configuration.TelegramValue)2 InputStream (java.io.InputStream)1 BigDecimal (java.math.BigDecimal)1 ByteBuffer (java.nio.ByteBuffer)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 ScriptException (javax.script.ScriptException)1 ObjectMapper (org.codehaus.jackson.map.ObjectMapper)1