diff --git a/homeassistant/components/air_quality/__init__.py b/homeassistant/components/air_quality/__init__.py index 9a80ee39e86..605a34a69e0 100644 --- a/homeassistant/components/air_quality/__init__.py +++ b/homeassistant/components/air_quality/__init__.py @@ -13,11 +13,13 @@ from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity import Entity from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType, StateType +from homeassistant.util.hass_dict import HassKey from .const import DOMAIN _LOGGER: Final = logging.getLogger(__name__) +DOMAIN_DATA: HassKey[EntityComponent[AirQualityEntity]] = HassKey(DOMAIN) ENTITY_ID_FORMAT: Final = DOMAIN + ".{}" PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE @@ -54,7 +56,7 @@ PROP_TO_ATTR: Final[dict[str, str]] = { async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the air quality component.""" - component = hass.data[DOMAIN] = EntityComponent[AirQualityEntity]( + component = hass.data[DOMAIN_DATA] = EntityComponent[AirQualityEntity]( _LOGGER, DOMAIN, hass, SCAN_INTERVAL ) await component.async_setup(config) @@ -63,14 +65,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" - component: EntityComponent[AirQualityEntity] = hass.data[DOMAIN] - return await component.async_setup_entry(entry) + return await hass.data[DOMAIN_DATA].async_setup_entry(entry) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - component: EntityComponent[AirQualityEntity] = hass.data[DOMAIN] - return await component.async_unload_entry(entry) + return await hass.data[DOMAIN_DATA].async_unload_entry(entry) class AirQualityEntity(Entity): diff --git a/homeassistant/components/alarm_control_panel/__init__.py b/homeassistant/components/alarm_control_panel/__init__.py index b09d5867d26..91d3a83df8e 100644 --- a/homeassistant/components/alarm_control_panel/__init__.py +++ b/homeassistant/components/alarm_control_panel/__init__.py @@ -33,6 +33,7 @@ from homeassistant.helpers.deprecation import ( from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType +from homeassistant.util.hass_dict import HassKey from .const import ( # noqa: F401 _DEPRECATED_FORMAT_NUMBER, @@ -52,6 +53,7 @@ from .const import ( # noqa: F401 _LOGGER: Final = logging.getLogger(__name__) +DOMAIN_DATA: HassKey[EntityComponent[AlarmControlPanelEntity]] = HassKey(DOMAIN) ENTITY_ID_FORMAT: Final = DOMAIN + ".{}" PLATFORM_SCHEMA: Final = cv.PLATFORM_SCHEMA PLATFORM_SCHEMA_BASE: Final = cv.PLATFORM_SCHEMA_BASE @@ -69,7 +71,7 @@ ALARM_SERVICE_SCHEMA: Final = make_entity_service_schema( async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Track states and offer events for sensors.""" - component = hass.data[DOMAIN] = EntityComponent[AlarmControlPanelEntity]( + component = hass.data[DOMAIN_DATA] = EntityComponent[AlarmControlPanelEntity]( _LOGGER, DOMAIN, hass, SCAN_INTERVAL ) @@ -122,14 +124,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" - component: EntityComponent[AlarmControlPanelEntity] = hass.data[DOMAIN] - return await component.async_setup_entry(entry) + return await hass.data[DOMAIN_DATA].async_setup_entry(entry) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - component: EntityComponent[AlarmControlPanelEntity] = hass.data[DOMAIN] - return await component.async_unload_entry(entry) + return await hass.data[DOMAIN_DATA].async_unload_entry(entry) class AlarmControlPanelEntityDescription(EntityDescription, frozen_or_thawed=True): diff --git a/homeassistant/components/assist_satellite/__init__.py b/homeassistant/components/assist_satellite/__init__.py index 2d4459ffd8c..77c9d8e678a 100644 --- a/homeassistant/components/assist_satellite/__init__.py +++ b/homeassistant/components/assist_satellite/__init__.py @@ -10,7 +10,7 @@ from homeassistant.helpers import config_validation as cv from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType -from .const import DOMAIN, AssistSatelliteEntityFeature +from .const import DOMAIN, DOMAIN_DATA, AssistSatelliteEntityFeature from .entity import ( AssistSatelliteConfiguration, AssistSatelliteEntity, @@ -36,7 +36,7 @@ PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: - component = hass.data[DOMAIN] = EntityComponent[AssistSatelliteEntity]( + component = hass.data[DOMAIN_DATA] = EntityComponent[AssistSatelliteEntity]( _LOGGER, DOMAIN, hass ) await component.async_setup(config) @@ -62,11 +62,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" - component: EntityComponent[AssistSatelliteEntity] = hass.data[DOMAIN] - return await component.async_setup_entry(entry) + return await hass.data[DOMAIN_DATA].async_setup_entry(entry) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - component: EntityComponent[AssistSatelliteEntity] = hass.data[DOMAIN] - return await component.async_unload_entry(entry) + return await hass.data[DOMAIN_DATA].async_unload_entry(entry) diff --git a/homeassistant/components/assist_satellite/const.py b/homeassistant/components/assist_satellite/const.py index 3a9ce896fb2..bd5453e06de 100644 --- a/homeassistant/components/assist_satellite/const.py +++ b/homeassistant/components/assist_satellite/const.py @@ -1,9 +1,21 @@ """Constants for assist satellite.""" +from __future__ import annotations + from enum import IntFlag +from typing import TYPE_CHECKING + +from homeassistant.util.hass_dict import HassKey + +if TYPE_CHECKING: + from homeassistant.helpers.entity_component import EntityComponent + + from .entity import AssistSatelliteEntity DOMAIN = "assist_satellite" +DOMAIN_DATA: HassKey[EntityComponent[AssistSatelliteEntity]] = HassKey(DOMAIN) + class AssistSatelliteEntityFeature(IntFlag): """Supported features of Assist satellite entity.""" diff --git a/homeassistant/components/assist_satellite/websocket_api.py b/homeassistant/components/assist_satellite/websocket_api.py index 0d7a434dba5..ee7bef7e4e8 100644 --- a/homeassistant/components/assist_satellite/websocket_api.py +++ b/homeassistant/components/assist_satellite/websocket_api.py @@ -9,10 +9,8 @@ from homeassistant.components import websocket_api from homeassistant.core import HomeAssistant, callback from homeassistant.exceptions import HomeAssistantError from homeassistant.helpers import config_validation as cv -from homeassistant.helpers.entity_component import EntityComponent -from .const import DOMAIN -from .entity import AssistSatelliteEntity +from .const import DOMAIN, DOMAIN_DATA @callback @@ -38,8 +36,7 @@ async def websocket_intercept_wake_word( msg: dict[str, Any], ) -> None: """Intercept the next wake word from a satellite.""" - component: EntityComponent[AssistSatelliteEntity] = hass.data[DOMAIN] - satellite = component.get_entity(msg["entity_id"]) + satellite = hass.data[DOMAIN_DATA].get_entity(msg["entity_id"]) if satellite is None: connection.send_error( msg["id"], websocket_api.ERR_NOT_FOUND, "Entity not found" @@ -77,8 +74,7 @@ def websocket_get_configuration( msg: dict[str, Any], ) -> None: """Get the current satellite configuration.""" - component: EntityComponent[AssistSatelliteEntity] = hass.data[DOMAIN] - satellite = component.get_entity(msg["entity_id"]) + satellite = hass.data[DOMAIN_DATA].get_entity(msg["entity_id"]) if satellite is None: connection.send_error( msg["id"], websocket_api.ERR_NOT_FOUND, "Entity not found" @@ -108,8 +104,7 @@ async def websocket_set_wake_words( msg: dict[str, Any], ) -> None: """Set the active wake words for the satellite.""" - component: EntityComponent[AssistSatelliteEntity] = hass.data[DOMAIN] - satellite = component.get_entity(msg["entity_id"]) + satellite = hass.data[DOMAIN_DATA].get_entity(msg["entity_id"]) if satellite is None: connection.send_error( msg["id"], websocket_api.ERR_NOT_FOUND, "Entity not found" diff --git a/homeassistant/components/automation/__init__.py b/homeassistant/components/automation/__init__.py index dacbe074e95..1db5125a8a6 100644 --- a/homeassistant/components/automation/__init__.py +++ b/homeassistant/components/automation/__init__.py @@ -94,6 +94,7 @@ from homeassistant.helpers.trigger import ( from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass from homeassistant.util.dt import parse_datetime +from homeassistant.util.hass_dict import HassKey from .config import AutomationConfig, ValidationStatus from .const import ( @@ -109,6 +110,7 @@ from .const import ( from .helpers import async_get_blueprints from .trace import trace_automation +DOMAIN_DATA: HassKey[EntityComponent[BaseAutomationEntity]] = HassKey(DOMAIN) ENTITY_ID_FORMAT = DOMAIN + ".{}" @@ -161,14 +163,12 @@ def _automations_with_x( hass: HomeAssistant, referenced_id: str, property_name: str ) -> list[str]: """Return all automations that reference the x.""" - if DOMAIN not in hass.data: + if DOMAIN_DATA not in hass.data: return [] - component: EntityComponent[BaseAutomationEntity] = hass.data[DOMAIN] - return [ automation_entity.entity_id - for automation_entity in component.entities + for automation_entity in hass.data[DOMAIN_DATA].entities if referenced_id in getattr(automation_entity, property_name) ] @@ -177,12 +177,10 @@ def _x_in_automation( hass: HomeAssistant, entity_id: str, property_name: str ) -> list[str]: """Return all x in an automation.""" - if DOMAIN not in hass.data: + if DOMAIN_DATA not in hass.data: return [] - component: EntityComponent[BaseAutomationEntity] = hass.data[DOMAIN] - - if (automation_entity := component.get_entity(entity_id)) is None: + if (automation_entity := hass.data[DOMAIN_DATA].get_entity(entity_id)) is None: return [] return list(getattr(automation_entity, property_name)) @@ -254,11 +252,9 @@ def automations_with_blueprint(hass: HomeAssistant, blueprint_path: str) -> list if DOMAIN not in hass.data: return [] - component: EntityComponent[BaseAutomationEntity] = hass.data[DOMAIN] - return [ automation_entity.entity_id - for automation_entity in component.entities + for automation_entity in hass.data[DOMAIN_DATA].entities if automation_entity.referenced_blueprint == blueprint_path ] @@ -266,12 +262,10 @@ def automations_with_blueprint(hass: HomeAssistant, blueprint_path: str) -> list @callback def blueprint_in_automation(hass: HomeAssistant, entity_id: str) -> str | None: """Return the blueprint the automation is based on or None.""" - if DOMAIN not in hass.data: + if DOMAIN_DATA not in hass.data: return None - component: EntityComponent[BaseAutomationEntity] = hass.data[DOMAIN] - - if (automation_entity := component.get_entity(entity_id)) is None: + if (automation_entity := hass.data[DOMAIN_DATA].get_entity(entity_id)) is None: return None return automation_entity.referenced_blueprint @@ -279,7 +273,7 @@ def blueprint_in_automation(hass: HomeAssistant, entity_id: str) -> str | None: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up all automations.""" - hass.data[DOMAIN] = component = EntityComponent[BaseAutomationEntity]( + hass.data[DOMAIN_DATA] = component = EntityComponent[BaseAutomationEntity]( LOGGER, DOMAIN, hass ) @@ -1210,9 +1204,7 @@ def websocket_config( msg: dict[str, Any], ) -> None: """Get automation config.""" - component: EntityComponent[BaseAutomationEntity] = hass.data[DOMAIN] - - automation = component.get_entity(msg["entity_id"]) + automation = hass.data[DOMAIN_DATA].get_entity(msg["entity_id"]) if automation is None: connection.send_error( diff --git a/homeassistant/components/binary_sensor/__init__.py b/homeassistant/components/binary_sensor/__init__.py index 0b3e423e339..5ed6014030f 100644 --- a/homeassistant/components/binary_sensor/__init__.py +++ b/homeassistant/components/binary_sensor/__init__.py @@ -24,10 +24,12 @@ from homeassistant.helpers.deprecation import ( from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType +from homeassistant.util.hass_dict import HassKey _LOGGER = logging.getLogger(__name__) DOMAIN = "binary_sensor" +DOMAIN_DATA: HassKey[EntityComponent[BinarySensorEntity]] = HassKey(DOMAIN) ENTITY_ID_FORMAT = DOMAIN + ".{}" PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE @@ -217,7 +219,7 @@ _DEPRECATED_DEVICE_CLASS_WINDOW = DeprecatedConstantEnum( async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Track states and offer events for binary sensors.""" - component = hass.data[DOMAIN] = EntityComponent[BinarySensorEntity]( + component = hass.data[DOMAIN_DATA] = EntityComponent[BinarySensorEntity]( logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL ) @@ -227,14 +229,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" - component: EntityComponent[BinarySensorEntity] = hass.data[DOMAIN] - return await component.async_setup_entry(entry) + return await hass.data[DOMAIN_DATA].async_setup_entry(entry) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - component: EntityComponent[BinarySensorEntity] = hass.data[DOMAIN] - return await component.async_unload_entry(entry) + return await hass.data[DOMAIN_DATA].async_unload_entry(entry) class BinarySensorEntityDescription(EntityDescription, frozen_or_thawed=True): diff --git a/homeassistant/components/button/__init__.py b/homeassistant/components/button/__init__.py index 3955fabdf00..614a6e6dba3 100644 --- a/homeassistant/components/button/__init__.py +++ b/homeassistant/components/button/__init__.py @@ -19,11 +19,13 @@ from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.restore_state import RestoreEntity from homeassistant.helpers.typing import ConfigType from homeassistant.util import dt as dt_util +from homeassistant.util.hass_dict import HassKey from .const import DOMAIN, SERVICE_PRESS _LOGGER = logging.getLogger(__name__) +DOMAIN_DATA: HassKey[EntityComponent[ButtonEntity]] = HassKey(DOMAIN) ENTITY_ID_FORMAT = DOMAIN + ".{}" PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE @@ -47,7 +49,7 @@ DEVICE_CLASSES_SCHEMA = vol.All(vol.Lower, vol.Coerce(ButtonDeviceClass)) async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up Button entities.""" - component = hass.data[DOMAIN] = EntityComponent[ButtonEntity]( + component = hass.data[DOMAIN_DATA] = EntityComponent[ButtonEntity]( _LOGGER, DOMAIN, hass, SCAN_INTERVAL ) await component.async_setup(config) @@ -63,14 +65,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" - component: EntityComponent[ButtonEntity] = hass.data[DOMAIN] - return await component.async_setup_entry(entry) + return await hass.data[DOMAIN_DATA].async_setup_entry(entry) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - component: EntityComponent[ButtonEntity] = hass.data[DOMAIN] - return await component.async_unload_entry(entry) + return await hass.data[DOMAIN_DATA].async_unload_entry(entry) class ButtonEntityDescription(EntityDescription, frozen_or_thawed=True): diff --git a/homeassistant/components/calendar/__init__.py b/homeassistant/components/calendar/__init__.py index 3e33f077e93..e1f206ca661 100644 --- a/homeassistant/components/calendar/__init__.py +++ b/homeassistant/components/calendar/__init__.py @@ -43,6 +43,8 @@ from homeassistant.util.json import JsonValueType from .const import ( CONF_EVENT, + DOMAIN, + DOMAIN_DATA, EVENT_DESCRIPTION, EVENT_DURATION, EVENT_END, @@ -70,7 +72,6 @@ from .const import ( _LOGGER = logging.getLogger(__name__) -DOMAIN = "calendar" ENTITY_ID_FORMAT = DOMAIN + ".{}" PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE @@ -285,7 +286,7 @@ SERVICE_GET_EVENTS_SCHEMA: Final = vol.All( async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Track states and offer events for calendars.""" - component = hass.data[DOMAIN] = EntityComponent[CalendarEntity]( + component = hass.data[DOMAIN_DATA] = EntityComponent[CalendarEntity]( _LOGGER, DOMAIN, hass, SCAN_INTERVAL ) @@ -318,14 +319,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" - component: EntityComponent[CalendarEntity] = hass.data[DOMAIN] - return await component.async_setup_entry(entry) + return await hass.data[DOMAIN_DATA].async_setup_entry(entry) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - component: EntityComponent[CalendarEntity] = hass.data[DOMAIN] - return await component.async_unload_entry(entry) + return await hass.data[DOMAIN_DATA].async_unload_entry(entry) def get_date(date: dict[str, Any]) -> datetime.datetime: @@ -702,8 +701,7 @@ async def handle_calendar_event_create( hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any] ) -> None: """Handle creation of a calendar event.""" - component: EntityComponent[CalendarEntity] = hass.data[DOMAIN] - if not (entity := component.get_entity(msg["entity_id"])): + if not (entity := hass.data[DOMAIN_DATA].get_entity(msg["entity_id"])): connection.send_error(msg["id"], ERR_NOT_FOUND, "Entity not found") return @@ -743,8 +741,7 @@ async def handle_calendar_event_delete( ) -> None: """Handle delete of a calendar event.""" - component: EntityComponent[CalendarEntity] = hass.data[DOMAIN] - if not (entity := component.get_entity(msg["entity_id"])): + if not (entity := hass.data[DOMAIN_DATA].get_entity(msg["entity_id"])): connection.send_error(msg["id"], ERR_NOT_FOUND, "Entity not found") return @@ -789,8 +786,7 @@ async def handle_calendar_event_update( hass: HomeAssistant, connection: ActiveConnection, msg: dict[str, Any] ) -> None: """Handle creation of a calendar event.""" - component: EntityComponent[CalendarEntity] = hass.data[DOMAIN] - if not (entity := component.get_entity(msg["entity_id"])): + if not (entity := hass.data[DOMAIN_DATA].get_entity(msg["entity_id"])): connection.send_error(msg["id"], ERR_NOT_FOUND, "Entity not found") return diff --git a/homeassistant/components/calendar/const.py b/homeassistant/components/calendar/const.py index e667510325b..6266a604c81 100644 --- a/homeassistant/components/calendar/const.py +++ b/homeassistant/components/calendar/const.py @@ -1,6 +1,19 @@ """Constants for calendar components.""" +from __future__ import annotations + from enum import IntFlag +from typing import TYPE_CHECKING + +from homeassistant.util.hass_dict import HassKey + +if TYPE_CHECKING: + from homeassistant.helpers.entity_component import EntityComponent + + from . import CalendarEntity + +DOMAIN = "calendar" +DOMAIN_DATA: HassKey[EntityComponent[CalendarEntity]] = HassKey(DOMAIN) CONF_EVENT = "event" diff --git a/homeassistant/components/calendar/trigger.py b/homeassistant/components/calendar/trigger.py index 523a634704c..4daa32f7fc7 100644 --- a/homeassistant/components/calendar/trigger.py +++ b/homeassistant/components/calendar/trigger.py @@ -23,7 +23,8 @@ from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo from homeassistant.helpers.typing import ConfigType from homeassistant.util import dt as dt_util -from . import DOMAIN, CalendarEntity, CalendarEvent +from . import CalendarEntity, CalendarEvent +from .const import DOMAIN, DOMAIN_DATA _LOGGER = logging.getLogger(__name__) @@ -94,7 +95,7 @@ type QueuedEventFetcher = Callable[[Timespan], Awaitable[list[QueuedCalendarEven def get_entity(hass: HomeAssistant, entity_id: str) -> CalendarEntity: """Get the calendar entity for the provided entity_id.""" - component: EntityComponent[CalendarEntity] = hass.data[DOMAIN] + component: EntityComponent[CalendarEntity] = hass.data[DOMAIN_DATA] if not (entity := component.get_entity(entity_id)) or not isinstance( entity, CalendarEntity ): diff --git a/homeassistant/components/camera/__init__.py b/homeassistant/components/camera/__init__.py index 859ced1ba86..14f884c1750 100644 --- a/homeassistant/components/camera/__init__.py +++ b/homeassistant/components/camera/__init__.py @@ -73,6 +73,7 @@ from .const import ( # noqa: F401 DATA_CAMERA_PREFS, DATA_RTSP_TO_WEB_RTC, DOMAIN, + DOMAIN_DATA, PREF_ORIENTATION, PREF_PRELOAD_STREAM, SERVICE_RECORD, @@ -362,7 +363,7 @@ def async_register_rtsp_to_web_rtc_provider( async def _async_refresh_providers(hass: HomeAssistant) -> None: """Check all cameras for any state changes for registered providers.""" - component: EntityComponent[Camera] = hass.data[DOMAIN] + component = hass.data[DOMAIN_DATA] await asyncio.gather( *(camera.async_refresh_providers() for camera in component.entities) ) @@ -380,7 +381,7 @@ def _async_get_rtsp_to_web_rtc_providers( async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up the camera component.""" - component = hass.data[DOMAIN] = EntityComponent[Camera]( + component = hass.data[DOMAIN_DATA] = EntityComponent[Camera]( _LOGGER, DOMAIN, hass, SCAN_INTERVAL ) @@ -455,14 +456,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" - component: EntityComponent[Camera] = hass.data[DOMAIN] - return await component.async_setup_entry(entry) + return await hass.data[DOMAIN_DATA].async_setup_entry(entry) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - component: EntityComponent[Camera] = hass.data[DOMAIN] - return await component.async_unload_entry(entry) + return await hass.data[DOMAIN_DATA].async_unload_entry(entry) CACHED_PROPERTIES_WITH_ATTR_ = { diff --git a/homeassistant/components/camera/const.py b/homeassistant/components/camera/const.py index ad863f374d1..d6a2372ffc1 100644 --- a/homeassistant/components/camera/const.py +++ b/homeassistant/components/camera/const.py @@ -1,8 +1,10 @@ """Constants for Camera component.""" +from __future__ import annotations + from enum import StrEnum from functools import partial -from typing import Final +from typing import TYPE_CHECKING, Final from homeassistant.helpers.deprecation import ( DeprecatedConstantEnum, @@ -10,8 +12,15 @@ from homeassistant.helpers.deprecation import ( check_if_deprecated_constant, dir_with_deprecated_constants, ) +from homeassistant.util.hass_dict import HassKey + +if TYPE_CHECKING: + from homeassistant.helpers.entity_component import EntityComponent + + from . import Camera DOMAIN: Final = "camera" +DOMAIN_DATA: HassKey[EntityComponent[Camera]] = HassKey(DOMAIN) DATA_CAMERA_PREFS: Final = "camera_prefs" DATA_RTSP_TO_WEB_RTC: Final = "rtsp_to_web_rtc" diff --git a/homeassistant/components/camera/media_source.py b/homeassistant/components/camera/media_source.py index 958235c684d..00c0e83b46f 100644 --- a/homeassistant/components/camera/media_source.py +++ b/homeassistant/components/camera/media_source.py @@ -16,10 +16,9 @@ from homeassistant.components.stream import FORMAT_CONTENT_TYPE, HLS_PROVIDER from homeassistant.const import ATTR_FRIENDLY_NAME from homeassistant.core import HomeAssistant from homeassistant.exceptions import HomeAssistantError -from homeassistant.helpers.entity_component import EntityComponent from . import Camera, _async_stream_endpoint_url -from .const import DOMAIN, StreamType +from .const import DOMAIN, DOMAIN_DATA, StreamType async def async_get_media_source(hass: HomeAssistant) -> CameraMediaSource: @@ -59,7 +58,7 @@ class CameraMediaSource(MediaSource): async def async_resolve_media(self, item: MediaSourceItem) -> PlayMedia: """Resolve media to a url.""" - component: EntityComponent[Camera] = self.hass.data[DOMAIN] + component = self.hass.data[DOMAIN_DATA] camera = component.get_entity(item.identifier) if not camera: @@ -108,7 +107,7 @@ class CameraMediaSource(MediaSource): return _media_source_for_camera(self.hass, camera, content_type) - component: EntityComponent[Camera] = self.hass.data[DOMAIN] + component = self.hass.data[DOMAIN_DATA] results = await asyncio.gather( *(_filter_browsable_camera(camera) for camera in component.entities), return_exceptions=True, diff --git a/homeassistant/components/climate/__init__.py b/homeassistant/components/climate/__init__.py index 7b016d9c90b..7213a2ebca0 100644 --- a/homeassistant/components/climate/__init__.py +++ b/homeassistant/components/climate/__init__.py @@ -37,6 +37,7 @@ from homeassistant.helpers.entity_platform import EntityPlatform from homeassistant.helpers.temperature import display_temp as show_temp from homeassistant.helpers.typing import ConfigType from homeassistant.loader import async_get_issue_tracker, async_suggest_report_issue +from homeassistant.util.hass_dict import HassKey from homeassistant.util.unit_conversion import TemperatureConverter from .const import ( # noqa: F401 @@ -114,6 +115,7 @@ from .const import ( # noqa: F401 _LOGGER = logging.getLogger(__name__) +DOMAIN_DATA: HassKey[EntityComponent[ClimateEntity]] = HassKey(DOMAIN) ENTITY_ID_FORMAT = DOMAIN + ".{}" PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE @@ -150,7 +152,7 @@ SET_TEMPERATURE_SCHEMA = vol.All( async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Set up climate entities.""" - component = hass.data[DOMAIN] = EntityComponent[ClimateEntity]( + component = hass.data[DOMAIN_DATA] = EntityComponent[ClimateEntity]( _LOGGER, DOMAIN, hass, SCAN_INTERVAL ) await component.async_setup(config) @@ -223,14 +225,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" - component: EntityComponent[ClimateEntity] = hass.data[DOMAIN] - return await component.async_setup_entry(entry) + return await hass.data[DOMAIN_DATA].async_setup_entry(entry) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - component: EntityComponent[ClimateEntity] = hass.data[DOMAIN] - return await component.async_unload_entry(entry) + return await hass.data[DOMAIN_DATA].async_unload_entry(entry) class ClimateEntityDescription(EntityDescription, frozen_or_thawed=True): diff --git a/homeassistant/components/conversation/__init__.py b/homeassistant/components/conversation/__init__.py index 2e06387765b..983d2074ab5 100644 --- a/homeassistant/components/conversation/__init__.py +++ b/homeassistant/components/conversation/__init__.py @@ -36,6 +36,7 @@ from .const import ( ATTR_LANGUAGE, ATTR_TEXT, DOMAIN, + DOMAIN_DATA, HOME_ASSISTANT_AGENT, OLD_HOME_ASSISTANT_AGENT, SERVICE_PROCESS, @@ -132,7 +133,6 @@ def async_get_conversation_languages( all conversation agents. """ agent_manager = get_agent_manager(hass) - entity_component: EntityComponent[ConversationEntity] = hass.data[DOMAIN] agents: list[ConversationEntity | AbstractConversationAgent] if agent_id: @@ -148,7 +148,7 @@ def async_get_conversation_languages( agents = [agent] else: - agents = list(entity_component.entities) + agents = list(hass.data[DOMAIN_DATA].entities) for info in agent_manager.async_get_agent_info(): agent = agent_manager.async_get_agent(info.id) assert agent is not None @@ -208,10 +208,8 @@ async def async_prepare_agent( async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Register the process service.""" - entity_component: EntityComponent[ConversationEntity] = EntityComponent( - _LOGGER, DOMAIN, hass - ) - hass.data[DOMAIN] = entity_component + entity_component = EntityComponent[ConversationEntity](_LOGGER, DOMAIN, hass) + hass.data[DOMAIN_DATA] = entity_component await async_setup_default_agent( hass, entity_component, config.get(DOMAIN, {}).get("intents", {}) @@ -269,11 +267,9 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" - component: EntityComponent[ConversationEntity] = hass.data[DOMAIN] - return await component.async_setup_entry(entry) + return await hass.data[DOMAIN_DATA].async_setup_entry(entry) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - component: EntityComponent[ConversationEntity] = hass.data[DOMAIN] - return await component.async_unload_entry(entry) + return await hass.data[DOMAIN_DATA].async_unload_entry(entry) diff --git a/homeassistant/components/conversation/agent_manager.py b/homeassistant/components/conversation/agent_manager.py index 8202b9a0ed4..ae7d9551140 100644 --- a/homeassistant/components/conversation/agent_manager.py +++ b/homeassistant/components/conversation/agent_manager.py @@ -10,9 +10,8 @@ import voluptuous as vol from homeassistant.core import Context, HomeAssistant, async_get_hass, callback from homeassistant.helpers import config_validation as cv, singleton -from homeassistant.helpers.entity_component import EntityComponent -from .const import DOMAIN, HOME_ASSISTANT_AGENT, OLD_HOME_ASSISTANT_AGENT +from .const import DOMAIN_DATA, HOME_ASSISTANT_AGENT, OLD_HOME_ASSISTANT_AGENT from .default_agent import async_get_default_agent from .entity import ConversationEntity from .models import ( @@ -54,8 +53,7 @@ def async_get_agent( return async_get_default_agent(hass) if "." in agent_id: - entity_component: EntityComponent[ConversationEntity] = hass.data[DOMAIN] - return entity_component.get_entity(agent_id) + return hass.data[DOMAIN_DATA].get_entity(agent_id) manager = get_agent_manager(hass) diff --git a/homeassistant/components/conversation/const.py b/homeassistant/components/conversation/const.py index 14b2d1d4955..b7e45142f8f 100644 --- a/homeassistant/components/conversation/const.py +++ b/homeassistant/components/conversation/const.py @@ -1,6 +1,16 @@ """Const for conversation integration.""" +from __future__ import annotations + from enum import IntFlag +from typing import TYPE_CHECKING + +from homeassistant.util.hass_dict import HassKey + +if TYPE_CHECKING: + from homeassistant.helpers.entity_component import EntityComponent + + from .entity import ConversationEntity DOMAIN = "conversation" DEFAULT_EXPOSED_ATTRIBUTES = {"device_class"} @@ -15,6 +25,8 @@ ATTR_CONVERSATION_ID = "conversation_id" SERVICE_PROCESS = "process" SERVICE_RELOAD = "reload" +DOMAIN_DATA: HassKey[EntityComponent[ConversationEntity]] = HassKey(DOMAIN) + class ConversationEntityFeature(IntFlag): """Supported features of the conversation entity.""" diff --git a/homeassistant/components/conversation/http.py b/homeassistant/components/conversation/http.py index 591298cbac1..982575b9957 100644 --- a/homeassistant/components/conversation/http.py +++ b/homeassistant/components/conversation/http.py @@ -19,7 +19,6 @@ from homeassistant.components.http.data_validator import RequestDataValidator from homeassistant.const import MATCH_ALL from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv, intent -from homeassistant.helpers.entity_component import EntityComponent from homeassistant.util import language as language_util from .agent_manager import ( @@ -28,7 +27,7 @@ from .agent_manager import ( async_get_agent, get_agent_manager, ) -from .const import DOMAIN +from .const import DOMAIN_DATA from .default_agent import ( METADATA_CUSTOM_FILE, METADATA_CUSTOM_SENTENCE, @@ -113,13 +112,11 @@ async def websocket_list_agents( hass: HomeAssistant, connection: websocket_api.ActiveConnection, msg: dict ) -> None: """List conversation agents and, optionally, if they support a given language.""" - entity_component: EntityComponent[ConversationEntity] = hass.data[DOMAIN] - country = msg.get("country") language = msg.get("language") agents = [] - for entity in entity_component.entities: + for entity in hass.data[DOMAIN_DATA].entities: supported_languages = entity.supported_languages if language and supported_languages != MATCH_ALL: supported_languages = language_util.matches( diff --git a/homeassistant/components/cover/__init__.py b/homeassistant/components/cover/__init__.py index d2ec6bee8fa..d64358896ba 100644 --- a/homeassistant/components/cover/__init__.py +++ b/homeassistant/components/cover/__init__.py @@ -41,11 +41,13 @@ from homeassistant.helpers.entity import Entity, EntityDescription from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.typing import ConfigType from homeassistant.loader import bind_hass +from homeassistant.util.hass_dict import HassKey from .const import DOMAIN, INTENT_CLOSE_COVER, INTENT_OPEN_COVER # noqa: F401 _LOGGER = logging.getLogger(__name__) +DOMAIN_DATA: HassKey[EntityComponent[CoverEntity]] = HassKey(DOMAIN) ENTITY_ID_FORMAT = DOMAIN + ".{}" PLATFORM_SCHEMA = cv.PLATFORM_SCHEMA PLATFORM_SCHEMA_BASE = cv.PLATFORM_SCHEMA_BASE @@ -151,7 +153,7 @@ def is_closed(hass: HomeAssistant, entity_id: str) -> bool: async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: """Track states and offer events for covers.""" - component = hass.data[DOMAIN] = EntityComponent[CoverEntity]( + component = hass.data[DOMAIN_DATA] = EntityComponent[CoverEntity]( _LOGGER, DOMAIN, hass, SCAN_INTERVAL ) @@ -231,14 +233,12 @@ async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool: async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up a config entry.""" - component: EntityComponent[CoverEntity] = hass.data[DOMAIN] - return await component.async_setup_entry(entry) + return await hass.data[DOMAIN_DATA].async_setup_entry(entry) async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Unload a config entry.""" - component: EntityComponent[CoverEntity] = hass.data[DOMAIN] - return await component.async_unload_entry(entry) + return await hass.data[DOMAIN_DATA].async_unload_entry(entry) class CoverEntityDescription(EntityDescription, frozen_or_thawed=True):