diff --git a/homeassistant/components/doorbird/__init__.py b/homeassistant/components/doorbird/__init__.py index 71786eac77990abde128e428508b5766085c66fc..38fae38d9b787edf8e15b49db4207e4d89246821 100644 --- a/homeassistant/components/doorbird/__init__.py +++ b/homeassistant/components/doorbird/__init__.py @@ -10,7 +10,6 @@ from doorbirdpy import DoorBird import requests from homeassistant.components import persistent_notification -from homeassistant.config_entries import ConfigEntry from homeassistant.const import ( CONF_HOST, CONF_NAME, @@ -25,7 +24,7 @@ from homeassistant.helpers.typing import ConfigType from .const import CONF_EVENTS, DOMAIN, PLATFORMS from .device import ConfiguredDoorBird -from .models import DoorBirdData +from .models import DoorBirdConfigEntry, DoorBirdData from .view import DoorBirdRequestView _LOGGER = logging.getLogger(__name__) @@ -37,13 +36,12 @@ CONFIG_SCHEMA = cv.removed(DOMAIN, raise_if_present=False) async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the DoorBird component.""" - hass.data.setdefault(DOMAIN, {}) # Provide an endpoint for the door stations to call to trigger events hass.http.register_view(DoorBirdRequestView) return True -async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_setup_entry(hass: HomeAssistant, entry: DoorBirdConfigEntry) -> bool: """Set up DoorBird from a config entry.""" _async_import_options_from_data_if_missing(hass, entry) @@ -91,7 +89,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: raise ConfigEntryNotReady entry.async_on_unload(entry.add_update_listener(_update_listener)) - hass.data[DOMAIN][config_entry_id] = door_bird_data + entry.runtime_data = door_bird_data await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS) return True @@ -102,12 +100,9 @@ def _init_door_bird_device(device: DoorBird) -> tuple[tuple[bool, int], dict[str return device.ready(), device.info() -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: +async def async_unload_entry(hass: HomeAssistant, entry: DoorBirdConfigEntry) -> bool: """Unload a config entry.""" - data: dict[str, DoorBirdData] = hass.data[DOMAIN] - if unload_ok := await hass.config_entries.async_unload_platforms(entry, PLATFORMS): - data.pop(entry.entry_id) - return unload_ok + return await hass.config_entries.async_unload_platforms(entry, PLATFORMS) async def _async_register_events( @@ -133,11 +128,9 @@ async def _async_register_events( return True -async def _update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: +async def _update_listener(hass: HomeAssistant, entry: DoorBirdConfigEntry) -> None: """Handle options update.""" - config_entry_id = entry.entry_id - data: DoorBirdData = hass.data[DOMAIN][config_entry_id] - door_station = data.door_station + door_station = entry.runtime_data.door_station door_station.update_events(entry.options[CONF_EVENTS]) # Subscribe to doorbell or motion events await _async_register_events(hass, door_station) @@ -145,7 +138,7 @@ async def _update_listener(hass: HomeAssistant, entry: ConfigEntry) -> None: @callback def _async_import_options_from_data_if_missing( - hass: HomeAssistant, entry: ConfigEntry + hass: HomeAssistant, entry: DoorBirdConfigEntry ) -> None: options = dict(entry.options) modified = False diff --git a/homeassistant/components/doorbird/button.py b/homeassistant/components/doorbird/button.py index 48709ceb9c1b80ffb27032b259d67d3affededc0..b83ff96617471d5357f3756e68ba637a090bdd8e 100644 --- a/homeassistant/components/doorbird/button.py +++ b/homeassistant/components/doorbird/button.py @@ -6,13 +6,11 @@ from dataclasses import dataclass from doorbirdpy import DoorBird 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 .const import DOMAIN from .entity import DoorBirdEntity -from .models import DoorBirdData +from .models import DoorBirdConfigEntry, DoorBirdData IR_RELAY = "__ir_light__" @@ -38,12 +36,11 @@ IR_ENTITY_DESCRIPTION = DoorbirdButtonEntityDescription( async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: DoorBirdConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the DoorBird button platform.""" - config_entry_id = config_entry.entry_id - door_bird_data: DoorBirdData = hass.data[DOMAIN][config_entry_id] + door_bird_data = config_entry.runtime_data relays = door_bird_data.door_station_info["RELAYS"] entities = [ diff --git a/homeassistant/components/doorbird/camera.py b/homeassistant/components/doorbird/camera.py index 961a3287799b229716aafbefee1c2aa44111c2ad..65af6fe20fb1517cc95a2ea27e584b2ca2492faa 100644 --- a/homeassistant/components/doorbird/camera.py +++ b/homeassistant/components/doorbird/camera.py @@ -9,15 +9,13 @@ import logging import aiohttp from homeassistant.components.camera import Camera, CameraEntityFeature -from homeassistant.config_entries import ConfigEntry from homeassistant.core import HomeAssistant from homeassistant.helpers.aiohttp_client import async_get_clientsession from homeassistant.helpers.entity_platform import AddEntitiesCallback import homeassistant.util.dt as dt_util -from .const import DOMAIN from .entity import DoorBirdEntity -from .models import DoorBirdData +from .models import DoorBirdConfigEntry, DoorBirdData _LAST_VISITOR_INTERVAL = datetime.timedelta(minutes=2) _LAST_MOTION_INTERVAL = datetime.timedelta(seconds=30) @@ -28,12 +26,11 @@ _TIMEOUT = 15 # seconds async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: DoorBirdConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the DoorBird camera platform.""" - config_entry_id = config_entry.entry_id - door_bird_data: DoorBirdData = hass.data[DOMAIN][config_entry_id] + door_bird_data = config_entry.runtime_data device = door_bird_data.door_station.device async_add_entities( diff --git a/homeassistant/components/doorbird/event.py b/homeassistant/components/doorbird/event.py index 082ddb6d487e5895cfee21fe53c7cbf6b4950a40..39da279a3e0cd163967f079e5cbf2c0b7dbd5678 100644 --- a/homeassistant/components/doorbird/event.py +++ b/homeassistant/components/doorbird/event.py @@ -7,14 +7,13 @@ from homeassistant.components.event import ( EventEntity, EventEntityDescription, ) -from homeassistant.config_entries import ConfigEntry from homeassistant.core import Event, HomeAssistant, callback from homeassistant.helpers.entity_platform import AddEntitiesCallback from .const import DOMAIN from .device import DoorbirdEvent from .entity import DoorBirdEntity -from .models import DoorBirdData +from .models import DoorBirdConfigEntry, DoorBirdData EVENT_DESCRIPTIONS = { "doorbell": EventEntityDescription( @@ -34,12 +33,11 @@ EVENT_DESCRIPTIONS = { async def async_setup_entry( hass: HomeAssistant, - config_entry: ConfigEntry, + config_entry: DoorBirdConfigEntry, async_add_entities: AddEntitiesCallback, ) -> None: """Set up the DoorBird event platform.""" - config_entry_id = config_entry.entry_id - door_bird_data: DoorBirdData = hass.data[DOMAIN][config_entry_id] + door_bird_data = config_entry.runtime_data async_add_entities( DoorBirdEventEntity(door_bird_data, doorbird_event, description) for doorbird_event in door_bird_data.door_station.event_descriptions @@ -48,7 +46,7 @@ async def async_setup_entry( class DoorBirdEventEntity(DoorBirdEntity, EventEntity): - """A relay in a DoorBird device.""" + """A doorbird event entity.""" entity_description: EventEntityDescription _attr_has_entity_name = True diff --git a/homeassistant/components/doorbird/logbook.py b/homeassistant/components/doorbird/logbook.py index 71a63557a2c92c05131a7764c57f347703f2036a..70fedf97faf4fe99eebbd526a7c35879f87421d4 100644 --- a/homeassistant/components/doorbird/logbook.py +++ b/homeassistant/components/doorbird/logbook.py @@ -13,7 +13,7 @@ from homeassistant.const import ATTR_ENTITY_ID from homeassistant.core import Event, HomeAssistant, callback from .const import DOMAIN -from .models import DoorBirdData +from .util import async_get_entries @callback @@ -35,8 +35,8 @@ def async_describe_events( LOGBOOK_ENTRY_ENTITY_ID: event.data.get(ATTR_ENTITY_ID), } - domain_data: dict[str, DoorBirdData] = hass.data[DOMAIN] - for data in domain_data.values(): + for entry in async_get_entries(hass): + data = entry.runtime_data for event in data.door_station.door_station_events: async_describe_event( DOMAIN, f"{DOMAIN}_{event}", async_describe_logbook_event diff --git a/homeassistant/components/doorbird/models.py b/homeassistant/components/doorbird/models.py index a8ecbf19d5d16666377f579bb633f6a7d80ffd61..e4ea64653a2bb82acfc7b02cefdab5b94c09a496 100644 --- a/homeassistant/components/doorbird/models.py +++ b/homeassistant/components/doorbird/models.py @@ -5,8 +5,12 @@ from __future__ import annotations from dataclasses import dataclass from typing import Any +from homeassistant.config_entries import ConfigEntry + from .device import ConfiguredDoorBird +type DoorBirdConfigEntry = ConfigEntry[DoorBirdData] + @dataclass class DoorBirdData: diff --git a/homeassistant/components/doorbird/util.py b/homeassistant/components/doorbird/util.py index c307a125b8d74d603177fef1703896d1be375ecc..b4961b93eb59840a2c6eb5d5c8a8b46e591df7bc 100644 --- a/homeassistant/components/doorbird/util.py +++ b/homeassistant/components/doorbird/util.py @@ -1,12 +1,12 @@ """DoorBird integration utils.""" -from typing import Any +from typing import Any, cast -from homeassistant.core import HomeAssistant +from homeassistant.core import HomeAssistant, callback from .const import DOMAIN from .device import ConfiguredDoorBird -from .models import DoorBirdData +from .models import DoorBirdConfigEntry def get_mac_address_from_door_station_info(door_station_info: dict[str, Any]) -> str: @@ -18,9 +18,18 @@ def get_door_station_by_token( hass: HomeAssistant, token: str ) -> ConfiguredDoorBird | None: """Get door station by token.""" - domain_data: dict[str, DoorBirdData] = hass.data[DOMAIN] - for data in domain_data.values(): - door_station = data.door_station + for entry in async_get_entries(hass): + door_station = entry.runtime_data.door_station if door_station.token == token: return door_station return None + + +@callback +def async_get_entries(hass: HomeAssistant) -> list[DoorBirdConfigEntry]: + """Get all the doorbird entries.""" + entries = hass.config_entries.async_entries( + DOMAIN, include_ignore=True, include_disabled=True + ) + active_entries = [entry for entry in entries if hasattr(entry, "runtime_data")] + return cast(list[DoorBirdConfigEntry], active_entries)