/** * Copyright (c) 2010-2016 by the respective copyright holders. * * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html */ package org.openhab.binding.rwesmarthome.internal.communicator.xmlresponse; import java.io.IOException; import java.io.InputStream; import java.util.HashMap; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import org.openhab.binding.rwesmarthome.RWESmarthomeBindingProvider; import org.openhab.binding.rwesmarthome.internal.RWESmarthomeContext; import org.openhab.binding.rwesmarthome.internal.model.LogicalDevice; import org.openhab.binding.rwesmarthome.internal.model.RoomTemperatureActuator; import org.openhab.core.library.types.DecimalType; import org.openhab.core.library.types.OnOffType; import org.openhab.core.library.types.OpenClosedType; import org.openhab.core.library.types.PercentType; import org.openhab.core.library.types.StringType; import org.openhab.core.types.State; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; /** * This class handles the response of the "GetAllLogicalDeviceStates" call, which * loads the current state of all logical devices. * * @author ollie-dev * */ public class GetAllLogicalDeviceStatesXMLResponse extends XMLResponse { private static final Logger logger = LoggerFactory.getLogger(GetAllLogicalDeviceStatesXMLResponse.class); private RWESmarthomeContext context = RWESmarthomeContext.getInstance(); /** * Constructor with an input stream. * * @param inputStream */ public GetAllLogicalDeviceStatesXMLResponse(InputStream is) { RWESmarthomeBindingProvider provider = context.getProviders().iterator().next(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); try { // Using factory get an instance of document builder DocumentBuilder db = dbf.newDocumentBuilder(); // parse using builder to get DOM representation of the XML file Document dom = db.parse(is); // get the root element Element docEle = dom.getDocumentElement(); // LogicalDeviceStates NodeList nodelist = docEle.getElementsByTagName("LogicalDeviceState"); if (nodelist != null && nodelist.getLength() > 0) { for (int i = 0; i < nodelist.getLength(); i++) { // LogicalDeviceState element Element element = (Element) nodelist.item(i); String deviceId = getTextValueFromAttribute(element, "LID"); String deviceType = getTextValueFromAttribute(element, "xsi:type"); // ROOMTEMPERATURESENSOR if (LogicalDevice.Type_RoomTemperatureSensorState.equals(deviceType)) { String itemName = provider.getItemNameByIdAndParam(deviceId, "temperature"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(getDoubleValueFromAttribute(element, "Temperature"))); logger.debug("Updated item '{}' to '{}'", itemName, getDoubleValueFromAttribute(element, "Temperature")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "temperature"); } // ROOMTEMPERATUREACTUATOR } else if (LogicalDevice.Type_RoomTemperatureActuatorState.equals(deviceType)) { // SETTEMPERATURE String itemName = provider.getItemNameByIdAndParam(deviceId, "settemperature"); if (itemName != null) { State newState = new DecimalType(getDoubleValueFromAttribute(element, "PtTmp")); if (!isEcho(itemName, newState.format("%.1f").replace(",", "."))) { context.getEventPublisher().postUpdate(itemName, newState); logger.debug("Updated item '{}' to '{}'", itemName, newState); } } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "settemperature"); } // OPERATIONMODEAUTO itemName = provider.getItemNameByIdAndParam(deviceId, "operationmodeauto"); if (itemName != null) { State newState = getTextValueFromAttribute(element, "OpnMd") .equals(RoomTemperatureActuator.OPERATION_MODE_AUTO) ? OnOffType.ON : OnOffType.OFF; if (!isEcho(itemName, newState.toString())) { context.getEventPublisher().postUpdate(itemName, newState); logger.debug("Updated item '{}' to '{}'", itemName, newState); } } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "operationmodeauto"); } // SWITCHACTUATOR } else if (LogicalDevice.Type_SwitchActuatorState.equals(deviceType)) { String itemName = provider.getItemNameByIdAndParam(deviceId, "switch"); if (itemName != null) { State newState = getBooleanValueFromAttribute(element, "IsOn") ? OnOffType.ON : OnOffType.OFF; if (!isEcho(itemName, newState.toString())) { context.getEventPublisher().postUpdate(itemName, newState); logger.debug("Updated item '{}' to '{}'", itemName, newState); } } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "switch"); } // WINDOWDOORSENSOR } else if (LogicalDevice.Type_WindowDoorSensorState.equals(deviceType)) { String itemName = provider.getItemNameByIdAndParam(deviceId, "contact"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, getBooleanValueFromElements(element, "IsOpen") ? OpenClosedType.OPEN : OpenClosedType.CLOSED); logger.debug("Updated item '{}' to '{}'", itemName, getBooleanValueFromElements(element, "IsOpen")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "contact"); } // LUMINANCESENSOR } else if (LogicalDevice.Type_LuminanceSensorState.equals(deviceType)) { String itemName = provider.getItemNameByIdAndParam(deviceId, "luminance"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(getIntValueFromElements(element, "Luminance"))); logger.debug("Updated item '{}' to '{}'", itemName, getIntValueFromElements(element, "Luminance")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "luminance"); } // HUMIDITYSENSOR } else if (LogicalDevice.Type_RoomHumiditySensorState.equals(deviceType)) { String itemName = provider.getItemNameByIdAndParam(deviceId, "humidity"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(getDoubleValueFromAttribute(element, "Humidity"))); logger.debug("Updated item '{}' to '{}'", itemName, getDoubleValueFromAttribute(element, "Humidity")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "humidity"); } // ROLLERSHUTTERACTUATOR } else if (LogicalDevice.Type_RollerShutterActuatorState.equals(deviceType)) { // ROLLERSHUTTER String itemName = provider.getItemNameByIdAndParam(deviceId, "rollershutter"); if (itemName != null) { State newState = new PercentType(getIntValueFromElements(element, "ShutterLevel")); if (!isEcho(itemName, newState.toString())) { context.getEventPublisher().postUpdate(itemName, newState); logger.debug("Updated item '{}' to '{}'", itemName, newState); } } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "rollershutter"); } // ROLLERSHUTTER INVERTED itemName = provider.getItemNameByIdAndParam(deviceId, "rollershutterinverted"); if (itemName != null) { State newState = new PercentType(100 - getIntValueFromElements(element, "ShutterLevel")); if (!isEcho(itemName, newState.toString())) { context.getEventPublisher().postUpdate(itemName, newState); logger.debug("Updated item '{}' to '{}'", itemName, newState); } } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "rollershutterinverted"); } // DIMMERACTUATOR } else if (LogicalDevice.Type_DimmerActuatorState.equals(deviceType)) { // DIMMER String itemName = provider.getItemNameByIdAndParam(deviceId, "dimmer"); if (itemName != null) { State newState = new PercentType(getIntValueFromAttribute(element, "DmLvl")); if (!isEcho(itemName, newState.toString())) { context.getEventPublisher().postUpdate(itemName, newState); logger.debug("Updated item '{}' to '{}'", itemName, newState); } } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "dimmer"); } // DIMMER INVERTED itemName = provider.getItemNameByIdAndParam(deviceId, "dimmerinverted"); if (itemName != null) { State newState = new PercentType(100 - getIntValueFromAttribute(element, "DmLvl")); if (!isEcho(itemName, newState.toString())) { context.getEventPublisher().postUpdate(itemName, newState); logger.debug("Updated item '{}' to '{}'", itemName, newState); } } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "dimmerinverted"); } // SMOKEDETECTORSENSOR } else if (LogicalDevice.Type_SmokeDetectionSensorState.equals(deviceType)) { String itemName = provider.getItemNameByIdAndParam(deviceId, "smokedetector"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, getBooleanValueFromElements(element, "IsSmokeAlarm") ? new StringType("ON") : new StringType("OFF")); logger.debug("Updated item '{}' to '{}'", itemName, getBooleanValueFromElements(element, "IsSmokeAlarm") ? "ON" : "OFF"); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "smokedetector"); } // ALARMACTUATOR } else if (LogicalDevice.Type_AlarmActuatorState.equals(deviceType)) { String itemName = provider.getItemNameByIdAndParam(deviceId, "alarm"); if (itemName != null) { State newState = getBooleanValueFromElements(element, "IsOn") ? OnOffType.ON : OnOffType.OFF; if (!isEcho(itemName, newState.toString())) { context.getEventPublisher().postUpdate(itemName, newState); logger.debug("Updated item '{}' to '{}'", itemName, newState); } } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "alarm"); } // GENERICACTUATOR } else if (LogicalDevice.Type_GenericDeviceState.equals(deviceType)) { // load the properties NodeList pptnodes = element.getElementsByTagName("Ppt"); HashMap<String, String> cache = new HashMap<String, String>(); for (int j = 0; j < pptnodes.getLength(); j++) { String name = getTextValueFromAttribute((Element) pptnodes.item(j), "Name"); String value = getTextValueFromAttribute((Element) pptnodes.item(j), "Value"); cache.put(name, value); } // VARIABLE if (cache.get("Value") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "variable"); if (itemName != null) { State newState = "True".equals(cache.get("Value")) ? OnOffType.ON : OnOffType.OFF; if (!isEcho(itemName, newState.toString())) { context.getEventPublisher().postUpdate(itemName, newState); logger.debug("Updated item '{}' to '{}'", itemName, newState); } } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "variable"); } // POWERCONTROLSOLAR // powerinwatt } else if (cache.get("PowerInWatt") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "powerinwatt"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("PowerInWatt"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("PowerInWatt")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "powerinwatt"); } } // totalenergy if (cache.get("TotalEnergy") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "totalenergy"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("TotalEnergy"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("TotalEnergy")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "totalenergy"); } } // energypermonthinkwh if (cache.get("EnergyPerMonthInKWh") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "energypermonthinkwh"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("EnergyPerMonthInKWh"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("EnergyPerMonthInKWh")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "energypermonthinkwh"); } } // energypermonthineuro if (cache.get("EnergyPerMonthInEuro") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "energypermonthineuro"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("EnergyPerMonthInEuro"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("EnergyPerMonthInEuro")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "energypermonthineuro"); } } // energyperdayinkwh if (cache.get("EnergyPerDayInKWh") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "energyperdayinkwh"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("EnergyPerDayInKWh"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("EnergyPerDayInKWh")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "energyperdayinkwh"); } } // energyperdayineuro if (cache.get("EnergyPerDayInEuro") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "energyperdayineuro"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("EnergyPerDayInEuro"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("EnergyPerDayInEuro")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "energyperdayineuro"); } } // POWERCONTROL // powerinwatt if (cache.get("PowerConsumptionWatt") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "powerinwatt"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("PowerConsumptionWatt"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("PowerConsumptionWatt")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "powerinwatt"); } } // totalenergy if (cache.get("AbsoluteEnergyConsumption") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "totalenergy"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("AbsoluteEnergyConsumption"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("AbsoluteEnergyConsumption")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "totalenergy"); } } // energypermonthinkwh if (cache.get("EnergyConsumptionMonthKWh") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "energypermonthinkwh"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("EnergyConsumptionMonthKWh"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("EnergyConsumptionMonthKWh")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "energypermonthinkwh"); } } // energypermonthineuro if (cache.get("EnergyConsumptionMonthEuro") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "energypermonthineuro"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("EnergyConsumptionMonthEuro"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("EnergyConsumptionMonthEuro")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "energypermonthineuro"); } } // energyperdayinkwh if (cache.get("EnergyConsumptionDayKWh") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "energyperdayinkwh"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("EnergyConsumptionDayKWh"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("EnergyConsumptionDayKWh")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "energyperdayinkwh"); } } // energyperdayineuro if (cache.get("EnergyConsumptionDayEuro") != null) { String itemName = provider.getItemNameByIdAndParam(deviceId, "energyperdayineuro"); if (itemName != null) { context.getEventPublisher().postUpdate(itemName, new DecimalType(cache.get("EnergyConsumptionDayEuro"))); logger.debug("Updated item '{}' to '{}'", itemName, cache.get("EnergyConsumptionDayEuro")); } else { logger.debug("Updated item {} [{},{}] ignored.", deviceType, deviceId, "energyperdayineuro"); } } } else { logger.debug("Updated itemtype {} [{}] not supported - ignored.", deviceType, deviceId); } } } } catch (SAXException ex) { logger.debug(ex.getMessage(), ex); } catch (IOException ex) { logger.debug(ex.getMessage(), ex); } catch (ParserConfigurationException ex) { logger.debug(ex.getMessage(), ex); } } /** * Checks if the update is just an echo of a command, we already sent to RWE. * * @param itemName * @param newState * @return */ private boolean isEcho(String itemName, String newState) { String ignoreEventListKey = itemName + newState; // Check eventlist and remove all items older than 15 seconds for (String key : context.getIgnoreEventList().keySet()) { if ((System.currentTimeMillis() - context.getIgnoreEventList().get(key)) > 15000) { context.getIgnoreEventList().remove(key); logger.debug("Ignorelist: removed ghost entry '{}'", key); } } if (context.getIgnoreEventList().remove(ignoreEventListKey) != null) { logger.debug("We sent this event (item='{}', command='{}') to RWE, so we don't handle it again -> ignore!", itemName, newState); return true; } else { logger.debug("Event (item='{}', command='{}') is not an echo!", itemName, newState); return false; } } }