use of org.openhab.binding.zwave.internal.protocol.ZWaveNode in project openhab1-addons by openhab.
the class ZWaveIndicatorConverter method handleEvent.
/**
* {@inheritDoc}
*
* Process Z-Wave Indicator Report events. Apply any pending changes (see receiveCommand) and if
* indicator is changed in any way issue an INDICATOR_SET message to update the node's indicator value
*/
@Override
public void handleEvent(ZWaveCommandClassValueEvent event, Item item, Map<String, String> arguments) {
ZWaveStateConverter<?, ?> converter = this.getStateConverter(item, event.getValue());
if (converter == null) {
logger.warn("NODE {}: No converter found for item = {}, ignoring event.", event.getNodeId(), item.getName());
return;
}
if (!arguments.containsKey("bit")) {
logger.error("NODE {}: You must specify an Indicator bit for item = {}, ignoring event.", event.getNodeId(), item.getName());
return;
}
int bit = Integer.parseInt(arguments.get("bit"));
ZWaveIndicatorCommandClassChangeEvent e = (ZWaveIndicatorCommandClassChangeEvent) event;
// Get INDICATOR Command Class to check if node supports it and later to generate the INDICATOR_SET message
// to the node to set the new indicator value
ZWaveNode node = this.getController().getNode(event.getNodeId());
ZWaveIndicatorCommandClass commandClass = (ZWaveIndicatorCommandClass) node.getCommandClass(CommandClass.INDICATOR);
if (commandClass == null) {
logger.warn("NODE {}: Indicator command Class not supported for Item = {}, ignoring event.", event.getNodeId(), item.getName());
return;
}
// Assume no changes and get the actual indicator value just received from the node
boolean madeChanges = false;
int indicator = (Integer) e.getValue();
logger.warn(String.format("NODE %d: Processing Indicator Event for Item %s indicator = 0x%02X, bit = %d.", event.getNodeId(), item.getName(), indicator, bit));
// Check if the bound bit is ON (1) or OFF (0)
int isOn = (((byte) indicator) >> bit) & 0x01;
// Check for pending changes from previous receiveCommand() method calls
if (pending.containsKey(item.getName())) {
if (pending.get(item.getName()).containsKey(bit)) {
logger.warn(String.format("NODE %d: There are pending changes to Item %s bit = %d", event.getNodeId(), item.getName(), bit));
// check if there are any pending set to ON for the bound bit, and if the current bit value is OFF
if (pending.get(item.getName()).get(bit) == PENDING_ON && isOn == OFF) {
// Set bit to ON in current indicator value
byte buttonMask = (byte) (0x01 << bit);
indicator = (byte) (indicator | buttonMask);
HashMap<Integer, Integer> h = new HashMap<Integer, Integer>();
h.put(bit, NO_PENDING_CHANGES);
pending.put(item.getName(), h);
madeChanges = true;
logger.warn(String.format("NODE %d: Item %s indicator = 0x%02X, Set bit = %d to ON - DONE", event.getNodeId(), item.getName(), indicator, bit));
}
if (pending.get(item.getName()).get(bit) == PENDING_OFF && isOn == ON) {
// Set bit to OFF in current indicator value
byte buttonMask = (byte) ~(0x01 << bit);
indicator = (byte) (indicator & buttonMask);
HashMap<Integer, Integer> h = new HashMap<Integer, Integer>();
h.put(bit, NO_PENDING_CHANGES);
pending.put(item.getName(), h);
madeChanges = true;
logger.warn(String.format("NODE %d: Item %s indicator = 0x%02X, Set bit = %d to OFF - DONE", event.getNodeId(), item.getName(), indicator, bit));
}
// Check if changes were made send an INDICATOR_SET message to update the node's indicator value
if (madeChanges) {
// recalculate because we made changes to Indicator
isOn = (((byte) indicator) >> bit) & 0x01;
// Create an Indicator SET message and send it to the node
SerialMessage serialMessage = node.encapsulate(commandClass.setValueMessage(indicator), commandClass, 0);
if (serialMessage == null) {
logger.warn("NODE {}: Generating message failed for command class = {}, endpoint = {}", node.getNodeId(), commandClass.getCommandClass().getLabel());
return;
}
this.getController().sendData(serialMessage);
logger.warn(String.format("NODE %d: Item %s indicator = 0x%02X, Send pending operations to node", event.getNodeId(), item.getName(), indicator, bit));
}
} else {
logger.warn(String.format("NODE %d: No pending indicator changes to Item %s bit = %d", event.getNodeId(), item.getName(), bit));
}
} else {
logger.warn(String.format("NODE %d: No pending Indicator changes to Item %s bit = %d", event.getNodeId(), item.getName(), bit));
}
if (isOn == ON) {
this.getEventPublisher().postUpdate(item.getName(), converter.convertFromValueToState(0xFF));
} else {
this.getEventPublisher().postUpdate(item.getName(), converter.convertFromValueToState(0x00));
}
}
use of org.openhab.binding.zwave.internal.protocol.ZWaveNode in project openhab1-addons by openhab.
the class ZWaveConverterHandler method executeRefresh.
/**
* 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.
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.getNodeState() != ZWaveNodeState.ALIVE || node.isInitializationComplete() == false) {
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());
SerialMessage serialMessage = converter.executeRefresh(node, commandClass, bindingConfiguration.getEndpoint(), bindingConfiguration.getArguments());
if (serialMessage == null) {
logger.warn("NODE {}: Generating message failed for command class = {}", node.getNodeId(), commandClass.getCommandClass().getLabel());
return;
}
// This is a poll - treat it as a low priority!
serialMessage.setPriority(SerialMessagePriority.Poll);
// Queue the message
this.controller.sendData(serialMessage);
}
use of org.openhab.binding.zwave.internal.protocol.ZWaveNode in project openhab1-addons by openhab.
the class ZWaveConverterHandler method receiveCommand.
/**
* 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());
if (node == null) {
logger.error("Item {} has non existant node {}", itemName, bindingConfiguration.getNodeId());
return;
}
ZWaveCommandClass commandClass;
String commandClassName = bindingConfiguration.getArguments().get("command");
if (commandClassName != null) {
if (node.getNodeId() == this.controller.getOwnNodeId() && commandClassName.equalsIgnoreCase("switch_all")) {
commandClass = ZWaveCommandClass.getInstance(0x27, node, this.controller);
} else {
commandClass = node.resolveCommandClass(CommandClass.getCommandClass(commandClassName), bindingConfiguration.getEndpoint());
if (commandClass == null) {
logger.warn("NODE {}: No command class found for item = {}. Class = {}({}), endpoint = {}. Ignoring command.", node.getNodeId(), itemName, commandClassName, CommandClass.getCommandClass(commandClassName).toString(), bindingConfiguration.getEndpoint());
return;
}
}
} else {
commandClass = resolveConverter(provider.getItem(itemName), node, bindingConfiguration.getEndpoint());
}
if (commandClass == null) {
logger.warn("NODE {}: No converter found for item = {}, ignoring command.", node.getNodeId(), itemName);
return;
}
ZWaveCommandClassConverter<ZWaveCommandClass> converter = (ZWaveCommandClassConverter<ZWaveCommandClass>) getConverter(commandClass.getCommandClass());
if (converter == null) {
logger.warn("NODE {}: No converter found for item = {}, ignoring command.", node.getNodeId(), itemName);
return;
}
converter.receiveCommand(provider.getItem(itemName), command, node, commandClass, bindingConfiguration.getEndpoint(), bindingConfiguration.getArguments());
}
use of org.openhab.binding.zwave.internal.protocol.ZWaveNode in project openhab1-addons by openhab.
the class ZWaveConfiguration method ZWaveIncomingEvent.
/**
* Event handler method for incoming Z-Wave events.
*
* @param event
* the incoming Z-Wave event.
*/
@Override
public void ZWaveIncomingEvent(ZWaveEvent event) {
if (event instanceof ZWaveConfigurationParameterEvent) {
// Write the node to disk
ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
nodeSerializer.SerializeNode(zController.getNode(event.getNodeId()));
// We've received an updated configuration parameter
// See if this is something in our 'pending' list and remove it
PendingCfg.Remove(ZWaveCommandClass.CommandClass.CONFIGURATION.getKey(), event.getNodeId(), ((ZWaveConfigurationParameterEvent) event).getParameter().getIndex());
return;
}
if (event instanceof ZWaveAssociationEvent) {
// Write the node to disk
ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
nodeSerializer.SerializeNode(zController.getNode(event.getNodeId()));
// See if this is something in our 'pending' list and remove it
for (ZWaveNode node : zController.getNodes()) {
PendingCfg.Remove(ZWaveCommandClass.CommandClass.ASSOCIATION.getKey(), event.getNodeId(), ((ZWaveAssociationEvent) event).getGroup(), node.getNodeId());
}
return;
}
if (event instanceof ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) {
// We only care about the wake-up report
if (((ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) event).getEvent() != ZWaveWakeUpCommandClass.WAKE_UP_INTERVAL_REPORT) {
return;
}
// Write the node to disk
ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
nodeSerializer.SerializeNode(zController.getNode(event.getNodeId()));
// Remove this node from the pending list
PendingCfg.Remove(ZWaveCommandClass.CommandClass.WAKE_UP.getKey(), event.getNodeId());
return;
}
if (event instanceof ZWaveSwitchAllCommandClass.ZWaveSwitchAllModeEvent) {
ZWaveSwitchAllCommandClass.ZWaveSwitchAllModeEvent e = (ZWaveSwitchAllCommandClass.ZWaveSwitchAllModeEvent) event;
// Write the node to disk
ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
nodeSerializer.SerializeNode(zController.getNode(event.getNodeId()));
// Remove this node from the pending list
PendingCfg.Remove(ZWaveCommandClass.CommandClass.SWITCH_ALL.getKey(), e.getNodeId());
return;
}
if (event instanceof ZWaveInclusionEvent) {
handleInclusionEvent((ZWaveInclusionEvent) event);
}
}
use of org.openhab.binding.zwave.internal.protocol.ZWaveNode in project openhab1-addons by openhab.
the class ApplicationUpdateMessageClass method handleRequest.
@Override
public boolean handleRequest(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) {
int nodeId;
boolean result = true;
UpdateState updateState = UpdateState.getUpdateState(incomingMessage.getMessagePayloadByte(0));
switch(updateState) {
case NODE_INFO_RECEIVED:
// We've received a NIF, and this contains the node ID.
nodeId = incomingMessage.getMessagePayloadByte(1);
logger.debug("NODE {}: Application update request. Node information received.", nodeId);
int length = incomingMessage.getMessagePayloadByte(2);
ZWaveNode node = zController.getNode(nodeId);
if (node == null) {
logger.debug("NODE {}: Application update request. Node not known!", nodeId);
// This allows everyone to be notified.
if (nodeId > 0 && nodeId <= 232) {
zController.notifyEventListeners(new ZWaveInclusionEvent(ZWaveInclusionEvent.Type.IncludeDone, incomingMessage.getMessagePayloadByte(2)));
}
break;
}
node.resetResendCount();
// Remember that we've received this so we can continue initialisation
node.setApplicationUpdateReceived(true);
// If we're finished initialisation, then we can treat this like a HAIL
if (node.getNodeInitializationStage() == ZWaveNodeInitStage.DONE) {
// If this node supports associations, then assume this should be handled through that mechanism
if (node.getCommandClass(CommandClass.ASSOCIATION) == null) {
// If we receive an Application Update Request and the node is already
// fully initialised we assume this is a request to the controller to
// re-get the current node values
logger.debug("NODE {}: Application update request. Requesting node state.", nodeId);
zController.pollNode(node);
}
} else {
List<Integer> nif = new ArrayList<Integer>();
for (int i = 6; i < length + 3; i++) {
int data = incomingMessage.getMessagePayloadByte(i);
if (data == 0xef) {
// TODO: Implement control command classes
break;
}
logger.trace(String.format("NODE %d: Command class 0x%02X is supported.", nodeId, data));
// See if the command class already exists on the node
CommandClass commandClass = CommandClass.getCommandClass(data);
if (node.getCommandClass(commandClass) == null) {
// add it
ZWaveCommandClass zwaveCommandClass = ZWaveCommandClass.getInstance(data, node, zController);
if (zwaveCommandClass != null) {
logger.trace(String.format("NODE %d: Application update request. Adding Command class %s.", nodeId, commandClass));
node.addCommandClass(zwaveCommandClass);
}
}
}
node.updateNIF(nif);
}
// Notify we received an info frame
zController.notifyEventListeners(new ZWaveNodeInfoEvent(nodeId));
// Treat the node information frame as a wakeup
ZWaveWakeUpCommandClass wakeUp = (ZWaveWakeUpCommandClass) node.getCommandClass(ZWaveCommandClass.CommandClass.WAKE_UP);
if (wakeUp != null) {
wakeUp.setAwake(true);
}
break;
case NODE_INFO_REQ_FAILED:
// Make sure we can correlate the request before we use the nodeId
if (lastSentMessage.getMessageClass() != SerialMessageClass.RequestNodeInfo) {
logger.warn("Got ApplicationUpdateMessage without request, ignoring. Last message was {}.", lastSentMessage.getMessageClass());
return false;
}
// The failed message doesn't contain the node number, so use the info from the request.
nodeId = lastSentMessage.getMessageNode();
logger.debug("NODE {}: Application update request. Node Info Request Failed.", nodeId);
// Handle retries
if (--lastSentMessage.attempts >= 0) {
logger.error("NODE {}: Got Node Info Request Failed. Requeueing", nodeId);
zController.enqueue(lastSentMessage);
} else {
logger.warn("NODE {}: Node Info Request Failed 3x. Discarding message: {}", nodeId, lastSentMessage.toString());
}
// Transaction is not successful
incomingMessage.setTransactionCanceled();
result = false;
break;
default:
logger.warn("TODO: Implement Application Update Request Handling of {} ({}).", updateState.getLabel(), updateState.getKey());
}
// Check if this completes the transaction
checkTransactionComplete(lastSentMessage, incomingMessage);
return result;
}
Aggregations