diff --git a/homeassistant/components/group/__init__.py b/homeassistant/components/group/__init__.py index 4bdabdf9c962..33df9822ac2b 100644 --- a/homeassistant/components/group/__init__.py +++ b/homeassistant/components/group/__init__.py @@ -28,7 +28,6 @@ from homeassistant.const import ( ) from homeassistant.core import ( CALLBACK_TYPE, - Event, HomeAssistant, ServiceCall, State, @@ -38,13 +37,16 @@ from homeassistant.core import ( from homeassistant.helpers import config_validation as cv, entity_registry as er, start from homeassistant.helpers.entity import Entity, async_generate_entity_id from homeassistant.helpers.entity_component import EntityComponent -from homeassistant.helpers.event import async_track_state_change_event +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) from homeassistant.helpers.integration_platform import ( async_process_integration_platform_for_component, async_process_integration_platforms, ) from homeassistant.helpers.reload import async_reload_integration_platforms -from homeassistant.helpers.typing import ConfigType +from homeassistant.helpers.typing import ConfigType, EventType from homeassistant.loader import bind_hass from .const import CONF_HIDE_MEMBERS @@ -737,7 +739,9 @@ class Group(Entity): """Handle removal from Home Assistant.""" self._async_stop() - async def _async_state_changed_listener(self, event: Event) -> None: + async def _async_state_changed_listener( + self, event: EventType[EventStateChangedData] + ) -> None: """Respond to a member state changing. This method must be run in the event loop. @@ -748,7 +752,7 @@ class Group(Entity): self.async_set_context(event.context) - if (new_state := event.data.get("new_state")) is None: + if (new_state := event.data["new_state"]) is None: # The state was removed from the state machine self._reset_tracked_state() diff --git a/homeassistant/components/group/binary_sensor.py b/homeassistant/components/group/binary_sensor.py index 112b111bdca5..7415ee8c60d3 100644 --- a/homeassistant/components/group/binary_sensor.py +++ b/homeassistant/components/group/binary_sensor.py @@ -21,11 +21,14 @@ from homeassistant.const import ( STATE_UNAVAILABLE, STATE_UNKNOWN, ) -from homeassistant.core import Event, HomeAssistant, callback +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from . import GroupEntity @@ -114,7 +117,9 @@ class BinarySensorGroup(GroupEntity, BinarySensorEntity): """Register callbacks.""" @callback - def async_state_changed_listener(event: Event) -> None: + def async_state_changed_listener( + event: EventType[EventStateChangedData], + ) -> None: """Handle child updates.""" self.async_set_context(event.context) self.async_defer_or_update_ha_state() diff --git a/homeassistant/components/group/cover.py b/homeassistant/components/group/cover.py index 38928302eb11..784ac9a94af2 100644 --- a/homeassistant/components/group/cover.py +++ b/homeassistant/components/group/cover.py @@ -38,11 +38,14 @@ from homeassistant.const import ( STATE_UNAVAILABLE, STATE_UNKNOWN, ) -from homeassistant.core import Event, HomeAssistant, State, callback +from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from . import GroupEntity from .util import attribute_equal, reduce_attribute @@ -126,10 +129,13 @@ class CoverGroup(GroupEntity, CoverEntity): self._attr_unique_id = unique_id @callback - def _update_supported_features_event(self, event: Event) -> None: + def _update_supported_features_event( + self, event: EventType[EventStateChangedData] + ) -> None: self.async_set_context(event.context) - if (entity := event.data.get("entity_id")) is not None: - self.async_update_supported_features(entity, event.data.get("new_state")) + self.async_update_supported_features( + event.data["entity_id"], event.data["new_state"] + ) @callback def async_update_supported_features( diff --git a/homeassistant/components/group/fan.py b/homeassistant/components/group/fan.py index 0c4c59d24545..1fcb859f9269 100644 --- a/homeassistant/components/group/fan.py +++ b/homeassistant/components/group/fan.py @@ -35,11 +35,14 @@ from homeassistant.const import ( STATE_UNAVAILABLE, STATE_UNKNOWN, ) -from homeassistant.core import Event, HomeAssistant, State, callback +from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from . import GroupEntity from .util import ( @@ -142,10 +145,13 @@ class FanGroup(GroupEntity, FanEntity): return self._oscillating @callback - def _update_supported_features_event(self, event: Event) -> None: + def _update_supported_features_event( + self, event: EventType[EventStateChangedData] + ) -> None: self.async_set_context(event.context) - if (entity := event.data.get("entity_id")) is not None: - self.async_update_supported_features(entity, event.data.get("new_state")) + self.async_update_supported_features( + event.data["entity_id"], event.data["new_state"] + ) @callback def async_update_supported_features( diff --git a/homeassistant/components/group/light.py b/homeassistant/components/group/light.py index 33d240a9a4d1..e0f7974631b9 100644 --- a/homeassistant/components/group/light.py +++ b/homeassistant/components/group/light.py @@ -44,11 +44,14 @@ from homeassistant.const import ( STATE_UNAVAILABLE, STATE_UNKNOWN, ) -from homeassistant.core import Event, HomeAssistant, callback +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from . import GroupEntity from .util import find_state_attributes, mean_tuple, reduce_attribute @@ -154,7 +157,9 @@ class LightGroup(GroupEntity, LightEntity): """Register callbacks.""" @callback - def async_state_changed_listener(event: Event) -> None: + def async_state_changed_listener( + event: EventType[EventStateChangedData], + ) -> None: """Handle child updates.""" self.async_set_context(event.context) self.async_defer_or_update_ha_state() diff --git a/homeassistant/components/group/lock.py b/homeassistant/components/group/lock.py index 07d08c7851d5..233d1155c53f 100644 --- a/homeassistant/components/group/lock.py +++ b/homeassistant/components/group/lock.py @@ -28,11 +28,14 @@ from homeassistant.const import ( STATE_UNKNOWN, STATE_UNLOCKING, ) -from homeassistant.core import Event, HomeAssistant, callback +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from . import GroupEntity @@ -115,7 +118,9 @@ class LockGroup(GroupEntity, LockEntity): """Register callbacks.""" @callback - def async_state_changed_listener(event: Event) -> None: + def async_state_changed_listener( + event: EventType[EventStateChangedData], + ) -> None: """Handle child updates.""" self.async_set_context(event.context) self.async_defer_or_update_ha_state() diff --git a/homeassistant/components/group/media_player.py b/homeassistant/components/group/media_player.py index ad375630beae..f0d076ec1302 100644 --- a/homeassistant/components/group/media_player.py +++ b/homeassistant/components/group/media_player.py @@ -44,11 +44,14 @@ from homeassistant.const import ( STATE_UNAVAILABLE, STATE_UNKNOWN, ) -from homeassistant.core import Event, HomeAssistant, State, callback +from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType KEY_ANNOUNCE = "announce" KEY_CLEAR_PLAYLIST = "clear_playlist" @@ -130,11 +133,11 @@ class MediaPlayerGroup(MediaPlayerEntity): } @callback - def async_on_state_change(self, event: Event) -> None: + def async_on_state_change(self, event: EventType[EventStateChangedData]) -> None: """Update supported features and state when a new state is received.""" self.async_set_context(event.context) self.async_update_supported_features( - event.data.get("entity_id"), event.data.get("new_state") # type: ignore[arg-type] + event.data["entity_id"], event.data["new_state"] ) self.async_update_state() diff --git a/homeassistant/components/group/sensor.py b/homeassistant/components/group/sensor.py index 4c6e8dccc1eb..d62447d99478 100644 --- a/homeassistant/components/group/sensor.py +++ b/homeassistant/components/group/sensor.py @@ -33,11 +33,19 @@ from homeassistant.const import ( STATE_UNAVAILABLE, STATE_UNKNOWN, ) -from homeassistant.core import Event, HomeAssistant, State, callback +from homeassistant.core import HomeAssistant, State, callback from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, StateType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ( + ConfigType, + DiscoveryInfoType, + EventType, + StateType, +) from . import GroupEntity from .const import CONF_IGNORE_NON_NUMERIC @@ -299,7 +307,9 @@ class SensorGroup(GroupEntity, SensorEntity): """Register callbacks.""" @callback - def async_state_changed_listener(event: Event) -> None: + def async_state_changed_listener( + event: EventType[EventStateChangedData], + ) -> None: """Handle child updates.""" self.async_set_context(event.context) self.async_defer_or_update_ha_state() diff --git a/homeassistant/components/group/switch.py b/homeassistant/components/group/switch.py index 4b6b959ba17a..f62c805ba1d7 100644 --- a/homeassistant/components/group/switch.py +++ b/homeassistant/components/group/switch.py @@ -19,11 +19,14 @@ from homeassistant.const import ( STATE_UNAVAILABLE, STATE_UNKNOWN, ) -from homeassistant.core import Event, HomeAssistant, callback +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from . import GroupEntity @@ -113,7 +116,9 @@ class SwitchGroup(GroupEntity, SwitchEntity): """Register callbacks.""" @callback - def async_state_changed_listener(event: Event) -> None: + def async_state_changed_listener( + event: EventType[EventStateChangedData], + ) -> None: """Handle child updates.""" self.async_set_context(event.context) self.async_defer_or_update_ha_state() diff --git a/homeassistant/components/history/websocket_api.py b/homeassistant/components/history/websocket_api.py index 93a5d2729652..24ec07b6a878 100644 --- a/homeassistant/components/history/websocket_api.py +++ b/homeassistant/components/history/websocket_api.py @@ -30,10 +30,12 @@ from homeassistant.core import ( valid_entity_id, ) from homeassistant.helpers.event import ( + EventStateChangedData, async_track_point_in_utc_time, async_track_state_change_event, ) from homeassistant.helpers.json import JSON_DUMP +from homeassistant.helpers.typing import EventType import homeassistant.util.dt as dt_util from .const import EVENT_COALESCE_TIME, MAX_PENDING_HISTORY_STATES @@ -373,14 +375,12 @@ def _async_subscribe_events( assert is_callback(target), "target must be a callback" @callback - def _forward_state_events_filtered(event: Event) -> None: + def _forward_state_events_filtered(event: EventType[EventStateChangedData]) -> None: """Filter state events and forward them.""" - if (new_state := event.data.get("new_state")) is None or ( - old_state := event.data.get("old_state") + if (new_state := event.data["new_state"]) is None or ( + old_state := event.data["old_state"] ) is None: return - assert isinstance(new_state, State) - assert isinstance(old_state, State) if ( (significant_changes_only or minimal_response) and new_state.state == old_state.state diff --git a/homeassistant/components/logbook/helpers.py b/homeassistant/components/logbook/helpers.py index 3a1ec971b54e..c2ea98235358 100644 --- a/homeassistant/components/logbook/helpers.py +++ b/homeassistant/components/logbook/helpers.py @@ -23,7 +23,11 @@ from homeassistant.core import ( split_entity_id, ) from homeassistant.helpers import device_registry as dr, entity_registry as er -from homeassistant.helpers.event import async_track_state_change_event +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import EventType from .const import ALWAYS_CONTINUOUS_DOMAINS, AUTOMATION_EVENTS, BUILT_IN_EVENTS, DOMAIN from .models import LogbookConfig @@ -184,11 +188,11 @@ def async_subscribe_events( return @callback - def _forward_state_events_filtered(event: Event) -> None: - if event.data.get("old_state") is None or event.data.get("new_state") is None: + def _forward_state_events_filtered(event: EventType[EventStateChangedData]) -> None: + if (old_state := event.data["old_state"]) is None or ( + new_state := event.data["new_state"] + ) is None: return - new_state: State = event.data["new_state"] - old_state: State = event.data["old_state"] if _is_state_filtered(ent_reg, new_state, old_state) or ( entities_filter and not entities_filter(new_state.entity_id) ): @@ -207,7 +211,7 @@ def async_subscribe_events( subscriptions.append( hass.bus.async_listen( EVENT_STATE_CHANGED, - _forward_state_events_filtered, + _forward_state_events_filtered, # type: ignore[arg-type] run_immediately=True, ) ) diff --git a/homeassistant/components/switch/light.py b/homeassistant/components/switch/light.py index fd2a5afff1c6..ffd345cea3bf 100644 --- a/homeassistant/components/switch/light.py +++ b/homeassistant/components/switch/light.py @@ -15,12 +15,15 @@ from homeassistant.const import ( STATE_ON, STATE_UNAVAILABLE, ) -from homeassistant.core import Event, HomeAssistant, callback +from homeassistant.core import HomeAssistant, callback from homeassistant.helpers import entity_registry as er import homeassistant.helpers.config_validation as cv from homeassistant.helpers.entity_platform import AddEntitiesCallback -from homeassistant.helpers.event import async_track_state_change_event -from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) +from homeassistant.helpers.typing import ConfigType, DiscoveryInfoType, EventType from .const import DOMAIN as SWITCH_DOMAIN @@ -93,7 +96,9 @@ class LightSwitch(LightEntity): """Register callbacks.""" @callback - def async_state_changed_listener(event: Event | None = None) -> None: + def async_state_changed_listener( + event: EventType[EventStateChangedData] | None = None, + ) -> None: """Handle child updates.""" if ( state := self.hass.states.get(self._switch_entity_id) diff --git a/homeassistant/components/zone/trigger.py b/homeassistant/components/zone/trigger.py index 54a2784467df..9412c612ca29 100644 --- a/homeassistant/components/zone/trigger.py +++ b/homeassistant/components/zone/trigger.py @@ -14,10 +14,8 @@ from homeassistant.const import ( ) from homeassistant.core import ( CALLBACK_TYPE, - Event, HassJob, HomeAssistant, - State, callback, ) from homeassistant.helpers import ( @@ -26,9 +24,12 @@ from homeassistant.helpers import ( entity_registry as er, location, ) -from homeassistant.helpers.event import async_track_state_change_event +from homeassistant.helpers.event import ( + EventStateChangedData, + async_track_state_change_event, +) from homeassistant.helpers.trigger import TriggerActionType, TriggerInfo -from homeassistant.helpers.typing import ConfigType +from homeassistant.helpers.typing import ConfigType, EventType EVENT_ENTER = "enter" EVENT_LEAVE = "leave" @@ -78,11 +79,11 @@ async def async_attach_trigger( job = HassJob(action) @callback - def zone_automation_listener(zone_event: Event) -> None: + def zone_automation_listener(zone_event: EventType[EventStateChangedData]) -> None: """Listen for state changes and calls action.""" - entity = zone_event.data.get("entity_id") - from_s: State | None = zone_event.data.get("old_state") - to_s: State | None = zone_event.data.get("new_state") + entity = zone_event.data["entity_id"] + from_s = zone_event.data["old_state"] + to_s = zone_event.data["new_state"] if ( from_s diff --git a/tests/helpers/test_event.py b/tests/helpers/test_event.py index 3740a6b177a2..434957dc1319 100644 --- a/tests/helpers/test_event.py +++ b/tests/helpers/test_event.py @@ -21,6 +21,7 @@ from homeassistant.exceptions import TemplateError from homeassistant.helpers.device_registry import EVENT_DEVICE_REGISTRY_UPDATED from homeassistant.helpers.entity_registry import EVENT_ENTITY_REGISTRY_UPDATED from homeassistant.helpers.event import ( + EventStateChangedData, TrackStates, TrackTemplate, TrackTemplateResult, @@ -45,6 +46,7 @@ from homeassistant.helpers.event import ( track_point_in_utc_time, ) from homeassistant.helpers.template import Template, result_as_boolean +from homeassistant.helpers.typing import EventType from homeassistant.setup import async_setup_component import homeassistant.util.dt as dt_util @@ -434,21 +436,21 @@ async def test_async_track_state_change_event(hass: HomeAssistant) -> None: multiple_entity_id_tracker = [] @ha.callback - def single_run_callback(event): - old_state = event.data.get("old_state") - new_state = event.data.get("new_state") + def single_run_callback(event: EventType[EventStateChangedData]) -> None: + old_state = event.data["old_state"] + new_state = event.data["new_state"] single_entity_id_tracker.append((old_state, new_state)) @ha.callback - def multiple_run_callback(event): - old_state = event.data.get("old_state") - new_state = event.data.get("new_state") + def multiple_run_callback(event: EventType[EventStateChangedData]) -> None: + old_state = event.data["old_state"] + new_state = event.data["new_state"] multiple_entity_id_tracker.append((old_state, new_state)) @ha.callback - def callback_that_throws(event): + def callback_that_throws(event: EventType[EventStateChangedData]) -> None: raise ValueError unsub_single = async_track_state_change_event( @@ -4302,16 +4304,16 @@ async def test_track_state_change_event_chain_multple_entity( tracker_unsub = [] @ha.callback - def chained_single_run_callback(event): - old_state = event.data.get("old_state") - new_state = event.data.get("new_state") + def chained_single_run_callback(event: EventType[EventStateChangedData]) -> None: + old_state = event.data["old_state"] + new_state = event.data["new_state"] chained_tracker_called.append((old_state, new_state)) @ha.callback - def single_run_callback(event): - old_state = event.data.get("old_state") - new_state = event.data.get("new_state") + def single_run_callback(event: EventType[EventStateChangedData]) -> None: + old_state = event.data["old_state"] + new_state = event.data["new_state"] tracker_called.append((old_state, new_state)) @@ -4356,16 +4358,16 @@ async def test_track_state_change_event_chain_single_entity( tracker_unsub = [] @ha.callback - def chained_single_run_callback(event): - old_state = event.data.get("old_state") - new_state = event.data.get("new_state") + def chained_single_run_callback(event: EventType[EventStateChangedData]) -> None: + old_state = event.data["old_state"] + new_state = event.data["new_state"] chained_tracker_called.append((old_state, new_state)) @ha.callback - def single_run_callback(event): - old_state = event.data.get("old_state") - new_state = event.data.get("new_state") + def single_run_callback(event: EventType[EventStateChangedData]) -> None: + old_state = event.data["old_state"] + new_state = event.data["new_state"] tracker_called.append((old_state, new_state))