From 22b62393041a37a1c9288fb9dbc912be4046d61d Mon Sep 17 00:00:00 2001 From: "Steven B." <51370195+sdb9696@users.noreply.github.com> Date: Tue, 3 Sep 2024 11:04:35 +0100 Subject: [PATCH] Convert ring integration to use entry.runtime_data (#125127) --- homeassistant/components/ring/__init__.py | 30 ++++++++----------- .../components/ring/binary_sensor.py | 8 ++--- homeassistant/components/ring/button.py | 8 ++--- homeassistant/components/ring/camera.py | 8 ++--- homeassistant/components/ring/diagnostics.py | 8 ++--- homeassistant/components/ring/light.py | 8 ++--- homeassistant/components/ring/sensor.py | 8 ++--- homeassistant/components/ring/siren.py | 8 ++--- homeassistant/components/ring/switch.py | 8 ++--- tests/components/ring/test_init.py | 4 +-- 10 files changed, 39 insertions(+), 59 deletions(-) diff --git a/homeassistant/components/ring/__init__.py b/homeassistant/components/ring/__init__.py index 14ab435fda6..3714802b63a 100644 --- a/homeassistant/components/ring/__init__.py +++ b/homeassistant/components/ring/__init__.py @@ -31,7 +31,10 @@ class RingData: notifications_coordinator: RingNotificationsCoordinator -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +type RingConfigEntry = ConfigEntry[RingData] + + +async def async_setup_entry(hass: HomeAssistant, entry: RingConfigEntry) -> bool: """Set up a config entry.""" def token_updater(token: dict[str, Any]) -> None: @@ -56,7 +59,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: await devices_coordinator.async_config_entry_first_refresh() await notifications_coordinator.async_config_entry_first_refresh() - hass.data.setdefault(DOMAIN, {})[entry.entry_id] = RingData( + entry.runtime_data = RingData( api=ring, devices=ring.devices(), devices_coordinator=devices_coordinator, @@ -86,11 +89,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: severity=IssueSeverity.WARNING, translation_key="deprecated_service_ring_update", ) - - for info in hass.data[DOMAIN].values(): - ring_data = cast(RingData, info) - await ring_data.devices_coordinator.async_refresh() - await ring_data.notifications_coordinator.async_refresh() + for loaded_entry in hass.config_entries.async_loaded_entries(DOMAIN): + await loaded_entry.runtime_data.devices_coordinator.async_refresh() + await loaded_entry.runtime_data.notifications_coordinator.async_refresh() # register service hass.services.async_register(DOMAIN, "update", async_refresh_all) @@ -100,18 +101,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload Ring entry.""" - if not await hass.config_entries.async_unload_platforms(entry, PLATFORMS): - return False + unload_ok = await hass.config_entries.async_unload_platforms(entry, PLATFORMS) - hass.data[DOMAIN].pop(entry.entry_id) + if len(hass.config_entries.async_loaded_entries(DOMAIN)) == 1: + # This is the last loaded entry, clean up service + hass.services.async_remove(DOMAIN, "update") - if len(hass.data[DOMAIN]) != 0: - return True - - # Last entry unloaded, clean up service - hass.services.async_remove(DOMAIN, "update") - - return True + return unload_ok async def async_remove_config_entry_device( diff --git a/homeassistant/components/ring/binary_sensor.py b/homeassistant/components/ring/binary_sensor.py index 2db04cfd461..2fb557ddde0 100644 --- a/homeassistant/components/ring/binary_sensor.py +++ b/homeassistant/components/ring/binary_sensor.py @@ -14,12 +14,10 @@ from homeassistant.components.binary_sensor import ( BinarySensorEntity, BinarySensorEntityDescription, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback -from . import RingData -from .const import DOMAIN +from . import RingConfigEntry from .coordinator import RingNotificationsCoordinator from .entity import RingBaseEntity @@ -50,11 +48,11 @@ BINARY_SENSOR_TYPES: tuple[RingBinarySensorEntityDescription, ...] = ( async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + entry: RingConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the Ring binary sensors from a config entry.""" - ring_data: RingData = hass.data[DOMAIN][config_entry.entry_id] + ring_data = entry.runtime_data entities = [ RingBinarySensor( diff --git a/homeassistant/components/ring/button.py b/homeassistant/components/ring/button.py index c8d7d902d18..b9d5cceb373 100644 --- a/homeassistant/components/ring/button.py +++ b/homeassistant/components/ring/button.py @@ -5,12 +5,10 @@ from __future__ import annotations from ring_doorbell import RingOther from homeassistant.components.button import ButtonEntity, ButtonEntityDescription -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from . import RingData -from .const import DOMAIN +from . import RingConfigEntry from .coordinator import RingDataCoordinator from .entity import RingEntity, exception_wrap @@ -21,11 +19,11 @@ BUTTON_DESCRIPTION = ButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + entry: RingConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Create the buttons for the Ring devices.""" - ring_data: RingData = hass.data[DOMAIN][config_entry.entry_id] + ring_data = entry.runtime_data devices_coordinator = ring_data.devices_coordinator async_add_entities( diff --git a/homeassistant/components/ring/camera.py b/homeassistant/components/ring/camera.py index df71de29089..9c66df9d89e 100644 --- a/homeassistant/components/ring/camera.py +++ b/homeassistant/components/ring/camera.py @@ -12,14 +12,12 @@ from ring_doorbell import RingDoorBell from homeassistant.components import ffmpeg from homeassistant.components.camera import Camera -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.aiohttp_client import async_aiohttp_proxy_stream from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.util import dt as dt_util -from . import RingData -from .const import DOMAIN +from . import RingConfigEntry from .coordinator import RingDataCoordinator from .entity import RingEntity, exception_wrap @@ -31,11 +29,11 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + entry: RingConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up a Ring Door Bell and StickUp Camera.""" - ring_data: RingData = hass.data[DOMAIN][config_entry.entry_id] + ring_data = entry.runtime_data devices_coordinator = ring_data.devices_coordinator ffmpeg_manager = ffmpeg.get_ffmpeg_manager(hass) diff --git a/homeassistant/components/ring/diagnostics.py b/homeassistant/components/ring/diagnostics.py index 2e7604d9f50..cecf26a46a7 100644 --- a/homeassistant/components/ring/diagnostics.py +++ b/homeassistant/components/ring/diagnostics.py @@ -5,11 +5,9 @@ from __future__ import annotations from typing import Any from homeassistant.components.diagnostics import async_redact_data -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant -from . import RingData -from .const import DOMAIN +from . import RingConfigEntry TO_REDACT = { "id", @@ -29,10 +27,10 @@ TO_REDACT = { async def async_get_config_entry_diagnostics( - hass: HomeAssistant, entry: ConfigEntry + hass: HomeAssistant, entry: RingConfigEntry ) -> dict[str, Any]: """Return diagnostics for a config entry.""" - ring_data: RingData = hass.data[DOMAIN][entry.entry_id] + ring_data = entry.runtime_data devices_data = ring_data.api.devices_data devices_raw = [ devices_data[device_type][device_id] diff --git a/homeassistant/components/ring/light.py b/homeassistant/components/ring/light.py index 99c4105f4e9..9e29373a3aa 100644 --- a/homeassistant/components/ring/light.py +++ b/homeassistant/components/ring/light.py @@ -8,13 +8,11 @@ from typing import Any from ring_doorbell import RingStickUpCam from homeassistant.components.light import ColorMode, LightEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback import homeassistant.util.dt as dt_util -from . import RingData -from .const import DOMAIN +from . import RingConfigEntry from .coordinator import RingDataCoordinator from .entity import RingEntity, exception_wrap @@ -38,11 +36,11 @@ class OnOffState(StrEnum): async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + entry: RingConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Create the lights for the Ring devices.""" - ring_data: RingData = hass.data[DOMAIN][config_entry.entry_id] + ring_data = entry.runtime_data devices_coordinator = ring_data.devices_coordinator async_add_entities( diff --git a/homeassistant/components/ring/sensor.py b/homeassistant/components/ring/sensor.py index b6849e37d96..83d07dbd9b4 100644 --- a/homeassistant/components/ring/sensor.py +++ b/homeassistant/components/ring/sensor.py @@ -21,7 +21,6 @@ from homeassistant.components.sensor import ( SensorEntityDescription, SensorStateClass, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( PERCENTAGE, SIGNAL_STRENGTH_DECIBELS_MILLIWATT, @@ -31,19 +30,18 @@ from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback from homeassistant.helpers.typing import StateType -from . import RingData -from .const import DOMAIN +from . import RingConfigEntry from .coordinator import RingDataCoordinator from .entity import RingDeviceT, RingEntity async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + entry: RingConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up a sensor for a Ring device.""" - ring_data: RingData = hass.data[DOMAIN][config_entry.entry_id] + ring_data = entry.runtime_data devices_coordinator = ring_data.devices_coordinator entities = [ diff --git a/homeassistant/components/ring/siren.py b/homeassistant/components/ring/siren.py index 665de07a5bb..f5730d942b8 100644 --- a/homeassistant/components/ring/siren.py +++ b/homeassistant/components/ring/siren.py @@ -6,12 +6,10 @@ from typing import Any from ring_doorbell import RingChime, RingEventKind from homeassistant.components.siren import ATTR_TONE, SirenEntity, SirenEntityFeature -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.entity_platform import AddEntitiesCallback -from . import RingData -from .const import DOMAIN +from . import RingConfigEntry from .coordinator import RingDataCoordinator from .entity import RingEntity, exception_wrap @@ -20,11 +18,11 @@ _LOGGER = logging.getLogger(__name__) async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + entry: RingConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Create the sirens for the Ring devices.""" - ring_data: RingData = hass.data[DOMAIN][config_entry.entry_id] + ring_data = entry.runtime_data devices_coordinator = ring_data.devices_coordinator async_add_entities( diff --git a/homeassistant/components/ring/switch.py b/homeassistant/components/ring/switch.py index effb43cedbe..01d321572ac 100644 --- a/homeassistant/components/ring/switch.py +++ b/homeassistant/components/ring/switch.py @@ -7,13 +7,11 @@ from typing import Any from ring_doorbell import RingStickUpCam from homeassistant.components.switch import SwitchEntity -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback import homeassistant.util.dt as dt_util -from . import RingData -from .const import DOMAIN +from . import RingConfigEntry from .coordinator import RingDataCoordinator from .entity import RingEntity, exception_wrap @@ -30,11 +28,11 @@ SKIP_UPDATES_DELAY = timedelta(seconds=5) async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + entry: RingConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Create the switches for the Ring devices.""" - ring_data: RingData = hass.data[DOMAIN][config_entry.entry_id] + ring_data = entry.runtime_data devices_coordinator = ring_data.devices_coordinator async_add_entities( diff --git a/tests/components/ring/test_init.py b/tests/components/ring/test_init.py index 4ab3e1bd366..97392e0c93b 100644 --- a/tests/components/ring/test_init.py +++ b/tests/components/ring/test_init.py @@ -186,7 +186,7 @@ async def test_error_on_global_update( assert log_msg in caplog.text - assert mock_config_entry.entry_id in hass.data[DOMAIN] + assert hass.config_entries.async_get_entry(mock_config_entry.entry_id) @pytest.mark.parametrize( @@ -226,7 +226,7 @@ async def test_error_on_device_update( await hass.async_block_till_done(wait_background_tasks=True) assert log_msg in caplog.text - assert mock_config_entry.entry_id in hass.data[DOMAIN] + assert hass.config_entries.async_get_entry(mock_config_entry.entry_id) async def test_issue_deprecated_service_ring_update(