"""Diagnostics support for HomeKit.""" from __future__ import annotations from typing import Any from pyhap.accessory_driver import AccessoryDriver from pyhap.state import State from homeassistant.components.diagnostics import async_redact_data from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from . import HomeKit from .accessories import HomeAccessory, HomeBridge from .const import DOMAIN, HOMEKIT TO_REDACT = {"access_token", "entity_picture"} async def async_get_config_entry_diagnostics( hass: HomeAssistant, entry: ConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" homekit: HomeKit = hass.data[DOMAIN][entry.entry_id][HOMEKIT] data: dict[str, Any] = { "status": homekit.status, "config-entry": { "title": entry.title, "version": entry.version, "data": dict(entry.data), "options": dict(entry.options), }, } if homekit.iid_storage: data["iid_storage"] = homekit.iid_storage.allocations if not homekit.driver: # not started yet or startup failed return data driver: AccessoryDriver = homekit.driver if driver.accessory: if isinstance(driver.accessory, HomeBridge): data["bridge"] = _get_bridge_diagnostics(hass, driver.accessory) else: data["accessory"] = _get_accessory_diagnostics(hass, driver.accessory) data.update(driver.get_accessories()) state: State = driver.state data.update( { "client_properties": { str(client): props for client, props in state.client_properties.items() }, "config_version": state.config_version, "pairing_id": state.mac, } ) return data def _get_bridge_diagnostics(hass: HomeAssistant, bridge: HomeBridge) -> dict[int, Any]: """Return diagnostics for a bridge.""" return { aid: _get_accessory_diagnostics(hass, accessory) for aid, accessory in bridge.accessories.items() } def _get_accessory_diagnostics( hass: HomeAssistant, accessory: HomeAccessory ) -> dict[str, Any]: """Return diagnostics for an accessory.""" entity_state = None if accessory.entity_id: entity_state = hass.states.get(accessory.entity_id) data = { "aid": accessory.aid, "config": accessory.config, "category": accessory.category, "name": accessory.display_name, "entity_id": accessory.entity_id, } if entity_state: data["entity_state"] = async_redact_data(entity_state, TO_REDACT) return data