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;
}
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;
}
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;
}
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;
}
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);
}
}
Aggregations