From 21a83c4875fbc0007b7a94c8ab53682778abf414 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Thu, 23 Jan 2025 18:53:04 +0100 Subject: [PATCH] Use runtime_data in canary (#136357) --- homeassistant/components/canary/__init__.py | 33 ++++++------------- .../components/canary/alarm_control_panel.py | 10 ++---- homeassistant/components/canary/camera.py | 17 +++------- homeassistant/components/canary/const.py | 4 --- .../components/canary/coordinator.py | 9 ++++- homeassistant/components/canary/sensor.py | 11 +++---- 6 files changed, 29 insertions(+), 55 deletions(-) diff --git a/homeassistant/components/canary/__init__.py b/homeassistant/components/canary/__init__.py index f879c308a88..a28c37580ce 100644 --- a/homeassistant/components/canary/__init__.py +++ b/homeassistant/components/canary/__init__.py @@ -11,7 +11,7 @@ from requests.exceptions import ConnectTimeout, HTTPError import voluptuous as vol from homeassistant.components.camera import DOMAIN as CAMERA_DOMAIN -from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry +from homeassistant.config_entries import SOURCE_IMPORT from homeassistant.const import CONF_PASSWORD, CONF_TIMEOUT, CONF_USERNAME, Platform from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady @@ -20,13 +20,11 @@ from homeassistant.helpers.typing import ConfigType from .const import ( CONF_FFMPEG_ARGUMENTS, - DATA_COORDINATOR, - DATA_UNDO_UPDATE_LISTENER, DEFAULT_FFMPEG_ARGUMENTS, DEFAULT_TIMEOUT, DOMAIN, ) -from .coordinator import CanaryDataUpdateCoordinator +from .coordinator import CanaryConfigEntry, CanaryDataUpdateCoordinator _LOGGER: Final = logging.getLogger(__name__) @@ -59,8 +57,6 @@ PLATFORMS: Final[list[Platform]] = [ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the Canary integration.""" - hass.data.setdefault(DOMAIN, {}) - if hass.config_entries.async_entries(DOMAIN): return True @@ -90,7 +86,7 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: return True -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: CanaryConfigEntry) -> bool: """Set up Canary from a config entry.""" if not entry.options: options = { @@ -107,38 +103,29 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: _LOGGER.error("Unable to connect to Canary service: %s", str(error)) raise ConfigEntryNotReady from error - coordinator = CanaryDataUpdateCoordinator(hass, api=canary_api) + coordinator = CanaryDataUpdateCoordinator(hass, entry, api=canary_api) await coordinator.async_config_entry_first_refresh() - undo_listener = entry.add_update_listener(_async_update_listener) + entry.async_on_unload(entry.add_update_listener(_async_update_listener)) - hass.data[DOMAIN][entry.entry_id] = { - DATA_COORDINATOR: coordinator, - DATA_UNDO_UPDATE_LISTENER: undo_listener, - } + entry.runtime_data = coordinator await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: CanaryConfigEntry) -> bool: """Unload a config entry.""" - unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) - - if unload_ok: - hass.data[DOMAIN][entry.entry_id][DATA_UNDO_UPDATE_LISTENER]() - hass.data[DOMAIN].pop(entry.entry_id) - - return unload_ok + return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) -async def _async_update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: +async def _async_update_listener(hass: HomeAssistant, entry: CanaryConfigEntry) -> None: """Handle options update.""" await hass.config_entries.async_reload(entry.entry_id) -def _get_canary_api_instance(entry: ConfigEntry) -> Api: +def _get_canary_api_instance(entry: CanaryConfigEntry) -> Api: """Initialize a new instance of CanaryApi.""" return Api( entry.data[CONF_USERNAME], diff --git a/homeassistant/components/canary/alarm_control_panel.py b/homeassistant/components/canary/alarm_control_panel.py index 69600e4bbc7..443944da8c3 100644 --- a/homeassistant/components/canary/alarm_control_panel.py +++ b/homeassistant/components/canary/alarm_control_panel.py @@ -12,24 +12,20 @@ from homeassistant.components.alarm_control_panel import ( AlarmControlPanelEntityFeature, AlarmControlPanelState, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DATA_COORDINATOR, DOMAIN -from .coordinator import CanaryDataUpdateCoordinator +from .coordinator import CanaryConfigEntry, CanaryDataUpdateCoordinator async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, + entry: CanaryConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up Canary alarm control panels based on a config entry.""" - coordinator: CanaryDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][ - DATA_COORDINATOR - ] + coordinator = entry.runtime_data alarms = [ CanaryAlarm(coordinator, location) for location_id, location in coordinator.data["locations"].items() diff --git a/homeassistant/components/canary/camera.py b/homeassistant/components/canary/camera.py index a56d1ebc3de..8f4a01c9968 100644 --- a/homeassistant/components/canary/camera.py +++ b/homeassistant/components/canary/camera.py @@ -18,7 +18,6 @@ from homeassistant.components.camera import ( Camera, ) from homeassistant.components.ffmpeg import FFmpegManager, get_ffmpeg_manager -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers import config_validation as cv from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream @@ -27,14 +26,8 @@ from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity from homeassistant.util import dt as dt_util -from .const import ( - CONF_FFMPEG_ARGUMENTS, - DATA_COORDINATOR, - DEFAULT_FFMPEG_ARGUMENTS, - DOMAIN, - MANUFACTURER, -) -from .coordinator import CanaryDataUpdateCoordinator +from .const import CONF_FFMPEG_ARGUMENTS, DEFAULT_FFMPEG_ARGUMENTS, DOMAIN, MANUFACTURER +from .coordinator import CanaryConfigEntry, CanaryDataUpdateCoordinator FORCE_CAMERA_REFRESH_INTERVAL: Final = timedelta(minutes=15) @@ -54,13 +47,11 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, + entry: CanaryConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up Canary sensors based on a config entry.""" - coordinator: CanaryDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][ - DATA_COORDINATOR - ] + coordinator = entry.runtime_data ffmpeg_arguments: str = entry.options.get( CONF_FFMPEG_ARGUMENTS, DEFAULT_FFMPEG_ARGUMENTS ) diff --git a/homeassistant/components/canary/const.py b/homeassistant/components/canary/const.py index 210da35c7c1..9b9229c3ac3 100644 --- a/homeassistant/components/canary/const.py +++ b/homeassistant/components/canary/const.py @@ -9,10 +9,6 @@ MANUFACTURER: Final = "Canary Connect, Inc" # Configuration CONF_FFMPEG_ARGUMENTS: Final = "ffmpeg_arguments" -# Data -DATA_COORDINATOR: Final = "coordinator" -DATA_UNDO_UPDATE_LISTENER: Final = "undo_update_listener" - # Defaults DEFAULT_FFMPEG_ARGUMENTS: Final = "-pred 1" DEFAULT_TIMEOUT: Final = 10 diff --git a/homeassistant/components/canary/coordinator.py b/homeassistant/components/canary/coordinator.py index d58d1da0f79..7c90074f81a 100644 --- a/homeassistant/components/canary/coordinator.py +++ b/homeassistant/components/canary/coordinator.py @@ -11,6 +11,7 @@ from canary.api import Api from canary.model import Location, Reading from requests.exceptions import ConnectTimeout, HTTPError +from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.update_coordinator import DataUpdateCoordinator, UpdateFailed @@ -20,10 +21,15 @@ from .model import CanaryData _LOGGER = logging.getLogger(__name__) +type CanaryConfigEntry = ConfigEntry[CanaryDataUpdateCoordinator] + + class CanaryDataUpdateCoordinator(DataUpdateCoordinator[CanaryData]): """Class to manage fetching Canary data.""" - def __init__(self, hass: HomeAssistant, *, api: Api) -> None: + def __init__( + self, hass: HomeAssistant, config_entry: CanaryConfigEntry, *, api: Api + ) -> None: """Initialize global Canary data updater.""" self.canary = api update_interval = timedelta(seconds=30) @@ -31,6 +37,7 @@ class CanaryDataUpdateCoordinator(DataUpdateCoordinator[CanaryData]): super().__init__( hass, _LOGGER, + config_entry=config_entry, name=DOMAIN, update_interval=update_interval, ) diff --git a/homeassistant/components/canary/sensor.py b/homeassistant/components/canary/sensor.py index 9aab4698bf3..22f3eada2cb 100644 --- a/homeassistant/components/canary/sensor.py +++ b/homeassistant/components/canary/sensor.py @@ -7,7 +7,6 @@ from typing import Final from canary.model import Device, Location, SensorType from homeassistant.components.sensor import SensorDeviceClass, SensorEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( PERCENTAGE, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, @@ -18,8 +17,8 @@ from homeassistant.helpers.device_registry import DeviceInfo from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DATA_COORDINATOR, DOMAIN, MANUFACTURER -from .coordinator import CanaryDataUpdateCoordinator +from .const import DOMAIN, MANUFACTURER +from .coordinator import CanaryConfigEntry, CanaryDataUpdateCoordinator type SensorTypeItem = tuple[ str, str | None, str | None, SensorDeviceClass | None, list[str] @@ -64,13 +63,11 @@ STATE_AIR_QUALITY_VERY_ABNORMAL: Final = "very_abnormal" async def async_setup_entry( hass: HomeAssistant, - entry: ConfigEntry, + entry: CanaryConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up Canary sensors based on a config entry.""" - coordinator: CanaryDataUpdateCoordinator = hass.data[DOMAIN][entry.entry_id][ - DATA_COORDINATOR - ] + coordinator = entry.runtime_data sensors: list[CanarySensor] = [] for location in coordinator.data["locations"].values():