Change Z-Wave JS discovery logic to adopt changes to DeviceClass (#46983)
Co-authored-by: raman325 <7243222+raman325@users.noreply.github.com>pull/47017/head
parent
afae253432
commit
23cbd2dda3
|
@ -429,10 +429,9 @@ async def websocket_update_log_config(
|
|||
"""Update the driver log config."""
|
||||
entry_id = msg[ENTRY_ID]
|
||||
client = hass.data[DOMAIN][entry_id][DATA_CLIENT]
|
||||
result = await client.driver.async_update_log_config(LogConfig(**msg[CONFIG]))
|
||||
await client.driver.async_update_log_config(LogConfig(**msg[CONFIG]))
|
||||
connection.send_result(
|
||||
msg[ID],
|
||||
result,
|
||||
)
|
||||
|
||||
|
||||
|
|
|
@ -287,7 +287,7 @@ class ZWaveBooleanBinarySensor(ZWaveBaseEntity, BinarySensorEntity):
|
|||
if self.info.primary_value.command_class == CommandClass.SENSOR_BINARY:
|
||||
# Legacy binary sensors are phased out (replaced by notification sensors)
|
||||
# Disable by default to not confuse users
|
||||
if self.info.node.device_class.generic != "Binary Sensor":
|
||||
if self.info.node.device_class.generic.key != 0x20:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ from dataclasses import dataclass
|
|||
from typing import Generator, List, Optional, Set, Union
|
||||
|
||||
from zwave_js_server.const import CommandClass
|
||||
from zwave_js_server.model.device_class import DeviceClassItem
|
||||
from zwave_js_server.model.node import Node as ZwaveNode
|
||||
from zwave_js_server.model.value import Value as ZwaveValue
|
||||
|
||||
|
@ -72,11 +73,11 @@ class ZWaveDiscoverySchema:
|
|||
# [optional] the node's firmware_version must match ANY of these values
|
||||
firmware_version: Optional[Set[str]] = None
|
||||
# [optional] the node's basic device class must match ANY of these values
|
||||
device_class_basic: Optional[Set[str]] = None
|
||||
device_class_basic: Optional[Set[Union[str, int]]] = None
|
||||
# [optional] the node's generic device class must match ANY of these values
|
||||
device_class_generic: Optional[Set[str]] = None
|
||||
device_class_generic: Optional[Set[Union[str, int]]] = None
|
||||
# [optional] the node's specific device class must match ANY of these values
|
||||
device_class_specific: Optional[Set[str]] = None
|
||||
device_class_specific: Optional[Set[Union[str, int]]] = None
|
||||
# [optional] additional values that ALL need to be present on the node for this scheme to pass
|
||||
required_values: Optional[List[ZWaveValueDiscoverySchema]] = None
|
||||
# [optional] bool to specify if this primary value may be discovered by multiple platforms
|
||||
|
@ -416,21 +417,18 @@ def async_discover_values(node: ZwaveNode) -> Generator[ZwaveDiscoveryInfo, None
|
|||
):
|
||||
continue
|
||||
# check device_class_basic
|
||||
if (
|
||||
schema.device_class_basic is not None
|
||||
and value.node.device_class.basic not in schema.device_class_basic
|
||||
if not check_device_class(
|
||||
value.node.device_class.basic, schema.device_class_basic
|
||||
):
|
||||
continue
|
||||
# check device_class_generic
|
||||
if (
|
||||
schema.device_class_generic is not None
|
||||
and value.node.device_class.generic not in schema.device_class_generic
|
||||
if not check_device_class(
|
||||
value.node.device_class.generic, schema.device_class_generic
|
||||
):
|
||||
continue
|
||||
# check device_class_specific
|
||||
if (
|
||||
schema.device_class_specific is not None
|
||||
and value.node.device_class.specific not in schema.device_class_specific
|
||||
if not check_device_class(
|
||||
value.node.device_class.specific, schema.device_class_specific
|
||||
):
|
||||
continue
|
||||
# check primary value
|
||||
|
@ -474,3 +472,18 @@ def check_value(value: ZwaveValue, schema: ZWaveValueDiscoverySchema) -> bool:
|
|||
if schema.type is not None and value.metadata.type not in schema.type:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
@callback
|
||||
def check_device_class(
|
||||
device_class: DeviceClassItem, required_value: Optional[Set[Union[str, int]]]
|
||||
) -> bool:
|
||||
"""Check if device class id or label matches."""
|
||||
if required_value is None:
|
||||
return True
|
||||
for val in required_value:
|
||||
if isinstance(val, str) and device_class.label == val:
|
||||
return True
|
||||
if isinstance(val, int) and device_class.key == val:
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Z-Wave JS",
|
||||
"config_flow": true,
|
||||
"documentation": "https://www.home-assistant.io/integrations/zwave_js",
|
||||
"requirements": ["zwave-js-server-python==0.18.0"],
|
||||
"requirements": ["zwave-js-server-python==0.19.0"],
|
||||
"codeowners": ["@home-assistant/z-wave"],
|
||||
"dependencies": ["http", "websocket_api"]
|
||||
}
|
||||
|
|
|
@ -2406,4 +2406,4 @@ zigpy==0.32.0
|
|||
zm-py==0.5.2
|
||||
|
||||
# homeassistant.components.zwave_js
|
||||
zwave-js-server-python==0.18.0
|
||||
zwave-js-server-python==0.19.0
|
||||
|
|
|
@ -1243,4 +1243,4 @@ zigpy-znp==0.4.0
|
|||
zigpy==0.32.0
|
||||
|
||||
# homeassistant.components.zwave_js
|
||||
zwave-js-server-python==0.18.0
|
||||
zwave-js-server-python==0.19.0
|
||||
|
|
|
@ -345,7 +345,6 @@ async def test_update_log_config(hass, client, integration, hass_ws_client):
|
|||
}
|
||||
)
|
||||
msg = await ws_client.receive_json()
|
||||
assert msg["result"]
|
||||
assert msg["success"]
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
|
@ -366,7 +365,6 @@ async def test_update_log_config(hass, client, integration, hass_ws_client):
|
|||
}
|
||||
)
|
||||
msg = await ws_client.receive_json()
|
||||
assert msg["result"]
|
||||
assert msg["success"]
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
|
@ -393,7 +391,6 @@ async def test_update_log_config(hass, client, integration, hass_ws_client):
|
|||
}
|
||||
)
|
||||
msg = await ws_client.receive_json()
|
||||
assert msg["result"]
|
||||
assert msg["success"]
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
|
|
|
@ -69,8 +69,8 @@ async def test_thermostat_v2(
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 13
|
||||
assert args["valueId"] == {
|
||||
|
@ -92,7 +92,7 @@ async def test_thermostat_v2(
|
|||
}
|
||||
assert args["value"] == 1
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test setting hvac mode
|
||||
await hass.services.async_call(
|
||||
|
@ -105,8 +105,8 @@ async def test_thermostat_v2(
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 13
|
||||
assert args["valueId"] == {
|
||||
|
@ -128,7 +128,7 @@ async def test_thermostat_v2(
|
|||
}
|
||||
assert args["value"] == 2
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test setting temperature
|
||||
await hass.services.async_call(
|
||||
|
@ -142,8 +142,8 @@ async def test_thermostat_v2(
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 2
|
||||
args = client.async_send_command.call_args_list[0][0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 2
|
||||
args = client.async_send_command_no_wait.call_args_list[0][0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 13
|
||||
assert args["valueId"] == {
|
||||
|
@ -164,7 +164,7 @@ async def test_thermostat_v2(
|
|||
"value": 1,
|
||||
}
|
||||
assert args["value"] == 2
|
||||
args = client.async_send_command.call_args_list[1][0][0]
|
||||
args = client.async_send_command_no_wait.call_args_list[1][0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 13
|
||||
assert args["valueId"] == {
|
||||
|
@ -186,7 +186,7 @@ async def test_thermostat_v2(
|
|||
}
|
||||
assert args["value"] == 77
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test cool mode update from value updated event
|
||||
event = Event(
|
||||
|
@ -237,7 +237,7 @@ async def test_thermostat_v2(
|
|||
assert state.attributes[ATTR_TARGET_TEMP_HIGH] == 22.8
|
||||
assert state.attributes[ATTR_TARGET_TEMP_LOW] == 22.2
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test setting temperature with heat_cool
|
||||
await hass.services.async_call(
|
||||
|
@ -251,8 +251,8 @@ async def test_thermostat_v2(
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 2
|
||||
args = client.async_send_command.call_args_list[0][0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 2
|
||||
args = client.async_send_command_no_wait.call_args_list[0][0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 13
|
||||
assert args["valueId"] == {
|
||||
|
@ -274,7 +274,7 @@ async def test_thermostat_v2(
|
|||
}
|
||||
assert args["value"] == 77
|
||||
|
||||
args = client.async_send_command.call_args_list[1][0][0]
|
||||
args = client.async_send_command_no_wait.call_args_list[1][0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 13
|
||||
assert args["valueId"] == {
|
||||
|
@ -296,7 +296,7 @@ async def test_thermostat_v2(
|
|||
}
|
||||
assert args["value"] == 86
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
# Test setting unknown preset mode
|
||||
|
@ -310,7 +310,7 @@ async def test_thermostat_v2(
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 0
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 0
|
||||
|
||||
# Test setting invalid hvac mode
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -336,7 +336,7 @@ async def test_thermostat_v2(
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test setting fan mode
|
||||
await hass.services.async_call(
|
||||
|
@ -349,8 +349,8 @@ async def test_thermostat_v2(
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 13
|
||||
assert args["valueId"] == {
|
||||
|
@ -373,7 +373,7 @@ async def test_thermostat_v2(
|
|||
}
|
||||
assert args["value"] == 1
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test setting invalid fan mode
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -408,7 +408,7 @@ async def test_setpoint_thermostat(hass, client, climate_danfoss_lc_13, integrat
|
|||
assert state.attributes[ATTR_HVAC_MODES] == [HVAC_MODE_HEAT]
|
||||
assert state.attributes[ATTR_PRESET_MODE] == PRESET_NONE
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test setting temperature
|
||||
await hass.services.async_call(
|
||||
|
@ -421,8 +421,8 @@ async def test_setpoint_thermostat(hass, client, climate_danfoss_lc_13, integrat
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args_list[0][0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args_list[0][0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 5
|
||||
assert args["valueId"] == {
|
||||
|
@ -444,7 +444,7 @@ async def test_setpoint_thermostat(hass, client, climate_danfoss_lc_13, integrat
|
|||
}
|
||||
assert args["value"] == 21.5
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test setpoint mode update from value updated event
|
||||
event = Event(
|
||||
|
@ -471,7 +471,7 @@ async def test_setpoint_thermostat(hass, client, climate_danfoss_lc_13, integrat
|
|||
assert state.state == HVAC_MODE_HEAT
|
||||
assert state.attributes[ATTR_TEMPERATURE] == 23
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
|
||||
async def test_thermostat_heatit(hass, client, climate_heatit_z_trm3, integration):
|
||||
|
|
|
@ -38,8 +38,8 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 6
|
||||
assert args["valueId"] == {
|
||||
|
@ -60,7 +60,7 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
}
|
||||
assert args["value"] == 50
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test setting position
|
||||
await hass.services.async_call(
|
||||
|
@ -70,8 +70,8 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 6
|
||||
assert args["valueId"] == {
|
||||
|
@ -92,7 +92,7 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
}
|
||||
assert args["value"] == 0
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test opening
|
||||
await hass.services.async_call(
|
||||
|
@ -102,8 +102,8 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 6
|
||||
assert args["valueId"] == {
|
||||
|
@ -124,7 +124,7 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
}
|
||||
assert args["value"]
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
# Test stop after opening
|
||||
await hass.services.async_call(
|
||||
"cover",
|
||||
|
@ -133,8 +133,8 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 2
|
||||
open_args = client.async_send_command.call_args_list[0][0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 2
|
||||
open_args = client.async_send_command_no_wait.call_args_list[0][0][0]
|
||||
assert open_args["command"] == "node.set_value"
|
||||
assert open_args["nodeId"] == 6
|
||||
assert open_args["valueId"] == {
|
||||
|
@ -153,7 +153,7 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
}
|
||||
assert not open_args["value"]
|
||||
|
||||
close_args = client.async_send_command.call_args_list[1][0][0]
|
||||
close_args = client.async_send_command_no_wait.call_args_list[1][0][0]
|
||||
assert close_args["command"] == "node.set_value"
|
||||
assert close_args["nodeId"] == 6
|
||||
assert close_args["valueId"] == {
|
||||
|
@ -191,7 +191,7 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
},
|
||||
)
|
||||
node.receive_event(event)
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
state = hass.states.get(WINDOW_COVER_ENTITY)
|
||||
assert state.state == "open"
|
||||
|
@ -203,8 +203,8 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
{"entity_id": WINDOW_COVER_ENTITY},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 6
|
||||
assert args["valueId"] == {
|
||||
|
@ -225,7 +225,7 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
}
|
||||
assert args["value"] == 0
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test stop after closing
|
||||
await hass.services.async_call(
|
||||
|
@ -235,8 +235,8 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 2
|
||||
open_args = client.async_send_command.call_args_list[0][0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 2
|
||||
open_args = client.async_send_command_no_wait.call_args_list[0][0][0]
|
||||
assert open_args["command"] == "node.set_value"
|
||||
assert open_args["nodeId"] == 6
|
||||
assert open_args["valueId"] == {
|
||||
|
@ -255,7 +255,7 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
}
|
||||
assert not open_args["value"]
|
||||
|
||||
close_args = client.async_send_command.call_args_list[1][0][0]
|
||||
close_args = client.async_send_command_no_wait.call_args_list[1][0][0]
|
||||
assert close_args["command"] == "node.set_value"
|
||||
assert close_args["nodeId"] == 6
|
||||
assert close_args["valueId"] == {
|
||||
|
@ -274,7 +274,7 @@ async def test_window_cover(hass, client, chain_actuator_zws12, integration):
|
|||
}
|
||||
assert not close_args["value"]
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
event = Event(
|
||||
type="value updated",
|
||||
|
@ -314,8 +314,8 @@ async def test_motor_barrier_cover(hass, client, gdc_zw062, integration):
|
|||
DOMAIN, SERVICE_OPEN_COVER, {"entity_id": GDC_COVER_ENTITY}, blocking=True
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 12
|
||||
assert args["value"] == 255
|
||||
|
@ -341,15 +341,15 @@ async def test_motor_barrier_cover(hass, client, gdc_zw062, integration):
|
|||
state = hass.states.get(GDC_COVER_ENTITY)
|
||||
assert state.state == STATE_CLOSED
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test close
|
||||
await hass.services.async_call(
|
||||
DOMAIN, SERVICE_CLOSE_COVER, {"entity_id": GDC_COVER_ENTITY}, blocking=True
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 12
|
||||
assert args["value"] == 0
|
||||
|
@ -375,7 +375,7 @@ async def test_motor_barrier_cover(hass, client, gdc_zw062, integration):
|
|||
state = hass.states.get(GDC_COVER_ENTITY)
|
||||
assert state.state == STATE_CLOSED
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Barrier sends an opening state
|
||||
event = Event(
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
async def test_iblinds_v2(hass, client, iblinds_v2, integration):
|
||||
"""Test that an iBlinds v2.0 multilevel switch value is discovered as a cover."""
|
||||
node = iblinds_v2
|
||||
assert node.device_class.specific == "Unused"
|
||||
assert node.device_class.specific.label == "Unused"
|
||||
|
||||
state = hass.states.get("light.window_blind_controller")
|
||||
assert not state
|
||||
|
@ -16,7 +16,7 @@ async def test_iblinds_v2(hass, client, iblinds_v2, integration):
|
|||
async def test_ge_12730(hass, client, ge_12730, integration):
|
||||
"""Test GE 12730 Fan Controller v2.0 multilevel switch is discovered as a fan."""
|
||||
node = ge_12730
|
||||
assert node.device_class.specific == "Multilevel Power Switch"
|
||||
assert node.device_class.specific.label == "Multilevel Power Switch"
|
||||
|
||||
state = hass.states.get("light.in_wall_smart_fan_control")
|
||||
assert not state
|
||||
|
|
|
@ -23,8 +23,8 @@ async def test_fan(hass, client, in_wall_smart_fan_control, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 17
|
||||
assert args["valueId"] == {
|
||||
|
@ -45,7 +45,7 @@ async def test_fan(hass, client, in_wall_smart_fan_control, integration):
|
|||
}
|
||||
assert args["value"] == 66
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test setting unknown speed
|
||||
with pytest.raises(ValueError):
|
||||
|
@ -56,7 +56,7 @@ async def test_fan(hass, client, in_wall_smart_fan_control, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test turn on no speed
|
||||
await hass.services.async_call(
|
||||
|
@ -66,8 +66,8 @@ async def test_fan(hass, client, in_wall_smart_fan_control, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 17
|
||||
assert args["valueId"] == {
|
||||
|
@ -88,7 +88,7 @@ async def test_fan(hass, client, in_wall_smart_fan_control, integration):
|
|||
}
|
||||
assert args["value"] == 255
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test turning off
|
||||
await hass.services.async_call(
|
||||
|
@ -98,8 +98,8 @@ async def test_fan(hass, client, in_wall_smart_fan_control, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 17
|
||||
assert args["valueId"] == {
|
||||
|
@ -120,7 +120,7 @@ async def test_fan(hass, client, in_wall_smart_fan_control, integration):
|
|||
}
|
||||
assert args["value"] == 0
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test speed update from value updated event
|
||||
event = Event(
|
||||
|
@ -146,7 +146,7 @@ async def test_fan(hass, client, in_wall_smart_fan_control, integration):
|
|||
assert state.state == "on"
|
||||
assert state.attributes[ATTR_SPEED] == "high"
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
event = Event(
|
||||
type="value updated",
|
||||
|
|
|
@ -36,8 +36,8 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 39
|
||||
assert args["valueId"] == {
|
||||
|
@ -58,7 +58,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
}
|
||||
assert args["value"] == 255
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test brightness update from value updated event
|
||||
event = Event(
|
||||
|
@ -93,9 +93,9 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test turning on with brightness
|
||||
await hass.services.async_call(
|
||||
|
@ -105,8 +105,8 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 39
|
||||
assert args["valueId"] == {
|
||||
|
@ -127,7 +127,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
}
|
||||
assert args["value"] == 50
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test turning on with rgb color
|
||||
await hass.services.async_call(
|
||||
|
@ -137,8 +137,10 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 5
|
||||
warm_args = client.async_send_command.call_args_list[0][0][0] # warm white 0
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 5
|
||||
warm_args = client.async_send_command_no_wait.call_args_list[0][0][
|
||||
0
|
||||
] # warm white 0
|
||||
assert warm_args["command"] == "node.set_value"
|
||||
assert warm_args["nodeId"] == 39
|
||||
assert warm_args["valueId"]["commandClassName"] == "Color Switch"
|
||||
|
@ -149,7 +151,9 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
assert warm_args["valueId"]["propertyName"] == "targetColor"
|
||||
assert warm_args["value"] == 0
|
||||
|
||||
cold_args = client.async_send_command.call_args_list[1][0][0] # cold white 0
|
||||
cold_args = client.async_send_command_no_wait.call_args_list[1][0][
|
||||
0
|
||||
] # cold white 0
|
||||
assert cold_args["command"] == "node.set_value"
|
||||
assert cold_args["nodeId"] == 39
|
||||
assert cold_args["valueId"]["commandClassName"] == "Color Switch"
|
||||
|
@ -159,7 +163,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
assert cold_args["valueId"]["property"] == "targetColor"
|
||||
assert cold_args["valueId"]["propertyName"] == "targetColor"
|
||||
assert cold_args["value"] == 0
|
||||
red_args = client.async_send_command.call_args_list[2][0][0] # red 255
|
||||
red_args = client.async_send_command_no_wait.call_args_list[2][0][0] # red 255
|
||||
assert red_args["command"] == "node.set_value"
|
||||
assert red_args["nodeId"] == 39
|
||||
assert red_args["valueId"]["commandClassName"] == "Color Switch"
|
||||
|
@ -169,7 +173,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
assert red_args["valueId"]["property"] == "targetColor"
|
||||
assert red_args["valueId"]["propertyName"] == "targetColor"
|
||||
assert red_args["value"] == 255
|
||||
green_args = client.async_send_command.call_args_list[3][0][0] # green 76
|
||||
green_args = client.async_send_command_no_wait.call_args_list[3][0][0] # green 76
|
||||
assert green_args["command"] == "node.set_value"
|
||||
assert green_args["nodeId"] == 39
|
||||
assert green_args["valueId"]["commandClassName"] == "Color Switch"
|
||||
|
@ -179,7 +183,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
assert green_args["valueId"]["property"] == "targetColor"
|
||||
assert green_args["valueId"]["propertyName"] == "targetColor"
|
||||
assert green_args["value"] == 76
|
||||
blue_args = client.async_send_command.call_args_list[4][0][0] # blue 255
|
||||
blue_args = client.async_send_command_no_wait.call_args_list[4][0][0] # blue 255
|
||||
assert blue_args["command"] == "node.set_value"
|
||||
assert blue_args["nodeId"] == 39
|
||||
assert blue_args["valueId"]["commandClassName"] == "Color Switch"
|
||||
|
@ -231,7 +235,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
assert state.attributes[ATTR_COLOR_TEMP] == 370
|
||||
assert state.attributes[ATTR_RGB_COLOR] == (255, 76, 255)
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test turning on with same rgb color
|
||||
await hass.services.async_call(
|
||||
|
@ -241,9 +245,9 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 5
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 5
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test turning on with color temp
|
||||
await hass.services.async_call(
|
||||
|
@ -253,8 +257,8 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 5
|
||||
red_args = client.async_send_command.call_args_list[0][0][0] # red 0
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 5
|
||||
red_args = client.async_send_command_no_wait.call_args_list[0][0][0] # red 0
|
||||
assert red_args["command"] == "node.set_value"
|
||||
assert red_args["nodeId"] == 39
|
||||
assert red_args["valueId"]["commandClassName"] == "Color Switch"
|
||||
|
@ -264,7 +268,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
assert red_args["valueId"]["property"] == "targetColor"
|
||||
assert red_args["valueId"]["propertyName"] == "targetColor"
|
||||
assert red_args["value"] == 0
|
||||
red_args = client.async_send_command.call_args_list[1][0][0] # green 0
|
||||
red_args = client.async_send_command_no_wait.call_args_list[1][0][0] # green 0
|
||||
assert red_args["command"] == "node.set_value"
|
||||
assert red_args["nodeId"] == 39
|
||||
assert red_args["valueId"]["commandClassName"] == "Color Switch"
|
||||
|
@ -274,7 +278,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
assert red_args["valueId"]["property"] == "targetColor"
|
||||
assert red_args["valueId"]["propertyName"] == "targetColor"
|
||||
assert red_args["value"] == 0
|
||||
red_args = client.async_send_command.call_args_list[2][0][0] # blue 0
|
||||
red_args = client.async_send_command_no_wait.call_args_list[2][0][0] # blue 0
|
||||
assert red_args["command"] == "node.set_value"
|
||||
assert red_args["nodeId"] == 39
|
||||
assert red_args["valueId"]["commandClassName"] == "Color Switch"
|
||||
|
@ -284,7 +288,9 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
assert red_args["valueId"]["property"] == "targetColor"
|
||||
assert red_args["valueId"]["propertyName"] == "targetColor"
|
||||
assert red_args["value"] == 0
|
||||
warm_args = client.async_send_command.call_args_list[3][0][0] # warm white 0
|
||||
warm_args = client.async_send_command_no_wait.call_args_list[3][0][
|
||||
0
|
||||
] # warm white 0
|
||||
assert warm_args["command"] == "node.set_value"
|
||||
assert warm_args["nodeId"] == 39
|
||||
assert warm_args["valueId"]["commandClassName"] == "Color Switch"
|
||||
|
@ -294,7 +300,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
assert warm_args["valueId"]["property"] == "targetColor"
|
||||
assert warm_args["valueId"]["propertyName"] == "targetColor"
|
||||
assert warm_args["value"] == 20
|
||||
red_args = client.async_send_command.call_args_list[4][0][0] # cold white
|
||||
red_args = client.async_send_command_no_wait.call_args_list[4][0][0] # cold white
|
||||
assert red_args["command"] == "node.set_value"
|
||||
assert red_args["nodeId"] == 39
|
||||
assert red_args["valueId"]["commandClassName"] == "Color Switch"
|
||||
|
@ -305,7 +311,7 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
assert red_args["valueId"]["propertyName"] == "targetColor"
|
||||
assert red_args["value"] == 235
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test color temp update from value updated event
|
||||
red_event = Event(
|
||||
|
@ -361,9 +367,9 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 5
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 5
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test turning off
|
||||
await hass.services.async_call(
|
||||
|
@ -373,8 +379,8 @@ async def test_light(hass, client, bulb_6_multi_color, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 39
|
||||
assert args["valueId"] == {
|
||||
|
|
|
@ -33,8 +33,8 @@ async def test_door_lock(hass, client, lock_schlage_be469, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 20
|
||||
assert args["valueId"] == {
|
||||
|
@ -64,7 +64,7 @@ async def test_door_lock(hass, client, lock_schlage_be469, integration):
|
|||
}
|
||||
assert args["value"] == 255
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test locked update from value updated event
|
||||
event = Event(
|
||||
|
@ -88,7 +88,7 @@ async def test_door_lock(hass, client, lock_schlage_be469, integration):
|
|||
|
||||
assert hass.states.get(SCHLAGE_BE469_LOCK_ENTITY).state == STATE_LOCKED
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test unlocking
|
||||
await hass.services.async_call(
|
||||
|
@ -98,8 +98,8 @@ async def test_door_lock(hass, client, lock_schlage_be469, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 20
|
||||
assert args["valueId"] == {
|
||||
|
@ -129,7 +129,7 @@ async def test_door_lock(hass, client, lock_schlage_be469, integration):
|
|||
}
|
||||
assert args["value"] == 0
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test set usercode service
|
||||
await hass.services.async_call(
|
||||
|
@ -143,8 +143,8 @@ async def test_door_lock(hass, client, lock_schlage_be469, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 20
|
||||
assert args["valueId"] == {
|
||||
|
@ -167,7 +167,7 @@ async def test_door_lock(hass, client, lock_schlage_be469, integration):
|
|||
}
|
||||
assert args["value"] == "1234"
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test clear usercode
|
||||
await hass.services.async_call(
|
||||
|
@ -177,8 +177,8 @@ async def test_door_lock(hass, client, lock_schlage_be469, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 20
|
||||
assert args["valueId"] == {
|
||||
|
|
|
@ -20,8 +20,8 @@ async def test_number(hass, client, aeotec_radiator_thermostat, integration):
|
|||
blocking=True,
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 4
|
||||
assert args["valueId"] == {
|
||||
|
@ -43,7 +43,7 @@ async def test_number(hass, client, aeotec_radiator_thermostat, integration):
|
|||
}
|
||||
assert args["value"] == 30.0
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test value update from value updated event
|
||||
event = Event(
|
||||
|
|
|
@ -302,15 +302,15 @@ async def test_poll_value(
|
|||
):
|
||||
"""Test the poll_value service."""
|
||||
# Test polling the primary value
|
||||
client.async_send_command.return_value = {"result": 2}
|
||||
client.async_send_command_no_wait.return_value = {"result": 2}
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_REFRESH_VALUE,
|
||||
{ATTR_ENTITY_ID: CLIMATE_RADIO_THERMOSTAT_ENTITY},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.poll_value"
|
||||
assert args["nodeId"] == 26
|
||||
assert args["valueId"] == {
|
||||
|
@ -339,10 +339,10 @@ async def test_poll_value(
|
|||
"ccVersion": 2,
|
||||
}
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test polling all watched values
|
||||
client.async_send_command.return_value = {"result": 2}
|
||||
client.async_send_command_no_wait.return_value = {"result": 2}
|
||||
await hass.services.async_call(
|
||||
DOMAIN,
|
||||
SERVICE_REFRESH_VALUE,
|
||||
|
@ -352,7 +352,7 @@ async def test_poll_value(
|
|||
},
|
||||
blocking=True,
|
||||
)
|
||||
assert len(client.async_send_command.call_args_list) == 8
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 8
|
||||
|
||||
# Test polling against an invalid entity raises ValueError
|
||||
with pytest.raises(ValueError):
|
||||
|
|
|
@ -21,7 +21,7 @@ async def test_switch(hass, hank_binary_switch, integration, client):
|
|||
"switch", "turn_on", {"entity_id": SWITCH_ENTITY}, blocking=True
|
||||
)
|
||||
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 32
|
||||
assert args["valueId"] == {
|
||||
|
@ -68,7 +68,7 @@ async def test_switch(hass, hank_binary_switch, integration, client):
|
|||
"switch", "turn_off", {"entity_id": SWITCH_ENTITY}, blocking=True
|
||||
)
|
||||
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 32
|
||||
assert args["valueId"] == {
|
||||
|
@ -102,8 +102,8 @@ async def test_barrier_signaling_switch(hass, gdc_zw062, integration, client):
|
|||
DOMAIN, SERVICE_TURN_OFF, {"entity_id": entity}, blocking=True
|
||||
)
|
||||
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 12
|
||||
assert args["value"] == 0
|
||||
|
@ -134,7 +134,7 @@ async def test_barrier_signaling_switch(hass, gdc_zw062, integration, client):
|
|||
state = hass.states.get(entity)
|
||||
assert state.state == STATE_OFF
|
||||
|
||||
client.async_send_command.reset_mock()
|
||||
client.async_send_command_no_wait.reset_mock()
|
||||
|
||||
# Test turning on
|
||||
await hass.services.async_call(
|
||||
|
@ -143,8 +143,8 @@ async def test_barrier_signaling_switch(hass, gdc_zw062, integration, client):
|
|||
|
||||
# Note: the valueId's value is still 255 because we never
|
||||
# received an updated value
|
||||
assert len(client.async_send_command.call_args_list) == 1
|
||||
args = client.async_send_command.call_args[0][0]
|
||||
assert len(client.async_send_command_no_wait.call_args_list) == 1
|
||||
args = client.async_send_command_no_wait.call_args[0][0]
|
||||
assert args["command"] == "node.set_value"
|
||||
assert args["nodeId"] == 12
|
||||
assert args["value"] == 255
|
||||
|
|
|
@ -6,10 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Binary Switch",
|
||||
"specific": "Binary Power Switch",
|
||||
"mandatorySupportedCCs": ["Basic", "Binary Switch", "All Switch"],
|
||||
"basic": {"key": 4, "label": "Routing Slave"},
|
||||
"generic": {"key": 16, "label":"Binary Switch"},
|
||||
"specific": {"key": 1, "label":"Binary Power Switch"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -53,6 +53,7 @@
|
|||
"userIcon": 1792
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"endpoint": 0,
|
||||
|
|
|
@ -6,16 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Thermostat",
|
||||
"specific": "Thermostat General V2",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Manufacturer Specific",
|
||||
"Thermostat Mode",
|
||||
"Thermostat Setpoint",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 8, "label":"Thermostat"},
|
||||
"specific": {"key": 6, "label":"Thermostat General V2"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": false,
|
||||
|
|
|
@ -6,14 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Static Controller",
|
||||
"generic": "Multilevel Switch",
|
||||
"specific": "Multilevel Power Switch",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Multilevel Switch",
|
||||
"All Switch"
|
||||
],
|
||||
"basic": {"key": 2, "label": "Static Controller"},
|
||||
"generic": {"key": 17, "label":"Multilevel Switch"},
|
||||
"specific": {"key": 1, "label":"Multilevel Power Switch"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -67,6 +63,7 @@
|
|||
"userIcon": 1536
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Multilevel Switch",
|
||||
|
|
|
@ -6,16 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Multilevel Switch",
|
||||
"specific": "Motor Control Class C",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Multilevel Switch",
|
||||
"Binary Switch",
|
||||
"Manufacturer Specific",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 17, "label":"Multilevel Switch"},
|
||||
"specific": {"key": 7, "label":"Motor Control Class C"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -52,6 +46,7 @@
|
|||
"endpoints": [
|
||||
{ "nodeId": 6, "index": 0, "installerIcon": 6656, "userIcon": 6656 }
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Multilevel Switch",
|
||||
|
|
|
@ -4,15 +4,10 @@
|
|||
"status": 1,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Thermostat",
|
||||
"specific": "Setpoint Thermostat",
|
||||
"mandatorySupportedCCs": [
|
||||
"Manufacturer Specific",
|
||||
"Multi Command",
|
||||
"Thermostat Setpoint",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 8, "label":"Thermostat"},
|
||||
"specific": {"key": 4, "label":"Setpoint Thermostat"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": false,
|
||||
|
@ -77,6 +72,7 @@
|
|||
"index": 0
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"endpoint": 0,
|
||||
|
|
|
@ -6,16 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Thermostat",
|
||||
"specific": "Thermostat General V2",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Manufacturer Specific",
|
||||
"Thermostat Mode",
|
||||
"Thermostat Setpoint",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 8, "label":"Thermostat"},
|
||||
"specific": {"key": 6, "label":"Thermostat General V2"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -116,6 +110,7 @@
|
|||
"userIcon": 3329
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"endpoint": 0,
|
||||
|
|
|
@ -6,16 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Thermostat",
|
||||
"specific": "Thermostat General V2",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Manufacturer Specific",
|
||||
"Thermostat Mode",
|
||||
"Thermostat Setpoint",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 8, "label":"Thermostat"},
|
||||
"specific": {"key": 6, "label":"Thermostat General V2"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -63,6 +57,7 @@
|
|||
"userIcon": 3333
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Manufacturer Specific",
|
||||
|
|
|
@ -6,16 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Static Controller",
|
||||
"generic": "Thermostat",
|
||||
"specific": "Thermostat General V2",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Manufacturer Specific",
|
||||
"Thermostat Mode",
|
||||
"Thermostat Setpoint",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 2, "label":"Static Controller"},
|
||||
"generic": {"key": 8, "label":"Thermostat"},
|
||||
"specific": {"key": 6, "label":"Thermostat General V2"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -63,6 +57,7 @@
|
|||
},
|
||||
{ "nodeId": 13, "index": 2 }
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Manufacturer Specific",
|
||||
|
|
|
@ -6,13 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Multilevel Switch",
|
||||
"specific": "Unused",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Multilevel Switch"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 17, "label":"Routing Slave"},
|
||||
"specific": {"key": 0, "label":"Unused"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": false,
|
||||
|
@ -75,6 +72,7 @@
|
|||
"userIcon": 6400
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"endpoint": 0,
|
||||
|
|
|
@ -6,26 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Entry Control",
|
||||
"specific": "Secure Barrier Add-on",
|
||||
"mandatorySupportedCCs": [
|
||||
"Application Status",
|
||||
"Association",
|
||||
"Association Group Information",
|
||||
"Barrier Operator",
|
||||
"Battery",
|
||||
"Device Reset Locally",
|
||||
"Manufacturer Specific",
|
||||
"Notification",
|
||||
"Powerlevel",
|
||||
"Security",
|
||||
"Security 2",
|
||||
"Supervision",
|
||||
"Transport Service",
|
||||
"Version",
|
||||
"Z-Wave Plus Info"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 64, "label":"Entry Control"},
|
||||
"specific": {"key": 7, "label":"Secure Barrier Add-on"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -94,6 +78,7 @@
|
|||
"userIcon": 7680
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"endpoint": 0,
|
||||
|
|
|
@ -6,14 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Multilevel Switch",
|
||||
"specific": "Multilevel Power Switch",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Multilevel Switch",
|
||||
"All Switch"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 17, "label":"Routing Slave"},
|
||||
"specific": {"key": 1, "label":"Multilevel Power Switch"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -74,6 +70,7 @@
|
|||
"userIcon": 1536
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Multilevel Switch",
|
||||
|
|
|
@ -4,16 +4,11 @@
|
|||
"status": 1,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Static Controller",
|
||||
"generic": "Binary Sensor",
|
||||
"specific": "Routing Binary Sensor",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Binary Sensor"
|
||||
],
|
||||
"mandatoryControlCCs": [
|
||||
|
||||
]
|
||||
"basic": {"key": 2, "label":"Static Controller"},
|
||||
"generic": {"key": 32, "label":"Binary Sensor"},
|
||||
"specific": {"key": 1, "label":"Routing Binary Sensor"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": false,
|
||||
"isFrequentListening": false,
|
||||
|
@ -61,6 +56,7 @@
|
|||
"index": 0
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Basic",
|
||||
|
|
|
@ -4,14 +4,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Multilevel Switch",
|
||||
"specific": "Multilevel Power Switch",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Multilevel Switch",
|
||||
"All Switch"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 17, "label":"Multilevel Switch"},
|
||||
"specific": {"key": 1, "label":"Multilevel Power Switch"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -57,6 +53,7 @@
|
|||
"index": 0
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"endpoint": 0,
|
||||
|
|
|
@ -6,14 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Static Controller",
|
||||
"generic": "Binary Switch",
|
||||
"specific": "Binary Power Switch",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Binary Switch",
|
||||
"All Switch"
|
||||
],
|
||||
"basic": {"key": 2, "label":"Static Controller"},
|
||||
"generic": {"key": 16, "label":"Binary Switch"},
|
||||
"specific": {"key": 1, "label":"Binary Power Switch"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -67,6 +63,7 @@
|
|||
"userIcon": 1792
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Binary Switch",
|
||||
|
|
|
@ -6,13 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Multilevel Switch",
|
||||
"specific": "Fan Switch",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Multilevel Switch"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 17, "label":"Multilevel Switch"},
|
||||
"specific": {"key": 8, "label":"Fan Switch"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -87,6 +84,7 @@
|
|||
"userIcon": 1024
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Multilevel Switch",
|
||||
|
|
|
@ -6,17 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Routing Slave",
|
||||
"generic": "Entry Control",
|
||||
"specific": "Secure Keypad Door Lock",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Door Lock",
|
||||
"User Code",
|
||||
"Manufacturer Specific",
|
||||
"Security",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 4, "label":"Routing Slave"},
|
||||
"generic": {"key": 64, "label":"Entry Control"},
|
||||
"specific": {"key": 3, "label":"Secure Keypad Door Lock"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": false,
|
||||
|
@ -73,6 +66,7 @@
|
|||
"userIcon": 768
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Door Lock",
|
||||
|
|
|
@ -4,17 +4,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Static Controller",
|
||||
"generic": "Entry Control",
|
||||
"specific": "Secure Keypad Door Lock",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Door Lock",
|
||||
"User Code",
|
||||
"Manufacturer Specific",
|
||||
"Security",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 2, "label":"Static Controller"},
|
||||
"generic": {"key": 64, "label":"Entry Control"},
|
||||
"specific": {"key": 3, "label":"Secure Keypad Door Lock"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": false,
|
||||
|
@ -57,6 +50,7 @@
|
|||
"index": 0
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Door Lock",
|
||||
|
|
|
@ -6,13 +6,10 @@
|
|||
"status": 1,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Static Controller",
|
||||
"generic": "Multilevel Sensor",
|
||||
"specific": "Routing Multilevel Sensor",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Multilevel Sensor"
|
||||
],
|
||||
"basic": {"key": 2, "label":"Static Controller"},
|
||||
"generic": {"key": 21, "label":"Multilevel Sensor"},
|
||||
"specific": {"key": 1, "label":"Routing Multilevel Sensor"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": true,
|
||||
|
@ -70,6 +67,7 @@
|
|||
"userIcon": 3079
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Basic",
|
||||
|
|
|
@ -7,16 +7,10 @@
|
|||
"status": 0,
|
||||
"ready": false,
|
||||
"deviceClass": {
|
||||
"basic": "Static Controller",
|
||||
"generic": "Thermostat",
|
||||
"specific": "Thermostat General V2",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Manufacturer Specific",
|
||||
"Thermostat Mode",
|
||||
"Thermostat Setpoint",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 2, "label":"Static Controller"},
|
||||
"generic": {"key": 8, "label":"Thermostat"},
|
||||
"specific": {"key": 6, "label":"Thermostat General V2"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"neighbors": [],
|
||||
|
@ -27,6 +21,7 @@
|
|||
"index": 0
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Basic",
|
||||
|
|
|
@ -7,16 +7,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Static Controller",
|
||||
"generic": "Thermostat",
|
||||
"specific": "Thermostat General V2",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Manufacturer Specific",
|
||||
"Thermostat Mode",
|
||||
"Thermostat Setpoint",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 2, "label":"Static Controller"},
|
||||
"generic": {"key": 8, "label":"Thermostat"},
|
||||
"specific": {"key": 6, "label":"Thermostat General V2"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": false,
|
||||
|
@ -67,6 +61,7 @@
|
|||
"index": 0
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Manufacturer Specific",
|
||||
|
|
|
@ -6,16 +6,10 @@
|
|||
"status": 4,
|
||||
"ready": true,
|
||||
"deviceClass": {
|
||||
"basic": "Static Controller",
|
||||
"generic": "Thermostat",
|
||||
"specific": "Thermostat General V2",
|
||||
"mandatorySupportedCCs": [
|
||||
"Basic",
|
||||
"Manufacturer Specific",
|
||||
"Thermostat Mode",
|
||||
"Thermostat Setpoint",
|
||||
"Version"
|
||||
],
|
||||
"basic": {"key": 2, "label":"Static Controller"},
|
||||
"generic": {"key": 8, "label":"Thermostat"},
|
||||
"specific": {"key": 6, "label":"Thermostat General V2"},
|
||||
"mandatorySupportedCCs": [],
|
||||
"mandatoryControlCCs": []
|
||||
},
|
||||
"isListening": false,
|
||||
|
@ -75,6 +69,7 @@
|
|||
"userIcon": 4608
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Manufacturer Specific",
|
||||
|
|
Loading…
Reference in New Issue