Skip to content
Merged
68 changes: 67 additions & 1 deletion test/util/test_node.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
"""Test node utility functions."""
import pytest

from zwave_js_server.const import CommandClass
from zwave_js_server.exceptions import InvalidNewValue, NotFoundError
from zwave_js_server.model.node import Node
from zwave_js_server.model.value import ConfigurationValue
from zwave_js_server.util.node import async_set_config_parameter
from zwave_js_server.util.node import (
async_bulk_set_partial_config_parameters,
async_set_config_parameter,
)


async def test_configuration_parameter_values(
Expand Down Expand Up @@ -101,3 +105,65 @@ async def test_configuration_parameter_values(
"value": 4,
"messageId": uuid4,
}


async def test_bulk_set_partial_config_parameters(multisensor_6, uuid4, mock_command):
"""Test bulk setting partial config parameters."""
node: Node = multisensor_6
ack_commands = mock_command(
{"command": "node.set_value", "nodeId": node.node_id},
{"success": True},
)
await async_bulk_set_partial_config_parameters(node, 241, 101)
assert len(ack_commands) == 1
assert ack_commands[0] == {
"command": "node.set_value",
"nodeId": node.node_id,
"valueId": {
"commandClass": CommandClass.CONFIGURATION.value,
"property": 101,
},
"value": 241,
"messageId": uuid4,
}

await async_bulk_set_partial_config_parameters(
node, {128: 1, 64: 1, 32: 1, 16: 1, 1: 1}, 101
)
assert len(ack_commands) == 2
assert ack_commands[1] == {
"command": "node.set_value",
"nodeId": node.node_id,
"valueId": {
"commandClass": CommandClass.CONFIGURATION.value,
"property": 101,
},
"value": 241,
"messageId": uuid4,
}

# Only set some values so we use cached values for the rest
await async_bulk_set_partial_config_parameters(
node, {64: 1, 32: 1, 16: 1, 1: 1}, 101
)
assert len(ack_commands) == 3
assert ack_commands[2] == {
"command": "node.set_value",
"nodeId": node.node_id,
"valueId": {
"commandClass": CommandClass.CONFIGURATION.value,
"property": 101,
},
"value": 241,
"messageId": uuid4,
}

# Use an invalid property
with pytest.raises(NotFoundError):
await async_bulk_set_partial_config_parameters(node, 99, 999)

# use an invalid bitmask
with pytest.raises(NotFoundError):
await async_bulk_set_partial_config_parameters(
node, {128: 1, 64: 1, 32: 1, 16: 1, 2: 1}, 101
)
14 changes: 7 additions & 7 deletions zwave_js_server/model/node.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def receive_event(self, event: Event) -> None:

self.emit(event.type, event.data)

async def _async_send_command(
async def async_send_command(
Comment thread
MartinHjelmare marked this conversation as resolved.
self,
cmd: str,
require_schema: Optional[int] = None,
Expand Down Expand Up @@ -367,7 +367,7 @@ async def async_set_value(
raise UnwriteableValue

# the value object needs to be send to the server
result = await self._async_send_command(
result = await self.async_send_command(
"set_value",
valueId=val.data,
value=new_value,
Expand All @@ -381,11 +381,11 @@ async def async_set_value(

async def async_refresh_info(self) -> None:
"""Send refreshInfo command to Node."""
await self._async_send_command("refresh_info", wait_for_result=False)
await self.async_send_command("refresh_info", wait_for_result=False)

async def async_get_defined_value_ids(self) -> List[Value]:
"""Send getDefinedValueIDs command to Node."""
data = await self._async_send_command(
data = await self.async_send_command(
"get_defined_value_ids", wait_for_result=True
)

Expand All @@ -403,21 +403,21 @@ async def async_get_value_metadata(self, val: Union[Value, str]) -> ValueMetadat
if not isinstance(val, Value):
val = self.values[val]
# the value object needs to be send to the server
data = await self._async_send_command(
data = await self.async_send_command(
"get_value_metadata", valueId=val.data, wait_for_result=True
)
return ValueMetadata(cast(MetaDataType, data))

async def async_abort_firmware_update(self) -> None:
"""Send abortFirmwareUpdate command to Node."""
await self._async_send_command("abort_firmware_update", wait_for_result=False)
await self.async_send_command("abort_firmware_update", wait_for_result=False)

async def async_poll_value(self, val: Union[Value, str]) -> None:
"""Send pollValue command to Node for given value (or value_id)."""
# a value may be specified as value_id or the value itself
if not isinstance(val, Value):
val = self.values[val]
await self._async_send_command("poll_value", valueId=val.data, require_schema=1)
await self.async_send_command("poll_value", valueId=val.data, require_schema=1)

def handle_wake_up(self, event: Event) -> None:
"""Process a node wake up event."""
Expand Down
6 changes: 6 additions & 0 deletions zwave_js_server/model/value.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ class MetaDataType(TypedDict, total=False):
states: Dict[int, str]
ccSpecific: Dict[str, Any]
allowManualEntry: bool
valueSize: int


class ValueDataType(TypedDict, total=False):
Expand Down Expand Up @@ -141,6 +142,11 @@ def allow_manual_entry(self) -> Optional[bool]:
"""Return allowManualEntry."""
return self.data.get("allowManualEntry")

@property
def value_size(self) -> Optional[int]:
"""Return valueSize."""
return self.data.get("valueSize")

def update(self, data: MetaDataType) -> None:
"""Update data."""
self.data.update(data)
Expand Down
2 changes: 1 addition & 1 deletion zwave_js_server/util/lock.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
)
from ..exceptions import NotFoundError
from ..model.node import Node
from ..model.value import get_value_id, Value
from ..model.value import Value, get_value_id


def get_code_slot_value(node: Node, code_slot: int, property_name: str) -> Value:
Expand Down
Loading