diff --git a/homeassistant/components/rainbird/__init__.py b/homeassistant/components/rainbird/__init__.py index 737b8a0341d..97dec9a681e 100644 --- a/homeassistant/components/rainbird/__init__.py +++ b/homeassistant/components/rainbird/__init__.py @@ -23,7 +23,12 @@ from homeassistant.helpers import device_registry as dr, entity_registry as er from homeassistant.helpers.device_registry import format_mac from .const import CONF_SERIAL_NUMBER -from .coordinator import RainbirdData, async_create_clientsession +from .coordinator import ( + RainbirdScheduleUpdateCoordinator, + RainbirdUpdateCoordinator, + async_create_clientsession, +) +from .types import RainbirdConfigEntry, RainbirdData _LOGGER = logging.getLogger(__name__) @@ -40,7 +45,9 @@ DOMAIN = "rainbird" def _async_register_clientsession_shutdown( - hass: HomeAssistant, entry: ConfigEntry, clientsession: aiohttp.ClientSession + hass: HomeAssistant, + entry: ConfigEntry, + clientsession: aiohttp.ClientSession, ) -> None: """Register cleanup hooks for the clientsession.""" @@ -55,7 +62,7 @@ def _async_register_clientsession_shutdown( entry.async_on_unload(_async_close_websession) -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: RainbirdConfigEntry) -> bool: """Set up the config entry for Rain Bird.""" hass.data.setdefault(DOMAIN, {}) @@ -96,11 +103,25 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: except RainbirdApiException as err: raise ConfigEntryNotReady from err - data = RainbirdData(hass, entry, controller, model_info) + data = RainbirdData( + controller, + model_info, + coordinator=RainbirdUpdateCoordinator( + hass, + name=entry.title, + controller=controller, + unique_id=entry.unique_id, + model_info=model_info, + ), + schedule_coordinator=RainbirdScheduleUpdateCoordinator( + hass, + name=f"{entry.title} Schedule", + controller=controller, + ), + ) await data.coordinator.async_config_entry_first_refresh() - hass.data[DOMAIN][entry.entry_id] = data - + entry.runtime_data = data await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True @@ -238,8 +259,4 @@ def _async_fix_device_id( async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - - if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): - hass.data[DOMAIN].pop(entry.entry_id) - - return unload_ok + return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) diff --git a/homeassistant/components/rainbird/binary_sensor.py b/homeassistant/components/rainbird/binary_sensor.py index d44022b0a2d..5722b8852dd 100644 --- a/homeassistant/components/rainbird/binary_sensor.py +++ b/homeassistant/components/rainbird/binary_sensor.py @@ -8,13 +8,12 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, BinarySensorEntityDescription, ) -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 DOMAIN from .coordinator import RainbirdUpdateCoordinator +from .types import RainbirdConfigEntry _LOGGER = logging.getLogger(__name__) @@ -27,11 +26,11 @@ RAIN_SENSOR_ENTITY_DESCRIPTION = BinarySensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: RainbirdConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up entry for a Rain Bird binary_sensor.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id].coordinator + coordinator = config_entry.runtime_data.coordinator async_add_entities([RainBirdSensor(coordinator, RAIN_SENSOR_ENTITY_DESCRIPTION)]) diff --git a/homeassistant/components/rainbird/calendar.py b/homeassistant/components/rainbird/calendar.py index 42c1cce69d3..160fe70c61e 100644 --- a/homeassistant/components/rainbird/calendar.py +++ b/homeassistant/components/rainbird/calendar.py @@ -6,7 +6,6 @@ from datetime import datetime import logging from homeassistant.components.calendar import CalendarEntity, CalendarEvent -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.device_registry import DeviceInfo @@ -14,19 +13,19 @@ 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 DOMAIN from .coordinator import RainbirdScheduleUpdateCoordinator +from .types import RainbirdConfigEntry _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: RainbirdConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up entry for a Rain Bird irrigation calendar.""" - data = hass.data[DOMAIN][config_entry.entry_id] + data = config_entry.runtime_data if not data.model_info.model_info.max_programs: return diff --git a/homeassistant/components/rainbird/coordinator.py b/homeassistant/components/rainbird/coordinator.py index 2657fd6433e..437aa7ddbd4 100644 --- a/homeassistant/components/rainbird/coordinator.py +++ b/homeassistant/components/rainbird/coordinator.py @@ -8,7 +8,6 @@ import datetime import logging import aiohttp -from propcache import cached_property from pyrainbird.async_client import ( AsyncRainbirdController, RainbirdApiException, @@ -166,36 +165,3 @@ class RainbirdScheduleUpdateCoordinator(DataUpdateCoordinator[Schedule]): return await self._controller.get_schedule() except RainbirdApiException as err: raise UpdateFailed(f"Error communicating with Device: {err}") from err - - -@dataclass -class RainbirdData: - """Holder for shared integration data. - - The coordinators are lazy since they may only be used by some platforms when needed. - """ - - hass: HomeAssistant - entry: ConfigEntry - controller: AsyncRainbirdController - model_info: ModelAndVersion - - @cached_property - def coordinator(self) -> RainbirdUpdateCoordinator: - """Return RainbirdUpdateCoordinator.""" - return RainbirdUpdateCoordinator( - self.hass, - name=self.entry.title, - controller=self.controller, - unique_id=self.entry.unique_id, - model_info=self.model_info, - ) - - @cached_property - def schedule_coordinator(self) -> RainbirdScheduleUpdateCoordinator: - """Return RainbirdScheduleUpdateCoordinator.""" - return RainbirdScheduleUpdateCoordinator( - self.hass, - name=f"{self.entry.title} Schedule", - controller=self.controller, - ) diff --git a/homeassistant/components/rainbird/number.py b/homeassistant/components/rainbird/number.py index 507a31e59a4..d8081a796b9 100644 --- a/homeassistant/components/rainbird/number.py +++ b/homeassistant/components/rainbird/number.py @@ -7,29 +7,28 @@ import logging from pyrainbird.exceptions import RainbirdApiException, RainbirdDeviceBusyException from homeassistant.components.number import NumberEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.const import UnitOfTime from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DOMAIN from .coordinator import RainbirdUpdateCoordinator +from .types import RainbirdConfigEntry _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: RainbirdConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up entry for a Rain Bird number platform.""" async_add_entities( [ RainDelayNumber( - hass.data[DOMAIN][config_entry.entry_id].coordinator, + config_entry.runtime_data.coordinator, ) ] ) diff --git a/homeassistant/components/rainbird/quality_scale.yaml b/homeassistant/components/rainbird/quality_scale.yaml index e918bf845ba..cd000c63fad 100644 --- a/homeassistant/components/rainbird/quality_scale.yaml +++ b/homeassistant/components/rainbird/quality_scale.yaml @@ -36,11 +36,7 @@ rules: docs-high-level-description: done config-flow-test-coverage: done docs-actions: done - runtime-data: - status: todo - comment: | - The integration currently stores config entry data in `hass.data` and - needs to be moved to `runtime_data`. + runtime-data: done # Silver log-when-unavailable: todo diff --git a/homeassistant/components/rainbird/sensor.py b/homeassistant/components/rainbird/sensor.py index 649d643a20c..4725a33bc9a 100644 --- a/homeassistant/components/rainbird/sensor.py +++ b/homeassistant/components/rainbird/sensor.py @@ -5,14 +5,13 @@ from __future__ import annotations import logging from homeassistant.components.sensor import SensorEntity, SensorEntityDescription -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType from homeassistant.helpers.update_coordinator import CoordinatorEntity -from .const import DOMAIN from .coordinator import RainbirdUpdateCoordinator +from .types import RainbirdConfigEntry _LOGGER = logging.getLogger(__name__) @@ -25,14 +24,14 @@ RAIN_DELAY_ENTITY_DESCRIPTION = SensorEntityDescription( async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: RainbirdConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up entry for a Rain Bird sensor.""" async_add_entities( [ RainBirdSensor( - hass.data[DOMAIN][config_entry.entry_id].coordinator, + config_entry.runtime_data.coordinator, RAIN_DELAY_ENTITY_DESCRIPTION, ) ] diff --git a/homeassistant/components/rainbird/switch.py b/homeassistant/components/rainbird/switch.py index 62a2a7c4a32..f622a1b9b2c 100644 --- a/homeassistant/components/rainbird/switch.py +++ b/homeassistant/components/rainbird/switch.py @@ -8,7 +8,6 @@ from pyrainbird.exceptions import RainbirdApiException, RainbirdDeviceBusyExcept import voluptuous as vol from homeassistant.components.switch import SwitchEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv, entity_platform @@ -19,6 +18,7 @@ from homeassistant.helpers.update_coordinator import CoordinatorEntity from .const import ATTR_DURATION, CONF_IMPORTED_NAMES, DOMAIN, MANUFACTURER from .coordinator import RainbirdUpdateCoordinator +from .types import RainbirdConfigEntry _LOGGER = logging.getLogger(__name__) @@ -31,11 +31,11 @@ SERVICE_SCHEMA_IRRIGATION: VolDictType = { async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: RainbirdConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up entry for a Rain Bird irrigation switches.""" - coordinator = hass.data[DOMAIN][config_entry.entry_id].coordinator + coordinator = config_entry.runtime_data.coordinator async_add_entities( RainBirdSwitch( coordinator, diff --git a/homeassistant/components/rainbird/types.py b/homeassistant/components/rainbird/types.py new file mode 100644 index 00000000000..b452712d971 --- /dev/null +++ b/homeassistant/components/rainbird/types.py @@ -0,0 +1,26 @@ +"""Types for Rain Bird integration.""" + +from dataclasses import dataclass + +from pyrainbird.async_client import AsyncRainbirdController +from pyrainbird.data import ModelAndVersion + +from homeassistant.config_entries import ConfigEntry + +from .coordinator import RainbirdScheduleUpdateCoordinator, RainbirdUpdateCoordinator + + +@dataclass +class RainbirdData: + """Holder for shared integration data. + + The coordinators are lazy since they may only be used by some platforms when needed. + """ + + controller: AsyncRainbirdController + model_info: ModelAndVersion + coordinator: RainbirdUpdateCoordinator + schedule_coordinator: RainbirdScheduleUpdateCoordinator + + +type RainbirdConfigEntry = ConfigEntry[RainbirdData]