"""Spook - Your homie.""" from __future__ import annotations from typing import TYPE_CHECKING from homeassistant.const import CONF_ENTITY_ID from homeassistant.core import callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.helper_integration import ( async_remove_helper_config_entry_from_source_device, ) from .config_flow import SpookInverseConfigFlowHandler from .const import CONF_HIDE_SOURCE MIGRATION_MINOR_VERSION = SpookInverseConfigFlowHandler.MINOR_VERSION if TYPE_CHECKING: from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant @callback def async_get_source_entity_device_id( hass: HomeAssistant, entity_id: str ) -> str | None: """Get the entity device id.""" registry = er.async_get(hass) if not (resolved_entity_id := er.async_resolve_entity_id(registry, entity_id)): return None if not (source_entity := registry.async_get(resolved_entity_id)): return None return source_entity.device_id async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up from a config entry.""" await hass.config_entries.async_forward_entry_setups( entry, (entry.options["inverse_type"],), ) entry.async_on_unload(entry.add_update_listener(config_entry_update_listener)) return True async def config_entry_update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: """Update listener, called when the config entry options are changed.""" await hass.config_entries.async_reload(entry.entry_id) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" return await hass.config_entries.async_unload_platforms( entry, (entry.options["inverse_type"],), ) async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None: """Remove a config entry, unhide the source entity.""" registry = er.async_get(hass) if not entry.options[CONF_HIDE_SOURCE]: return if not ( entity_id := er.async_resolve_entity_id(registry, entry.options[CONF_ENTITY_ID]) ): return if (entity_entry := registry.async_get(entity_id)) is None: return if entity_entry.hidden_by != er.RegistryEntryHider.INTEGRATION: return registry.async_update_entity(entity_id, hidden_by=None) async def async_migrate_entry(hass: HomeAssistant, config_entry: ConfigEntry) -> bool: """Migrate old entry.""" if ( config_entry.version == 1 and config_entry.minor_version < 2 # noqa: PLR2004 ): options = {**config_entry.options} if (source_entity_id := options.get(CONF_ENTITY_ID)) and ( source_device_id := async_get_source_entity_device_id( hass, source_entity_id ) ): # Remove the spook_inverse config entry from the source device async_remove_helper_config_entry_from_source_device( hass, helper_config_entry_id=config_entry.entry_id, source_device_id=source_device_id, ) hass.config_entries.async_update_entry( config_entry, options=options, minor_version=MIGRATION_MINOR_VERSION ) return True