Skip to content

Commit bc17e45

Browse files
committed
Refactor ZWave node actions to return status messages
Changed ZWaveThingActions and related handlers to return descriptive String status messages instead of booleans for node operations (check failed, remove, reinit, heal). Improved user feedback for battery nodes and error cases. Updated i18n labels and descriptions for clarity. Fixed RemoveFailedNodeMessageClass to remove fixed callback and adjusted related test. Signed-off-by: Bob Eckhoff <katmandodo@yahoo.com>
1 parent 6a3afb0 commit bc17e45

9 files changed

Lines changed: 60 additions & 42 deletions

File tree

src/main/java/org/openhab/binding/zwave/actions/ZWaveThingActions.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,31 +35,31 @@
3535
public class ZWaveThingActions implements ThingActions {
3636
private @Nullable ZWaveThingHandler handler;
3737

38-
public static boolean setNodeAsFailed(ThingActions actions) {
38+
public static String checkIsNodeFailed(ThingActions actions) {
3939
if (actions instanceof ZWaveThingActions nodeActions) {
40-
return nodeActions.setNodeAsFailed();
40+
return nodeActions.checkIsNodeFailed();
4141
} else {
4242
throw new IllegalArgumentException("The 'actions' argument is not an instance of ZWaveThingActions");
4343
}
4444
}
4545

46-
public static boolean removeFailedNode(ThingActions actions) {
46+
public static String removeFailedNode(ThingActions actions) {
4747
if (actions instanceof ZWaveThingActions nodeActions) {
4848
return nodeActions.removeFailedNode();
4949
} else {
5050
throw new IllegalArgumentException("The 'actions' argument is not an instance of ZWaveThingActions");
5151
}
5252
}
5353

54-
public static boolean reinitNode(ThingActions actions) {
54+
public static String reinitNode(ThingActions actions) {
5555
if (actions instanceof ZWaveThingActions nodeActions) {
5656
return nodeActions.reinitNode();
5757
} else {
5858
throw new IllegalArgumentException("The 'actions' argument is not an instance of ZWaveThingActions");
5959
}
6060
}
6161

62-
public static boolean healNode(ThingActions actions) {
62+
public static String healNode(ThingActions actions) {
6363
if (actions instanceof ZWaveThingActions nodeActions) {
6464
return nodeActions.healNode();
6565
} else {
@@ -78,38 +78,38 @@ public void setThingHandler(ThingHandler thingHandler) {
7878
}
7979

8080
@RuleAction(label = "@text/actions.node-failed.label", description = "@text/actions.node-failed.description", visibility = Visibility.EXPERT)
81-
public @ActionOutput(type = "boolean", label = "Success") boolean setNodeAsFailed() {
81+
public @ActionOutput(type = "String") String checkIsNodeFailed() {
8282
ZWaveThingHandler handler = this.handler;
8383
if (handler != null) {
84-
return handler.setNodeAsFailed();
84+
return handler.checkIsNodeFailed();
8585
}
86-
return false;
86+
return "Thing handler is null, check not possible";
8787
}
8888

8989
@RuleAction(label = "@text/actions.node-remove.label", description = "@text/actions.node-remove.description", visibility = Visibility.EXPERT)
90-
public @ActionOutput(type = "boolean", label = "Success") boolean removeFailedNode() {
90+
public @ActionOutput(type = "String") String removeFailedNode() {
9191
ZWaveThingHandler handler = this.handler;
9292
if (handler != null) {
9393
return handler.removeFailedNode();
9494
}
95-
return false;
95+
return "Thing handler is null, removal not possible";
9696
}
9797

9898
@RuleAction(label = "@text/actions.node-reinit.label", description = "@text/actions.node-reinit.description")
99-
public @ActionOutput(type = "boolean", label = "Success") boolean reinitNode() {
99+
public @ActionOutput(type = "String") String reinitNode() {
100100
ZWaveThingHandler handler = this.handler;
101101
if (handler != null) {
102102
return handler.reinitNode();
103103
}
104-
return false;
104+
return "Thing handler is null, re-interview not possible";
105105
}
106106

107107
@RuleAction(label = "@text/actions.node-heal.label", description = "@text/actions.node-heal.description")
108-
public @ActionOutput(type = "boolean", label = "Success") boolean healNode() {
108+
public @ActionOutput(type = "String") String healNode() {
109109
ZWaveThingHandler handler = this.handler;
110110
if (handler != null) {
111111
return handler.healNode();
112112
}
113-
return false;
113+
return "Thing handler is null, Heal not possible.";
114114
}
115115
}

src/main/java/org/openhab/binding/zwave/handler/ZWaveControllerHandler.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ public void replaceFailedNode(int nodeId) {
559559
if (controller == null) {
560560
return;
561561
}
562-
controller.requestSetFailedNode(nodeId);
562+
controller.replaceFailedNode(nodeId);
563563
}
564564

565565
public void reinitialiseNode(int nodeId) {
@@ -569,19 +569,19 @@ public void reinitialiseNode(int nodeId) {
569569
controller.reinitialiseNode(nodeId);
570570
}
571571

572-
public boolean healNode(int nodeId) {
572+
public String healNode(int nodeId) {
573573
if (controller == null) {
574-
return false;
574+
return "Controller is null, Heal not possible.";
575575
}
576576
ZWaveNode node = controller.getNode(nodeId);
577577
if (node == null) {
578578
logger.debug("NODE {}: Can't be found!", nodeId);
579-
return false;
579+
return "Node not found, Heal not possible.";
580580
}
581581

582582
node.healNode();
583583

584-
return true;
584+
return "Rebuilding route tables started on node " + nodeId;
585585
}
586586

587587
public boolean isControllerMaster() {

src/main/java/org/openhab/binding/zwave/handler/ZWaveThingHandler.java

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,27 +1102,35 @@ public void handleConfigurationUpdate(Map<String, Object> configurationParameter
11021102
}
11031103
}
11041104

1105-
public boolean setNodeAsFailed() {
1105+
public String checkIsNodeFailed() {
1106+
ZWaveNode node = controllerHandler.getNode(nodeId);
1107+
if (!node.isListening() && !node.isFrequentlyListening()) {
1108+
return "Battery (sleeping) nodes cannot be checked for failure";
1109+
}
11061110
if (controllerHandler.getNode(nodeId).getNodeState() != ZWaveNodeState.FAILED) {
11071111
controllerHandler.checkNodeFailed(nodeId);
1108-
return true;
1112+
return "Check for node failure started, check logs to confirm";
11091113
}
1110-
return false;
1114+
return "Node is already in FAILED state";
11111115
}
11121116

1113-
public boolean removeFailedNode() {
1114-
if (controllerHandler.getNode(nodeId).getNodeState() == ZWaveNodeState.FAILED) {
1117+
public String removeFailedNode() {
1118+
ZWaveNode node = controllerHandler.getNode(nodeId);
1119+
if (!node.isListening() && !node.isFrequentlyListening()) {
1120+
return "Battery (sleeping) nodes cannot be removed";
1121+
}
1122+
if (node.getNodeState() == ZWaveNodeState.FAILED) {
11151123
controllerHandler.removeFailedNode(nodeId);
1116-
return true;
1124+
return "Failed node remove started, check logs for errors";
11171125
}
1118-
return false;
1126+
return "Node is not in FAILED state, cannot be removed";
11191127
}
11201128

1121-
public boolean reinitNode() {
1129+
public String reinitNode() {
11221130
ZWaveNode node = controllerHandler.getNode(nodeId);
11231131

11241132
if (!node.isInitializationComplete()) {
1125-
return false;
1133+
return "Initialization not complete, re-interview not possible";
11261134
}
11271135

11281136
logger.debug("NODE {}: Re-initialising node!", nodeId);
@@ -1132,10 +1140,16 @@ public boolean reinitNode() {
11321140
nodeSerializer.deleteNode(node.getHomeId(), nodeId);
11331141

11341142
controllerHandler.reinitialiseNode(nodeId);
1135-
return true;
1143+
return "Re-interview started for node " + nodeId;
11361144
}
11371145

1138-
public boolean healNode() {
1146+
public String healNode() {
1147+
ZWaveNode node = controllerHandler.getNode(nodeId);
1148+
1149+
if (!node.isInitializationComplete()) {
1150+
return "Initialization not complete, Heal not possible.";
1151+
}
1152+
11391153
logger.debug("NODE {}: Starting heal on node!", nodeId);
11401154
return controllerHandler.healNode(nodeId);
11411155
}

src/main/java/org/openhab/binding/zwave/internal/protocol/SerialMessage.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -552,9 +552,9 @@ public enum SerialMessageClass {
552552
RequestNodeNeighborUpdateOptions(0x5a), // Allow options for request node neighbor update
553553
ExploreRequestInclusion(0x5e), // Initiate a Network-Wide Inclusion process
554554
RequestNodeInfo(0x60, true, false, true), // Get info (supported command classes) for the specified node
555-
RemoveFailedNodeID(0x61, true, true, false), // Mark a specified node id as failed
555+
RemoveFailedNodeID(0x61, true, true, false), // Remove a failed node from the controller
556556
IsFailedNodeID(0x62, true, false, false), // Check to see if a specified node has failed
557-
ReplaceFailedNode(0x63, true, true, false), // Remove a failed node from the controller's list (?)
557+
ReplaceFailedNode(0x63, true, true, false), // Replace a failed node with a new node of same number
558558
GetRoutingInfo(0x80, true, false, false), // Get a specified node's neighbor information from
559559
// the controller
560560
LockRoute(0x90),

src/main/java/org/openhab/binding/zwave/internal/protocol/ZWaveController.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -850,12 +850,13 @@ public void requestRemoveFailedNode(int nodeId) {
850850
}
851851

852852
/**
853-
* Marks a node as failed
853+
* Substitutes a failed node in the network. Note that this won't substitute
854+
* nodes that are not marked as failed.
854855
*
855856
* @param nodeId
856-
* The address of the node to set failed
857+
* The address of the node to be replaced
857858
*/
858-
public void requestSetFailedNode(int nodeId) {
859+
public void replaceFailedNode(int nodeId) {
859860
enqueue(new ReplaceFailedNodeMessageClass().doRequest(nodeId));
860861
}
861862

src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/IsFailedNodeMessageClass.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,14 @@ public boolean handleResponse(ZWaveController zController, ZWaveTransaction tran
5252
return false;
5353
}
5454

55+
// With Thing Actions, need to inform the user via non-debug log the status.
56+
// The Thing UI page may only show OFFLINE for both a success and failure when
57+
// testing an OFFLINE node for failed node status.
5558
if (incomingMessage.getMessagePayloadByte(0) != 0x00) {
56-
logger.debug("NODE {}: Is currently marked as failed by the controller!", nodeId);
59+
logger.info("NODE {}: Is currently marked as failed by the controller!", nodeId);
5760
node.setNodeState(ZWaveNodeState.FAILED);
5861
} else {
59-
logger.debug("NODE {}: Is currently marked as healthy by the controller", nodeId);
62+
logger.info("NODE {}: Is currently marked as healthy by the controller", nodeId);
6063
// ZWaveNodeState.ALIVE is not necessarily true - The check is only whether the node is in
6164
// the controller's failed nodes list. No ZWave traffic to the node is sent here to verify.
6265
// Node state should be updated by other mechanisms such as polling or application commands.

src/main/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RemoveFailedNodeMessageClass.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public ZWaveSerialPayload doRequest(int nodeId) {
6262
logger.debug("NODE {}: Marking node as having failed.", nodeId);
6363

6464
// Create the request
65-
return new ZWaveTransactionMessageBuilder(SerialMessageClass.RemoveFailedNodeID).withPayload(nodeId, 1).build();
65+
return new ZWaveTransactionMessageBuilder(SerialMessageClass.RemoveFailedNodeID).withPayload(nodeId).build();
6666
}
6767

6868
@Override

src/main/resources/OH-INF/i18n/actions.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ actions.controller-sync.label=Synchronize network
1111
actions.controller-sync.description=Download the network with the SUC.
1212

1313
actions.node-failed.label=Check if node is failed
14-
actions.node-failed.description=Check if the Controller considers this node has failed, not just offline.
14+
actions.node-failed.description=Check if the Controller considers this node is failed. For mains powered nodes only.
1515

1616
actions.node-remove.label=Remove failed node from the controller
17-
actions.node-remove.description=ONLY works if the node is marked as failed. Normally use controller Exclude Devices action.
17+
actions.node-remove.description= Node must marked as failed first. For mains powered nodes only. Controller Exclude Devices is preferred.
1818

1919
actions.node-reinit.label=Re-Interview the node
2020
actions.node-reinit.description=Clear all info about this node and make a new full interview.

src/test/java/org/openhab/binding/zwave/internal/protocol/serialmessage/RemoveFailedNodeMessageClassTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,13 @@
2424
* Test cases for RemoveFailedNodeMessageClass message.
2525
* This takes some example packets, processes them, and checks that the processing is correct.
2626
*
27-
* @author Chris Jackson
27+
* @author Chris Jackson - Initial contribution
2828
*
2929
*/
3030
public class RemoveFailedNodeMessageClassTest {
3131
@Test
3232
public void doRequest() {
33-
byte[] expectedResponse = { 12, 1 };
33+
byte[] expectedResponse = { 12 };
3434

3535
RemoveFailedNodeMessageClass handler = new RemoveFailedNodeMessageClass();
3636
ZWaveSerialPayload msg = handler.doRequest(12);

0 commit comments

Comments
 (0)