Use EventType for state changed [core] (#97115)

This commit is contained in:
Marc Mueller 2023-07-24 01:10:03 +02:00 committed by GitHub
parent 051929984d
commit 2618bfc073
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 145 additions and 84 deletions

View File

@ -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()

View File

@ -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()

View File

@ -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(

View File

@ -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(

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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

View File

@ -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,
)
)

View File

@ -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)

View File

@ -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

View File

@ -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))