Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add zwave700 support (test on silabs zwave 700 ) #1765

Open
wants to merge 1 commit into
base: 3.0.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ public enum SerialMessageClass {
SetSlaveLearnMode(0xA4), // Enter slave learn mode
GetVirtualNodes(0xA5), // Return all virtual nodes
IsVirtualNode(0xA6), // Virtual node test
AppCmdHandlerBridge(0xA8), // FUNC_ID_APPLICATION_COMMAND_HANDLER_BRIDGE
SetWutTimeout(0xB4),
WatchDogEnable(0xB6),
WatchDogDisable(0xB7),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1515,7 +1515,7 @@ private synchronized void setSleepTimer() {
if (isInitializationComplete()) {
timerDelay = sleepDelay;
} else {
timerDelay = 5000;
timerDelay = 25000; // give enough time, original 5000ms
}
logger.debug("NODE {}: Start sleep timer at {}ms", getNodeId(), timerDelay);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,18 @@ public void run() {
}

// Manage incoming command class messages separately so we can manage transaction responses
if (incomingMessage.getMessageClass() == SerialMessageClass.ApplicationCommandHandler) {
if (incomingMessage.getMessageClass() == SerialMessageClass.ApplicationCommandHandler
|| incomingMessage.getMessageClass() == SerialMessageClass.AppCmdHandlerBridge) {
if (incomingMessage.getMessageClass() == SerialMessageClass.AppCmdHandlerBridge) {
// zwave700 seems to be 1 more byte than legacy
int arr_len = incomingMessage.getMessagePayload().length-1;
byte[] arr_new = new byte[arr_len];
for(int i=0; i<arr_len; i++){
arr_new[i]=incomingMessage.getMessagePayload()[i+1];
}
incomingMessage.setMessagePayload(arr_new);
}

try {
int nodeId = incomingMessage.getMessagePayloadByte(1);
ZWaveNode node = controller.getNode(nodeId);
Expand Down Expand Up @@ -566,8 +577,8 @@ public void run() {
continue;
}

if (transaction
.getExpectedReplyClass() == SerialMessageClass.ApplicationCommandHandler
if ((transaction.getExpectedReplyClass() == SerialMessageClass.ApplicationCommandHandler ||
transaction.getExpectedReplyClass() == SerialMessageClass.AppCmdHandlerBridge)
&& transaction.getExpectedCommandClass() != null
&& command.getCommandClassId() == transaction
.getExpectedCommandClass().getKey()
Expand All @@ -577,6 +588,19 @@ public void run() {
logger.debug("NODE {}: Command verified {}.", nodeId, command);

transaction.transactionAdvance(incomingMessage);

logger.debug("NODE {}: zwave700 dbg msg_class {}, cmd_id {} cmd_class {} replay_class {}.",
nodeId, incomingMessage.getMessageClass(), command.getCommandClassId(),
command.getCommandClassCommand(),
transaction.getExpectedReplyClass());

// Manufacture report
if (incomingMessage.getMessageClass() == SerialMessageClass.AppCmdHandlerBridge) {
logger.debug("NODE {}: zwave700 dbg => cmd_id {} cmd_class {} replay_class {}.",
nodeId, command.getCommandClassId(), command.getCommandClassCommand(),
transaction.getExpectedReplyClass());
transaction.setTransactionComplete();
}

// Notify the sender
notifyTransactionComplete(transaction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,13 @@ private void doInitialStages() {
// return;
// }

if (node.getNodeId() == 1) {
// workaround for zwave700, seems no better solution ??
logger.debug("NODE 1: Controller node, Node device class and type {}. Zwave700 Init Done!!", node.getDeviceClass().getSpecificDeviceClass());
setCurrentStage(ZWaveNodeInitStage.DONE);
return;
}

// Controllers aren't designed to allow communication with their node.
// If this is a controller, we're done
if (node.getDeviceClass().getSpecificDeviceClass() == Specific.SPECIFIC_TYPE_PC_CONTROLLER) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/**
* Copyright (c) 2010-2020 Contributors to the openHAB project
*
* See the NOTICE file(s) distributed with this work for additional
* information.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0
*
* SPDX-License-Identifier: EPL-2.0
*/
package org.openhab.binding.zwave.internal.protocol.serialmessage;

import org.openhab.binding.zwave.internal.protocol.SerialMessage;
import org.openhab.binding.zwave.internal.protocol.ZWaveCommandClassPayload;
import org.openhab.binding.zwave.internal.protocol.ZWaveController;
import org.openhab.binding.zwave.internal.protocol.ZWaveNode;
import org.openhab.binding.zwave.internal.protocol.ZWaveSerialMessageException;
import org.openhab.binding.zwave.internal.protocol.ZWaveTransaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* This class processes a serial message from the zwave controller
*
* @author Chris Jackson
*/
public class AppCmdHandlerBridgeMessageClass extends ZWaveCommandProcessor {
private final Logger logger = LoggerFactory.getLogger(AppCmdHandlerBridgeMessageClass.class);

@Override
public boolean handleResponse(ZWaveController zController, ZWaveTransaction transaction,
SerialMessage incomingMessage) {

// pwj, seems to be 1 more byte than legacy
int arr_len = incomingMessage.getMessagePayload().length-1;
byte[] arr_new = new byte[arr_len];
for(int i=0; i<arr_len; i++){
arr_new[i]=incomingMessage.getMessagePayload()[i+1];
}
incomingMessage.setMessagePayload(arr_new);

try {
int nodeId = incomingMessage.getMessagePayloadByte(1);
ZWaveNode node = zController.getNode(nodeId);

if (node == null) {
logger.warn("NODE {}: Not initialized yet (ie node unknown), ignoring message.", nodeId);
return false;
}
logger.debug("NODE {}: Application Command (bridge) Request ({}:{})", nodeId, node.getNodeState().toString(),
node.getNodeInitStage().toString());

node.processCommand(new ZWaveCommandClassPayload(incomingMessage));

// If we have a transaction, then it's been correlated with the expected response.
// We can therefore complete it
if (transaction != null) {
transaction.setTransactionComplete();
}
} catch (ZWaveSerialMessageException e) {
logger.error("Error processing frame: {} >> {}", incomingMessage.toString(), e.getMessage());
}
return true;
}

@Override
public boolean correlateTransactionResponse(ZWaveTransaction transaction, SerialMessage incomingMessage) {
if (transaction == null) {
return false;
}

logger.debug("AppCmdHandlerBridgeClass correlateTransactionResponse: transaction: {}", transaction);
logger.debug("AppCmdHandlerBridgeClass correlateTransactionResponse: expected cmd class: {}",
transaction.getExpectedCommandClass());
logger.debug("AppCmdHandlerBridgeClass correlateTransactionResponse: expected cmd: {}",
transaction.getExpectedCommandClassCommand());

if (transaction.getExpectedReplyClass() != incomingMessage.getMessageClass()) {
logger.debug("NO EXPECTED REPLY CLASS match! ({} <> {})", transaction.getExpectedReplyClass(),
incomingMessage.getMessageClass());
return false;
}

// If this is a response, check the callbackId
try {
// If the expected command class is defined, then check it
if (transaction.getExpectedCommandClass() == null
|| transaction.getExpectedCommandClass().getKey() != incomingMessage.getMessagePayloadByte(3)) {
logger.debug("NO EXPECTED COMMAND CLASS match! ({} <> {}) - {}", transaction.getExpectedCommandClass(),
incomingMessage.getMessagePayloadByte(3), SerialMessage.bb2hex(transaction.getPayloadBuffer()));

return false;
}

// If the expected command class command is defined, then check it
if (transaction.getExpectedCommandClassCommand() == null
|| transaction.getExpectedCommandClassCommand() != incomingMessage.getMessagePayloadByte(4)) {
logger.debug("NO EXPECTED COMMAND CLASS COMMAND match! ({} <> {}) - {}",
transaction.getExpectedCommandClassCommand(), incomingMessage.getMessagePayloadByte(4),
SerialMessage.bb2hex(transaction.getPayloadBuffer()));

return false;
}

return true;
} catch (ZWaveSerialMessageException e) {
logger.debug("Exception ", e);
}

return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ public static ZWaveCommandProcessor getMessageDispatcher(SerialMessage.SerialMes
messageMap.put(SerialMessage.SerialMessageClass.SerialApiSoftReset, SerialApiSoftResetMessageClass.class);
messageMap.put(SerialMessage.SerialMessageClass.SetSucNodeID, SetSucNodeMessageClass.class);
messageMap.put(SerialMessage.SerialMessageClass.SetDefault, ControllerSetDefaultMessageClass.class);
messageMap.put(SerialMessage.SerialMessageClass.AppCmdHandlerBridge, AppCmdHandlerBridgeMessageClass.class);
}

Constructor<? extends ZWaveCommandProcessor> constructor;
Expand Down