1 """Provides diagnostics for Z-Wave JS."""
3 from __future__
import annotations
5 from copy
import deepcopy
8 from zwave_js_server.client
import Client
9 from zwave_js_server.const
import CommandClass
10 from zwave_js_server.dump
import dump_msgs
11 from zwave_js_server.model.node
import Node
12 from zwave_js_server.model.value
import ValueDataType
13 from zwave_js_server.util.node
import dump_node_state
22 from .const
import DATA_CLIENT, USER_AGENT
23 from .helpers
import (
25 get_home_and_node_id_from_device_entry,
26 get_state_key_from_unique_id,
27 get_value_id_from_unique_id,
28 value_matches_matcher,
31 KEYS_TO_REDACT = {
"homeId",
"location"}
39 """Return redacted value of a Z-Wave value."""
40 redacted_value: ValueDataType = deepcopy(zwave_value)
41 redacted_value[
"value"] = REDACTED
46 """Redact value of a Z-Wave value if it matches criteria to redact."""
48 if zwave_value.get(
"value")
in (
None,
""):
50 if zwave_value.get(
"metadata", {}).
get(
"secret"):
52 for value_to_redact
in VALUES_TO_REDACT:
59 """Redact node state."""
60 redacted_state: dict = deepcopy(node_state)
62 if isinstance(node_state[
"values"], list):
63 redacted_state[
"values"] = [
65 for zwave_value
in node_state[
"values"]
68 redacted_state[
"values"] = {
70 for value_id, zwave_value
in node_state[
"values"].items()
76 hass: HomeAssistant, node: Node, config_entry: ConfigEntry, device: dr.DeviceEntry
77 ) -> list[dict[str, Any]]:
78 """Get entities for a device."""
79 entity_entries = er.async_entries_for_device(
80 er.async_get(hass), device.id, include_disabled_entities=
True
83 for entry
in sorted(entity_entries):
85 if entry.config_entry_id != config_entry.entry_id:
92 primary_value_data =
None
93 if (zwave_value := node.values.get(value_id))
is not None:
94 primary_value_data = {
95 "command_class": zwave_value.command_class,
96 "command_class_name": zwave_value.command_class_name,
97 "endpoint": zwave_value.endpoint,
98 "property": zwave_value.property_,
99 "property_name": zwave_value.property_name,
100 "property_key": zwave_value.property_key,
101 "property_key_name": zwave_value.property_key_name,
105 if state_key
is not None:
106 primary_value_data[
"state_key"] = state_key
109 "domain": entry.domain,
110 "entity_id": entry.entity_id,
111 "original_name": entry.original_name,
112 "original_device_class": entry.original_device_class,
113 "disabled": entry.disabled,
114 "disabled_by": entry.disabled_by,
115 "hidden_by": entry.hidden_by,
116 "original_icon": entry.original_icon,
117 "entity_category": entry.entity_category,
118 "supported_features": entry.supported_features,
119 "unit_of_measurement": entry.unit_of_measurement,
120 "value_id": value_id,
121 "primary_value": primary_value_data,
123 entities.append(entity)
128 hass: HomeAssistant, config_entry: ConfigEntry
130 """Return diagnostics for a config entry."""
137 handshake_msgs = msgs[:-1]
138 network_state = msgs[-1]
139 network_state[
"result"][
"state"][
"nodes"] = [
141 for node_data
in network_state[
"result"][
"state"][
"nodes"]
143 return {
"messages": [*handshake_msgs, network_state]}
147 hass: HomeAssistant, config_entry: ConfigEntry, device: dr.DeviceEntry
149 """Return diagnostics for a device."""
150 client: Client = config_entry.runtime_data[DATA_CLIENT]
152 node_id = identifiers[1]
if identifiers
else None
153 driver = client.driver
155 if node_id
is None or node_id
not in driver.controller.nodes:
156 raise ValueError(f
"Node for device {device.id} can't be found")
157 node = driver.controller.nodes[node_id]
159 assert client.version
165 "driverVersion": client.version.driver_version,
166 "serverVersion": client.version.server_version,
167 "minSchemaVersion": client.version.min_schema_version,
168 "maxSchemaVersion": client.version.max_schema_version,
170 "entities": entities,
web.Response get(self, web.Request request, str config_key)
dict async_redact_data(Mapping data, Iterable[Any] to_redact)
dict[str, Any] async_get_device_diagnostics(HomeAssistant hass, ConfigEntry config_entry, dr.DeviceEntry device)
ValueDataType _redacted_value(ValueDataType zwave_value)
dict redact_node_state(dict node_state)
dict[str, Any] async_get_config_entry_diagnostics(HomeAssistant hass, ConfigEntry config_entry)
list[dict[str, Any]] get_device_entities(HomeAssistant hass, Node node, ConfigEntry config_entry, dr.DeviceEntry device)
ValueDataType optionally_redact_value_of_zwave_value(ValueDataType zwave_value)
tuple[str, int]|None get_home_and_node_id_from_device_entry(dr.DeviceEntry device_entry)
int|None get_state_key_from_unique_id(str unique_id)
str|None get_value_id_from_unique_id(str unique_id)
bool value_matches_matcher(ZwaveValueMatcher matcher, ValueDataType value_data)
aiohttp.ClientSession async_get_clientsession(HomeAssistant hass, bool verify_ssl=True, socket.AddressFamily family=socket.AF_UNSPEC, ssl_util.SSLCipherList ssl_cipher=ssl_util.SSLCipherList.PYTHON_DEFAULT)