use of org.openhab.binding.zwave.internal.protocol.ZWaveNode in project openhab1-addons by openhab.
the class SendDataMessageClass method handleRequest.
@Override
public boolean handleRequest(ZWaveController zController, SerialMessage lastSentMessage, SerialMessage incomingMessage) {
logger.trace("Handle Message Send Data Request");
int callbackId = incomingMessage.getMessagePayloadByte(0);
TransmissionState status = TransmissionState.getTransmissionState(incomingMessage.getMessagePayloadByte(1));
if (status == null) {
logger.warn("Transmission state not found, ignoring.");
return false;
}
ZWaveNode node = zController.getNode(lastSentMessage.getMessageNode());
if (node == null) {
logger.warn("Node not found!");
return false;
}
logger.debug("NODE {}: SendData Request. CallBack ID = {}, Status = {}({})", node.getNodeId(), callbackId, status.getLabel(), status.getKey());
if (lastSentMessage == null || lastSentMessage.getCallbackId() != callbackId) {
logger.warn("NODE {}: Already processed another send data request for this callback Id, ignoring.", node.getNodeId());
return false;
}
// This response is our controller ACK
lastSentMessage.setAckRecieved();
switch(status) {
case COMPLETE_OK:
// Consider this as a received frame since the controller did receive an ACK from the device.
node.incrementReceiveCount();
// If the node is DEAD, but we've just received an ACK from it, then it's not dead!
if (node.isDead()) {
node.setNodeState(ZWaveNodeState.ALIVE);
;
} else {
node.resetResendCount();
}
checkTransactionComplete(lastSentMessage, incomingMessage);
return true;
case COMPLETE_NO_ACK:
// Handle WAKE_UP_NO_MORE_INFORMATION differently
// Since the system can time out if the node goes to sleep before
// we get the response, then don't treat this like a timeout
byte[] payload = lastSentMessage.getMessagePayload();
if (payload.length >= 4 && (payload[2] & 0xFF) == ZWaveCommandClass.CommandClass.WAKE_UP.getKey() && (payload[3] & 0xFF) == ZWaveWakeUpCommandClass.WAKE_UP_NO_MORE_INFORMATION) {
checkTransactionComplete(lastSentMessage, incomingMessage);
logger.debug("NODE {}: WAKE_UP_NO_MORE_INFORMATION. Treated as ACK.", node.getNodeId());
return true;
}
case COMPLETE_FAIL:
case COMPLETE_NOT_IDLE:
case COMPLETE_NOROUTE:
try {
handleFailedSendDataRequest(zController, lastSentMessage);
} finally {
transactionComplete = true;
}
break;
default:
break;
}
return false;
}
use of org.openhab.binding.zwave.internal.protocol.ZWaveNode in project openhab1-addons by openhab.
the class SendDataMessageClass method handleFailedSendDataRequest.
public boolean handleFailedSendDataRequest(ZWaveController zController, SerialMessage originalMessage) {
ZWaveNode node = zController.getNode(originalMessage.getMessageNode());
logger.trace("NODE {}: Handling failed message.", node.getNodeId());
// Increment the resend count.
// This will set the node to DEAD if we've exceeded the retries.
node.incrementResendCount();
// No retries if the node is DEAD or FAILED
if (node.isDead()) {
logger.error("NODE {}: Node is DEAD. Dropping message.", node.getNodeId());
return false;
}
// If this device isn't listening, queue the message in the wakeup class
if (!node.isListening() && !node.isFrequentlyListening()) {
ZWaveWakeUpCommandClass wakeUpCommandClass = (ZWaveWakeUpCommandClass) node.getCommandClass(CommandClass.WAKE_UP);
if (wakeUpCommandClass != null) {
// It's a battery operated device, place in wake-up queue.
wakeUpCommandClass.setAwake(false);
wakeUpCommandClass.processOutgoingWakeupMessage(originalMessage);
return false;
}
}
logger.error("NODE {}: Got an error while sending data. Resending message.", node.getNodeId());
// Set priority to Immediate since this is a retry
originalMessage.setPriority(SerialMessagePriority.Immediate);
zController.enqueue(originalMessage);
return true;
}
use of org.openhab.binding.zwave.internal.protocol.ZWaveNode in project openhab1-addons by openhab.
the class ZWaveActiveBinding method rebuildPollingTable.
/**
* This method rebuilds the polling table. The polling table is a list of items that have
* polling enabled (ie a refresh interval is set). This list is then checked periodically
* and any item that has passed its polling interval will be polled.
*/
private void rebuildPollingTable() {
// Rebuild the polling table
pollingList.clear();
if (converterHandler == null) {
logger.debug("ConverterHandler not initialised. Polling disabled.");
return;
}
// Loop all binding providers for the Z-wave binding.
for (ZWaveBindingProvider eachProvider : providers) {
// Loop all bound items for this provider
for (String name : eachProvider.getItemNames()) {
// Find the node and check if it's completed initialisation.
ZWaveBindingConfig cfg = eachProvider.getZwaveBindingConfig(name);
ZWaveNode node = this.zController.getNode(cfg.getNodeId());
if (node == null) {
logger.debug("NODE {}: Polling list: can't get node for item {}", cfg.getNodeId(), name);
continue;
}
if (node.getNodeInitializationStage() != ZWaveNodeInitStage.DONE) {
logger.debug("NODE {}: Polling list: item {} is not completed initialisation", cfg.getNodeId(), name);
continue;
}
logger.trace("Polling list: Checking {} == {}", name, converterHandler.getRefreshInterval(eachProvider, name));
// If this binding is configured to poll - add it to the list
if (converterHandler.getRefreshInterval(eachProvider, name) > 0) {
ZWavePollItem item = new ZWavePollItem();
item.item = name;
item.provider = eachProvider;
pollingList.add(item);
logger.trace("Polling list added {}", name);
}
}
}
pollingIterator = null;
}
use of org.openhab.binding.zwave.internal.protocol.ZWaveNode in project openhab1-addons by openhab.
the class ZWaveNetworkMonitor method ZWaveIncomingEvent.
/**
* Capture events that might be useful during the heal process We need to
* know when a network event happens - these are specific events that are
* used in the heal process (routing etc). We need to know if a device wakes
* up so we can heal it (if needed) We need to know when a PING transaction
* completes.
*/
@Override
public void ZWaveIncomingEvent(ZWaveEvent event) {
// Handle network events
if (event instanceof ZWaveNetworkEvent) {
ZWaveNetworkEvent nwEvent = (ZWaveNetworkEvent) event;
// Get the heal class for this notification
HealNode node = healNodes.get(nwEvent.getNodeId());
if (node == null) {
return;
}
// Is this the event we're waiting for
if (nwEvent.getEvent() != node.event) {
return;
}
switch(nwEvent.getState()) {
case Success:
node.retryCnt = 0;
node.state = node.stateNext;
break;
case Failure:
logger.debug("NODE {}: Network heal received FAILURE event", node.nodeId);
break;
}
// been a successful route set - remove this node
if (node.retryCnt == 0 && node.routeList != null && node.routeList.size() > 0) {
node.routeList.remove(0);
}
// Continue....
nextHealStage(node);
} else if (event instanceof ZWaveTransactionCompletedEvent) {
SerialMessage serialMessage = ((ZWaveTransactionCompletedEvent) event).getCompletedMessage();
if (serialMessage.getMessageClass() != SerialMessageClass.SendData && serialMessage.getMessageType() != SerialMessageType.Request) {
return;
}
byte[] payload = serialMessage.getMessagePayload();
if (payload.length < 3) {
return;
}
HealNode node = healNodes.get(payload[0] & 0xFF);
if (node == null) {
return;
}
// See if this node is waiting for a PING
if (node.state == HealState.PING && payload.length >= 3 && (payload[2] & 0xFF) == ZWaveCommandClass.CommandClass.NO_OPERATION.getKey()) {
node.state = node.stateNext;
node.retryCnt = 0;
nextHealStage(node);
return;
}
} else if (event instanceof ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) {
// We only care about the wake-up notification
if (((ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) event).getEvent() != ZWaveWakeUpCommandClass.WAKE_UP_NOTIFICATION) {
return;
}
// A wakeup event is received. Find the node in the node list
HealNode node = healNodes.get(event.getNodeId());
if (node == null) {
return;
}
// and only process if there's something to do
if (!node.state.isActive()) {
return;
}
logger.debug("NODE {}: Heal WakeUp EVENT {}", node.nodeId, node.state);
nextHealStage(node);
} else if (event instanceof ZWaveNodeStatusEvent) {
ZWaveNodeStatusEvent statusEvent = (ZWaveNodeStatusEvent) event;
logger.debug("NODE {}: Node Status event - Node is {}", statusEvent.getNodeId(), statusEvent.getState());
switch(statusEvent.getState()) {
case DEAD:
case FAILED:
ZWaveNode node = zController.getNode(statusEvent.getNodeId());
if (node == null) {
logger.error("NODE {}: Status event received, but node not found.", statusEvent.getNodeId());
return;
}
// If this is a DEAD notification, then ask the controller if it's really FAILED
if (statusEvent.getState() == ZWaveNodeState.DEAD) {
zController.requestIsFailedNode(node.getNodeId());
}
// The node is dead, but we may have already started a Heal
// If so, it won't be started again!
startNodeHeal(node.getNodeId());
break;
case ALIVE:
break;
}
} else if (event instanceof ZWaveInitializationCompletedEvent) {
logger.debug("Network initialised - starting network monitor.");
// Remember that we've initialised the binding.
initialised = true;
// Calculate the next heal time
networkHealNightlyTime = calculateNextHeal();
networkHealNextTime = networkHealNightlyTime;
// Set the next PING time
pingNodeTime = System.currentTimeMillis() + pollPeriod;
}
}
use of org.openhab.binding.zwave.internal.protocol.ZWaveNode in project openhab1-addons by openhab.
the class ZWaveNetworkMonitor method rescheduleHeal.
/**
* Start a full network heal manually.
*
* @return true if the heal is started otherwise false
*/
public boolean rescheduleHeal() {
// fully optimize the network, this is required
for (ZWaveNode node : zController.getNodes()) {
// Ignore devices that haven't initialized yet
if (node.isInitializationComplete() == false) {
logger.debug("NODE {}: Initialisation NOT yet complete. Skipping heal.", node.getNodeId());
continue;
}
startNodeHeal(node.getNodeId());
}
if (healNodes.size() == 0) {
return false;
}
// If we want to do a soft reset on the controller, do it now....
if (doSoftReset == true) {
logger.debug("HEAL - Performing soft reset!");
zController.requestSoftReset();
}
return true;
}
Aggregations