1 """Provides diagnostics for ZHA."""
3 from __future__
import annotations
6 from importlib.metadata
import version
9 from zha.application.const
import (
19 from zha.application.gateway
import Gateway
20 from zha.zigbee.device
import Device
21 from zigpy.config
import CONF_NWK_EXTENDED_PAN_ID
22 from zigpy.profiles
import PROFILES
23 from zigpy.types
import Channels
24 from zigpy.zcl
import Cluster
32 from .const
import CONF_ALARM_MASTER_CODE
33 from .helpers
import (
35 async_get_zha_device_proxy,
43 CONF_ALARM_MASTER_CODE,
45 CONF_NWK_EXTENDED_PAN_ID,
49 ATTRIBUTES =
"attributes"
50 CLUSTER_DETAILS =
"cluster_details"
51 UNSUPPORTED_ATTRIBUTES =
"unsupported_attributes"
55 ZIGPY_DECONZ_VERSION =
version(
"zigpy-deconz")
56 ZIGPY_XBEE_VERSION =
version(
"zigpy-xbee")
58 ZIGPY_ZIGATE_VERSION =
version(
"zigpy-zigate")
59 ZHA_QUIRKS_VERSION =
version(
"zha-quirks")
64 """Return a shallow copy of a dataclass as a dict."""
65 if hasattr(obj,
"__dataclass_fields__"):
68 for field
in dataclasses.fields(obj):
72 if hasattr(obj,
"as_dict"):
78 hass: HomeAssistant, config_entry: ConfigEntry
80 """Return diagnostics for a config entry."""
83 app = gateway.application_controller
85 energy_scan = await app.energy_scan(
86 channels=Channels.ALL_CHANNELS, duration_exp=4, count=1
91 "config": zha_data.yaml_config,
92 "config_entry": config_entry.as_dict(),
95 channel: 100 * energy / 255
for channel, energy
in energy_scan.items()
98 "bellows": BELLOWS_VERSION,
99 "zigpy": ZIGPY_VERSION,
100 "zigpy_deconz": ZIGPY_DECONZ_VERSION,
101 "zigpy_xbee": ZIGPY_XBEE_VERSION,
102 "zigpy_znp": ZIGPY_ZNP_VERSION,
103 "zigpy_zigate": ZIGPY_ZIGATE_VERSION,
104 "zhaquirks": ZHA_QUIRKS_VERSION,
109 "manufacturer": device.manufacturer,
110 "model": device.model,
111 "logical_type": device.device_type,
113 for device
in gateway.devices.values()
121 hass: HomeAssistant, config_entry: ConfigEntry, device: dr.DeviceEntry
123 """Return diagnostics for a device."""
125 device_info: dict[str, Any] = zha_device_proxy.zha_device_info
127 zha_device_proxy.device
133 """Return endpoint cluster attribute data."""
135 for ep_id, endpoint
in zha_device.device.endpoints.items():
139 f
"{PROFILES.get(endpoint.profile_id).DeviceType(endpoint.device_type).name}"
140 if PROFILES.get(endpoint.profile_id)
is not None
141 and endpoint.device_type
is not None
144 cluster_details[ep_id] = {
146 CONF_NAME: endpoint_key,
147 CONF_ID: endpoint.device_type,
149 ATTR_PROFILE_ID: endpoint.profile_id,
151 f
"0x{cluster_id:04x}": {
152 "endpoint_attribute": cluster.ep_attribute,
155 for cluster_id, cluster
in endpoint.in_clusters.items()
158 f
"0x{cluster_id:04x}": {
159 "endpoint_attribute": cluster.ep_attribute,
162 for cluster_id, cluster
in endpoint.out_clusters.items()
165 return cluster_details
169 """Return cluster attribute data."""
172 f
"0x{attr_id:04x}": {
173 ATTR_ATTRIBUTE: repr(attr_def),
174 ATTR_VALUE: cluster.get(attr_def.name),
176 for attr_id, attr_def
in cluster.attributes.items()
178 UNSUPPORTED_ATTRIBUTES: sorted(
179 cluster.unsupported_attributes, key=
lambda v: (isinstance(v, str), v)
dict async_redact_data(Mapping data, Iterable[Any] to_redact)
dict shallow_asdict(Any obj)
dict get_cluster_attr_data(Cluster cluster)
dict[str, Any] async_get_device_diagnostics(HomeAssistant hass, ConfigEntry config_entry, dr.DeviceEntry device)
dict get_endpoint_cluster_attr_data(Device zha_device)
dict[str, Any] async_get_config_entry_diagnostics(HomeAssistant hass, ConfigEntry config_entry)
Gateway get_zha_gateway(HomeAssistant hass)
ZHADeviceProxy async_get_zha_device_proxy(HomeAssistant hass, str device_id)
HAZHAData get_zha_data(HomeAssistant hass)