Add zwave_js device triggers (#51968)
* Initial support for zwave_js device triggers * lint * Add node status changed trigger * comments * create helper function and simplify trigger logic * simplify code * fix exception * remove unused type ignore * switch to append to make future changes easier * make exception consistent * Add state config schema validation * comment * remove 0 from falsy check * increase test coverage * typos * Add central scene and scene activation value notification triggers * reorder things for readability and enumerate node statuses * Add support for Basic CC value notifications * fix schemas since additional fields on triggers aren't very flexible * pylint * remove extra logger statement * fix comment * dont use get when we know key will be available in dict * tweak text * use better schema for required extra fields that are ints * rename trigger types to make them easier to parse * fix strings * missed renaming of one trigger type * typo * Fix strings * reduce complexity * Use Al's suggestion for strings * add additional failure test cases * remove errant logging statement * make CC required * raise vol.Invalid when value ID isn't legit to prepare for next PR * Use helper function * fix tests * black
This commit is contained in:
parent
4d711898c7
commit
dd908caeba
8 changed files with 1970 additions and 1 deletions
|
@ -429,6 +429,12 @@ def wallmote_central_scene_state_fixture():
|
|||
return json.loads(load_fixture("zwave_js/wallmote_central_scene_state.json"))
|
||||
|
||||
|
||||
@pytest.fixture(name="ge_in_wall_dimmer_switch_state", scope="session")
|
||||
def ge_in_wall_dimmer_switch_state_fixture():
|
||||
"""Load the ge in-wall dimmer switch node state fixture data."""
|
||||
return json.loads(load_fixture("zwave_js/ge_in_wall_dimmer_switch_state.json"))
|
||||
|
||||
|
||||
@pytest.fixture(name="aeotec_zw164_siren_state", scope="session")
|
||||
def aeotec_zw164_siren_state_fixture():
|
||||
"""Load the aeotec zw164 siren node state fixture data."""
|
||||
|
@ -795,6 +801,14 @@ def wallmote_central_scene_fixture(client, wallmote_central_scene_state):
|
|||
return node
|
||||
|
||||
|
||||
@pytest.fixture(name="ge_in_wall_dimmer_switch")
|
||||
def ge_in_wall_dimmer_switch_fixture(client, ge_in_wall_dimmer_switch_state):
|
||||
"""Mock a ge in-wall dimmer switch scene node."""
|
||||
node = Node(client, copy.deepcopy(ge_in_wall_dimmer_switch_state))
|
||||
client.driver.controller.nodes[node.node_id] = node
|
||||
return node
|
||||
|
||||
|
||||
@pytest.fixture(name="aeotec_zw164_siren")
|
||||
def aeotec_zw164_siren_fixture(client, aeotec_zw164_siren_state):
|
||||
"""Mock a wallmote central scene node."""
|
||||
|
|
831
tests/components/zwave_js/test_device_trigger.py
Normal file
831
tests/components/zwave_js/test_device_trigger.py
Normal file
|
@ -0,0 +1,831 @@
|
|||
"""The tests for Z-Wave JS device triggers."""
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
import voluptuous_serialize
|
||||
from zwave_js_server.const import CommandClass
|
||||
from zwave_js_server.event import Event
|
||||
from zwave_js_server.model.node import Node
|
||||
|
||||
from homeassistant.components import automation
|
||||
from homeassistant.components.zwave_js import DOMAIN, device_trigger
|
||||
from homeassistant.components.zwave_js.device_trigger import (
|
||||
async_attach_trigger,
|
||||
async_get_trigger_capabilities,
|
||||
)
|
||||
from homeassistant.components.zwave_js.helpers import (
|
||||
async_get_node_status_sensor_entity_id,
|
||||
)
|
||||
from homeassistant.exceptions import HomeAssistantError
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.device_registry import (
|
||||
async_entries_for_config_entry,
|
||||
async_get as async_get_dev_reg,
|
||||
)
|
||||
from homeassistant.helpers.entity_registry import async_get as async_get_ent_reg
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from tests.common import (
|
||||
assert_lists_same,
|
||||
async_get_device_automations,
|
||||
async_mock_service,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def calls(hass):
|
||||
"""Track calls to a mock service."""
|
||||
return async_mock_service(hass, "test", "automation")
|
||||
|
||||
|
||||
async def test_get_notification_notification_triggers(
|
||||
hass, client, lock_schlage_be469, integration
|
||||
):
|
||||
"""Test we get the expected triggers from a zwave_js device with the Notification CC."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
expected_trigger = {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": "event.notification.notification",
|
||||
"device_id": device.id,
|
||||
"command_class": CommandClass.NOTIFICATION,
|
||||
}
|
||||
triggers = await async_get_device_automations(hass, "trigger", device.id)
|
||||
assert expected_trigger in triggers
|
||||
|
||||
|
||||
async def test_if_notification_notification_fires(
|
||||
hass, client, lock_schlage_be469, integration, calls
|
||||
):
|
||||
"""Test for event.notification.notification trigger firing."""
|
||||
node: Node = lock_schlage_be469
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device.id,
|
||||
"type": "event.notification.notification",
|
||||
"command_class": CommandClass.NOTIFICATION.value,
|
||||
"type.": 6,
|
||||
"event": 5,
|
||||
"label": "Access Control",
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data_template": {
|
||||
"some": (
|
||||
"event.notification.notification - "
|
||||
"{{ trigger.platform}} - "
|
||||
"{{ trigger.event.event_type}} - "
|
||||
"{{ trigger.event.data.command_class }}"
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
# Publish fake Notification CC notification
|
||||
event = Event(
|
||||
type="notification",
|
||||
data={
|
||||
"source": "node",
|
||||
"event": "notification",
|
||||
"nodeId": node.node_id,
|
||||
"ccId": 113,
|
||||
"args": {
|
||||
"type": 6,
|
||||
"event": 5,
|
||||
"label": "Access Control",
|
||||
"eventLabel": "Keypad lock operation",
|
||||
"parameters": {"userId": 1},
|
||||
},
|
||||
},
|
||||
)
|
||||
node.receive_event(event)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data[
|
||||
"some"
|
||||
] == "event.notification.notification - device - zwave_js_notification - {}".format(
|
||||
CommandClass.NOTIFICATION
|
||||
)
|
||||
|
||||
|
||||
async def test_get_trigger_capabilities_notification_notification(
|
||||
hass, client, lock_schlage_be469, integration
|
||||
):
|
||||
"""Test we get the expected capabilities from a notification.notification trigger."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
capabilities = await device_trigger.async_get_trigger_capabilities(
|
||||
hass,
|
||||
{
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device.id,
|
||||
"type": "event.notification.notification",
|
||||
"command_class": CommandClass.NOTIFICATION.value,
|
||||
},
|
||||
)
|
||||
assert capabilities and "extra_fields" in capabilities
|
||||
|
||||
assert_lists_same(
|
||||
voluptuous_serialize.convert(
|
||||
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
|
||||
),
|
||||
[
|
||||
{"name": "type.", "optional": True, "type": "string"},
|
||||
{"name": "label", "optional": True, "type": "string"},
|
||||
{"name": "event", "optional": True, "type": "string"},
|
||||
{"name": "event_label", "optional": True, "type": "string"},
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
async def test_if_entry_control_notification_fires(
|
||||
hass, client, lock_schlage_be469, integration, calls
|
||||
):
|
||||
"""Test for notification.entry_control trigger firing."""
|
||||
node: Node = lock_schlage_be469
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device.id,
|
||||
"type": "event.notification.entry_control",
|
||||
"command_class": CommandClass.ENTRY_CONTROL.value,
|
||||
"event_type": 5,
|
||||
"data_type": 2,
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data_template": {
|
||||
"some": (
|
||||
"event.notification.notification - "
|
||||
"{{ trigger.platform}} - "
|
||||
"{{ trigger.event.event_type}} - "
|
||||
"{{ trigger.event.data.command_class }}"
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
# Publish fake Entry Control CC notification
|
||||
event = Event(
|
||||
type="notification",
|
||||
data={
|
||||
"source": "node",
|
||||
"event": "notification",
|
||||
"nodeId": node.node_id,
|
||||
"ccId": 111,
|
||||
"args": {"eventType": 5, "dataType": 2, "eventData": "555"},
|
||||
},
|
||||
)
|
||||
node.receive_event(event)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data[
|
||||
"some"
|
||||
] == "event.notification.notification - device - zwave_js_notification - {}".format(
|
||||
CommandClass.ENTRY_CONTROL
|
||||
)
|
||||
|
||||
|
||||
async def test_get_trigger_capabilities_entry_control_notification(
|
||||
hass, client, lock_schlage_be469, integration
|
||||
):
|
||||
"""Test we get the expected capabilities from a notification.entry_control trigger."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
capabilities = await device_trigger.async_get_trigger_capabilities(
|
||||
hass,
|
||||
{
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device.id,
|
||||
"type": "event.notification.entry_control",
|
||||
"command_class": CommandClass.ENTRY_CONTROL.value,
|
||||
},
|
||||
)
|
||||
assert capabilities and "extra_fields" in capabilities
|
||||
|
||||
assert_lists_same(
|
||||
voluptuous_serialize.convert(
|
||||
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
|
||||
),
|
||||
[
|
||||
{"name": "event_type", "optional": True, "type": "string"},
|
||||
{"name": "data_type", "optional": True, "type": "string"},
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
async def test_get_node_status_triggers(hass, client, lock_schlage_be469, integration):
|
||||
"""Test we get the expected triggers from a device with node status sensor enabled."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
ent_reg = async_get_ent_reg(hass)
|
||||
entity_id = async_get_node_status_sensor_entity_id(
|
||||
hass, device.id, ent_reg, dev_reg
|
||||
)
|
||||
ent_reg.async_update_entity(entity_id, **{"disabled_by": None})
|
||||
await hass.config_entries.async_reload(integration.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
expected_trigger = {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": "state.node_status",
|
||||
"device_id": device.id,
|
||||
"entity_id": entity_id,
|
||||
}
|
||||
triggers = await async_get_device_automations(hass, "trigger", device.id)
|
||||
assert expected_trigger in triggers
|
||||
|
||||
|
||||
async def test_if_node_status_change_fires(
|
||||
hass, client, lock_schlage_be469, integration, calls
|
||||
):
|
||||
"""Test for node_status trigger firing."""
|
||||
node: Node = lock_schlage_be469
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
ent_reg = async_get_ent_reg(hass)
|
||||
entity_id = async_get_node_status_sensor_entity_id(
|
||||
hass, device.id, ent_reg, dev_reg
|
||||
)
|
||||
ent_reg.async_update_entity(entity_id, **{"disabled_by": None})
|
||||
await hass.config_entries.async_reload(integration.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device.id,
|
||||
"entity_id": entity_id,
|
||||
"type": "state.node_status",
|
||||
"from": "alive",
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data_template": {
|
||||
"some": (
|
||||
"state.node_status - "
|
||||
"{{ trigger.platform}} - "
|
||||
"{{ trigger.from_state.state }}"
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
# Test status change
|
||||
event = Event(
|
||||
"dead", data={"source": "node", "event": "dead", "nodeId": node.node_id}
|
||||
)
|
||||
node.receive_event(event)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data["some"] == "state.node_status - device - alive"
|
||||
|
||||
|
||||
async def test_get_trigger_capabilities_node_status(
|
||||
hass, client, lock_schlage_be469, integration
|
||||
):
|
||||
"""Test we get the expected capabilities from a node_status trigger."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
ent_reg = async_get_ent_reg(hass)
|
||||
entity_id = async_get_node_status_sensor_entity_id(
|
||||
hass, device.id, ent_reg, dev_reg
|
||||
)
|
||||
ent_reg.async_update_entity(entity_id, **{"disabled_by": None})
|
||||
await hass.config_entries.async_reload(integration.entry_id)
|
||||
await hass.async_block_till_done()
|
||||
|
||||
capabilities = await device_trigger.async_get_trigger_capabilities(
|
||||
hass,
|
||||
{
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device.id,
|
||||
"entity_id": entity_id,
|
||||
"type": "state.node_status",
|
||||
},
|
||||
)
|
||||
assert capabilities and "extra_fields" in capabilities
|
||||
|
||||
assert voluptuous_serialize.convert(
|
||||
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
|
||||
) == [
|
||||
{
|
||||
"name": "from",
|
||||
"optional": True,
|
||||
"options": [
|
||||
("asleep", "asleep"),
|
||||
("awake", "awake"),
|
||||
("dead", "dead"),
|
||||
("alive", "alive"),
|
||||
],
|
||||
"type": "select",
|
||||
},
|
||||
{
|
||||
"name": "to",
|
||||
"optional": True,
|
||||
"options": [
|
||||
("asleep", "asleep"),
|
||||
("awake", "awake"),
|
||||
("dead", "dead"),
|
||||
("alive", "alive"),
|
||||
],
|
||||
"type": "select",
|
||||
},
|
||||
{"name": "for", "optional": True, "type": "positive_time_period_dict"},
|
||||
]
|
||||
|
||||
|
||||
async def test_get_basic_value_notification_triggers(
|
||||
hass, client, ge_in_wall_dimmer_switch, integration
|
||||
):
|
||||
"""Test we get the expected triggers from a zwave_js device with the Basic CC."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
expected_trigger = {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": "event.value_notification.basic",
|
||||
"device_id": device.id,
|
||||
"command_class": CommandClass.BASIC,
|
||||
"property": "event",
|
||||
"property_key": None,
|
||||
"endpoint": 0,
|
||||
"subtype": "Endpoint 0",
|
||||
}
|
||||
triggers = await async_get_device_automations(hass, "trigger", device.id)
|
||||
assert expected_trigger in triggers
|
||||
|
||||
|
||||
async def test_if_basic_value_notification_fires(
|
||||
hass, client, ge_in_wall_dimmer_switch, integration, calls
|
||||
):
|
||||
"""Test for event.value_notification.basic trigger firing."""
|
||||
node: Node = ge_in_wall_dimmer_switch
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": "event.value_notification.basic",
|
||||
"device_id": device.id,
|
||||
"command_class": CommandClass.BASIC.value,
|
||||
"property": "event",
|
||||
"property_key": None,
|
||||
"endpoint": 0,
|
||||
"subtype": "Endpoint 0",
|
||||
"value": 0,
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data_template": {
|
||||
"some": (
|
||||
"event.value_notification.basic - "
|
||||
"{{ trigger.platform}} - "
|
||||
"{{ trigger.event.event_type}} - "
|
||||
"{{ trigger.event.data.command_class }}"
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
# Publish fake Basic CC value notification
|
||||
event = Event(
|
||||
type="value notification",
|
||||
data={
|
||||
"source": "node",
|
||||
"event": "value notification",
|
||||
"nodeId": node.node_id,
|
||||
"args": {
|
||||
"commandClassName": "Basic",
|
||||
"commandClass": 32,
|
||||
"endpoint": 0,
|
||||
"property": "event",
|
||||
"propertyName": "event",
|
||||
"value": 0,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": True,
|
||||
"writeable": False,
|
||||
"label": "Event value",
|
||||
"min": 0,
|
||||
"max": 255,
|
||||
},
|
||||
"ccVersion": 1,
|
||||
},
|
||||
},
|
||||
)
|
||||
node.receive_event(event)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data[
|
||||
"some"
|
||||
] == "event.value_notification.basic - device - zwave_js_value_notification - {}".format(
|
||||
CommandClass.BASIC
|
||||
)
|
||||
|
||||
|
||||
async def test_get_trigger_capabilities_basic_value_notification(
|
||||
hass, client, ge_in_wall_dimmer_switch, integration
|
||||
):
|
||||
"""Test we get the expected capabilities from a value_notification.basic trigger."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
capabilities = await device_trigger.async_get_trigger_capabilities(
|
||||
hass,
|
||||
{
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": "event.value_notification.basic",
|
||||
"device_id": device.id,
|
||||
"command_class": CommandClass.BASIC.value,
|
||||
"property": "event",
|
||||
"property_key": None,
|
||||
"endpoint": 0,
|
||||
"subtype": "Endpoint 0",
|
||||
},
|
||||
)
|
||||
assert capabilities and "extra_fields" in capabilities
|
||||
|
||||
assert voluptuous_serialize.convert(
|
||||
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
|
||||
) == [
|
||||
{
|
||||
"name": "value",
|
||||
"required": True,
|
||||
"type": "integer",
|
||||
"valueMin": 0,
|
||||
"valueMax": 255,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
async def test_get_central_scene_value_notification_triggers(
|
||||
hass, client, wallmote_central_scene, integration
|
||||
):
|
||||
"""Test we get the expected triggers from a zwave_js device with the Central Scene CC."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
expected_trigger = {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": "event.value_notification.central_scene",
|
||||
"device_id": device.id,
|
||||
"command_class": CommandClass.CENTRAL_SCENE,
|
||||
"property": "scene",
|
||||
"property_key": "001",
|
||||
"endpoint": 0,
|
||||
"subtype": "Endpoint 0 Scene 001",
|
||||
}
|
||||
triggers = await async_get_device_automations(hass, "trigger", device.id)
|
||||
assert expected_trigger in triggers
|
||||
|
||||
|
||||
async def test_if_central_scene_value_notification_fires(
|
||||
hass, client, wallmote_central_scene, integration, calls
|
||||
):
|
||||
"""Test for event.value_notification.central_scene trigger firing."""
|
||||
node: Node = wallmote_central_scene
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device.id,
|
||||
"type": "event.value_notification.central_scene",
|
||||
"command_class": CommandClass.CENTRAL_SCENE.value,
|
||||
"property": "scene",
|
||||
"property_key": "001",
|
||||
"endpoint": 0,
|
||||
"subtype": "Endpoint 0 Scene 001",
|
||||
"value": 0,
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data_template": {
|
||||
"some": (
|
||||
"event.value_notification.central_scene - "
|
||||
"{{ trigger.platform}} - "
|
||||
"{{ trigger.event.event_type}} - "
|
||||
"{{ trigger.event.data.command_class }}"
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
# Publish fake Central Scene CC value notification
|
||||
event = Event(
|
||||
type="value notification",
|
||||
data={
|
||||
"source": "node",
|
||||
"event": "value notification",
|
||||
"nodeId": node.node_id,
|
||||
"args": {
|
||||
"commandClassName": "Central Scene",
|
||||
"commandClass": 91,
|
||||
"endpoint": 0,
|
||||
"property": "scene",
|
||||
"propertyName": "scene",
|
||||
"propertyKey": "001",
|
||||
"propertyKey": "001",
|
||||
"value": 0,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": True,
|
||||
"writeable": False,
|
||||
"min": 0,
|
||||
"max": 255,
|
||||
"label": "Scene 004",
|
||||
"states": {
|
||||
"0": "KeyPressed",
|
||||
"1": "KeyReleased",
|
||||
"2": "KeyHeldDown",
|
||||
},
|
||||
},
|
||||
"ccVersion": 1,
|
||||
},
|
||||
},
|
||||
)
|
||||
node.receive_event(event)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data[
|
||||
"some"
|
||||
] == "event.value_notification.central_scene - device - zwave_js_value_notification - {}".format(
|
||||
CommandClass.CENTRAL_SCENE
|
||||
)
|
||||
|
||||
|
||||
async def test_get_trigger_capabilities_central_scene_value_notification(
|
||||
hass, client, wallmote_central_scene, integration
|
||||
):
|
||||
"""Test we get the expected capabilities from a value_notification.central_scene trigger."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
capabilities = await device_trigger.async_get_trigger_capabilities(
|
||||
hass,
|
||||
{
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": "event.value_notification.central_scene",
|
||||
"device_id": device.id,
|
||||
"command_class": CommandClass.CENTRAL_SCENE.value,
|
||||
"property": "scene",
|
||||
"property_key": "001",
|
||||
"endpoint": 0,
|
||||
"subtype": "Endpoint 0 Scene 001",
|
||||
},
|
||||
)
|
||||
assert capabilities and "extra_fields" in capabilities
|
||||
|
||||
assert voluptuous_serialize.convert(
|
||||
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
|
||||
) == [
|
||||
{
|
||||
"name": "value",
|
||||
"required": True,
|
||||
"type": "select",
|
||||
"options": [(0, "KeyPressed"), (1, "KeyReleased"), (2, "KeyHeldDown")],
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
async def test_get_scene_activation_value_notification_triggers(
|
||||
hass, client, hank_binary_switch, integration
|
||||
):
|
||||
"""Test we get the expected triggers from a zwave_js device with the SceneActivation CC."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
expected_trigger = {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": "event.value_notification.scene_activation",
|
||||
"device_id": device.id,
|
||||
"command_class": CommandClass.SCENE_ACTIVATION.value,
|
||||
"property": "sceneId",
|
||||
"property_key": None,
|
||||
"endpoint": 0,
|
||||
"subtype": "Endpoint 0",
|
||||
}
|
||||
triggers = await async_get_device_automations(hass, "trigger", device.id)
|
||||
assert expected_trigger in triggers
|
||||
|
||||
|
||||
async def test_if_scene_activation_value_notification_fires(
|
||||
hass, client, hank_binary_switch, integration, calls
|
||||
):
|
||||
"""Test for event.value_notification.scene_activation trigger firing."""
|
||||
node: Node = hank_binary_switch
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"device_id": device.id,
|
||||
"type": "event.value_notification.scene_activation",
|
||||
"command_class": CommandClass.SCENE_ACTIVATION.value,
|
||||
"property": "sceneId",
|
||||
"property_key": None,
|
||||
"endpoint": 0,
|
||||
"subtype": "Endpoint 0",
|
||||
"value": 1,
|
||||
},
|
||||
"action": {
|
||||
"service": "test.automation",
|
||||
"data_template": {
|
||||
"some": (
|
||||
"event.value_notification.scene_activation - "
|
||||
"{{ trigger.platform}} - "
|
||||
"{{ trigger.event.event_type}} - "
|
||||
"{{ trigger.event.data.command_class }}"
|
||||
)
|
||||
},
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
|
||||
# Publish fake Scene Activation CC value notification
|
||||
event = Event(
|
||||
type="value notification",
|
||||
data={
|
||||
"source": "node",
|
||||
"event": "value notification",
|
||||
"nodeId": node.node_id,
|
||||
"args": {
|
||||
"commandClassName": "Scene Activation",
|
||||
"commandClass": 43,
|
||||
"endpoint": 0,
|
||||
"property": "sceneId",
|
||||
"propertyName": "sceneId",
|
||||
"value": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": True,
|
||||
"writeable": True,
|
||||
"min": 1,
|
||||
"max": 255,
|
||||
"label": "Scene ID",
|
||||
},
|
||||
"ccVersion": 1,
|
||||
},
|
||||
},
|
||||
)
|
||||
node.receive_event(event)
|
||||
await hass.async_block_till_done()
|
||||
assert len(calls) == 1
|
||||
assert calls[0].data[
|
||||
"some"
|
||||
] == "event.value_notification.scene_activation - device - zwave_js_value_notification - {}".format(
|
||||
CommandClass.SCENE_ACTIVATION
|
||||
)
|
||||
|
||||
|
||||
async def test_get_trigger_capabilities_scene_activation_value_notification(
|
||||
hass, client, hank_binary_switch, integration
|
||||
):
|
||||
"""Test we get the expected capabilities from a value_notification.scene_activation trigger."""
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
capabilities = await device_trigger.async_get_trigger_capabilities(
|
||||
hass,
|
||||
{
|
||||
"platform": "device",
|
||||
"domain": DOMAIN,
|
||||
"type": "event.value_notification.scene_activation",
|
||||
"device_id": device.id,
|
||||
"command_class": CommandClass.SCENE_ACTIVATION.value,
|
||||
"property": "sceneId",
|
||||
"property_key": None,
|
||||
"endpoint": 0,
|
||||
"subtype": "Endpoint 0",
|
||||
},
|
||||
)
|
||||
assert capabilities and "extra_fields" in capabilities
|
||||
|
||||
assert voluptuous_serialize.convert(
|
||||
capabilities["extra_fields"], custom_serializer=cv.custom_serializer
|
||||
) == [
|
||||
{
|
||||
"name": "value",
|
||||
"required": True,
|
||||
"type": "integer",
|
||||
"valueMin": 1,
|
||||
"valueMax": 255,
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
async def test_failure_scenarios(hass, client, hank_binary_switch, integration):
|
||||
"""Test failure scenarios."""
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await async_attach_trigger(
|
||||
hass, {"type": "failed.test", "device_id": "invalid_device_id"}, None, {}
|
||||
)
|
||||
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await async_attach_trigger(
|
||||
hass,
|
||||
{"type": "event.failed_type", "device_id": "invalid_device_id"},
|
||||
None,
|
||||
{},
|
||||
)
|
||||
|
||||
dev_reg = async_get_dev_reg(hass)
|
||||
device = async_entries_for_config_entry(dev_reg, integration.entry_id)[0]
|
||||
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await async_attach_trigger(
|
||||
hass, {"type": "failed.test", "device_id": device.id}, None, {}
|
||||
)
|
||||
|
||||
with pytest.raises(HomeAssistantError):
|
||||
await async_attach_trigger(
|
||||
hass,
|
||||
{"type": "event.failed_type", "device_id": device.id},
|
||||
None,
|
||||
{},
|
||||
)
|
||||
|
||||
with patch(
|
||||
"homeassistant.components.zwave_js.device_trigger.async_get_node_from_device_id",
|
||||
return_value=None,
|
||||
), patch(
|
||||
"homeassistant.components.zwave_js.helpers.get_zwave_value_from_config",
|
||||
return_value=None,
|
||||
):
|
||||
assert (
|
||||
await async_get_trigger_capabilities(
|
||||
hass, {"type": "failed.test", "device_id": "invalid_device_id"}
|
||||
)
|
||||
== {}
|
||||
)
|
||||
|
||||
with pytest.raises(HomeAssistantError):
|
||||
async_get_node_status_sensor_entity_id(hass, "invalid_device_id")
|
642
tests/fixtures/zwave_js/ge_in_wall_dimmer_switch_state.json
vendored
Normal file
642
tests/fixtures/zwave_js/ge_in_wall_dimmer_switch_state.json
vendored
Normal file
|
@ -0,0 +1,642 @@
|
|||
{
|
||||
"nodeId": 2,
|
||||
"index": 0,
|
||||
"installerIcon": 1536,
|
||||
"userIcon": 1536,
|
||||
"status": 4,
|
||||
"ready": true,
|
||||
"isListening": true,
|
||||
"isRouting": true,
|
||||
"isSecure": false,
|
||||
"manufacturerId": 99,
|
||||
"productId": 12344,
|
||||
"productType": 18756,
|
||||
"firmwareVersion": "5.26",
|
||||
"zwavePlusVersion": 1,
|
||||
"name": "LivingRoomLight",
|
||||
"location": "LivingRoom",
|
||||
"deviceConfig": {
|
||||
"filename": "/opt/node_modules/@zwave-js/config/config/devices/0x0063/ge_14294_zw3005.json",
|
||||
"manufacturer": "GE/Jasco",
|
||||
"manufacturerId": 99,
|
||||
"label": "14294 / ZW3005",
|
||||
"description": "In-Wall Dimmer Switch",
|
||||
"devices": [
|
||||
{
|
||||
"productType": 18756,
|
||||
"productId": 12344
|
||||
}
|
||||
],
|
||||
"firmwareVersion": {
|
||||
"min": "0.0",
|
||||
"max": "255.255"
|
||||
},
|
||||
"associations": {},
|
||||
"paramInformation": {
|
||||
"_map": {}
|
||||
},
|
||||
"compat": {
|
||||
"valueIdRegex": {},
|
||||
"treatBasicSetAsEvent": true
|
||||
},
|
||||
"isEmbedded": true
|
||||
},
|
||||
"label": "14294 / ZW3005",
|
||||
"interviewAttempts": 0,
|
||||
"endpoints": [
|
||||
{
|
||||
"nodeId": 2,
|
||||
"index": 0,
|
||||
"installerIcon": 1536,
|
||||
"userIcon": 1536,
|
||||
"deviceClass": {
|
||||
"basic": {
|
||||
"key": 4,
|
||||
"label": "Routing Slave"
|
||||
},
|
||||
"generic": {
|
||||
"key": 17,
|
||||
"label": "Multilevel Switch"
|
||||
},
|
||||
"specific": {
|
||||
"key": 1,
|
||||
"label": "Multilevel Power Switch"
|
||||
},
|
||||
"mandatorySupportedCCs": [32, 38, 39],
|
||||
"mandatoryControlledCCs": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"values": [
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 32,
|
||||
"commandClassName": "Basic",
|
||||
"property": "currentValue",
|
||||
"propertyName": "currentValue",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": false,
|
||||
"label": "Current value",
|
||||
"min": 0,
|
||||
"max": 99
|
||||
}
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 32,
|
||||
"commandClassName": "Basic",
|
||||
"property": "targetValue",
|
||||
"propertyName": "targetValue",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"label": "Target value",
|
||||
"min": 0,
|
||||
"max": 99
|
||||
}
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 32,
|
||||
"commandClassName": "Basic",
|
||||
"property": "event",
|
||||
"propertyName": "event",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": false,
|
||||
"label": "Event value",
|
||||
"min": 0,
|
||||
"max": 255
|
||||
}
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 38,
|
||||
"commandClassName": "Multilevel Switch",
|
||||
"property": "targetValue",
|
||||
"propertyName": "targetValue",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"label": "Target value",
|
||||
"min": 0,
|
||||
"max": 99
|
||||
},
|
||||
"value": 255
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 38,
|
||||
"commandClassName": "Multilevel Switch",
|
||||
"property": "duration",
|
||||
"propertyName": "duration",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "duration",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"label": "Transition duration"
|
||||
}
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 38,
|
||||
"commandClassName": "Multilevel Switch",
|
||||
"property": "currentValue",
|
||||
"propertyName": "currentValue",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": false,
|
||||
"label": "Current value",
|
||||
"min": 0,
|
||||
"max": 99
|
||||
},
|
||||
"value": 35
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 38,
|
||||
"commandClassName": "Multilevel Switch",
|
||||
"property": "Up",
|
||||
"propertyName": "Up",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "boolean",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"label": "Perform a level change (Up)",
|
||||
"ccSpecific": {
|
||||
"switchType": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 38,
|
||||
"commandClassName": "Multilevel Switch",
|
||||
"property": "Down",
|
||||
"propertyName": "Down",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "boolean",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"label": "Perform a level change (Down)",
|
||||
"ccSpecific": {
|
||||
"switchType": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 43,
|
||||
"commandClassName": "Scene Activation",
|
||||
"property": "sceneId",
|
||||
"propertyName": "sceneId",
|
||||
"ccVersion": 0,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"label": "Scene ID",
|
||||
"min": 1,
|
||||
"max": 255
|
||||
}
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 43,
|
||||
"commandClassName": "Scene Activation",
|
||||
"property": "dimmingDuration",
|
||||
"propertyName": "dimmingDuration",
|
||||
"ccVersion": 0,
|
||||
"metadata": {
|
||||
"type": "any",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"label": "Dimming duration"
|
||||
}
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 112,
|
||||
"commandClassName": "Configuration",
|
||||
"property": 3,
|
||||
"propertyName": "Night Light",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"description": "Defines the behavior of the blue LED. Default is on when switch is off.",
|
||||
"label": "Night Light",
|
||||
"default": 0,
|
||||
"min": 0,
|
||||
"max": 2,
|
||||
"states": {
|
||||
"0": "LED on when switch is OFF",
|
||||
"1": "LED on when switch is ON",
|
||||
"2": "LED always off"
|
||||
},
|
||||
"valueSize": 1,
|
||||
"format": 0,
|
||||
"allowManualEntry": false,
|
||||
"isFromConfig": true
|
||||
},
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 112,
|
||||
"commandClassName": "Configuration",
|
||||
"property": 4,
|
||||
"propertyName": "Invert Switch",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"description": "Invert the ON/OFF Switch State.",
|
||||
"label": "Invert Switch",
|
||||
"default": 0,
|
||||
"min": 0,
|
||||
"max": 1,
|
||||
"states": {
|
||||
"0": "No",
|
||||
"1": "Yes"
|
||||
},
|
||||
"valueSize": 1,
|
||||
"format": 0,
|
||||
"allowManualEntry": false,
|
||||
"isFromConfig": true
|
||||
},
|
||||
"value": 0
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 112,
|
||||
"commandClassName": "Configuration",
|
||||
"property": 7,
|
||||
"propertyName": "Dim Rate Steps (Z-Wave Command)",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"description": "Number of steps or levels",
|
||||
"label": "Dim Rate Steps (Z-Wave Command)",
|
||||
"default": 1,
|
||||
"min": 0,
|
||||
"max": 99,
|
||||
"valueSize": 1,
|
||||
"format": 1,
|
||||
"allowManualEntry": true,
|
||||
"isFromConfig": true
|
||||
},
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 112,
|
||||
"commandClassName": "Configuration",
|
||||
"property": 8,
|
||||
"propertyName": "Dim Rate Timing (Z-Wave)",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"description": "Timing of steps or levels",
|
||||
"label": "Dim Rate Timing (Z-Wave)",
|
||||
"default": 3,
|
||||
"min": 1,
|
||||
"max": 255,
|
||||
"unit": "10ms",
|
||||
"valueSize": 2,
|
||||
"format": 1,
|
||||
"allowManualEntry": true,
|
||||
"isFromConfig": true
|
||||
},
|
||||
"value": 3
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 112,
|
||||
"commandClassName": "Configuration",
|
||||
"property": 9,
|
||||
"propertyName": "Dim Rate Steps (Manual)",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"description": "Number of steps or levels",
|
||||
"label": "Dim Rate Steps (Manual)",
|
||||
"default": 1,
|
||||
"min": 1,
|
||||
"max": 99,
|
||||
"valueSize": 1,
|
||||
"format": 1,
|
||||
"allowManualEntry": true,
|
||||
"isFromConfig": true
|
||||
},
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 112,
|
||||
"commandClassName": "Configuration",
|
||||
"property": 10,
|
||||
"propertyName": "Dim Rate Timing (Manual)",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"description": "Timing of steps",
|
||||
"label": "Dim Rate Timing (Manual)",
|
||||
"default": 3,
|
||||
"min": 1,
|
||||
"max": 255,
|
||||
"unit": "10ms",
|
||||
"valueSize": 2,
|
||||
"format": 1,
|
||||
"allowManualEntry": true,
|
||||
"isFromConfig": true
|
||||
},
|
||||
"value": 3
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 112,
|
||||
"commandClassName": "Configuration",
|
||||
"property": 11,
|
||||
"propertyName": "Dim Rate Steps (All-On/All-Off)",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"description": "Number of steps or levels",
|
||||
"label": "Dim Rate Steps (All-On/All-Off)",
|
||||
"default": 1,
|
||||
"min": 1,
|
||||
"max": 99,
|
||||
"valueSize": 1,
|
||||
"format": 1,
|
||||
"allowManualEntry": true,
|
||||
"isFromConfig": true
|
||||
},
|
||||
"value": 1
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 112,
|
||||
"commandClassName": "Configuration",
|
||||
"property": 12,
|
||||
"propertyName": "Dim Rate Timing (All-On/All-Off)",
|
||||
"ccVersion": 1,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": true,
|
||||
"description": "Timing of steps or levels",
|
||||
"label": "Dim Rate Timing (All-On/All-Off)",
|
||||
"default": 3,
|
||||
"min": 1,
|
||||
"max": 255,
|
||||
"unit": "10ms",
|
||||
"valueSize": 2,
|
||||
"format": 1,
|
||||
"allowManualEntry": true,
|
||||
"isFromConfig": true
|
||||
},
|
||||
"value": 3
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 114,
|
||||
"commandClassName": "Manufacturer Specific",
|
||||
"property": "manufacturerId",
|
||||
"propertyName": "manufacturerId",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": false,
|
||||
"label": "Manufacturer ID",
|
||||
"min": 0,
|
||||
"max": 65535
|
||||
},
|
||||
"value": 99
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 114,
|
||||
"commandClassName": "Manufacturer Specific",
|
||||
"property": "productType",
|
||||
"propertyName": "productType",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": false,
|
||||
"label": "Product type",
|
||||
"min": 0,
|
||||
"max": 65535
|
||||
},
|
||||
"value": 18756
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 114,
|
||||
"commandClassName": "Manufacturer Specific",
|
||||
"property": "productId",
|
||||
"propertyName": "productId",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "number",
|
||||
"readable": true,
|
||||
"writeable": false,
|
||||
"label": "Product ID",
|
||||
"min": 0,
|
||||
"max": 65535
|
||||
},
|
||||
"value": 12344
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 134,
|
||||
"commandClassName": "Version",
|
||||
"property": "libraryType",
|
||||
"propertyName": "libraryType",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "any",
|
||||
"readable": true,
|
||||
"writeable": false,
|
||||
"label": "Library type"
|
||||
},
|
||||
"value": 3
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 134,
|
||||
"commandClassName": "Version",
|
||||
"property": "protocolVersion",
|
||||
"propertyName": "protocolVersion",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "any",
|
||||
"readable": true,
|
||||
"writeable": false,
|
||||
"label": "Z-Wave protocol version"
|
||||
},
|
||||
"value": "4.34"
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 134,
|
||||
"commandClassName": "Version",
|
||||
"property": "firmwareVersions",
|
||||
"propertyName": "firmwareVersions",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "any",
|
||||
"readable": true,
|
||||
"writeable": false,
|
||||
"label": "Z-Wave chip firmware versions"
|
||||
},
|
||||
"value": ["5.26"]
|
||||
},
|
||||
{
|
||||
"endpoint": 0,
|
||||
"commandClass": 134,
|
||||
"commandClassName": "Version",
|
||||
"property": "hardwareVersion",
|
||||
"propertyName": "hardwareVersion",
|
||||
"ccVersion": 2,
|
||||
"metadata": {
|
||||
"type": "any",
|
||||
"readable": true,
|
||||
"writeable": false,
|
||||
"label": "Z-Wave chip hardware version"
|
||||
}
|
||||
}
|
||||
],
|
||||
"isFrequentListening": false,
|
||||
"maxDataRate": 40000,
|
||||
"supportedDataRates": [40000],
|
||||
"protocolVersion": 3,
|
||||
"zwavePlusNodeType": 0,
|
||||
"zwavePlusRoleType": 5,
|
||||
"deviceClass": {
|
||||
"basic": {
|
||||
"key": 4,
|
||||
"label": "Routing Slave"
|
||||
},
|
||||
"generic": {
|
||||
"key": 17,
|
||||
"label": "Multilevel Switch"
|
||||
},
|
||||
"specific": {
|
||||
"key": 1,
|
||||
"label": "Multilevel Power Switch"
|
||||
},
|
||||
"mandatorySupportedCCs": [32, 38, 39],
|
||||
"mandatoryControlledCCs": []
|
||||
},
|
||||
"commandClasses": [
|
||||
{
|
||||
"id": 32,
|
||||
"name": "Basic",
|
||||
"version": 1,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 38,
|
||||
"name": "Multilevel Switch",
|
||||
"version": 2,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 43,
|
||||
"name": "Scene Activation",
|
||||
"version": 1,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 44,
|
||||
"name": "Scene Actuator Configuration",
|
||||
"version": 1,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 86,
|
||||
"name": "CRC-16 Encapsulation",
|
||||
"version": 1,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 89,
|
||||
"name": "Association Group Information",
|
||||
"version": 1,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 90,
|
||||
"name": "Device Reset Locally",
|
||||
"version": 1,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 94,
|
||||
"name": "Z-Wave Plus Info",
|
||||
"version": 2,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 112,
|
||||
"name": "Configuration",
|
||||
"version": 1,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 114,
|
||||
"name": "Manufacturer Specific",
|
||||
"version": 2,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 122,
|
||||
"name": "Firmware Update Meta Data",
|
||||
"version": 2,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 133,
|
||||
"name": "Association",
|
||||
"version": 2,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 134,
|
||||
"name": "Version",
|
||||
"version": 2,
|
||||
"isSecure": false
|
||||
}
|
||||
],
|
||||
"interviewStage": "Complete",
|
||||
"deviceDatabaseUrl": "https://devices.zwave-js.io/?jumpTo=0x0063:0x4944:0x3038:5.26"
|
||||
}
|
|
@ -50,7 +50,68 @@
|
|||
"index": 0
|
||||
}
|
||||
],
|
||||
"commandClasses": [],
|
||||
"commandClasses": [
|
||||
{
|
||||
"id": 98,
|
||||
"name": "Door Lock",
|
||||
"version": 1,
|
||||
"isSecure": true
|
||||
},
|
||||
{
|
||||
"id": 99,
|
||||
"name": "User Code",
|
||||
"version": 1,
|
||||
"isSecure": true
|
||||
},
|
||||
{
|
||||
"id": 112,
|
||||
"name": "Configuration",
|
||||
"version": 1,
|
||||
"isSecure": true
|
||||
},
|
||||
{
|
||||
"id": 113,
|
||||
"name": "Notification",
|
||||
"version": 1,
|
||||
"isSecure": true
|
||||
},
|
||||
{
|
||||
"id": 114,
|
||||
"name": "Manufacturer Specific",
|
||||
"version": 1,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 122,
|
||||
"name": "Firmware Update Meta Data",
|
||||
"version": 1,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 128,
|
||||
"name": "Battery",
|
||||
"version": 1,
|
||||
"isSecure": true
|
||||
},
|
||||
{
|
||||
"id": 133,
|
||||
"name": "Association",
|
||||
"version": 1,
|
||||
"isSecure": true
|
||||
},
|
||||
{
|
||||
"id": 134,
|
||||
"name": "Version",
|
||||
"version": 1,
|
||||
"isSecure": false
|
||||
},
|
||||
{
|
||||
"id": 152,
|
||||
"name": "Security",
|
||||
"version": 1,
|
||||
"isSecure": true
|
||||
}
|
||||
],
|
||||
"values": [
|
||||
{
|
||||
"commandClassName": "Door Lock",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue