/** * 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.zwave.internal.converter; import java.util.HashMap; import java.util.Map; import org.openhab.binding.zwave.internal.converter.state.BooleanOnOffTypeConverter; import org.openhab.binding.zwave.internal.converter.state.BooleanOpenClosedTypeConverter; import org.openhab.binding.zwave.internal.converter.state.DateDateTimeTypeConverter; import org.openhab.binding.zwave.internal.converter.state.IntegerDecimalTypeConverter; import org.openhab.binding.zwave.internal.converter.state.IntegerPercentTypeConverter; import org.openhab.binding.zwave.internal.converter.state.StringStringTypeConverter; import org.openhab.binding.zwave.internal.converter.state.ZWaveStateConverter; import org.openhab.binding.zwave.internal.protocol.ZWaveController; import org.openhab.binding.zwave.internal.protocol.ZWaveNode; import org.openhab.core.events.EventPublisher; import org.openhab.core.items.Item; import org.openhab.core.types.State; import org.openhab.core.types.UnDefType; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * ZWaveInfoConverter class. Converters between binding items * and the Z-Wave API to gather statistic information. * * @author Jan-Willem Spuij * @since 1.4.0 */ public class ZWaveInfoConverter extends ZWaveConverterBase { private static final Logger logger = LoggerFactory.getLogger(ZWaveInfoConverter.class); private static final int REFRESH_INTERVAL = 10; // refresh interval in seconds /** * Constructor. Creates a new instance of the {@link ZWaveConverterBase} * class. * * @param controller the {@link ZWaveController} to use to send messages. * @param eventPublisher the {@link EventPublisher} that can be used to send updates. */ public ZWaveInfoConverter(ZWaveController controller, EventPublisher eventPublisher) { super(controller, eventPublisher); // State converters used by this converter. this.addStateConverter(new StringStringTypeConverter()); this.addStateConverter(new DateDateTimeTypeConverter()); this.addStateConverter(new IntegerDecimalTypeConverter()); this.addStateConverter(new IntegerPercentTypeConverter()); this.addStateConverter(new BooleanOnOffTypeConverter()); this.addStateConverter(new BooleanOpenClosedTypeConverter()); } /** * Execute refresh method. This method is called every time a binding item is * refreshed and information for the corresponding node should be looked up. * * @param item the item to refresh. * @param node the {@link ZWaveNode} that is bound to the item. * @param endpointId the endpoint id to send the message. * @param arguments the arguments for the converter. */ public void executeRefresh(Item item, ZWaveNode node, int endpointId, Map<String, String> arguments) { if (item == null) { return; } // not bound to an item. if (!arguments.containsKey("item")) { return; } ZWaveInformationItem informationItem = ZWaveInformationItem.getZWaveBindingAction(arguments.get("item")); // item not recognized. if (informationItem == null) { logger.warn("Incorrect information item specified. item name = {}", arguments.get("item")); return; } State state = UnDefType.UNDEF; // extract the appropriate information value Object value = getInformationItemValue(node, informationItem); if (value != null) { ZWaveStateConverter<?, ?> converter = this.getStateConverter(item, value); if (converter == null) { logger.warn("No converter found for item = {}, node = {} endpoint = {}, ignoring event.", item.getName(), node.getNodeId(), endpointId); return; } state = converter.convertFromValueToState(value); } this.getEventPublisher().postUpdate(item.getName(), state); } /** * {@inheritDoc} */ @Override int getRefreshInterval() { return REFRESH_INTERVAL; } private Object getInformationItemValue(ZWaveNode node, ZWaveInformationItem informationItem) { switch (informationItem) { case REPORT_HOMEID: return String.format("0x%08x", node.getHomeId()); case REPORT_NODEID: return node.getNodeId(); case REPORT_MANUFACTURER: return String.format("0x%04x", node.getManufacturer()); case REPORT_DEVICE_TYPE: return String.format("0x%04x", node.getDeviceType()); case REPORT_DEVICE_ID: return String.format("0x%04x", node.getDeviceId()); case REPORT_BASIC: return String.format("0x%02x", node.getDeviceClass().getBasicDeviceClass().getKey()); case REPORT_BASIC_LABEL: return node.getDeviceClass().getBasicDeviceClass().getLabel(); case REPORT_GENERIC: return String.format("0x%02x", node.getDeviceClass().getGenericDeviceClass().getKey()); case REPORT_GENERIC_LABEL: return node.getDeviceClass().getGenericDeviceClass().getLabel(); case REPORT_SPECIFIC: return String.format("0x%02x", node.getDeviceClass().getSpecificDeviceClass().getKey()); case REPORT_SPECIFIC_LABEL: return node.getDeviceClass().getSpecificDeviceClass().getLabel(); case REPORT_VERSION: return node.getVersion(); case REPORT_ROUTING: return node.isRouting(); case REPORT_LISTENING: return node.isListening(); case REPORT_DEAD: return node.isDead(); case REPORT_LASTUPDATE: return node.getLastReceived(); case REPORT_NAK: return this.getController().getNAKCount(); case REPORT_SOF: return this.getController().getSOFCount(); case REPORT_CAN: return this.getController().getCANCount(); case REPORT_ACK: return this.getController().getACKCount(); case REPORT_OOF: return this.getController().getOOFCount(); case REPORT_TIME_OUT: return this.getController().getTimeOutCount(); case REPORT_TX_QUEUE: return this.getController().getSendQueueLength(); } return null; } /** * Z-Wave information item enumeration. It Defines the information that can be * requested by the binding on the item. * * @author Jan-Willem Spuij * @author Brian Crosby * @since 1.3.0 */ public enum ZWaveInformationItem { /** * Reports the Home ID. */ REPORT_HOMEID("HOME_ID"), /** * Reports the Node ID. */ REPORT_NODEID("NODE_ID"), /** * Reports whether the node is listening. */ REPORT_LISTENING("LISTENING"), /** * Reports whether the node is dead or not. */ REPORT_DEAD("DEAD"), /** * Reports whether the node is routing Z-Wave messages. */ REPORT_ROUTING("ROUTING"), /** * Reports Node version. */ REPORT_VERSION("VERSION"), /** * Reports the basic device class of the node (in hex). */ REPORT_BASIC("BASIC"), /** * Reports the basic device class of the node (as text). */ REPORT_BASIC_LABEL("BASIC_LABEL"), /** * Reports the Generic device class of the node (in hex). */ REPORT_GENERIC("GENERIC"), /** * Reports the Generic device class of the node (as text). */ REPORT_GENERIC_LABEL("GENERIC_LABEL"), /** * Reports the Specific device class of the node (in hex). */ REPORT_SPECIFIC("SPECIFIC"), /** * Reports the Specific device class of the node (as text). */ REPORT_SPECIFIC_LABEL("SPECIFIC_LABEL"), /** * Reports the manufacturer of the node. */ REPORT_MANUFACTURER("MANUFACTURER"), /** * Reports the Device type of the node (in hex). */ REPORT_DEVICE_ID("DEVICE_ID"), /** * Reports the Device type of the node (as text). */ REPORT_DEVICE_TYPE("DEVICE_TYPE"), /** * Reports the date / time the node value was last updated. */ REPORT_LASTUPDATE("LAST_UPDATE"), /** * Reports the amount of Start of frames this node has received. */ REPORT_SOF("SOF"), /** * Reports the amount of Canceled frames this node has received. */ REPORT_CAN("CAN"), /** * Reports the amount of not acknowledged frames this node has received. */ REPORT_NAK("NAK"), /** * Reports the amount of out of order frames this node has received. */ REPORT_OOF("OOF"), /** * Reports the amount of out of acknowledged frames this node has received. */ REPORT_ACK("ACK"), /** * Reports the amount of out of timed out packets this node has received. */ REPORT_TIME_OUT("TIME_OUT"), /** * Reports the total number of frames in the transmit queue(s) */ REPORT_TX_QUEUE("TX_QUEUE"); private String label; private static Map<String, ZWaveInformationItem> labelToZWaveInfoItemMapping; private ZWaveInformationItem(String label) { this.label = label; } private static void initMapping() { labelToZWaveInfoItemMapping = new HashMap<String, ZWaveInformationItem>(); for (ZWaveInformationItem s : values()) { labelToZWaveInfoItemMapping.put(s.label.toLowerCase(), s); } } /** * Returns the label of the ZWaveInformationItem enumeration * * @return the label */ public String getLabel() { return label; } /** * Lookup function based on the binding information label. * Returns null if the binding information item is not found. * * @param label the label to lookup * @return enumeration value of the binding information item. */ public static ZWaveInformationItem getZWaveBindingAction(String label) { if (labelToZWaveInfoItemMapping == null) { initMapping(); } return labelToZWaveInfoItemMapping.get(label.toLowerCase()); } } }