Skip to content

Commit

Permalink
Add additional data to zwave_js device statistics WS API (#72520)
Browse files Browse the repository at this point in the history
* Add additional data to zwave_js device statistics WS API

* Rename variables

* fix logic

* correct typehint

* Update homeassistant/components/zwave_js/api.py

Co-authored-by: Martin Hjelmare <[email protected]>

* black

Co-authored-by: Martin Hjelmare <[email protected]>
  • Loading branch information
raman325 and MartinHjelmare authored May 26, 2022
1 parent d8295e2 commit 5e52b11
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 16 deletions.
36 changes: 32 additions & 4 deletions homeassistant/components/zwave_js/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
from .helpers import (
async_enable_statistics,
async_get_node_from_device_id,
get_device_id,
update_data_collection_preference,
)

Expand Down Expand Up @@ -2107,15 +2108,42 @@ def forward_stats(event: dict) -> None:
)


def _get_node_statistics_dict(statistics: NodeStatistics) -> dict[str, int]:
def _get_node_statistics_dict(
hass: HomeAssistant, statistics: NodeStatistics
) -> dict[str, Any]:
"""Get dictionary of node statistics."""
return {
dev_reg = dr.async_get(hass)

def _convert_node_to_device_id(node: Node) -> str:
"""Convert a node to a device id."""
driver = node.client.driver
assert driver
device = dev_reg.async_get_device({get_device_id(driver, node)})
assert device
return device.id

data: dict = {
"commands_tx": statistics.commands_tx,
"commands_rx": statistics.commands_rx,
"commands_dropped_tx": statistics.commands_dropped_tx,
"commands_dropped_rx": statistics.commands_dropped_rx,
"timeout_response": statistics.timeout_response,
"rtt": statistics.rtt,
"rssi": statistics.rssi,
"lwr": statistics.lwr.as_dict() if statistics.lwr else None,
"nlwr": statistics.nlwr.as_dict() if statistics.nlwr else None,
}
for key in ("lwr", "nlwr"):
if not data[key]:
continue
for key_2 in ("repeaters", "route_failed_between"):
if not data[key][key_2]:
continue
data[key][key_2] = [
_convert_node_to_device_id(node) for node in data[key][key_2]
]

return data


@websocket_api.require_admin
Expand Down Expand Up @@ -2151,7 +2179,7 @@ def forward_stats(event: dict) -> None:
"event": event["event"],
"source": "node",
"node_id": node.node_id,
**_get_node_statistics_dict(statistics),
**_get_node_statistics_dict(hass, statistics),
},
)
)
Expand All @@ -2167,7 +2195,7 @@ def forward_stats(event: dict) -> None:
"event": "statistics updated",
"source": "node",
"nodeId": node.node_id,
**_get_node_statistics_dict(node.statistics),
**_get_node_statistics_dict(hass, node.statistics),
},
)
)
80 changes: 68 additions & 12 deletions tests/components/zwave_js/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -3768,18 +3768,26 @@ async def test_subscribe_controller_statistics(


async def test_subscribe_node_statistics(
hass, multisensor_6, integration, client, hass_ws_client
hass,
multisensor_6,
wallmote_central_scene,
zen_31,
integration,
client,
hass_ws_client,
):
"""Test the subscribe_node_statistics command."""
entry = integration
ws_client = await hass_ws_client(hass)
device = get_device(hass, multisensor_6)
multisensor_6_device = get_device(hass, multisensor_6)
zen_31_device = get_device(hass, zen_31)
wallmote_central_scene_device = get_device(hass, wallmote_central_scene)

await ws_client.send_json(
{
ID: 1,
TYPE: "zwave_js/subscribe_node_statistics",
DEVICE_ID: device.id,
DEVICE_ID: multisensor_6_device.id,
}
)

Expand All @@ -3797,6 +3805,10 @@ async def test_subscribe_node_statistics(
"commands_dropped_tx": 0,
"commands_dropped_rx": 0,
"timeout_response": 0,
"rtt": None,
"rssi": None,
"lwr": None,
"nlwr": None,
}

# Fire statistics updated
Expand All @@ -3808,10 +3820,32 @@ async def test_subscribe_node_statistics(
"nodeId": multisensor_6.node_id,
"statistics": {
"commandsTX": 1,
"commandsRX": 1,
"commandsDroppedTX": 1,
"commandsDroppedRX": 1,
"timeoutResponse": 1,
"commandsRX": 2,
"commandsDroppedTX": 3,
"commandsDroppedRX": 4,
"timeoutResponse": 5,
"rtt": 6,
"rssi": 7,
"lwr": {
"protocolDataRate": 1,
"rssi": 1,
"repeaters": [wallmote_central_scene.node_id],
"repeaterRSSI": [1],
"routeFailedBetween": [
zen_31.node_id,
multisensor_6.node_id,
],
},
"nlwr": {
"protocolDataRate": 2,
"rssi": 2,
"repeaters": [],
"repeaterRSSI": [127],
"routeFailedBetween": [
multisensor_6.node_id,
zen_31.node_id,
],
},
},
},
)
Expand All @@ -3822,10 +3856,32 @@ async def test_subscribe_node_statistics(
"source": "node",
"node_id": multisensor_6.node_id,
"commands_tx": 1,
"commands_rx": 1,
"commands_dropped_tx": 1,
"commands_dropped_rx": 1,
"timeout_response": 1,
"commands_rx": 2,
"commands_dropped_tx": 3,
"commands_dropped_rx": 4,
"timeout_response": 5,
"rtt": 6,
"rssi": 7,
"lwr": {
"protocol_data_rate": 1,
"rssi": 1,
"repeaters": [wallmote_central_scene_device.id],
"repeater_rssi": [1],
"route_failed_between": [
zen_31_device.id,
multisensor_6_device.id,
],
},
"nlwr": {
"protocol_data_rate": 2,
"rssi": 2,
"repeaters": [],
"repeater_rssi": [127],
"route_failed_between": [
multisensor_6_device.id,
zen_31_device.id,
],
},
}

# Test sending command with improper entry ID fails
Expand All @@ -3849,7 +3905,7 @@ async def test_subscribe_node_statistics(
{
ID: 4,
TYPE: "zwave_js/subscribe_node_statistics",
DEVICE_ID: device.id,
DEVICE_ID: multisensor_6_device.id,
}
)
msg = await ws_client.receive_json()
Expand Down

0 comments on commit 5e52b11

Please sign in to comment.