Dump entities in zwave_js device diagnostics (#68536)
This commit is contained in:
parent
a11a5366be
commit
45a80f182d
2 changed files with 67 additions and 2 deletions
|
@ -1,9 +1,11 @@
|
||||||
"""Provides diagnostics for Z-Wave JS."""
|
"""Provides diagnostics for Z-Wave JS."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
from zwave_js_server.client import Client
|
from zwave_js_server.client import Client
|
||||||
from zwave_js_server.dump import dump_msgs
|
from zwave_js_server.dump import dump_msgs
|
||||||
from zwave_js_server.model.node import NodeDataType
|
from zwave_js_server.model.node import Node, NodeDataType
|
||||||
|
|
||||||
from homeassistant.components.diagnostics.util import async_redact_data
|
from homeassistant.components.diagnostics.util import async_redact_data
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
|
@ -11,6 +13,8 @@ from homeassistant.const import CONF_URL
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.helpers import device_registry as dr
|
from homeassistant.helpers import device_registry as dr
|
||||||
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
from homeassistant.helpers.aiohttp_client import async_get_clientsession
|
||||||
|
from homeassistant.helpers.device_registry import DeviceEntry
|
||||||
|
from homeassistant.helpers.entity_registry import async_entries_for_device, async_get
|
||||||
|
|
||||||
from .const import DATA_CLIENT, DOMAIN
|
from .const import DATA_CLIENT, DOMAIN
|
||||||
from .helpers import get_home_and_node_id_from_device_entry
|
from .helpers import get_home_and_node_id_from_device_entry
|
||||||
|
@ -18,6 +22,59 @@ from .helpers import get_home_and_node_id_from_device_entry
|
||||||
TO_REDACT = {"homeId", "location"}
|
TO_REDACT = {"homeId", "location"}
|
||||||
|
|
||||||
|
|
||||||
|
def get_device_entities(
|
||||||
|
hass: HomeAssistant, node: Node, device: DeviceEntry
|
||||||
|
) -> list[dict[str, Any]]:
|
||||||
|
"""Get entities for a device."""
|
||||||
|
entity_entries = async_entries_for_device(
|
||||||
|
async_get(hass), device.id, include_disabled_entities=True
|
||||||
|
)
|
||||||
|
entities = []
|
||||||
|
for entry in entity_entries:
|
||||||
|
state_key = None
|
||||||
|
split_unique_id = entry.unique_id.split(".")
|
||||||
|
# If the unique ID has three parts, it's either one of the generic per node
|
||||||
|
# entities (node status sensor, ping button) or a binary sensor for a particular
|
||||||
|
# state. If we can get the state key, we will add it to the dictionary.
|
||||||
|
if len(split_unique_id) == 3:
|
||||||
|
try:
|
||||||
|
state_key = int(split_unique_id[-1])
|
||||||
|
# If the third part of the unique ID isn't a state key, the entity must be a
|
||||||
|
# generic entity. We won't add those since they won't help with
|
||||||
|
# troubleshooting.
|
||||||
|
except ValueError:
|
||||||
|
continue
|
||||||
|
value_id = split_unique_id[1]
|
||||||
|
zwave_value = node.values[value_id]
|
||||||
|
primary_value_data = {
|
||||||
|
"command_class": zwave_value.command_class,
|
||||||
|
"command_class_name": zwave_value.command_class_name,
|
||||||
|
"endpoint": zwave_value.endpoint,
|
||||||
|
"property": zwave_value.property_,
|
||||||
|
"property_name": zwave_value.property_name,
|
||||||
|
"property_key": zwave_value.property_key,
|
||||||
|
"property_key_name": zwave_value.property_key_name,
|
||||||
|
}
|
||||||
|
if state_key is not None:
|
||||||
|
primary_value_data["state_key"] = state_key
|
||||||
|
entity = {
|
||||||
|
"domain": entry.domain,
|
||||||
|
"entity_id": entry.entity_id,
|
||||||
|
"original_name": entry.original_name,
|
||||||
|
"original_device_class": entry.original_device_class,
|
||||||
|
"disabled": entry.disabled,
|
||||||
|
"disabled_by": entry.disabled_by,
|
||||||
|
"hidden_by": entry.hidden_by,
|
||||||
|
"original_icon": entry.original_icon,
|
||||||
|
"entity_category": entry.entity_category,
|
||||||
|
"supported_features": entry.supported_features,
|
||||||
|
"unit_of_measurement": entry.unit_of_measurement,
|
||||||
|
"primary_value": primary_value_data,
|
||||||
|
}
|
||||||
|
entities.append(entity)
|
||||||
|
return entities
|
||||||
|
|
||||||
|
|
||||||
async def async_get_config_entry_diagnostics(
|
async def async_get_config_entry_diagnostics(
|
||||||
hass: HomeAssistant, config_entry: ConfigEntry
|
hass: HomeAssistant, config_entry: ConfigEntry
|
||||||
) -> list[dict]:
|
) -> list[dict]:
|
||||||
|
@ -38,6 +95,7 @@ async def async_get_device_diagnostics(
|
||||||
if node_id is None or node_id not in client.driver.controller.nodes:
|
if node_id is None or node_id not in client.driver.controller.nodes:
|
||||||
raise ValueError(f"Node for device {device.id} can't be found")
|
raise ValueError(f"Node for device {device.id} can't be found")
|
||||||
node = client.driver.controller.nodes[node_id]
|
node = client.driver.controller.nodes[node_id]
|
||||||
|
entities = get_device_entities(hass, node, device)
|
||||||
return {
|
return {
|
||||||
"versionInfo": {
|
"versionInfo": {
|
||||||
"driverVersion": client.version.driver_version,
|
"driverVersion": client.version.driver_version,
|
||||||
|
@ -45,5 +103,6 @@ async def async_get_device_diagnostics(
|
||||||
"minSchemaVersion": client.version.min_schema_version,
|
"minSchemaVersion": client.version.min_schema_version,
|
||||||
"maxSchemaVersion": client.version.max_schema_version,
|
"maxSchemaVersion": client.version.max_schema_version,
|
||||||
},
|
},
|
||||||
|
"entities": entities,
|
||||||
"state": async_redact_data(node.data, TO_REDACT),
|
"state": async_redact_data(node.data, TO_REDACT),
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import pytest
|
||||||
from zwave_js_server.event import Event
|
from zwave_js_server.event import Event
|
||||||
|
|
||||||
from homeassistant.components.zwave_js.diagnostics import async_get_device_diagnostics
|
from homeassistant.components.zwave_js.diagnostics import async_get_device_diagnostics
|
||||||
|
from homeassistant.components.zwave_js.discovery import async_discover_node_values
|
||||||
from homeassistant.components.zwave_js.helpers import get_device_id
|
from homeassistant.components.zwave_js.helpers import get_device_id
|
||||||
from homeassistant.helpers.device_registry import async_get
|
from homeassistant.helpers.device_registry import async_get
|
||||||
|
|
||||||
|
@ -69,7 +70,12 @@ async def test_device_diagnostics(
|
||||||
"minSchemaVersion": 0,
|
"minSchemaVersion": 0,
|
||||||
"maxSchemaVersion": 0,
|
"maxSchemaVersion": 0,
|
||||||
}
|
}
|
||||||
|
# Assert that we only have the entities that were discovered for this device
|
||||||
|
# Entities that are created outside of discovery (e.g. node status sensor and
|
||||||
|
# ping button) should not be in dump.
|
||||||
|
assert len(diagnostics_data["entities"]) == len(
|
||||||
|
list(async_discover_node_values(multisensor_6, device, {device.id: set()}))
|
||||||
|
)
|
||||||
assert diagnostics_data["state"] == multisensor_6.data
|
assert diagnostics_data["state"] == multisensor_6.data
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue