Use device ID as input for zwave_js WS device cmds (#71667)

* Use device ID as input for zwave_js WS device cmds

* Additionally missed commands, update network_status command to include node status data

* revert change to removed function

* Revert register device change
This commit is contained in:
Raman Gupta 2022-05-19 13:31:24 -04:00 committed by GitHub
parent 1c4c0f1eb3
commit 487819bbe5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 179 additions and 372 deletions

View File

@ -68,7 +68,11 @@ from .const import (
EVENT_DEVICE_ADDED_TO_REGISTRY, EVENT_DEVICE_ADDED_TO_REGISTRY,
LOGGER, LOGGER,
) )
from .helpers import async_enable_statistics, update_data_collection_preference from .helpers import (
async_enable_statistics,
async_get_node_from_device_id,
update_data_collection_preference,
)
from .migrate import ( from .migrate import (
ZWaveMigrationData, ZWaveMigrationData,
async_get_migration_data, async_get_migration_data,
@ -83,6 +87,7 @@ ID = "id"
ENTRY_ID = "entry_id" ENTRY_ID = "entry_id"
ERR_NOT_LOADED = "not_loaded" ERR_NOT_LOADED = "not_loaded"
NODE_ID = "node_id" NODE_ID = "node_id"
DEVICE_ID = "device_id"
COMMAND_CLASS_ID = "command_class_id" COMMAND_CLASS_ID = "command_class_id"
TYPE = "type" TYPE = "type"
PROPERTY = "property" PROPERTY = "property"
@ -254,21 +259,20 @@ def async_get_entry(orig_func: Callable) -> Callable:
def async_get_node(orig_func: Callable) -> Callable: def async_get_node(orig_func: Callable) -> Callable:
"""Decorate async function to get node.""" """Decorate async function to get node."""
@async_get_entry
@wraps(orig_func) @wraps(orig_func)
async def async_get_node_func( async def async_get_node_func(
hass: HomeAssistant, hass: HomeAssistant, connection: ActiveConnection, msg: dict
connection: ActiveConnection,
msg: dict,
entry: ConfigEntry,
client: Client,
) -> None: ) -> None:
"""Provide user specific data and store to function.""" """Provide user specific data and store to function."""
node_id = msg[NODE_ID] device_id = msg[DEVICE_ID]
node = client.driver.controller.nodes.get(node_id)
if node is None: try:
connection.send_error(msg[ID], ERR_NOT_FOUND, f"Node {node_id} not found") node = async_get_node_from_device_id(hass, device_id)
except ValueError as err:
error_code = ERR_NOT_FOUND
if "loaded" in err.args[0]:
error_code = ERR_NOT_LOADED
connection.send_error(msg[ID], error_code, err.args[0])
return return
await orig_func(hass, connection, msg, node) await orig_func(hass, connection, msg, node)
@ -299,13 +303,26 @@ def async_handle_failed_command(orig_func: Callable) -> Callable:
return async_handle_failed_command_func return async_handle_failed_command_func
def node_status(node: Node) -> dict[str, Any]:
"""Get node status."""
return {
"node_id": node.node_id,
"is_routing": node.is_routing,
"status": node.status,
"is_secure": node.is_secure,
"ready": node.ready,
"zwave_plus_version": node.zwave_plus_version,
"highest_security_class": node.highest_security_class,
"is_controller_node": node.is_controller_node,
}
@callback @callback
def async_register_api(hass: HomeAssistant) -> None: def async_register_api(hass: HomeAssistant) -> None:
"""Register all of our api endpoints.""" """Register all of our api endpoints."""
websocket_api.async_register_command(hass, websocket_network_status) websocket_api.async_register_command(hass, websocket_network_status)
websocket_api.async_register_command(hass, websocket_node_status) websocket_api.async_register_command(hass, websocket_node_status)
websocket_api.async_register_command(hass, websocket_node_metadata) websocket_api.async_register_command(hass, websocket_node_metadata)
websocket_api.async_register_command(hass, websocket_ping_node)
websocket_api.async_register_command(hass, websocket_add_node) websocket_api.async_register_command(hass, websocket_add_node)
websocket_api.async_register_command(hass, websocket_grant_security_classes) websocket_api.async_register_command(hass, websocket_grant_security_classes)
websocket_api.async_register_command(hass, websocket_validate_dsk_and_enter_pin) websocket_api.async_register_command(hass, websocket_validate_dsk_and_enter_pin)
@ -395,7 +412,9 @@ async def websocket_network_status(
"supports_timers": controller.supports_timers, "supports_timers": controller.supports_timers,
"is_heal_network_active": controller.is_heal_network_active, "is_heal_network_active": controller.is_heal_network_active,
"inclusion_state": controller.inclusion_state, "inclusion_state": controller.inclusion_state,
"nodes": list(client.driver.controller.nodes), "nodes": [
node_status(node) for node in client.driver.controller.nodes.values()
],
}, },
} }
connection.send_result( connection.send_result(
@ -407,8 +426,7 @@ async def websocket_network_status(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/node_ready", vol.Required(TYPE): "zwave_js/node_ready",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
} }
) )
@websocket_api.async_response @websocket_api.async_response
@ -443,8 +461,7 @@ async def websocket_node_ready(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/node_status", vol.Required(TYPE): "zwave_js/node_status",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
} }
) )
@websocket_api.async_response @websocket_api.async_response
@ -456,27 +473,13 @@ async def websocket_node_status(
node: Node, node: Node,
) -> None: ) -> None:
"""Get the status of a Z-Wave JS node.""" """Get the status of a Z-Wave JS node."""
data = { connection.send_result(msg[ID], node_status(node))
"node_id": node.node_id,
"is_routing": node.is_routing,
"status": node.status,
"is_secure": node.is_secure,
"ready": node.ready,
"zwave_plus_version": node.zwave_plus_version,
"highest_security_class": node.highest_security_class,
"is_controller_node": node.is_controller_node,
}
connection.send_result(
msg[ID],
data,
)
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/node_metadata", vol.Required(TYPE): "zwave_js/node_metadata",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
} }
) )
@websocket_api.async_response @websocket_api.async_response
@ -504,30 +507,6 @@ async def websocket_node_metadata(
) )
@websocket_api.websocket_command(
{
vol.Required(TYPE): "zwave_js/ping_node",
vol.Required(ENTRY_ID): str,
vol.Required(NODE_ID): int,
}
)
@websocket_api.async_response
@async_handle_failed_command
@async_get_node
async def websocket_ping_node(
hass: HomeAssistant,
connection: ActiveConnection,
msg: dict,
node: Node,
) -> None:
"""Ping a Z-Wave JS node."""
result = await node.async_ping()
connection.send_result(
msg[ID],
result,
)
@websocket_api.require_admin @websocket_api.require_admin
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
@ -1189,23 +1168,20 @@ async def websocket_replace_failed_node(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/remove_failed_node", vol.Required(TYPE): "zwave_js/remove_failed_node",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
} }
) )
@websocket_api.async_response @websocket_api.async_response
@async_handle_failed_command @async_handle_failed_command
@async_get_entry @async_get_node
async def websocket_remove_failed_node( async def websocket_remove_failed_node(
hass: HomeAssistant, hass: HomeAssistant,
connection: ActiveConnection, connection: ActiveConnection,
msg: dict, msg: dict,
entry: ConfigEntry, node: Node,
client: Client,
) -> None: ) -> None:
"""Remove a failed node from the Z-Wave network.""" """Remove a failed node from the Z-Wave network."""
controller = client.driver.controller controller = node.client.driver.controller
node_id = msg[NODE_ID]
@callback @callback
def async_cleanup() -> None: def async_cleanup() -> None:
@ -1215,10 +1191,7 @@ async def websocket_remove_failed_node(
@callback @callback
def node_removed(event: dict) -> None: def node_removed(event: dict) -> None:
node = event["node"] node_details = {"node_id": event["node"].node_id}
node_details = {
"node_id": node.node_id,
}
connection.send_message( connection.send_message(
websocket_api.event_message( websocket_api.event_message(
@ -1229,7 +1202,7 @@ async def websocket_remove_failed_node(
connection.subscriptions[msg["id"]] = async_cleanup connection.subscriptions[msg["id"]] = async_cleanup
msg[DATA_UNSUBSCRIBE] = unsubs = [controller.on("node removed", node_removed)] msg[DATA_UNSUBSCRIBE] = unsubs = [controller.on("node removed", node_removed)]
result = await controller.async_remove_failed_node(node_id) result = await controller.async_remove_failed_node(node.node_id)
connection.send_result( connection.send_result(
msg[ID], msg[ID],
result, result,
@ -1335,24 +1308,21 @@ async def websocket_stop_healing_network(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/heal_node", vol.Required(TYPE): "zwave_js/heal_node",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
} }
) )
@websocket_api.async_response @websocket_api.async_response
@async_handle_failed_command @async_handle_failed_command
@async_get_entry @async_get_node
async def websocket_heal_node( async def websocket_heal_node(
hass: HomeAssistant, hass: HomeAssistant,
connection: ActiveConnection, connection: ActiveConnection,
msg: dict, msg: dict,
entry: ConfigEntry, node: Node,
client: Client,
) -> None: ) -> None:
"""Heal a node on the Z-Wave network.""" """Heal a node on the Z-Wave network."""
controller = client.driver.controller controller = node.client.driver.controller
node_id = msg[NODE_ID] result = await controller.async_heal_node(node.node_id)
result = await controller.async_heal_node(node_id)
connection.send_result( connection.send_result(
msg[ID], msg[ID],
result, result,
@ -1363,8 +1333,7 @@ async def websocket_heal_node(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/refresh_node_info", vol.Required(TYPE): "zwave_js/refresh_node_info",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
}, },
) )
@websocket_api.async_response @websocket_api.async_response
@ -1414,8 +1383,7 @@ async def websocket_refresh_node_info(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/refresh_node_values", vol.Required(TYPE): "zwave_js/refresh_node_values",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
}, },
) )
@websocket_api.async_response @websocket_api.async_response
@ -1436,8 +1404,7 @@ async def websocket_refresh_node_values(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/refresh_node_cc_values", vol.Required(TYPE): "zwave_js/refresh_node_cc_values",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
vol.Required(COMMAND_CLASS_ID): int, vol.Required(COMMAND_CLASS_ID): int,
}, },
) )
@ -1469,8 +1436,7 @@ async def websocket_refresh_node_cc_values(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/set_config_parameter", vol.Required(TYPE): "zwave_js/set_config_parameter",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
vol.Required(PROPERTY): int, vol.Required(PROPERTY): int,
vol.Optional(PROPERTY_KEY): int, vol.Optional(PROPERTY_KEY): int,
vol.Required(VALUE): vol.Any(int, BITMASK_SCHEMA), vol.Required(VALUE): vol.Any(int, BITMASK_SCHEMA),
@ -1521,8 +1487,7 @@ async def websocket_set_config_parameter(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/get_config_parameters", vol.Required(TYPE): "zwave_js/get_config_parameters",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
} }
) )
@websocket_api.async_response @websocket_api.async_response
@ -1762,8 +1727,7 @@ async def websocket_data_collection_status(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/abort_firmware_update", vol.Required(TYPE): "zwave_js/abort_firmware_update",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
} }
) )
@websocket_api.async_response @websocket_api.async_response
@ -1794,8 +1758,7 @@ def _get_firmware_update_progress_dict(
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/subscribe_firmware_update_status", vol.Required(TYPE): "zwave_js/subscribe_firmware_update_status",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
} }
) )
@websocket_api.async_response @websocket_api.async_response
@ -2047,8 +2010,7 @@ def _get_node_statistics_dict(statistics: NodeStatistics) -> dict[str, int]:
@websocket_api.websocket_command( @websocket_api.websocket_command(
{ {
vol.Required(TYPE): "zwave_js/subscribe_node_statistics", vol.Required(TYPE): "zwave_js/subscribe_node_statistics",
vol.Required(ENTRY_ID): str, vol.Required(DEVICE_ID): str,
vol.Required(NODE_ID): int,
} }
) )
@websocket_api.async_response @websocket_api.async_response

