Skip to content

Commit 8212e1a

Browse files
Return command status when setting a config parameter (#177)
Co-authored-by: Martin Hjelmare <[email protected]>
1 parent 02df775 commit 8212e1a

File tree

3 files changed

+89
-16
lines changed

3 files changed

+89
-16
lines changed

test/util/test_node.py

Lines changed: 63 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
"""Test node utility functions."""
22
import pytest
33

4-
from zwave_js_server.const import CommandClass
5-
from zwave_js_server.exceptions import InvalidNewValue, NotFoundError, ValueTypeError
4+
from zwave_js_server.const import CommandClass, CommandStatus
5+
from zwave_js_server.exceptions import (
6+
InvalidNewValue,
7+
NotFoundError,
8+
SetValueFailed,
9+
ValueTypeError,
10+
)
611
from zwave_js_server.model.node import Node
712
from zwave_js_server.model.value import ConfigurationValue
813
from zwave_js_server.util.node import (
@@ -47,7 +52,9 @@ async def test_configuration_parameter_values(
4752
{"success": True},
4853
)
4954

50-
await async_set_config_parameter(node_2, 190, 8, 255)
55+
zwave_value, cmd_status = await async_set_config_parameter(node_2, 190, 8, 255)
56+
assert isinstance(zwave_value, ConfigurationValue)
57+
assert cmd_status == CommandStatus.ACCEPTED
5158

5259
value = node_2.values["31-112-0-8-255"]
5360
assert len(ack_commands_2) == 1
@@ -59,7 +66,9 @@ async def test_configuration_parameter_values(
5966
"messageId": uuid4,
6067
}
6168

62-
await async_set_config_parameter(node_2, "Blue", 8, 255)
69+
zwave_value, cmd_status = await async_set_config_parameter(node_2, "Blue", 8, 255)
70+
assert isinstance(zwave_value, ConfigurationValue)
71+
assert cmd_status == CommandStatus.ACCEPTED
6372

6473
value = node_2.values["31-112-0-8-255"]
6574
assert len(ack_commands_2) == 2
@@ -92,9 +101,11 @@ async def test_configuration_parameter_values(
92101
await async_set_config_parameter(node, 1, 1, property_key=1)
93102

94103
# Test setting a configuration parameter by state label and property name
95-
await async_set_config_parameter(
104+
zwave_value, cmd_status = await async_set_config_parameter(
96105
node, "2.0\u00b0 F", "Temperature Reporting Threshold"
97106
)
107+
assert isinstance(zwave_value, ConfigurationValue)
108+
assert cmd_status == CommandStatus.ACCEPTED
98109

99110
value = node.values["13-112-0-1"]
100111
assert len(ack_commands) == 3
@@ -114,7 +125,8 @@ async def test_bulk_set_partial_config_parameters(multisensor_6, uuid4, mock_com
114125
{"command": "node.set_value", "nodeId": node.node_id},
115126
{"success": True},
116127
)
117-
await async_bulk_set_partial_config_parameters(node, 101, 241)
128+
cmd_status = await async_bulk_set_partial_config_parameters(node, 101, 241)
129+
assert cmd_status == CommandStatus.QUEUED
118130
assert len(ack_commands) == 1
119131
assert ack_commands[0] == {
120132
"command": "node.set_value",
@@ -127,9 +139,10 @@ async def test_bulk_set_partial_config_parameters(multisensor_6, uuid4, mock_com
127139
"messageId": uuid4,
128140
}
129141

130-
await async_bulk_set_partial_config_parameters(
142+
cmd_status = await async_bulk_set_partial_config_parameters(
131143
node, 101, {128: 1, 64: 1, 32: 1, 16: 1, 1: 1}
132144
)
145+
assert cmd_status == CommandStatus.QUEUED
133146
assert len(ack_commands) == 2
134147
assert ack_commands[1] == {
135148
"command": "node.set_value",
@@ -143,9 +156,10 @@ async def test_bulk_set_partial_config_parameters(multisensor_6, uuid4, mock_com
143156
}
144157

145158
# Only set some values so we use cached values for the rest
146-
await async_bulk_set_partial_config_parameters(
159+
cmd_status = await async_bulk_set_partial_config_parameters(
147160
node, 101, {64: 1, 32: 1, 16: 1, 1: 1}
148161
)
162+
assert cmd_status == CommandStatus.QUEUED
149163
assert len(ack_commands) == 3
150164
assert ack_commands[2] == {
151165
"command": "node.set_value",
@@ -171,3 +185,44 @@ async def test_bulk_set_partial_config_parameters(multisensor_6, uuid4, mock_com
171185
# Try to bulkset a property that isn't broken into partials
172186
with pytest.raises(ValueTypeError):
173187
await async_bulk_set_partial_config_parameters(node, 252, 1)
188+
189+
190+
async def test_failures(multisensor_6, mock_command):
191+
"""Test setting config parameter failures."""
192+
node: Node = multisensor_6
193+
# We need the node to be alive so we wait for a response
194+
node.handle_alive(node)
195+
196+
mock_command(
197+
{"command": "node.set_value", "nodeId": node.node_id},
198+
{"success": False},
199+
)
200+
201+
with pytest.raises(SetValueFailed):
202+
await async_bulk_set_partial_config_parameters(
203+
node, 101, {64: 1, 32: 1, 16: 1, 1: 1}
204+
)
205+
206+
with pytest.raises(SetValueFailed):
207+
await async_set_config_parameter(node, 1, 101, 64)
208+
209+
210+
async def test_returned_values(multisensor_6, mock_command):
211+
"""Test returned values from setting config parameters."""
212+
node: Node = multisensor_6
213+
# We need the node to be alive so we wait for a response
214+
node.handle_alive(node)
215+
216+
mock_command(
217+
{"command": "node.set_value", "nodeId": node.node_id},
218+
{"success": True},
219+
)
220+
221+
cmd_status = await async_bulk_set_partial_config_parameters(
222+
node, 101, {64: 1, 32: 1, 16: 1, 1: 1}
223+
)
224+
assert cmd_status == CommandStatus.ACCEPTED
225+
226+
zwave_value, cmd_status = await async_set_config_parameter(node, 1, 101, 64)
227+
assert isinstance(zwave_value, ConfigurationValue)
228+
assert cmd_status == CommandStatus.ACCEPTED

zwave_js_server/const.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
VALUE_UNKNOWN = "unknown"
1111

1212

13+
class CommandStatus(str, Enum):
14+
"""Status of a command sent to zwave-js-server."""
15+
16+
ACCEPTED = "accepted"
17+
QUEUED = "queued"
18+
19+
1320
class EntryControlEventType(IntEnum):
1421
"""Entry control event types."""
1522

zwave_js_server/util/node.py

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""Utility functions for Z-Wave JS nodes."""
22
import json
3-
from typing import Dict, Optional, Union, cast
3+
from typing import Dict, Optional, Tuple, Union, cast
44

5-
from ..const import CommandClass, ConfigurationValueType
5+
from ..const import CommandClass, CommandStatus, ConfigurationValueType
66
from ..exceptions import InvalidNewValue, NotFoundError, SetValueFailed, ValueTypeError
77
from ..model.node import Node
88
from ..model.value import ConfigurationValue, get_value_id
@@ -88,7 +88,7 @@ async def async_bulk_set_partial_config_parameters(
8888
node: Node,
8989
property_: int,
9090
new_value: Union[int, Dict[int, Union[int, str]]],
91-
) -> None:
91+
) -> CommandStatus:
9292
"""Bulk set partial configuration values on this node."""
9393
config_values = node.get_configuration_values()
9494
property_values = [
@@ -153,28 +153,36 @@ async def async_bulk_set_partial_config_parameters(
153153
remaining_value = remaining_value % multiplication_factor
154154
_validate_and_transform_new_value(zwave_value, partial_value)
155155

156-
response = await node.async_send_command(
156+
cmd_response = await node.async_send_command(
157157
"set_value",
158158
valueId={
159159
"commandClass": CommandClass.CONFIGURATION.value,
160160
"property": property_,
161161
},
162162
value=new_value,
163163
)
164-
if response and not cast(bool, response["success"]):
164+
165+
# If we didn't wait for a response, we assume the command has been queued
166+
if cmd_response is None:
167+
return CommandStatus.QUEUED
168+
169+
if not cast(bool, cmd_response["success"]):
165170
raise SetValueFailed(
166171
"Unable to set value, refer to "
167172
"https://zwave-js.github.io/node-zwave-js/#/api/node?id=setvalue for "
168173
"possible reasons"
169174
)
170175

176+
# If we received a response that is not false, the command was successful
177+
return CommandStatus.ACCEPTED
178+
171179

172180
async def async_set_config_parameter(
173181
node: Node,
174182
new_value: Union[int, str],
175183
property_or_property_name: Union[int, str],
176184
property_key: Optional[Union[int, str]] = None,
177-
) -> ConfigurationValue:
185+
) -> Tuple[ConfigurationValue, CommandStatus]:
178186
"""
179187
Set a value for a config parameter on this node.
180188
@@ -216,11 +224,14 @@ async def async_set_config_parameter(
216224
new_value = _validate_and_transform_new_value(zwave_value, new_value)
217225

218226
# Finally attempt to set the value and return the Value object if successful
219-
if await node.async_set_value(zwave_value, new_value) is False:
227+
success = await node.async_set_value(zwave_value, new_value)
228+
if success is False:
220229
raise SetValueFailed(
221230
"Unable to set value, refer to "
222231
"https://zwave-js.github.io/node-zwave-js/#/api/node?id=setvalue for "
223232
"possible reasons"
224233
)
225234

226-
return zwave_value
235+
status = CommandStatus.ACCEPTED if success else CommandStatus.QUEUED
236+
237+
return zwave_value, status

0 commit comments

Comments
 (0)