use of org.openhab.binding.zwave.internal.protocol.event.ZWaveTransactionCompletedEvent in project openhab1-addons by openhab.
the class ZWaveWakeUpCommandClass method ZWaveIncomingEvent.
/**
* Event handler for incoming Z-Wave events. We monitor Z-Wave events for completed
* transactions. Once a transaction is completed for the WAKE_UP_NO_MORE_INFORMATION
* event, we set the node state to asleep.
* {@inheritDoc}
*/
@Override
public void ZWaveIncomingEvent(ZWaveEvent event) {
if (!(event instanceof ZWaveTransactionCompletedEvent)) {
return;
}
SerialMessage serialMessage = ((ZWaveTransactionCompletedEvent) event).getCompletedMessage();
if (serialMessage.getMessageClass() != SerialMessageClass.SendData && serialMessage.getMessageType() != SerialMessageType.Request) {
return;
}
byte[] payload = serialMessage.getMessagePayload();
// Check if it's addressed to this node
if (payload.length == 0 || (payload[0] & 0xFF) != this.getNode().getNodeId()) {
return;
}
// If it's not the WAKE_UP_NO_MORE_INFORMATION, then we need to set the wakeup timer
if (payload.length >= 4 && (payload[2] & 0xFF) == this.getCommandClass().getKey() && (payload[3] & 0xFF) == WAKE_UP_NO_MORE_INFORMATION) {
// This is confirmation of our 'go to sleep' message
logger.debug("NODE {}: Went to sleep", this.getNode().getNodeId());
this.setAwake(false);
return;
}
// Send the next message in the wake-up queue
if (!this.wakeUpQueue.isEmpty()) {
// Get the next message from the queue.
// Bump its priority to highest to try and send it while the node is awake
serialMessage = this.wakeUpQueue.poll();
serialMessage.setPriority(SerialMessagePriority.Immediate);
this.getController().sendData(serialMessage);
} else if (isAwake() == true) {
// No more messages in the queue.
// Start a timer to send the "Go To Sleep" message
// This gives other tasks some time to do something if they want
setSleepTimer();
}
}
use of org.openhab.binding.zwave.internal.protocol.event.ZWaveTransactionCompletedEvent in project openhab1-addons by openhab.
the class ZWaveController method handleIncomingResponseMessage.
/**
* Handles an incoming response message.
* An incoming response message is a response, based one of our own requests.
*
* @param incomingMessage the response message to process.
*/
private void handleIncomingResponseMessage(SerialMessage incomingMessage) {
logger.trace("Incoming Message type = RESPONSE");
ZWaveCommandProcessor processor = ZWaveCommandProcessor.getMessageDispatcher(incomingMessage.getMessageClass());
if (processor == null) {
logger.warn(String.format("TODO: Implement processing of Response Message = %s (0x%02X)", incomingMessage.getMessageClass().getLabel(), incomingMessage.getMessageClass().getKey()));
return;
}
boolean result = processor.handleResponse(this, lastSentMessage, incomingMessage);
if (processor.isTransactionComplete()) {
notifyEventListeners(new ZWaveTransactionCompletedEvent(this.lastSentMessage, result));
transactionCompleted.release();
logger.trace("Released. Transaction completed permit count -> {}", transactionCompleted.availablePermits());
}
switch(incomingMessage.getMessageClass()) {
case GetVersion:
this.zWaveVersion = ((GetVersionMessageClass) processor).getVersion();
this.ZWaveLibraryType = ((GetVersionMessageClass) processor).getLibraryType();
break;
case MemoryGetId:
this.ownNodeId = ((MemoryGetIdMessageClass) processor).getNodeId();
this.homeId = ((MemoryGetIdMessageClass) processor).getHomeId();
break;
case SerialApiGetInitData:
this.isConnected = true;
for (Integer nodeId : ((SerialApiGetInitDataMessageClass) processor).getNodes()) {
addNode(nodeId);
}
break;
case GetSucNodeId:
// Remember the SUC ID
this.sucID = ((GetSucNodeIdMessageClass) processor).getSucNodeId();
// If we want to be the SUC, enable it here
if (this.setSUC == true && this.sucID == 0) {
// We want to be SUC
this.enqueue(new EnableSucMessageClass().doRequest(EnableSucMessageClass.SUCType.SERVER));
this.enqueue(new SetSucNodeMessageClass().doRequest(this.ownNodeId, SetSucNodeMessageClass.SUCType.SERVER));
} else if (this.setSUC == false && this.sucID == this.ownNodeId) {
// We don't want to be SUC, but we currently are!
// Disable SERVER functionality, and set the node to 0
this.enqueue(new EnableSucMessageClass().doRequest(EnableSucMessageClass.SUCType.NONE));
this.enqueue(new SetSucNodeMessageClass().doRequest(this.ownNodeId, SetSucNodeMessageClass.SUCType.NONE));
}
this.enqueue(new GetControllerCapabilitiesMessageClass().doRequest());
break;
case SerialApiGetCapabilities:
this.serialAPIVersion = ((SerialApiGetCapabilitiesMessageClass) processor).getSerialAPIVersion();
this.manufactureId = ((SerialApiGetCapabilitiesMessageClass) processor).getManufactureId();
this.deviceId = ((SerialApiGetCapabilitiesMessageClass) processor).getDeviceId();
this.deviceType = ((SerialApiGetCapabilitiesMessageClass) processor).getDeviceType();
this.enqueue(new SerialApiGetInitDataMessageClass().doRequest());
break;
case GetControllerCapabilities:
this.controllerType = ((GetControllerCapabilitiesMessageClass) processor).getDeviceType();
break;
default:
break;
}
}
use of org.openhab.binding.zwave.internal.protocol.event.ZWaveTransactionCompletedEvent in project openhab1-addons by openhab.
the class ZWaveNodeStageAdvancer method ZWaveIncomingEvent.
@Override
public void ZWaveIncomingEvent(ZWaveEvent event) {
// If we've already completed initialisation, then we're done!
if (currentStage == ZWaveNodeInitStage.DONE) {
return;
}
// Process transaction complete events
if (event instanceof ZWaveTransactionCompletedEvent) {
ZWaveTransactionCompletedEvent completeEvent = (ZWaveTransactionCompletedEvent) event;
SerialMessage serialMessage = completeEvent.getCompletedMessage();
byte[] payload = serialMessage.getMessagePayload();
// Make sure this is addressed to us
if (payload.length == 0 || node.getNodeId() != (payload[0] & 0xFF)) {
// This will allow battery devices stuck in WAIT state to get moving.
if (controller.getSendQueueLength() < 2 && currentStage == ZWaveNodeInitStage.WAIT) {
logger.debug("NODE {}: Node advancer - WAIT: The WAIT is over!", node.getNodeId());
currentStage = currentStage.getNextStage();
handleNodeQueue(null);
}
return;
}
switch(serialMessage.getMessageClass()) {
case SendData:
case IdentifyNode:
case RequestNodeInfo:
case GetRoutingInfo:
case IsFailedNodeID:
logger.debug("NODE {}: Node advancer - {}: Transaction complete ({}:{}) success({})", node.getNodeId(), currentStage.toString(), serialMessage.getMessageClass(), serialMessage.getMessageType(), completeEvent.getState());
// If this frame was successfully sent, then handle the stage advancer
if (((ZWaveTransactionCompletedEvent) event).getState() == true) {
handleNodeQueue(serialMessage);
}
break;
default:
break;
}
} else if (event instanceof ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) {
// WAKEUP EVENT - only act if this is a wakeup notification
if (((ZWaveWakeUpCommandClass.ZWaveWakeUpEvent) event).getEvent() != ZWaveWakeUpCommandClass.WAKE_UP_NOTIFICATION) {
return;
}
// A wakeup event is received. Make sure it's for this node
if (node.getNodeId() != event.getNodeId()) {
return;
}
logger.debug("NODE {}: Wakeup during initialisation.", node.getNodeId());
wakeupCount++;
advanceNodeStage(null);
} else if (event instanceof ZWaveNodeStatusEvent) {
ZWaveNodeStatusEvent statusEvent = (ZWaveNodeStatusEvent) event;
// A network status event is received. Make sure it's for this node.
if (node.getNodeId() != event.getNodeId()) {
return;
}
logger.debug("NODE {}: Node Status event during initialisation - Node is {}", statusEvent.getNodeId(), statusEvent.getState());
switch(statusEvent.getState()) {
case DEAD:
case FAILED:
break;
case ALIVE:
advanceNodeStage(null);
break;
}
logger.trace("NODE {}: Node Status event during initialisation processed", statusEvent.getNodeId());
} else if (event instanceof ZWaveNodeInfoEvent) {
logger.debug("NODE {}: {} NIF event during initialisation stage {}", event.getNodeId(), node.getNodeId(), currentStage);
if (node.getNodeId() != event.getNodeId()) {
return;
}
if (currentStage == ZWaveNodeInitStage.PING) {
logger.debug("NODE {}: NIF event during initialisation stage PING - advancing", event.getNodeId());
setCurrentStage(currentStage.getNextStage());
}
logger.debug("NODE {}: NIF event during initialisation stage {}", event.getNodeId(), currentStage);
advanceNodeStage(null);
/*
* } else if (event instanceof ZWaveCommandClassValueEvent) {
* // This code is used to detect an event during the IDLE stage.
* // This is used to kick start the initialisation for battery nodes that do not support
* // the WAKE_UP class and don't send the ApplicationUpdateMessage when they are initialised.
* logger.debug("NODE {}: {} CC event during initialisation stage {}", event.getNodeId(), node.getNodeId(),
* currentStage);
* // A command class event is received. Make sure it's for this node.
* if (node.getNodeId() != event.getNodeId() || currentStage != ZWaveNodeInitStage.PING) {
* return;
* }
* logger.debug("NODE {}: CC event during initialisation stage PING - advancing", event.getNodeId());
* setCurrentStage(currentStage.getNextStage());
* logger.debug("NODE {}: CC event during initialisation stage PING - now {} - next", event.getNodeId(),
* currentStage);
* advanceNodeStage(null);
*/
}
}
use of org.openhab.binding.zwave.internal.protocol.event.ZWaveTransactionCompletedEvent 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.event.ZWaveTransactionCompletedEvent in project openhab1-addons by openhab.
the class ZWaveController method handleIncomingRequestMessage.
/**
* Handles an incoming request message.
* An incoming request message is a message initiated by a node or the controller.
*
* @param incomingMessage the incoming message to process.
*/
private void handleIncomingRequestMessage(SerialMessage incomingMessage) {
logger.trace("Incoming Message type = REQUEST");
ZWaveCommandProcessor processor = ZWaveCommandProcessor.getMessageDispatcher(incomingMessage.getMessageClass());
if (processor == null) {
logger.warn(String.format("TODO: Implement processing of Request Message = %s (0x%02X)", incomingMessage.getMessageClass().getLabel(), incomingMessage.getMessageClass().getKey()));
return;
}
boolean result = processor.handleRequest(this, lastSentMessage, incomingMessage);
if (processor.isTransactionComplete()) {
notifyEventListeners(new ZWaveTransactionCompletedEvent(this.lastSentMessage, result));
transactionCompleted.release();
logger.trace("Released. Transaction completed permit count -> {}", transactionCompleted.availablePermits());
}
}
Aggregations