View File

@ -179,24 +179,22 @@ def async_get_node_from_device_id(
# Use device config entry ID's to validate that this is a valid zwave_js device # Use device config entry ID's to validate that this is a valid zwave_js device
# and to get the client # and to get the client
config_entry_ids = device_entry.config_entries config_entry_ids = device_entry.config_entries
config_entry_id = next( entry = next(
( (
config_entry_id entry
for config_entry_id in config_entry_ids for entry in hass.config_entries.async_entries(DOMAIN)
if cast( if entry.entry_id in config_entry_ids
ConfigEntry,
hass.config_entries.async_get_entry(config_entry_id),
).domain
== DOMAIN
), ),
None, None,
) )
if config_entry_id is None or config_entry_id not in hass.data[DOMAIN]: if entry and entry.state != ConfigEntryState.LOADED:
raise ValueError(f"Device {device_id} config entry is not loaded")
if entry is None or entry.entry_id not in hass.data[DOMAIN]:
raise ValueError( raise ValueError(
f"Device {device_id} is not from an existing zwave_js config entry" f"Device {device_id} is not from an existing zwave_js config entry"
) )
client = hass.data[DOMAIN][config_entry_id][DATA_CLIENT] client = hass.data[DOMAIN][entry.entry_id][DATA_CLIENT]
# Get node ID from device identifier, perform some validation, and then get the # Get node ID from device identifier, perform some validation, and then get the
# node # node
@ -390,21 +388,6 @@ def copy_available_params(
) )
@callback
def async_is_device_config_entry_not_loaded(
hass: HomeAssistant, device_id: str
) -> bool:
"""Return whether device's config entries are not loaded."""
dev_reg = dr.async_get(hass)
if (device := dev_reg.async_get(device_id)) is None:
raise ValueError(f"Device {device_id} not found")
return any(
(entry := hass.config_entries.async_get_entry(entry_id))
and entry.state != ConfigEntryState.LOADED
for entry_id in device.config_entries
)
def get_value_state_schema( def get_value_state_schema(
value: ZwaveValue, value: ZwaveValue,
) -> vol.Schema | None: ) -> vol.Schema | None:

