From 30373a668cf3c6637cb08b8850979c9b76cd15b4 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 21 Jul 2024 09:06:51 -0500 Subject: [PATCH] Migrate harmony to use entry.runtime_data (#122312) --- homeassistant/components/harmony/__init__.py | 43 ++++++------------- .../components/harmony/config_flow.py | 8 ++-- homeassistant/components/harmony/const.py | 5 --- homeassistant/components/harmony/data.py | 4 ++ homeassistant/components/harmony/remote.py | 11 +++-- homeassistant/components/harmony/select.py | 12 +++--- 6 files changed, 31 insertions(+), 52 deletions(-) diff --git a/homeassistant/components/harmony/__init__.py b/homeassistant/components/harmony/__init__.py index a1c513a4654..12f7d903f0d 100644 --- a/homeassistant/components/harmony/__init__.py +++ b/homeassistant/components/harmony/__init__.py @@ -3,26 +3,18 @@ import logging from homeassistant.components.remote import ATTR_ACTIVITY, ATTR_DELAY_SECS -from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST, CONF_NAME, EVENT_HOMEASSISTANT_STOP from homeassistant.core import Event, HomeAssistant, callback from homeassistant.helpers import entity_registry as er from homeassistant.helpers.dispatcher import async_dispatcher_send -from .const import ( - CANCEL_LISTENER, - CANCEL_STOP, - DOMAIN, - HARMONY_DATA, - HARMONY_OPTIONS_UPDATE, - PLATFORMS, -) -from .data import HarmonyData +from .const import DOMAIN, HARMONY_OPTIONS_UPDATE, PLATFORMS # noqa: F401 +from .data import HarmonyConfigEntry, HarmonyData _LOGGER = logging.getLogger(__name__) -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: HarmonyConfigEntry) -> bool: """Set up Logitech Harmony Hub from a config entry.""" # As there currently is no way to import options from yaml # when setting up a config entry, we fallback to adding @@ -37,19 +29,16 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: await _migrate_old_unique_ids(hass, entry.entry_id, data) - cancel_listener = entry.add_update_listener(_update_listener) + entry.async_on_unload(entry.add_update_listener(_update_listener)) async def _async_on_stop(event: Event) -> None: await data.shutdown() - cancel_stop = hass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, _async_on_stop) - - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = { - HARMONY_DATA: data, - CANCEL_LISTENER: cancel_listener, - CANCEL_STOP: cancel_stop, - } + entry.async_on_unload( + hass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, _async_on_stop) + ) + entry.runtime_data = data await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True @@ -84,7 +73,7 @@ async def _migrate_old_unique_ids( @callback def _async_import_options_from_data_if_missing( - hass: HomeAssistant, entry: ConfigEntry + hass: HomeAssistant, entry: HarmonyConfigEntry ) -> None: options = dict(entry.options) modified = 0 @@ -97,24 +86,16 @@ def _async_import_options_from_data_if_missing( hass.config_entries.async_update_entry(entry, options=options) -async def _update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: +async def _update_listener(hass: HomeAssistant, entry: HarmonyConfigEntry) -> None: """Handle options update.""" async_dispatcher_send( hass, f"{HARMONY_OPTIONS_UPDATE}-{entry.unique_id}", entry.options ) -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: HarmonyConfigEntry) -> bool: """Unload a config entry.""" unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) - # Shutdown a harmony remote for removal - entry_data = hass.data[DOMAIN][entry.entry_id] - entry_data[CANCEL_LISTENER]() - entry_data[CANCEL_STOP]() - await entry_data[HARMONY_DATA].shutdown() - - if unload_ok: - hass.data[DOMAIN].pop(entry.entry_id) - + await entry.runtime_data.shutdown() return unload_ok diff --git a/homeassistant/components/harmony/config_flow.py b/homeassistant/components/harmony/config_flow.py index 629c54a3571..87eb657a0a9 100644 --- a/homeassistant/components/harmony/config_flow.py +++ b/homeassistant/components/harmony/config_flow.py @@ -27,7 +27,8 @@ from homeassistant.const import CONF_HOST, CONF_NAME from homeassistant.core import callback from homeassistant.exceptions import HomeAssistantError -from .const import DOMAIN, HARMONY_DATA, PREVIOUS_ACTIVE_ACTIVITY, UNIQUE_ID +from .const import DOMAIN, PREVIOUS_ACTIVE_ACTIVITY, UNIQUE_ID +from .data import HarmonyConfigEntry from .util import ( find_best_name_for_remote, find_unique_id_for_remote, @@ -185,7 +186,7 @@ def _options_from_user_input(user_input: dict[str, Any]) -> dict[str, Any]: class OptionsFlowHandler(OptionsFlow): """Handle a option flow for Harmony.""" - def __init__(self, config_entry: ConfigEntry) -> None: + def __init__(self, config_entry: HarmonyConfigEntry) -> None: """Initialize options flow.""" self.config_entry = config_entry @@ -196,8 +197,7 @@ class OptionsFlowHandler(OptionsFlow): if user_input is not None: return self.async_create_entry(title="", data=user_input) - remote = self.hass.data[DOMAIN][self.config_entry.entry_id][HARMONY_DATA] - + remote = self.config_entry.runtime_data data_schema = vol.Schema( { vol.Optional( diff --git a/homeassistant/components/harmony/const.py b/homeassistant/components/harmony/const.py index f474783b736..3b8f0e40fe3 100644 --- a/homeassistant/components/harmony/const.py +++ b/homeassistant/components/harmony/const.py @@ -13,8 +13,3 @@ ATTR_DEVICES_LIST = "devices_list" ATTR_LAST_ACTIVITY = "last_activity" ATTR_ACTIVITY_STARTING = "activity_starting" PREVIOUS_ACTIVE_ACTIVITY = "Previous Active Activity" - - -HARMONY_DATA = "harmony_data" -CANCEL_LISTENER = "cancel_listener" -CANCEL_STOP = "cancel_stop" diff --git a/homeassistant/components/harmony/data.py b/homeassistant/components/harmony/data.py index cdb31b4388c..41c55bfc855 100644 --- a/homeassistant/components/harmony/data.py +++ b/homeassistant/components/harmony/data.py @@ -9,6 +9,7 @@ from aioharmony.const import ClientCallbackType, SendCommandDevice import aioharmony.exceptions as aioexc from aioharmony.harmonyapi import HarmonyAPI as HarmonyClient +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady from homeassistant.helpers.device_registry import DeviceInfo @@ -19,6 +20,9 @@ from .subscriber import HarmonySubscriberMixin _LOGGER = logging.getLogger(__name__) +type HarmonyConfigEntry = ConfigEntry[HarmonyData] + + class HarmonyData(HarmonySubscriberMixin): """HarmonyData registers for Harmony hub updates.""" diff --git a/homeassistant/components/harmony/remote.py b/homeassistant/components/harmony/remote.py index a52f298dc41..d30aa475944 100644 --- a/homeassistant/components/harmony/remote.py +++ b/homeassistant/components/harmony/remote.py @@ -19,7 +19,6 @@ from homeassistant.components.remote import ( RemoteEntity, RemoteEntityFeature, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HassJob, HomeAssistant, callback from homeassistant.helpers import entity_platform import homeassistant.helpers.config_validation as cv @@ -34,13 +33,12 @@ from .const import ( ATTR_DEVICES_LIST, ATTR_LAST_ACTIVITY, DOMAIN, - HARMONY_DATA, HARMONY_OPTIONS_UPDATE, PREVIOUS_ACTIVE_ACTIVITY, SERVICE_CHANGE_CHANNEL, SERVICE_SYNC, ) -from .data import HarmonyData +from .data import HarmonyConfigEntry, HarmonyData from .entity import HarmonyEntity from .subscriber import HarmonyCallback @@ -57,11 +55,12 @@ HARMONY_CHANGE_CHANNEL_SCHEMA: VolDictType = { async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: HarmonyConfigEntry, + async_add_entities: AddEntitiesCallback, ) -> None: """Set up the Harmony config entry.""" - - data: HarmonyData = hass.data[DOMAIN][entry.entry_id][HARMONY_DATA] + data = entry.runtime_data _LOGGER.debug("HarmonyData : %s", data) diff --git a/homeassistant/components/harmony/select.py b/homeassistant/components/harmony/select.py index 0bb8f462419..731b6836386 100644 --- a/homeassistant/components/harmony/select.py +++ b/homeassistant/components/harmony/select.py @@ -5,12 +5,11 @@ from __future__ import annotations import logging from homeassistant.components.select import SelectEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HassJob, HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback -from .const import ACTIVITY_POWER_OFF, DOMAIN, HARMONY_DATA -from .data import HarmonyData +from .const import ACTIVITY_POWER_OFF, DOMAIN +from .data import HarmonyConfigEntry, HarmonyData from .entity import HarmonyEntity from .subscriber import HarmonyCallback @@ -20,11 +19,12 @@ TRANSLATABLE_POWER_OFF = "power_off" async def async_setup_entry( - hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback + hass: HomeAssistant, + entry: HarmonyConfigEntry, + async_add_entities: AddEntitiesCallback, ) -> None: """Set up harmony activities select.""" - data: HarmonyData = hass.data[DOMAIN][entry.entry_id][HARMONY_DATA] - async_add_entities([HarmonyActivitySelect(data)]) + async_add_entities([HarmonyActivitySelect(entry.runtime_data)]) class HarmonyActivitySelect(HarmonyEntity, SelectEntity):