"""Spook - Your homie.""" from __future__ import annotations from typing import Any from homeassistant.components import automation from homeassistant.helpers import device_registry as dr from ....entity_filtering import async_filter_known_device_ids, async_get_all_device_ids from ....repairs import AbstractSpookEntityComponentUnknownReferencesRepair def extract_event_data_device_ids_from_trigger_config( config: dict[str, Any] | list, ) -> set[str]: """Extract device IDs from event trigger data.""" device_ids = set() if not config: return device_ids if isinstance(config, list): for item in config: device_ids.update(extract_event_data_device_ids_from_trigger_config(item)) return device_ids if not isinstance(config, dict): return device_ids if config.get("platform", config.get("trigger")) == "event" and isinstance( event_data := config.get("event_data"), dict ): value = event_data.get("device_id") if isinstance(value, str): device_ids.add(value) elif isinstance(value, list): device_ids.update(item for item in value if isinstance(item, str)) for value in config.values(): if isinstance(value, (dict, list)): device_ids.update(extract_event_data_device_ids_from_trigger_config(value)) return device_ids class SpookRepair(AbstractSpookEntityComponentUnknownReferencesRepair): """Spook repair tries to find unknown referenced devices in automations.""" domain = automation.DOMAIN repair = "automation_unknown_device_references" inspect_events = { automation.EVENT_AUTOMATION_RELOADED, dr.EVENT_DEVICE_REGISTRY_UPDATED, } inspect_config_entry_changed = True inspect_on_reload = True unavailable_entity_class = automation.UnavailableAutomationEntity entity_label = "automation" reference_label = "devices" edit_url_pattern = "/config/automation/edit/{unique_id}" _known_device_ids: set[str] async def _async_setup_inspection(self) -> None: """Cache known device IDs for this inspection cycle.""" self._known_device_ids = async_get_all_device_ids(self.hass) async def _async_compute_unknown_references(self, entity: Any) -> set[str]: """Return unknown device IDs referenced by ``entity``.""" device_ids = set(entity.referenced_devices) if hasattr(entity, "raw_config") and entity.raw_config: device_ids.difference_update( extract_event_data_device_ids_from_trigger_config( entity.raw_config.get("trigger") ) ) device_ids.difference_update( extract_event_data_device_ids_from_trigger_config( entity.raw_config.get("triggers") ) ) return async_filter_known_device_ids( self.hass, device_ids=device_ids, known_device_ids=self._known_device_ids, )