/** * Receives a command from openHAB and translates it to an operation on the Z-Wave network. * * @param provider the {@link ZWaveBindingProvider} that provides the item * @param itemName the name of the item that will receive the event. * @param command the received {@link Command} */ @SuppressWarnings("unchecked") public void receiveCommand(ZWaveBindingProvider provider, String itemName, Command command) { ZWaveBindingConfig bindingConfiguration = provider.getZwaveBindingConfig(itemName); ZWaveNode node = this.controller.getNode(bindingConfiguration.getNodeId()); ZWaveCommandClass commandClass; String commandClassName = bindingConfiguration.getArguments().get("command"); // ignore nodes that are not initialized or dead. if (node.getNodeStage() != NodeStage.DONE) return; if (commandClassName != null) { commandClass = node.resolveCommandClass( CommandClass.getCommandClass(commandClassName), bindingConfiguration.getEndpoint()); if (commandClass == null) { logger.warn( "No command class found for item = {}, command class name = {}, ignoring command.", itemName, commandClassName); return; } } else { commandClass = resolveConverter(provider.getItem(itemName), node, bindingConfiguration.getEndpoint()); } if (commandClass == null) { logger.warn("No converter found for item = {}, ignoring command.", itemName); return; } ZWaveCommandClassConverter<ZWaveCommandClass> converter = (ZWaveCommandClassConverter<ZWaveCommandClass>) getConverter(commandClass.getCommandClass()); if (converter == null) { logger.warn("No converter found for item = {}, ignoring command.", itemName); return; } converter.receiveCommand( provider.getItem(itemName), command, node, commandClass, bindingConfiguration.getEndpoint(), bindingConfiguration.getArguments()); }
/** * Adds a command class to the list of supported command classes by this endpoint. Does nothing if * command class is already added. * * @param commandClass the command class instance to add. */ public void addCommandClass(ZWaveCommandClass commandClass) { CommandClass key = commandClass.getCommandClass(); if (!supportedCommandClasses.containsKey(key)) { supportedCommandClasses.put(key, commandClass); } }
/** * Returns the command class that provides the best suitable converter to convert between the * Z-Wave API and the binding. * * @param item the {@link item} to resolve a converter for. * @param node the {@link ZWaveNode} node to resolve a Command class on. * @param the enpoint ID to use to resolve a converter. * @return the {@link ZWaveCommandClass} that can be used to get a converter suitable to do the * conversion. */ private ZWaveCommandClass resolveConverter(Item item, ZWaveNode node, int endpointId) { if (item == null) return null; ZWaveMultiInstanceCommandClass multiInstanceCommandClass = null; ZWaveCommandClass result = null; if (endpointId != 1) multiInstanceCommandClass = (ZWaveMultiInstanceCommandClass) node.getCommandClass(CommandClass.MULTI_INSTANCE); if (!preferredCommandClasses.containsKey(item.getClass())) { logger.warn( "No preferred command classes found for item class = {}", item.getClass().toString()); return null; } for (CommandClass commandClass : preferredCommandClasses.get(item.getClass())) { if (multiInstanceCommandClass != null && multiInstanceCommandClass.getVersion() == 2) { ZWaveEndpoint endpoint = multiInstanceCommandClass.getEndpoint(endpointId); if (endpoint != null) { result = endpoint.getCommandClass(commandClass); } } if (result == null) result = node.getCommandClass(commandClass); if (result == null) continue; if (multiInstanceCommandClass != null && multiInstanceCommandClass.getVersion() == 1 && result.getInstances() < endpointId) continue; if (converters.containsKey(commandClass)) return result; } logger.warn( "No matching command classes found for item class = {}, node id = {}, endpoint id = {}", item.getClass().toString(), node.getNodeId(), endpointId); return null; }
/** * Execute refresh method. This method is called every time a binding item is refreshed and the * corresponding node should be sent a message. * * @param provider the {@link ZWaveBindingProvider} that provides the item * @param itemName the name of the item to poll. * @param forceRefresh indicates that a polling refresh should be forced. */ @SuppressWarnings("unchecked") public void executeRefresh(ZWaveBindingProvider provider, String itemName, boolean forceRefresh) { ZWaveBindingConfig bindingConfiguration = provider.getZwaveBindingConfig(itemName); ZWaveCommandClass commandClass; String commandClassName = bindingConfiguration.getArguments().get("command"); // this binding is configured not to poll. if (!forceRefresh && bindingConfiguration.getRefreshInterval() != null && 0 == bindingConfiguration.getRefreshInterval()) return; ZWaveNode node = this.controller.getNode(bindingConfiguration.getNodeId()); // ignore nodes that are not initialized or dead. if (node == null) return; if (commandClassName != null) { // this is a report item, handle it with the report info converter. if (commandClassName.equalsIgnoreCase("info")) { infoConverter.executeRefresh( provider.getItem(itemName), node, bindingConfiguration.getEndpoint(), bindingConfiguration.getArguments()); return; } // ignore nodes that are not initialized or dead. if (node.getNodeStage() != NodeStage.DONE) return; commandClass = node.resolveCommandClass( CommandClass.getCommandClass(commandClassName), bindingConfiguration.getEndpoint()); if (commandClass == null) { logger.warn( "No command class found for item = {}, command class name = {}, ignoring execute refresh.", itemName, commandClassName); return; } } else { commandClass = resolveConverter(provider.getItem(itemName), node, bindingConfiguration.getEndpoint()); } if (commandClass == null) { logger.warn("No converter found for item = {}, ignoring execute refresh.", itemName); return; } ZWaveCommandClassConverter<ZWaveCommandClass> converter = (ZWaveCommandClassConverter<ZWaveCommandClass>) getConverter(commandClass.getCommandClass()); if (converter == null) { logger.warn("No converter found for item = {}, ignoring execute refresh.", itemName); return; } if (bindingConfiguration.getRefreshInterval() == null) { bindingConfiguration.setRefreshInterval(converter.getRefreshInterval()); // this binding is configured not to poll. if (!forceRefresh && 0 == bindingConfiguration.getRefreshInterval()) return; } // not enough time has passed to refresh the item. if (!forceRefresh && bindingConfiguration.getLastRefreshed() != null && (bindingConfiguration.getLastRefreshed().getTime() + (bindingConfiguration.getRefreshInterval() * 1000) > Calendar.getInstance().getTimeInMillis())) return; bindingConfiguration.setLastRefreshed(Calendar.getInstance().getTime()); converter.executeRefresh( node, commandClass, bindingConfiguration.getEndpoint(), bindingConfiguration.getArguments()); }