View File

@ -35,6 +35,7 @@ from homeassistant.components.zwave_js.api import (
CLIENT_SIDE_AUTH, CLIENT_SIDE_AUTH,
COMMAND_CLASS_ID, COMMAND_CLASS_ID,
CONFIG, CONFIG,
DEVICE_ID,
DSK, DSK,
ENABLED, ENABLED,
ENTRY_ID, ENTRY_ID,
@ -70,9 +71,17 @@ from homeassistant.components.zwave_js.const import (
CONF_DATA_COLLECTION_OPTED_IN, CONF_DATA_COLLECTION_OPTED_IN,
DOMAIN, DOMAIN,
) )
from homeassistant.components.zwave_js.helpers import get_device_id
from homeassistant.helpers import device_registry as dr from homeassistant.helpers import device_registry as dr
def get_device(hass, node):
"""Get device ID for a node."""
dev_reg = dr.async_get(hass)
device_id = get_device_id(node.client, node)
return dev_reg.async_get_device({device_id})
async def test_network_status(hass, integration, hass_ws_client): async def test_network_status(hass, integration, hass_ws_client):
"""Test the network status websocket command.""" """Test the network status websocket command."""
entry = integration entry = integration
@ -117,12 +126,16 @@ async def test_node_ready(
node.data["ready"] = False node.data["ready"] = False
client.driver.controller.nodes[node.node_id] = node client.driver.controller.nodes[node.node_id] = node
dev_reg = dr.async_get(hass)
device = dev_reg.async_get_or_create(
config_entry_id=entry.entry_id, identifiers={get_device_id(client, node)}
)
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 3, ID: 3,
TYPE: "zwave_js/node_ready", TYPE: "zwave_js/node_ready",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
"node_id": node.node_id,
} }
) )
@ -153,12 +166,12 @@ async def test_node_status(hass, multisensor_6, integration, hass_ws_client):
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
node = multisensor_6 node = multisensor_6
device = get_device(hass, node)
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 3, ID: 3,
TYPE: "zwave_js/node_status", TYPE: "zwave_js/node_status",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: node.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -178,8 +191,7 @@ async def test_node_status(hass, multisensor_6, integration, hass_ws_client):
{ {
ID: 4, ID: 4,
TYPE: "zwave_js/node_status", TYPE: "zwave_js/node_status",
ENTRY_ID: entry.entry_id, DEVICE_ID: "fake_device",
NODE_ID: 99999,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -194,8 +206,7 @@ async def test_node_status(hass, multisensor_6, integration, hass_ws_client):
{ {
ID: 5, ID: 5,
TYPE: "zwave_js/node_status", TYPE: "zwave_js/node_status",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: node.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -210,12 +221,12 @@ async def test_node_metadata(hass, wallmote_central_scene, integration, hass_ws_
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
node = wallmote_central_scene node = wallmote_central_scene
device = get_device(hass, node)
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 3, ID: 3,
TYPE: "zwave_js/node_metadata", TYPE: "zwave_js/node_metadata",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: node.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -256,8 +267,7 @@ async def test_node_metadata(hass, wallmote_central_scene, integration, hass_ws_
{ {
ID: 4, ID: 4,
TYPE: "zwave_js/node_metadata", TYPE: "zwave_js/node_metadata",
ENTRY_ID: entry.entry_id, DEVICE_ID: "fake_device",
NODE_ID: 99999,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -272,81 +282,7 @@ async def test_node_metadata(hass, wallmote_central_scene, integration, hass_ws_
{ {
ID: 5, ID: 5,
TYPE: "zwave_js/node_metadata", TYPE: "zwave_js/node_metadata",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: node.node_id,
}
)
msg = await ws_client.receive_json()
assert not msg["success"]
assert msg["error"]["code"] == ERR_NOT_LOADED
async def test_ping_node(
hass, wallmote_central_scene, integration, client, hass_ws_client
):
"""Test the ping_node websocket command."""
entry = integration
ws_client = await hass_ws_client(hass)
node = wallmote_central_scene
client.async_send_command.return_value = {"responded": True}
await ws_client.send_json(
{
ID: 3,
TYPE: "zwave_js/ping_node",
ENTRY_ID: entry.entry_id,
NODE_ID: node.node_id,
}
)
msg = await ws_client.receive_json()
assert msg["success"]
assert msg["result"]
# Test getting non-existent node fails
await ws_client.send_json(
{
ID: 4,
TYPE: "zwave_js/ping_node",
ENTRY_ID: entry.entry_id,
NODE_ID: 99999,
}
)
msg = await ws_client.receive_json()
assert not msg["success"]
assert msg["error"]["code"] == ERR_NOT_FOUND
# Test FailedZWaveCommand is caught
with patch(
"zwave_js_server.model.node.Node.async_ping",
side_effect=FailedZWaveCommand("failed_command", 1, "error message"),
):
await ws_client.send_json(
{
ID: 5,
TYPE: "zwave_js/ping_node",
ENTRY_ID: entry.entry_id,
NODE_ID: node.node_id,
}
)
msg = await ws_client.receive_json()
assert not msg["success"]
assert msg["error"]["code"] == "zwave_error"
assert msg["error"]["message"] == "Z-Wave error 1: error message"
# Test sending command with not loaded entry fails
await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done()
await ws_client.send_json(
{
ID: 6,
TYPE: "zwave_js/ping_node",
ENTRY_ID: entry.entry_id,
NODE_ID: node.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -1812,19 +1748,38 @@ async def test_remove_failed_node(
client, client,
hass_ws_client, hass_ws_client,
nortek_thermostat_removed_event, nortek_thermostat_removed_event,
nortek_thermostat_added_event,
): ):
"""Test the remove_failed_node websocket command.""" """Test the remove_failed_node websocket command."""
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, nortek_thermostat)
client.async_send_command.return_value = {"success": True} client.async_send_command.return_value = {"success": True}
# Test FailedZWaveCommand is caught
with patch(
"zwave_js_server.model.controller.Controller.async_remove_failed_node",
side_effect=FailedZWaveCommand("failed_command", 1, "error message"),
):
await ws_client.send_json(
{
ID: 1,
TYPE: "zwave_js/remove_failed_node",
DEVICE_ID: device.id,
}
)
msg = await ws_client.receive_json()
assert not msg["success"]
assert msg["error"]["code"] == "zwave_error"
assert msg["error"]["message"] == "Z-Wave error 1: error message"
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 3, ID: 2,
TYPE: "zwave_js/remove_failed_node", TYPE: "zwave_js/remove_failed_node",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 67,
} }
) )
@ -1846,29 +1801,15 @@ async def test_remove_failed_node(
assert msg["event"]["event"] == "node removed" assert msg["event"]["event"] == "node removed"
# Verify device was removed from device registry # Verify device was removed from device registry
device = dev_reg.async_get_device( assert (
identifiers={(DOMAIN, "3245146787-67")}, dev_reg.async_get_device(
) identifiers={(DOMAIN, "3245146787-67")},
assert device is None
# Test FailedZWaveCommand is caught
with patch(
"zwave_js_server.model.controller.Controller.async_remove_failed_node",
side_effect=FailedZWaveCommand("failed_command", 1, "error message"),
):
await ws_client.send_json(
{
ID: 4,
TYPE: "zwave_js/remove_failed_node",
ENTRY_ID: entry.entry_id,
NODE_ID: 67,
}
) )
msg = await ws_client.receive_json() is None
)
assert not msg["success"] # Re-add node so we can test config entry not loaded
assert msg["error"]["code"] == "zwave_error" client.driver.receive_event(nortek_thermostat_added_event)
assert msg["error"]["message"] == "Z-Wave error 1: error message"
# Test sending command with not loaded entry fails # Test sending command with not loaded entry fails
await hass.config_entries.async_unload(entry.entry_id) await hass.config_entries.async_unload(entry.entry_id)
@ -1876,10 +1817,9 @@ async def test_remove_failed_node(
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 5, ID: 3,
TYPE: "zwave_js/remove_failed_node", TYPE: "zwave_js/remove_failed_node",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 67,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2091,6 +2031,7 @@ async def test_stop_healing_network(
async def test_heal_node( async def test_heal_node(
hass, hass,
multisensor_6,
integration, integration,
client, client,
hass_ws_client, hass_ws_client,
@ -2098,6 +2039,7 @@ async def test_heal_node(
"""Test the heal_node websocket command.""" """Test the heal_node websocket command."""
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
client.async_send_command.return_value = {"success": True} client.async_send_command.return_value = {"success": True}
@ -2105,8 +2047,7 @@ async def test_heal_node(
{ {
ID: 3, ID: 3,
TYPE: "zwave_js/heal_node", TYPE: "zwave_js/heal_node",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 67,
} }
) )
@ -2123,8 +2064,7 @@ async def test_heal_node(
{ {
ID: 4, ID: 4,
TYPE: "zwave_js/heal_node", TYPE: "zwave_js/heal_node",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 67,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2141,8 +2081,7 @@ async def test_heal_node(
{ {
ID: 5, ID: 5,
TYPE: "zwave_js/heal_node", TYPE: "zwave_js/heal_node",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 67,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2158,13 +2097,14 @@ async def test_refresh_node_info(
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
client.async_send_command_no_wait.return_value = None client.async_send_command_no_wait.return_value = None
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 1, ID: 1,
TYPE: "zwave_js/refresh_node_info", TYPE: "zwave_js/refresh_node_info",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2232,8 +2172,7 @@ async def test_refresh_node_info(
{ {
ID: 2, ID: 2,
TYPE: "zwave_js/refresh_node_info", TYPE: "zwave_js/refresh_node_info",
ENTRY_ID: entry.entry_id, DEVICE_ID: "fake_device",
NODE_ID: 9999,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2249,8 +2188,7 @@ async def test_refresh_node_info(
{ {
ID: 3, ID: 3,
TYPE: "zwave_js/refresh_node_info", TYPE: "zwave_js/refresh_node_info",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2267,8 +2205,7 @@ async def test_refresh_node_info(
{ {
ID: 4, ID: 4,
TYPE: "zwave_js/refresh_node_info", TYPE: "zwave_js/refresh_node_info",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2283,14 +2220,14 @@ async def test_refresh_node_values(
"""Test that the refresh_node_values WS API call works.""" """Test that the refresh_node_values WS API call works."""
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
client.async_send_command_no_wait.return_value = None client.async_send_command_no_wait.return_value = None
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 1, ID: 1,
TYPE: "zwave_js/refresh_node_values", TYPE: "zwave_js/refresh_node_values",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2303,26 +2240,12 @@ async def test_refresh_node_values(
client.async_send_command_no_wait.reset_mock() client.async_send_command_no_wait.reset_mock()
# Test getting non-existent node fails # Test getting non-existent device fails
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 2, ID: 2,
TYPE: "zwave_js/refresh_node_values", TYPE: "zwave_js/refresh_node_values",
ENTRY_ID: entry.entry_id, DEVICE_ID: "fake_device",
NODE_ID: 99999,
}
)
msg = await ws_client.receive_json()
assert not msg["success"]
assert msg["error"]["code"] == ERR_NOT_FOUND
# Test getting non-existent entry fails
await ws_client.send_json(
{
ID: 3,
TYPE: "zwave_js/refresh_node_values",
ENTRY_ID: "fake_entry_id",
NODE_ID: 52,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2338,8 +2261,7 @@ async def test_refresh_node_values(
{ {
ID: 4, ID: 4,
TYPE: "zwave_js/refresh_node_values", TYPE: "zwave_js/refresh_node_values",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2356,8 +2278,7 @@ async def test_refresh_node_values(
{ {
ID: 5, ID: 5,
TYPE: "zwave_js/refresh_node_values", TYPE: "zwave_js/refresh_node_values",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2367,19 +2288,19 @@ async def test_refresh_node_values(
async def test_refresh_node_cc_values( async def test_refresh_node_cc_values(
hass, client, multisensor_6, integration, hass_ws_client hass, multisensor_6, client, integration, hass_ws_client
): ):
"""Test that the refresh_node_cc_values WS API call works.""" """Test that the refresh_node_cc_values WS API call works."""
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
client.async_send_command_no_wait.return_value = None client.async_send_command_no_wait.return_value = None
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 1, ID: 1,
TYPE: "zwave_js/refresh_node_cc_values", TYPE: "zwave_js/refresh_node_cc_values",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
COMMAND_CLASS_ID: 112, COMMAND_CLASS_ID: 112,
} }
) )
@ -2399,8 +2320,7 @@ async def test_refresh_node_cc_values(
{ {
ID: 2, ID: 2,
TYPE: "zwave_js/refresh_node_cc_values", TYPE: "zwave_js/refresh_node_cc_values",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
COMMAND_CLASS_ID: 9999, COMMAND_CLASS_ID: 9999,
} }
) )
@ -2408,13 +2328,12 @@ async def test_refresh_node_cc_values(
assert not msg["success"] assert not msg["success"]
assert msg["error"]["code"] == ERR_NOT_FOUND assert msg["error"]["code"] == ERR_NOT_FOUND
# Test getting non-existent node fails # Test getting non-existent device fails
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 3, ID: 3,
TYPE: "zwave_js/refresh_node_cc_values", TYPE: "zwave_js/refresh_node_cc_values",
ENTRY_ID: entry.entry_id, DEVICE_ID: "fake_device",
NODE_ID: 9999,
COMMAND_CLASS_ID: 112, COMMAND_CLASS_ID: 112,
} }
) )
@ -2431,8 +2350,7 @@ async def test_refresh_node_cc_values(
{ {
ID: 4, ID: 4,
TYPE: "zwave_js/refresh_node_cc_values", TYPE: "zwave_js/refresh_node_cc_values",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
COMMAND_CLASS_ID: 112, COMMAND_CLASS_ID: 112,
} }
) )
@ -2450,8 +2368,7 @@ async def test_refresh_node_cc_values(
{ {
ID: 5, ID: 5,
TYPE: "zwave_js/refresh_node_cc_values", TYPE: "zwave_js/refresh_node_cc_values",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
COMMAND_CLASS_ID: 112, COMMAND_CLASS_ID: 112,
} }
) )
@ -2462,11 +2379,12 @@ async def test_refresh_node_cc_values(
async def test_set_config_parameter( async def test_set_config_parameter(
hass, client, hass_ws_client, multisensor_6, integration hass, multisensor_6, client, hass_ws_client, integration
): ):
"""Test the set_config_parameter service.""" """Test the set_config_parameter service."""
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
client.async_send_command_no_wait.return_value = None client.async_send_command_no_wait.return_value = None
@ -2474,8 +2392,7 @@ async def test_set_config_parameter(
{ {
ID: 1, ID: 1,
TYPE: "zwave_js/set_config_parameter", TYPE: "zwave_js/set_config_parameter",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
PROPERTY: 102, PROPERTY: 102,
PROPERTY_KEY: 1, PROPERTY_KEY: 1,
VALUE: 1, VALUE: 1,
@ -2523,8 +2440,7 @@ async def test_set_config_parameter(
{ {
ID: 2, ID: 2,
TYPE: "zwave_js/set_config_parameter", TYPE: "zwave_js/set_config_parameter",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
PROPERTY: 102, PROPERTY: 102,
PROPERTY_KEY: 1, PROPERTY_KEY: 1,
VALUE: "0x1", VALUE: "0x1",
@ -2573,8 +2489,7 @@ async def test_set_config_parameter(
{ {
ID: 3, ID: 3,
TYPE: "zwave_js/set_config_parameter", TYPE: "zwave_js/set_config_parameter",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
PROPERTY: 102, PROPERTY: 102,
PROPERTY_KEY: 1, PROPERTY_KEY: 1,
VALUE: 1, VALUE: 1,
@ -2593,8 +2508,7 @@ async def test_set_config_parameter(
{ {
ID: 4, ID: 4,
TYPE: "zwave_js/set_config_parameter", TYPE: "zwave_js/set_config_parameter",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
PROPERTY: 102, PROPERTY: 102,
PROPERTY_KEY: 1, PROPERTY_KEY: 1,
VALUE: 1, VALUE: 1,
@ -2613,8 +2527,7 @@ async def test_set_config_parameter(
{ {
ID: 5, ID: 5,
TYPE: "zwave_js/set_config_parameter", TYPE: "zwave_js/set_config_parameter",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
PROPERTY: 102, PROPERTY: 102,
PROPERTY_KEY: 1, PROPERTY_KEY: 1,
VALUE: 1, VALUE: 1,
@ -2633,8 +2546,7 @@ async def test_set_config_parameter(
{ {
ID: 6, ID: 6,
TYPE: "zwave_js/set_config_parameter", TYPE: "zwave_js/set_config_parameter",
ENTRY_ID: entry.entry_id, DEVICE_ID: "fake_device",
NODE_ID: 9999,
PROPERTY: 102, PROPERTY: 102,
PROPERTY_KEY: 1, PROPERTY_KEY: 1,
VALUE: 1, VALUE: 1,
@ -2653,8 +2565,7 @@ async def test_set_config_parameter(
{ {
ID: 7, ID: 7,
TYPE: "zwave_js/set_config_parameter", TYPE: "zwave_js/set_config_parameter",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
PROPERTY: 102, PROPERTY: 102,
PROPERTY_KEY: 1, PROPERTY_KEY: 1,
VALUE: 1, VALUE: 1,
@ -2674,8 +2585,7 @@ async def test_set_config_parameter(
{ {
ID: 8, ID: 8,
TYPE: "zwave_js/set_config_parameter", TYPE: "zwave_js/set_config_parameter",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: 52,
PROPERTY: 102, PROPERTY: 102,
PROPERTY_KEY: 1, PROPERTY_KEY: 1,
VALUE: 1, VALUE: 1,
@ -2693,14 +2603,14 @@ async def test_get_config_parameters(hass, multisensor_6, integration, hass_ws_c
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
node = multisensor_6 node = multisensor_6
device = get_device(hass, node)
# Test getting configuration parameter values # Test getting configuration parameter values
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 4, ID: 4,
TYPE: "zwave_js/get_config_parameters", TYPE: "zwave_js/get_config_parameters",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: node.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2722,8 +2632,7 @@ async def test_get_config_parameters(hass, multisensor_6, integration, hass_ws_c
{ {
ID: 5, ID: 5,
TYPE: "zwave_js/get_config_parameters", TYPE: "zwave_js/get_config_parameters",
ENTRY_ID: entry.entry_id, DEVICE_ID: "fake_device",
NODE_ID: 99999,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -2738,8 +2647,7 @@ async def test_get_config_parameters(hass, multisensor_6, integration, hass_ws_c
{ {
ID: 6, ID: 6,
TYPE: "zwave_js/get_config_parameters", TYPE: "zwave_js/get_config_parameters",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: node.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -3276,14 +3184,14 @@ async def test_abort_firmware_update(
"""Test that the abort_firmware_update WS API call works.""" """Test that the abort_firmware_update WS API call works."""
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
client.async_send_command_no_wait.return_value = {} client.async_send_command_no_wait.return_value = {}
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 1, ID: 1,
TYPE: "zwave_js/abort_firmware_update", TYPE: "zwave_js/abort_firmware_update",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: multisensor_6.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -3303,8 +3211,7 @@ async def test_abort_firmware_update(
{ {
ID: 2, ID: 2,
TYPE: "zwave_js/abort_firmware_update", TYPE: "zwave_js/abort_firmware_update",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: multisensor_6.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -3321,8 +3228,7 @@ async def test_abort_firmware_update(
{ {
ID: 3, ID: 3,
TYPE: "zwave_js/abort_firmware_update", TYPE: "zwave_js/abort_firmware_update",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: multisensor_6.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -3332,32 +3238,19 @@ async def test_abort_firmware_update(
async def test_abort_firmware_update_failures( async def test_abort_firmware_update_failures(
hass, integration, multisensor_6, client, hass_ws_client hass, multisensor_6, client, integration, hass_ws_client
): ):
"""Test failures for the abort_firmware_update websocket command.""" """Test failures for the abort_firmware_update websocket command."""
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
# Test sending command with improper entry ID fails device = get_device(hass, multisensor_6)
await ws_client.send_json(
{
ID: 1,
TYPE: "zwave_js/abort_firmware_update",
ENTRY_ID: "fake_entry_id",
NODE_ID: multisensor_6.node_id,
}
)
msg = await ws_client.receive_json()
assert not msg["success"] # Test sending command with improper device ID fails
assert msg["error"]["code"] == ERR_NOT_FOUND
# Test sending command with improper node ID fails
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 2, ID: 2,
TYPE: "zwave_js/abort_firmware_update", TYPE: "zwave_js/abort_firmware_update",
ENTRY_ID: entry.entry_id, DEVICE_ID: "fake_device",
NODE_ID: multisensor_6.node_id + 100,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -3373,8 +3266,7 @@ async def test_abort_firmware_update_failures(
{ {
ID: 3, ID: 3,
TYPE: "zwave_js/abort_firmware_update", TYPE: "zwave_js/abort_firmware_update",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: multisensor_6.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -3384,11 +3276,11 @@ async def test_abort_firmware_update_failures(
async def test_subscribe_firmware_update_status( async def test_subscribe_firmware_update_status(
hass, integration, multisensor_6, client, hass_ws_client hass, multisensor_6, integration, client, hass_ws_client
): ):
"""Test the subscribe_firmware_update_status websocket command.""" """Test the subscribe_firmware_update_status websocket command."""
entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
client.async_send_command_no_wait.return_value = {} client.async_send_command_no_wait.return_value = {}
@ -3396,8 +3288,7 @@ async def test_subscribe_firmware_update_status(
{ {
ID: 1, ID: 1,
TYPE: "zwave_js/subscribe_firmware_update_status", TYPE: "zwave_js/subscribe_firmware_update_status",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: multisensor_6.node_id,
} }
) )
@ -3445,11 +3336,11 @@ async def test_subscribe_firmware_update_status(
async def test_subscribe_firmware_update_status_initial_value( async def test_subscribe_firmware_update_status_initial_value(
hass, integration, multisensor_6, client, hass_ws_client hass, multisensor_6, client, integration, hass_ws_client
): ):
"""Test subscribe_firmware_update_status websocket command with in progress update.""" """Test subscribe_firmware_update_status websocket command with in progress update."""
entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
assert multisensor_6.firmware_update_progress is None assert multisensor_6.firmware_update_progress is None
@ -3472,8 +3363,7 @@ async def test_subscribe_firmware_update_status_initial_value(
{ {
ID: 1, ID: 1,
TYPE: "zwave_js/subscribe_firmware_update_status", TYPE: "zwave_js/subscribe_firmware_update_status",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: multisensor_6.node_id,
} }
) )
@ -3490,32 +3380,18 @@ async def test_subscribe_firmware_update_status_initial_value(
async def test_subscribe_firmware_update_status_failures( async def test_subscribe_firmware_update_status_failures(
hass, integration, multisensor_6, client, hass_ws_client hass, multisensor_6, client, integration, hass_ws_client
): ):
"""Test failures for the subscribe_firmware_update_status websocket command.""" """Test failures for the subscribe_firmware_update_status websocket command."""
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
# Test sending command with improper entry ID fails # Test sending command with improper entry ID fails
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 1, ID: 1,
TYPE: "zwave_js/subscribe_firmware_update_status", TYPE: "zwave_js/subscribe_firmware_update_status",
ENTRY_ID: "fake_entry_id", DEVICE_ID: "fake_device",
NODE_ID: multisensor_6.node_id,
}
)
msg = await ws_client.receive_json()
assert not msg["success"]
assert msg["error"]["code"] == ERR_NOT_FOUND
# Test sending command with improper node ID fails
await ws_client.send_json(
{
ID: 2,
TYPE: "zwave_js/subscribe_firmware_update_status",
ENTRY_ID: entry.entry_id,
NODE_ID: multisensor_6.node_id + 100,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -3531,8 +3407,7 @@ async def test_subscribe_firmware_update_status_failures(
{ {
ID: 3, ID: 3,
TYPE: "zwave_js/subscribe_firmware_update_status", TYPE: "zwave_js/subscribe_firmware_update_status",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: multisensor_6.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -3783,13 +3658,13 @@ async def test_subscribe_node_statistics(
"""Test the subscribe_node_statistics command.""" """Test the subscribe_node_statistics command."""
entry = integration entry = integration
ws_client = await hass_ws_client(hass) ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
await ws_client.send_json( await ws_client.send_json(
{ {
ID: 1, ID: 1,
TYPE: "zwave_js/subscribe_node_statistics", TYPE: "zwave_js/subscribe_node_statistics",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: multisensor_6.node_id,
} }
) )
@ -3843,8 +3718,7 @@ async def test_subscribe_node_statistics(
{ {
ID: 2, ID: 2,
TYPE: "zwave_js/subscribe_node_statistics", TYPE: "zwave_js/subscribe_node_statistics",
ENTRY_ID: "fake_entry_id", DEVICE_ID: "fake_device",
NODE_ID: multisensor_6.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()
@ -3852,17 +3726,6 @@ async def test_subscribe_node_statistics(
assert not msg["success"] assert not msg["success"]
assert msg["error"]["code"] == ERR_NOT_FOUND assert msg["error"]["code"] == ERR_NOT_FOUND
# Test sending command with improper node ID fails
await ws_client.send_json(
{
ID: 3,
TYPE: "zwave_js/subscribe_node_statistics",
ENTRY_ID: entry.entry_id,
NODE_ID: multisensor_6.node_id + 100,
}
)
msg = await ws_client.receive_json()
# Test sending command with not loaded entry fails # Test sending command with not loaded entry fails
await hass.config_entries.async_unload(entry.entry_id) await hass.config_entries.async_unload(entry.entry_id)
await hass.async_block_till_done() await hass.async_block_till_done()
@ -3871,8 +3734,7 @@ async def test_subscribe_node_statistics(
{ {
ID: 4, ID: 4,
TYPE: "zwave_js/subscribe_node_statistics", TYPE: "zwave_js/subscribe_node_statistics",
ENTRY_ID: entry.entry_id, DEVICE_ID: device.id,
NODE_ID: multisensor_6.node_id,
} }
) )
msg = await ws_client.receive_json() msg = await ws_client.receive_json()