use of org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass in project openhab1-addons by openhab.
the class ZWaveNetworkMonitor method nextHealStage.
/**
* Perform the next step in the heal process. This function also handles the
* retries. Each time through the loop it increments the retry counter. If
* the max retries is exceeded then the failed state is saved and we return
* to allow other nodes to continue.
*
* @param healing
* The node on which to perform the heal
*/
private void nextHealStage(HealNode healing) {
// Don't do anything if it's failed already
if (healing.state == HealState.FAILED) {
return;
}
healing.lastChange = Calendar.getInstance().getTime();
// Set the ping time into the future.
// This holds off the routine ping when there's a heal in progress
// to avoid congestion and false timeouts.
pingNodeTime = System.currentTimeMillis() + HEAL_TIMEOUT_PERIOD + 20000;
// Set the timeout
networkHealNextTime = System.currentTimeMillis() + HEAL_TIMEOUT_PERIOD;
// Only do something if the node is awake!
ZWaveNode node = zController.getNode(healing.nodeId);
if (node != null) {
ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.WAKE_UP);
if (wakeupCommandClass != null && wakeupCommandClass.isAwake() == false) {
// Device is asleep - don't do anything now!
logger.debug("NODE {}: Node is asleep. Defer heal until it's awake", healing.nodeId);
return;
}
}
// Handle retries
healing.retryCnt++;
if (healing.retryCnt >= HEAL_MAX_RETRIES) {
logger.debug("NODE {}: Maximum retries in state {}", healing.nodeId, healing.state);
// continue with the heal than to abort here.
if (healing.state == HealState.UPDATENEIGHBORS) {
healing.state = healing.stateNext;
healing.retryCnt = 0;
logger.debug("NODE {}: Heal - continuing to state {}", healing.nodeId, healing.stateNext);
} else {
logger.debug("NODE {}: Network heal has exceeded maximum retries!", healing.nodeId);
healing.failState = healing.state;
healing.state = HealState.FAILED;
// Save the XML file. This serialises the data we've just updated
// (neighbors etc)
healing.node.setHealState(this.getNodeState(healing.node.getNodeId()));
ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
nodeSerializer.SerializeNode(healing.node);
return;
}
}
// Set the timeout
networkHealNextTime = System.currentTimeMillis() + HEAL_TIMEOUT_PERIOD;
switch(healing.state) {
case WAITING:
// Log what we're up to...
logger.debug("NODE {}: NETWORK HEAL - STARTING", healing.nodeId);
// Reset the resend count.
// This also resets the time so that we cycle through all the nodes
healing.node.resetResendCount();
healing.state = HealState.PING;
case PING:
// Log what we're up to...
logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state);
if (healing.nodeId != zController.getOwnNodeId()) {
healing.state = HealState.PING;
ZWaveNoOperationCommandClass zwaveCommandClass = (ZWaveNoOperationCommandClass) healing.node.getCommandClass(CommandClass.NO_OPERATION);
if (zwaveCommandClass != null) {
zController.sendData(zwaveCommandClass.getNoOperationMessage());
healing.stateNext = HealState.SETSUCROUTE;
break;
}
}
healing.state = HealState.SETSUCROUTE;
case SETSUCROUTE:
// Log what we're up to...
logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state);
// Only set the route if this is not the controller and there is an SUC in the network
if (healing.nodeId != zController.getOwnNodeId() && zController.getSucId() != 0) {
// Update the route to the controller
logger.debug("NODE {}: Heal is setting SUC route.", healing.nodeId);
healing.event = ZWaveNetworkEvent.Type.AssignSucReturnRoute;
healing.stateNext = HealState.UPDATENEIGHBORS;
zController.requestAssignSucReturnRoute(healing.nodeId);
break;
}
healing.state = HealState.UPDATENEIGHBORS;
case UPDATENEIGHBORS:
// Log what we're up to...
logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state);
healing.event = ZWaveNetworkEvent.Type.NodeNeighborUpdate;
healing.stateNext = HealState.GETASSOCIATIONS;
zController.requestNodeNeighborUpdate(healing.nodeId);
break;
case GETASSOCIATIONS:
// Log what we're up to...
logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state);
// Check if this node supports associations
ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) healing.node.getCommandClass(CommandClass.ASSOCIATION);
if (associationCommandClass != null) {
logger.debug("NODE {}: Heal is requesting device associations.", healing.nodeId);
healing.stateNext = HealState.UPDATEROUTES;
healing.event = ZWaveNetworkEvent.Type.AssociationUpdate;
associationCommandClass.getAllAssociations();
break;
}
healing.stateNext = HealState.UPDATEROUTES;
case UPDATEROUTES:
// Log what we're up to...
logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state);
// Get the list of routes for this node
healing.routeList = healing.node.getRoutingList();
if (healing.routeList != null && healing.routeList.size() != 0) {
// Delete all the return routes for the node
logger.debug("NODE {}: Heal is deleting routes.", healing.nodeId);
healing.event = ZWaveNetworkEvent.Type.DeleteReturnRoute;
healing.stateNext = HealState.UPDATEROUTESNEXT;
zController.requestDeleteAllReturnRoutes(healing.nodeId);
break;
}
healing.stateNext = HealState.UPDATEROUTESNEXT;
case UPDATEROUTESNEXT:
// Log what we're up to...
logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state);
if (healing.routeList != null && healing.routeList.size() != 0) {
// Loop through all the nodes and set the return route
logger.debug("NODE {}: Adding return route to {}", healing.nodeId, healing.routeList.get(0));
healing.stateNext = HealState.GETNEIGHBORS;
healing.event = ZWaveNetworkEvent.Type.AssignReturnRoute;
zController.requestAssignReturnRoute(healing.nodeId, healing.routeList.get(0));
break;
}
healing.stateNext = HealState.GETNEIGHBORS;
case GETNEIGHBORS:
// Log what we're up to...
logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state);
healing.event = ZWaveNetworkEvent.Type.NodeRoutingInfo;
healing.stateNext = HealState.SAVE;
logger.debug("NODE {}: Heal is requesting node neighbor info.", healing.nodeId);
zController.requestNodeRoutingInfo(healing.nodeId);
break;
case SAVE:
// Log what we're up to...
logger.debug("NODE {}: NETWORK HEAL - {}", healing.nodeId, healing.state);
healing.state = HealState.DONE;
networkHealNextTime = System.currentTimeMillis() + HEAL_DELAY_PERIOD;
// Save the XML file. This serialises the data we've just updated
// (neighbors etc)
healing.node.setHealState(this.getNodeState(healing.node.getNodeId()));
ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
nodeSerializer.SerializeNode(healing.node);
break;
default:
break;
}
healing.node.setHealState(this.getNodeState(healing.node.getNodeId()));
}
use of org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass in project openhab1-addons by openhab.
the class ZWaveConfiguration method doSet.
@Override
public void doSet(String domain, String value) {
logger.debug("doSet domain '{}' to '{}'", domain, value);
String[] splitDomain = domain.split("/");
// If the controller isn't ready, then ignore any requests
if (zController.isConnected() == false) {
logger.debug("Controller not ready - Ignoring request to '{}'", domain);
return;
}
// There must be at least 2 components to the domain
if (splitDomain.length < 2) {
logger.error("Error malformed domain in doSet '{}'", domain);
return;
}
if (splitDomain[0].equals("nodes")) {
int nodeId = Integer.parseInt(splitDomain[1].substring(4));
ZWaveNode node = zController.getNode(nodeId);
if (node == null) {
logger.error("Error finding node in doSet '{}'", domain);
return;
}
// TODO: Should we check that the node is finished initialising
ZWaveProductDatabase database = new ZWaveProductDatabase();
if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) {
logger.error("NODE {}: Error in doSet - no database found", nodeId);
return;
}
if (splitDomain.length == 3) {
if (splitDomain[2].equals("Name")) {
node.setName(value);
}
if (splitDomain[2].equals("Location")) {
node.setLocation(value);
}
if (splitDomain[2].equals("SwitchAll")) {
ZWaveSwitchAllCommandClass switchAllCommandClass = (ZWaveSwitchAllCommandClass) node.getCommandClass(CommandClass.SWITCH_ALL);
if (switchAllCommandClass == null) {
logger.error("NODE {}: Error getting switchAllCommandClass in doSet", nodeId);
return;
}
// Set the switch all mode
int mode = Integer.parseInt(value);
PendingCfg.Add(ZWaveSwitchAllCommandClass.CommandClass.SWITCH_ALL.getKey(), node.getNodeId(), 0, mode);
SerialMessage msg = switchAllCommandClass.setValueMessage(mode);
this.zController.sendData(msg);
// And request a read-back
this.zController.sendData(switchAllCommandClass.getValueMessage());
}
// Write the node to disk
ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
nodeSerializer.SerializeNode(node);
} else if (splitDomain.length == 4) {
if (splitDomain[2].equals("parameters")) {
ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node.getCommandClass(CommandClass.CONFIGURATION);
if (configurationCommandClass == null) {
logger.error("NODE {}: Error getting configurationCommandClass in doSet", nodeId);
return;
}
int paramIndex = Integer.parseInt(splitDomain[3].substring(13));
List<ZWaveDbConfigurationParameter> configList = database.getProductConfigParameters();
// Get the size
int size = 1;
for (ZWaveDbConfigurationParameter parameter : configList) {
if (parameter.Index == paramIndex) {
size = parameter.Size;
break;
}
}
logger.debug("Set parameter index '{}' to '{}'", paramIndex, value);
PendingCfg.Add(ZWaveCommandClass.CommandClass.CONFIGURATION.getKey(), nodeId, paramIndex, Integer.valueOf(value));
ConfigurationParameter configurationParameter = new ConfigurationParameter(paramIndex, Integer.valueOf(value), size);
// Set the parameter
this.zController.sendData(configurationCommandClass.setConfigMessage(configurationParameter));
// And request a read-back
this.zController.sendData(configurationCommandClass.getConfigMessage(paramIndex));
}
if (splitDomain[2].equals("wakeup")) {
ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.WAKE_UP);
if (wakeupCommandClass == null) {
logger.error("NODE {}: Error getting wakeupCommandClass in doSet", nodeId);
return;
}
logger.debug("NODE {}: Set wakeup interval to '{}'", nodeId, value);
// Add this as a pending transaction
PendingCfg.Add(ZWaveCommandClass.CommandClass.WAKE_UP.getKey(), node.getNodeId(), Integer.parseInt(value));
// Set the wake-up interval
this.zController.sendData(wakeupCommandClass.setInterval(Integer.parseInt(value)));
// And request a read-back
this.zController.sendData(wakeupCommandClass.getIntervalMessage());
}
if (splitDomain[2].equals("controller")) {
if (splitDomain[3].equals("Type")) {
ZWaveDeviceType type = ZWaveDeviceType.fromString(value);
logger.error("NODE {}: Setting controller type to {}", nodeId, type.toString());
// ZW_EnableSUC and ZW_SetSUCNodeID
}
}
} else if (splitDomain.length == 5) {
if (splitDomain[2].equals("associations")) {
ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node.getCommandClass(CommandClass.ASSOCIATION);
if (associationCommandClass == null) {
logger.error("NODE {}: Error getting associationCommandClass in doSet", nodeId);
return;
}
int assocId = Integer.parseInt(splitDomain[3].substring(11));
int assocArg = Integer.parseInt(splitDomain[4].substring(4));
if (value.equalsIgnoreCase("true")) {
PendingCfg.Add(ZWaveCommandClass.CommandClass.ASSOCIATION.getKey(), nodeId, assocId, assocArg, 1);
logger.debug("Add association index '{}' to '{}'", assocId, assocArg);
this.zController.sendData(associationCommandClass.setAssociationMessage(assocId, assocArg));
} else {
PendingCfg.Add(ZWaveCommandClass.CommandClass.ASSOCIATION.getKey(), nodeId, assocId, assocArg, 0);
logger.debug("Remove association index '{}' to '{}'", assocId, assocArg);
this.zController.sendData(associationCommandClass.removeAssociationMessage(assocId, assocArg));
}
// Request an update to the group
this.zController.sendData(associationCommandClass.getAssociationMessage(assocId));
// So, let's start a network heal - just for this node right now
if (networkMonitor != null) {
networkMonitor.startNodeHeal(nodeId);
}
}
}
}
}
use of org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass in project openhab1-addons by openhab.
the class ZWaveConfiguration method doAction.
@Override
public void doAction(String domain, String action) {
logger.trace("doAction domain '{}' to '{}'", domain, action);
String[] splitDomain = domain.split("/");
// There must be at least 2 components to the domain
if (splitDomain.length < 2) {
logger.error("Error malformed domain in doAction '{}'", domain);
return;
}
// Process Controller Reset requests even if the controller isn't initialised
if (splitDomain[0].equals("binding") && splitDomain[1].equals("network")) {
if (action.equals("SoftReset")) {
zController.requestSoftReset();
} else if (action.equals("HardReset")) {
zController.requestHardReset();
}
}
// If the controller isn't ready, then ignore any further requests
if (zController.isConnected() == false) {
logger.debug("Controller not ready - Ignoring request to '{}'", domain);
return;
}
if (splitDomain[0].equals("binding")) {
if (splitDomain[1].equals("network")) {
if (action.equals("Heal")) {
if (networkMonitor != null) {
networkMonitor.rescheduleHeal();
}
}
if (action.equals("Include") || action.equals("Exclude")) {
// Only do include/exclude if it's not already in progress
if (inclusion == false && exclusion == false) {
if (action.equals("Include")) {
inclusion = true;
zController.requestAddNodesStart();
setInclusionTimer();
}
if (action.equals("Exclude")) {
exclusion = true;
zController.requestRemoveNodesStart();
setInclusionTimer();
}
} else {
logger.debug("Exclusion/Inclusion already in progress.");
}
}
}
}
if (splitDomain[0].equals("nodes")) {
int nodeId = Integer.parseInt(splitDomain[1].substring(4));
// Get the node - if it exists
ZWaveNode node = zController.getNode(nodeId);
if (node == null) {
logger.error("NODE {}: Error finding node in doAction", nodeId);
return;
}
if (splitDomain.length == 2) {
if (action.equals("Heal")) {
logger.debug("NODE {}: Heal node", nodeId);
if (networkMonitor != null) {
networkMonitor.startNodeHeal(nodeId);
}
}
if (action.equals("Save")) {
logger.debug("NODE {}: Saving node", nodeId);
// Write the node to disk
ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
nodeSerializer.SerializeNode(node);
}
if (action.equals("Initialise")) {
logger.debug("NODE {}: re-initialising node", nodeId);
// Delete the saved XML
ZWaveNodeSerializer nodeSerializer = new ZWaveNodeSerializer();
nodeSerializer.DeleteNode(nodeId);
this.zController.reinitialiseNode(nodeId);
}
if (action.equals("Delete")) {
logger.debug("NODE {}: Delete node", nodeId);
this.zController.requestRemoveFailedNode(nodeId);
}
// in the domain array
return;
}
if (splitDomain[2].equals("parameters")) {
ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node.getCommandClass(CommandClass.CONFIGURATION);
if (configurationCommandClass == null) {
return;
}
if (action.equals("Refresh")) {
logger.debug("NODE {}: Refresh parameters", nodeId);
ZWaveProductDatabase database = new ZWaveProductDatabase();
if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) {
return;
}
List<ZWaveDbConfigurationParameter> configList = database.getProductConfigParameters();
// Request all parameters for this node
for (ZWaveDbConfigurationParameter parameter : configList) {
this.zController.sendData(configurationCommandClass.getConfigMessage(parameter.Index));
}
}
}
if (splitDomain[2].equals("wakeup")) {
if (action.equals("Refresh")) {
// Only update if we support the wakeup class
ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.WAKE_UP);
if (wakeupCommandClass == null) {
return;
}
logger.debug("NODE {}: Refresh wakeup capabilities", nodeId);
// Request the wakeup interval for this node
this.zController.sendData(wakeupCommandClass.getIntervalMessage());
// Request the wakeup parameters for this node
this.zController.sendData(wakeupCommandClass.getIntervalCapabilitiesMessage());
}
}
if (splitDomain[2].equals("neighbors")) {
if (action.equals("Refresh")) {
// this.zController.requestNodeNeighborUpdate(nodeId);
// .requestNodeNeighborUpdate(nodeId);
this.zController.requestNodeRoutingInfo(nodeId);
}
}
if (splitDomain[2].equals("associations")) {
if (action.equals("Refresh")) {
// Make sure the association class is supported
ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node.getCommandClass(CommandClass.ASSOCIATION);
if (associationCommandClass == null) {
return;
}
logger.debug("NODE {}: Refresh associations", nodeId);
ZWaveProductDatabase database = new ZWaveProductDatabase();
if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) {
logger.error("NODE {}: Error in doAction - no database found", nodeId);
return;
}
if (splitDomain.length == 3) {
// Request all groups for this node
associationCommandClass.getAllAssociations();
} else if (splitDomain.length == 4) {
// Request a single group
int nodeArg = Integer.parseInt(splitDomain[3].substring(11));
this.zController.sendData(associationCommandClass.getAssociationMessage(nodeArg));
}
}
}
}
}
use of org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass in project openhab1-addons by openhab.
the class ZWaveNodeStageAdvancer method advanceNodeStage.
/**
* Advances the initialization stage for this node. This method is called
* after a response is received. We don't necessarily know if the response
* is to the frame we requested though, so to be sure the initialisation
* gets all the information it needs, the command class itself gets queried.
* This method also handles the sending of frames. Since the initialisation
* phase is a busy one we try and only have one outstanding request. Again
* though, we can't be sure that a response is aligned with the node
* advancer request so it is possible that more than one packet can be
* released at once, but it will constrain things.
*/
public void advanceNodeStage(SerialMessageClass eventClass) {
// handler when we're done, but just to be sure...
if (currentStage == ZWaveNodeInitStage.DONE) {
return;
}
logger.debug("NODE {}: Node advancer - {}: queue length({}), free to send({})", node.getNodeId(), currentStage.toString(), msgQueue.size(), freeToSend);
// the stage, then reset.
if (wakeupCount >= 3) {
msgQueue.clear();
wakeupCount = 0;
}
// Start the retry timer
startIdleTimer();
// again.
if (eventClass == null) {
freeToSend = true;
}
// If the queue is not empty, then we can't advance any further.
if (sendMessage() == true) {
// We're still sending messages, so we're not ready to proceed.
return;
}
// The stageAdvanced flag is used to tell command classes that this
// is the first iteration.
// During the first iteration all messages are queued. After this,
// only outstanding requests are returned.
// This continues until there are no requests required.
stageAdvanced = false;
ZWaveProductDatabase database;
// Then we will wait for the response before continuing
do {
// something that is broken, or not responding to a particular request
if (stageAdvanced == true) {
retryCount = 0;
} else {
retryCount++;
if (retryCount > MAX_RETRIES) {
retryCount = 0;
logger.error("NODE {}: Node advancer: Retries exceeded at {}", node.getNodeId(), currentStage.toString());
if (currentStage.isStageMandatory() == false) {
// If the current stage is not mandatory, then we skip forward to the next
// stage.
logger.debug("NODE {}: Retry timout: Advancing", node.getNodeId());
setCurrentStage(currentStage.getNextStage());
} else {
// For static stages, we MUST complete all steps otherwise we end
// up with incomplete information about the device.
// During the static stages, we use the back off timer to pace things
// and retry until the stage is complete
logger.debug("NODE {}: Retry timout: Can't advance", node.getNodeId());
break;
}
}
}
logger.debug("NODE {}: Node advancer: loop - {} try {}: stageAdvanced({})", node.getNodeId(), currentStage.toString(), retryCount, stageAdvanced);
switch(currentStage) {
case EMPTYNODE:
logger.debug("NODE {}: Node advancer: Initialisation starting", node.getNodeId());
break;
case PROTOINFO:
// If the incoming frame is the IdentifyNode, then we continue
if (eventClass == SerialMessageClass.IdentifyNode) {
break;
}
logger.debug("NODE {}: Node advancer: PROTOINFO - send IdentifyNode", node.getNodeId());
addToQueue(new IdentifyNodeMessageClass().doRequest(node.getNodeId()));
break;
case NEIGHBORS:
// If the incoming frame is the IdentifyNode, then we continue
if (eventClass == SerialMessageClass.GetRoutingInfo) {
break;
}
logger.debug("NODE {}: Node advancer: NEIGHBORS - send RoutingInfo", node.getNodeId());
addToQueue(new GetRoutingInfoMessageClass().doRequest(node.getNodeId()));
break;
case FAILED_CHECK:
// If this is a controller, we're done
if (node.getDeviceClass().getSpecificDeviceClass() == Specific.PC_CONTROLLER) {
logger.debug("NODE {}: Node advancer: FAILED_CHECK - Controller - terminating initialisation", node.getNodeId());
currentStage = ZWaveNodeInitStage.DONE;
break;
}
// If the incoming frame is the IdentifyNode, then we continue
if (eventClass == SerialMessageClass.IsFailedNodeID) {
break;
}
addToQueue(new IsFailedNodeMessageClass().doRequest(node.getNodeId()));
break;
case WAIT:
logger.debug("NODE {}: Node advancer: WAIT - Listening={}, FrequentlyListening={}", node.getNodeId(), node.isListening(), node.isFrequentlyListening());
// If the node is listening, or frequently listening, then we progress.
if (node.isListening() == true || node.isFrequentlyListening() == true) {
logger.debug("NODE {}: Node advancer: WAIT - Advancing", node.getNodeId());
break;
}
// If the device supports the wakeup class, then see if we're awake
ZWaveWakeUpCommandClass wakeUpCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.WAKE_UP);
if (wakeUpCommandClass != null && wakeUpCommandClass.isAwake() == true) {
logger.debug("NODE {}: Node advancer: WAIT - Node is awake", node.getNodeId());
break;
}
// If it's not listening, and not awake,
// we'll wait a while before progressing with initialisation.
logger.debug("NODE {}: Node advancer: WAIT - Still waiting!", node.getNodeId());
return;
case PING:
// who cares!
if (eventClass == SerialMessageClass.SendData) {
break;
}
ZWaveNoOperationCommandClass noOpCommandClass = (ZWaveNoOperationCommandClass) node.getCommandClass(CommandClass.NO_OPERATION);
if (noOpCommandClass == null) {
break;
}
logger.debug("NODE {}: Node advancer: PING - send NoOperation", node.getNodeId());
SerialMessage msg = noOpCommandClass.getNoOperationMessage();
if (msg != null) {
// We only send out a single PING - no retries at controller
// level! This is to try and reduce network congestion during
// initialisation.
// For battery devices, the PING will time-out. This takes 5
// seconds and if there are retries, it will be 15 seconds!
// This will block the network for a considerable time if there
// are a lot of battery devices (eg. 2 minutes for 8 battery devices!).
msg.attempts = 1;
addToQueue(msg);
}
break;
case SECURITY_REPORT:
// response to come back
if (this.node.supportsCommandClass(CommandClass.SECURITY)) {
ZWaveSecurityCommandClassWithInitialization securityCommandClass = (ZWaveSecurityCommandClassWithInitialization) this.node.getCommandClass(CommandClass.SECURITY);
// For a node restored from a config file, this may or may not return a message
Collection<SerialMessage> messageList = securityCommandClass.initialize(stageAdvanced);
// Speed up retry timer as we use this to fetch outgoing messages instead of just retries
retryTimer = 400;
if (messageList == null) {
// This means we're waiting for a reply or we are done
if (isRestoredFromConfigfile()) {
// Since we were restored from a config file, redo from the dynamic node stage.
logger.debug("NODE {}: Node advancer: Restored from file - skipping static initialisation", node.getNodeId());
currentStage = ZWaveNodeInitStage.SESSION_START;
securityCommandClass.startSecurityEncapsulationThread();
break;
} else {
// This node was just included, check for success or failure
if (securityCommandClass.wasSecureInclusionSuccessful()) {
logger.debug("NODE {}: Secure inclusion complete, continuing with inclusion", node.getNodeId());
securityCommandClass.startSecurityEncapsulationThread();
// TODO: DB remove
nodeSerializer.SerializeNode(node);
// retryTimer will be reset to a normal value below
break;
} else {
// securityCommandClass output a message about the failure
logger.debug("NODE {}: Since secure inclusion failed, the node must be manually excluded via habmin", node.getNodeId());
// Stop the retry timer
resetIdleTimer();
// Remove the security command class since without a key, it's unusable
node.removeCommandClass(CommandClass.SECURITY);
// We remove the event listener to reduce loading now that we're done
controller.removeEventListener(this);
return;
}
}
} else if (messageList.isEmpty()) {
// Let ZWaveInputThread go back and wait for an incoming message
return;
} else {
// Add one or more messages to the queue
addToQueue(messageList);
SerialMessage nextSecurityMessageToSend = messageList.iterator().next();
if (!nextSecurityMessageToSend.equals(securityLastSentMessage)) {
// Reset our retry count since this is a different message
retryCount = 0;
securityLastSentMessage = nextSecurityMessageToSend;
}
}
} else {
// !node.supportsCommandClass(CommandClass.SECURITY)
if (isRestoredFromConfigfile()) {
// Since we were restored from a config file, redo from the dynamic node stage.
logger.debug("NODE {}: Node advancer: Restored from file - skipping static initialisation", node.getNodeId());
currentStage = ZWaveNodeInitStage.SESSION_START;
}
logger.debug("NODE {}: does not support SECURITY_REPORT, proceeding to next stage.", this.node.getNodeId());
}
break;
case DETAILS:
// If restored from a config file, redo from the dynamic node stage.
if (isRestoredFromConfigfile()) {
logger.debug("NODE {}: Node advancer: Restored from file - skipping static initialisation", node.getNodeId());
currentStage = ZWaveNodeInitStage.SESSION_START;
break;
}
// If the incoming frame is the IdentifyNode, then we continue
if (node.getApplicationUpdateReceived() == true) {
logger.debug("NODE {}: Node advancer: received RequestNodeInfo", node.getNodeId());
break;
}
logger.debug("NODE {}: Node advancer: DETAILS - send RequestNodeInfo", node.getNodeId());
addToQueue(new RequestNodeInfoMessageClass().doRequest(node.getNodeId()));
break;
case MANUFACTURER:
// If we already know the device information, then continue
if (node.getManufacturer() != Integer.MAX_VALUE && node.getDeviceType() != Integer.MAX_VALUE && node.getDeviceId() != Integer.MAX_VALUE) {
break;
}
// try and get the manufacturerSpecific command class.
ZWaveManufacturerSpecificCommandClass manufacturerSpecific = (ZWaveManufacturerSpecificCommandClass) node.getCommandClass(CommandClass.MANUFACTURER_SPECIFIC);
if (manufacturerSpecific != null) {
// If this node implements the Manufacturer Specific command
// class, we use it to get manufacturer info.
logger.debug("NODE {}: Node advancer: MANUFACTURER - send ManufacturerSpecific", node.getNodeId());
addToQueue(manufacturerSpecific.getManufacturerSpecificMessage());
}
break;
case VERSION:
// Try and get the version command class.
ZWaveVersionCommandClass version = (ZWaveVersionCommandClass) node.getCommandClass(CommandClass.VERSION);
// using the Version command class
for (ZWaveCommandClass zwaveVersionClass : node.getCommandClasses()) {
logger.debug("NODE {}: Node advancer: VERSION - checking {}, version is {}", node.getNodeId(), zwaveVersionClass.getCommandClass().getLabel(), zwaveVersionClass.getVersion());
// See if we want to force the version of this command class
// We now should know all the command classes, so run through the database and set any options
database = new ZWaveProductDatabase();
if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == true) {
List<ZWaveDbCommandClass> classList = database.getProductCommandClasses();
if (classList != null) {
// Loop through the command classes in the data and update the records...
for (ZWaveDbCommandClass dbClass : classList) {
if (dbClass.version != null && zwaveVersionClass.getCommandClass().getKey() == dbClass.Id) {
logger.debug("NODE {}: Node advancer: VERSION - Set {} to Version {}", node.getNodeId(), zwaveVersionClass.getCommandClass().getLabel(), dbClass.version);
zwaveVersionClass.setVersion(dbClass.version);
}
}
}
}
if (version != null && zwaveVersionClass.getMaxVersion() > 1 && zwaveVersionClass.getVersion() == 0) {
logger.debug("NODE {}: Node advancer: VERSION - queued {}", node.getNodeId(), zwaveVersionClass.getCommandClass().getLabel());
addToQueue(version.checkVersion(zwaveVersionClass));
} else if (zwaveVersionClass.getVersion() == 0) {
logger.debug("NODE {}: Node advancer: VERSION - VERSION default to 1", node.getNodeId());
zwaveVersionClass.setVersion(1);
}
}
logger.debug("NODE {}: Node advancer: VERSION - queued {} frames", node.getNodeId(), msgQueue.size());
break;
case APP_VERSION:
ZWaveVersionCommandClass versionCommandClass = (ZWaveVersionCommandClass) node.getCommandClass(CommandClass.VERSION);
if (versionCommandClass == null) {
logger.debug("NODE {}: Node advancer: APP_VERSION - VERSION node supported", node.getNodeId());
break;
}
// If we know the library type, then we've got the app version
if (versionCommandClass.getLibraryType() != LibraryType.LIB_UNKNOWN) {
break;
}
// Request the version report for this node
logger.debug("NODE {}: Node advancer: APP_VERSION - send VersionMessage", node.getNodeId());
addToQueue(versionCommandClass.getVersionMessage());
break;
case ENDPOINTS:
// Try and get the multi instance / channel command class.
ZWaveMultiInstanceCommandClass multiInstance = (ZWaveMultiInstanceCommandClass) node.getCommandClass(CommandClass.MULTI_INSTANCE);
if (multiInstance != null) {
logger.debug("NODE {}: Node advancer: ENDPOINTS - MultiInstance is supported", node.getNodeId());
addToQueue(multiInstance.initEndpoints(stageAdvanced));
logger.debug("NODE {}: Node advancer: ENDPOINTS - queued {} frames", node.getNodeId(), msgQueue.size());
} else {
logger.debug("NODE {}: Node advancer: ENDPOINTS - MultiInstance not supported.", node.getNodeId());
// Set all classes to 1 instance.
for (ZWaveCommandClass commandClass : node.getCommandClasses()) {
commandClass.setInstances(1);
}
}
break;
case UPDATE_DATABASE:
// This stage reads information from the database to allow us to modify the configuration
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE", node.getNodeId());
// We now should know all the command classes, so run through the database and set any options
database = new ZWaveProductDatabase();
if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == true) {
List<ZWaveDbCommandClass> classList = database.getProductCommandClasses();
if (classList != null) {
// Loop through the command classes and update the records...
for (ZWaveDbCommandClass dbClass : classList) {
// If we want to remove the class, then remove it!
if (dbClass.remove != null && dbClass.remove == true) {
// TODO: This will only remove the root nodes and ignores endpoint
// TODO: Do we need to search into multi_instance?
node.removeCommandClass(CommandClass.getCommandClass(dbClass.Id));
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - removing {}", node.getNodeId(), CommandClass.getCommandClass(dbClass.Id).getLabel());
continue;
}
// Get the command class
int endpoint = dbClass.endpoint == null ? 0 : dbClass.endpoint;
ZWaveCommandClass zwaveClass = node.resolveCommandClass(CommandClass.getCommandClass(dbClass.Id), endpoint);
// If we found the command class, then set its options
if (zwaveClass != null) {
zwaveClass.setOptions(dbClass);
continue;
}
// TODO: Does this need to account for multiple endpoints!?!
if (dbClass.add != null && dbClass.add == true) {
ZWaveCommandClass commandClass = ZWaveCommandClass.getInstance(dbClass.Id, node, controller);
if (commandClass != null) {
logger.debug("NODE {}: Node advancer: UPDATE_DATABASE - adding {}", node.getNodeId(), CommandClass.getCommandClass(dbClass.Id).getLabel());
node.addCommandClass(commandClass);
}
}
}
}
}
break;
case STATIC_VALUES:
// Loop through all classes looking for static initialisation
for (ZWaveCommandClass zwaveStaticClass : node.getCommandClasses()) {
logger.debug("NODE {}: Node advancer: STATIC_VALUES - checking {}", node.getNodeId(), zwaveStaticClass.getCommandClass().getLabel());
if (zwaveStaticClass instanceof ZWaveCommandClassInitialization) {
logger.debug("NODE {}: Node advancer: STATIC_VALUES - found {}", node.getNodeId(), zwaveStaticClass.getCommandClass().getLabel());
ZWaveCommandClassInitialization zcci = (ZWaveCommandClassInitialization) zwaveStaticClass;
int instances = zwaveStaticClass.getInstances();
logger.debug("NODE {}: Found {} instances of {}", node.getNodeId(), instances, zwaveStaticClass.getCommandClass());
if (instances == 1) {
addToQueue(zcci.initialize(stageAdvanced));
} else {
for (int i = 1; i <= instances; i++) {
addToQueue(zcci.initialize(stageAdvanced), zwaveStaticClass, i);
}
}
} else if (zwaveStaticClass instanceof ZWaveMultiInstanceCommandClass) {
ZWaveMultiInstanceCommandClass multiInstanceCommandClass = (ZWaveMultiInstanceCommandClass) zwaveStaticClass;
for (ZWaveEndpoint endpoint : multiInstanceCommandClass.getEndpoints()) {
for (ZWaveCommandClass endpointCommandClass : endpoint.getCommandClasses()) {
logger.debug("NODE {}: Node advancer: STATIC_VALUES - checking {} for endpoint {}", node.getNodeId(), endpointCommandClass.getCommandClass().getLabel(), endpoint.getEndpointId());
if (endpointCommandClass instanceof ZWaveCommandClassInitialization) {
logger.debug("NODE {}: Node advancer: STATIC_VALUES - found {}", node.getNodeId(), endpointCommandClass.getCommandClass().getLabel());
ZWaveCommandClassInitialization zcci2 = (ZWaveCommandClassInitialization) endpointCommandClass;
addToQueue(zcci2.initialize(stageAdvanced), endpointCommandClass, endpoint.getEndpointId());
}
}
}
}
}
logger.debug("NODE {}: Node advancer: STATIC_VALUES - queued {} frames", node.getNodeId(), msgQueue.size());
break;
case ASSOCIATIONS:
// Do we support associations
ZWaveAssociationCommandClass associationCommandClass = (ZWaveAssociationCommandClass) node.getCommandClass(CommandClass.ASSOCIATION);
if (associationCommandClass == null) {
break;
}
// so just do this once
if (stageAdvanced == false) {
break;
}
// Open the product database
ZWaveProductDatabase associations = new ZWaveProductDatabase();
if (associations.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == true) {
// We have this device in the database
// Assume the database is correct since some devices report invalid number of groups!
List<ZWaveDbAssociationGroup> groupList = associations.getProductAssociationGroups();
// No groups known
if (groupList == null) {
logger.debug("NODE {}: Node advancer: ASSOCIATIONS - none in database", node.getNodeId());
break;
}
// Request every group
for (ZWaveDbAssociationGroup group : groupList) {
logger.debug("NODE {}: Node advancer: ASSOCIATIONS request group {}", node.getNodeId(), group.Index);
addToQueue(associationCommandClass.getAssociationMessage(group.Index));
}
} else {
for (int group = 1; group <= associationCommandClass.getMaxGroups(); group++) {
logger.debug("NODE {}: Node advancer: ASSOCIATIONS request group {}", node.getNodeId(), group);
addToQueue(associationCommandClass.getAssociationMessage(group));
}
}
break;
case SET_WAKEUP:
// It sets the node to point to us, and the time is left along
if (controller.isMasterController() == false) {
break;
}
ZWaveWakeUpCommandClass wakeupCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.WAKE_UP);
if (wakeupCommandClass == null) {
logger.debug("NODE {}: Node advancer: SET_WAKEUP - Wakeup command class not supported", node.getNodeId());
break;
}
if (wakeupCommandClass.getTargetNodeId() == controller.getOwnNodeId()) {
logger.debug("NODE {}: Node advancer: SET_WAKEUP - TargetNode is set to controller", node.getNodeId());
break;
}
int value = 3600;
if (wakeupCommandClass.getInterval() == 0) {
logger.debug("NODE {}: Node advancer: SET_WAKEUP - Interval is currently 0. Set to 3600", node.getNodeId());
} else {
value = wakeupCommandClass.getInterval();
}
logger.debug("NODE {}: Node advancer: SET_WAKEUP - Set wakeup node to controller ({}), period {}", node.getNodeId(), controller.getOwnNodeId(), value);
// Set the wake-up interval, and request an update
addToQueue(wakeupCommandClass.setInterval(value));
addToQueue(wakeupCommandClass.getIntervalMessage());
break;
case SET_ASSOCIATION:
if (controller.isMasterController() == false) {
break;
}
database = new ZWaveProductDatabase();
if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) {
// No database entry for this device!
logger.warn("NODE {}: Node advancer: SET_ASSOCIATION - Unknown device: {}:{}:{}", node.getNodeId(), Integer.toHexString(node.getManufacturer()), Integer.toHexString(node.getDeviceType()), Integer.toHexString(node.getDeviceId()));
break;
}
List<ZWaveDbAssociationGroup> groups = database.getProductAssociationGroups();
if (groups == null || groups.size() == 0) {
logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - No association groups", node.getNodeId());
break;
}
// Get the group members
ZWaveAssociationCommandClass associationCls = (ZWaveAssociationCommandClass) node.getCommandClass(CommandClass.ASSOCIATION);
if (associationCls == null) {
logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - ASSOCIATION class not supported", node.getNodeId());
break;
}
// Loop through all the groups in the database
for (ZWaveDbAssociationGroup group : groups) {
if (group.SetToController == true) {
// Check if we're already a member
if (associationCls.getGroupMembers(group.Index).contains(controller.getOwnNodeId())) {
logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - ASSOCIATION set for group {}", node.getNodeId(), group.Index);
} else {
logger.debug("NODE {}: Node advancer: SET_ASSOCIATION - Adding ASSOCIATION to group {}", node.getNodeId(), group.Index);
// Set the association, and request the update so we confirm if it's set
addToQueue(associationCls.setAssociationMessage(group.Index, controller.getOwnNodeId()));
addToQueue(associationCls.getAssociationMessage(group.Index));
}
}
}
break;
case GET_CONFIGURATION:
database = new ZWaveProductDatabase();
if (database.FindProduct(node.getManufacturer(), node.getDeviceType(), node.getDeviceId(), node.getApplicationVersion()) == false) {
// No database entry for this device!
logger.warn("NODE {}: Node advancer: GET_CONFIGURATION - Unknown device: {}:{}:{}", node.getNodeId(), Integer.toHexString(node.getManufacturer()), Integer.toHexString(node.getDeviceType()), Integer.toHexString(node.getDeviceId()));
break;
}
ZWaveConfigurationCommandClass configurationCommandClass = (ZWaveConfigurationCommandClass) node.getCommandClass(CommandClass.CONFIGURATION);
// If there are no configuration entries for this node, then continue.
List<ZWaveDbConfigurationParameter> configList = database.getProductConfigParameters();
if (configList == null || configList.size() == 0) {
break;
}
// If the node doesn't support configuration class, then we better let people know!
if (configurationCommandClass == null) {
logger.error("NODE {}: Node advancer: GET_CONFIGURATION - CONFIGURATION class not supported", node.getNodeId());
break;
}
// Request all parameters for this node
for (ZWaveDbConfigurationParameter parameter : configList) {
// Some parameters don't return anything, so don't request them!
if (parameter.WriteOnly != null && parameter.WriteOnly == true) {
configurationCommandClass.setParameterWriteOnly(parameter.Index, parameter.Size, true);
continue;
}
// then request it!
if (configurationCommandClass.getParameter(parameter.Index) == null) {
addToQueue(configurationCommandClass.getConfigMessage(parameter.Index));
}
}
break;
case DYNAMIC_VALUES:
for (ZWaveCommandClass zwaveDynamicClass : node.getCommandClasses()) {
logger.debug("NODE {}: Node advancer: DYNAMIC_VALUES - checking {}", node.getNodeId(), zwaveDynamicClass.getCommandClass().getLabel());
if (zwaveDynamicClass instanceof ZWaveCommandClassDynamicState) {
logger.debug("NODE {}: Node advancer: DYNAMIC_VALUES - found {}", node.getNodeId(), zwaveDynamicClass.getCommandClass().getLabel());
ZWaveCommandClassDynamicState zdds = (ZWaveCommandClassDynamicState) zwaveDynamicClass;
int instances = zwaveDynamicClass.getInstances();
logger.debug("NODE {}: Found {} instances of {}", node.getNodeId(), instances, zwaveDynamicClass.getCommandClass());
if (instances == 1) {
addToQueue(zdds.getDynamicValues(stageAdvanced));
} else {
for (int i = 1; i <= instances; i++) {
addToQueue(zdds.getDynamicValues(stageAdvanced), zwaveDynamicClass, i);
}
}
} else if (zwaveDynamicClass instanceof ZWaveMultiInstanceCommandClass) {
ZWaveMultiInstanceCommandClass multiInstanceCommandClass = (ZWaveMultiInstanceCommandClass) zwaveDynamicClass;
for (ZWaveEndpoint endpoint : multiInstanceCommandClass.getEndpoints()) {
for (ZWaveCommandClass endpointCommandClass : endpoint.getCommandClasses()) {
logger.debug("NODE {}: Node advancer: DYNAMIC_VALUES - checking {} for endpoint {}", node.getNodeId(), endpointCommandClass.getCommandClass().getLabel(), endpoint.getEndpointId());
if (endpointCommandClass instanceof ZWaveCommandClassDynamicState) {
logger.debug("NODE {}: Node advancer: DYNAMIC_VALUES - found {}", node.getNodeId(), endpointCommandClass.getCommandClass().getLabel());
ZWaveCommandClassDynamicState zdds2 = (ZWaveCommandClassDynamicState) endpointCommandClass;
addToQueue(zdds2.getDynamicValues(stageAdvanced), endpointCommandClass, endpoint.getEndpointId());
}
}
}
}
}
logger.debug("NODE {}: Node advancer: DYNAMIC_VALUES - queued {} frames", node.getNodeId(), msgQueue.size());
break;
case STATIC_END:
case DONE:
// Save the node information to file
nodeSerializer.SerializeNode(node);
if (currentStage != ZWaveNodeInitStage.DONE) {
break;
}
logger.debug("NODE {}: Node advancer: Initialisation complete!", node.getNodeId());
// Stop the retry timer
resetIdleTimer();
// We remove the event listener to reduce loading now that we're done
controller.removeEventListener(this);
// Notify everyone!
ZWaveEvent zEvent = new ZWaveInitializationCompletedEvent(node.getNodeId());
controller.notifyEventListeners(zEvent);
// increment the stage!
return;
case SESSION_START:
// where to start initialisation if we restored from XML.
break;
default:
logger.debug("NODE {}: Node advancer: Unknown node state {} encountered.", node.getNodeId(), currentStage.toString().toString());
break;
}
// that we're starting again, then loop around again.
if (currentStage != ZWaveNodeInitStage.DONE && sendMessage() == false) {
// Move on to the next stage
setCurrentStage(currentStage.getNextStage());
stageAdvanced = true;
// Reset the backoff timer
retryTimer = BACKOFF_TIMER_START;
logger.debug("NODE {}: Node advancer - advancing to {}", node.getNodeId(), currentStage.toString());
}
} while (msgQueue.isEmpty());
}
use of org.openhab.binding.zwave.internal.protocol.commandclass.ZWaveWakeUpCommandClass 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