From d589eaf440f614024db2f05110145c0e30a6ffbc Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 26 Jun 2024 11:23:26 +0200 Subject: [PATCH] Simplify EVENT_STATE_REPORTED (#120508) --- homeassistant/const.py | 4 ++-- homeassistant/core.py | 38 +++++++++++++++++--------------------- tests/test_core.py | 8 ++++---- 3 files changed, 23 insertions(+), 27 deletions(-) diff --git a/homeassistant/const.py b/homeassistant/const.py index 577e8df6f39..3a970aefd38 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -18,7 +18,7 @@ from .util.hass_dict import HassKey from .util.signal_type import SignalType if TYPE_CHECKING: - from .core import EventStateChangedData + from .core import EventStateChangedData, EventStateReportedData from .helpers.typing import NoEventData APPLICATION_NAME: Final = "HomeAssistant" @@ -321,7 +321,7 @@ EVENT_LOGGING_CHANGED: Final = "logging_changed" EVENT_SERVICE_REGISTERED: Final = "service_registered" EVENT_SERVICE_REMOVED: Final = "service_removed" EVENT_STATE_CHANGED: EventType[EventStateChangedData] = EventType("state_changed") -EVENT_STATE_REPORTED: Final = "state_reported" +EVENT_STATE_REPORTED: EventType[EventStateReportedData] = EventType("state_reported") EVENT_THEMES_UPDATED: Final = "themes_updated" EVENT_PANELS_UPDATED: Final = "panels_updated" EVENT_LOVELACE_UPDATED: Final = "lovelace_updated" diff --git a/homeassistant/core.py b/homeassistant/core.py index f114049b2b2..2b43b2d40ff 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -159,13 +159,27 @@ class ConfigSource(enum.StrEnum): class EventStateChangedData(TypedDict): - """EventStateChanged data.""" + """EVENT_STATE_CHANGED data. + + A state changed event is fired when on state write when the state is changed. + """ entity_id: str old_state: State | None new_state: State | None +class EventStateReportedData(TypedDict): + """EVENT_STATE_REPORTED data. + + A state reported event is fired when on state write when the state is unchanged. + """ + + entity_id: str + old_last_reported: datetime.datetime + new_state: State | None + + # SOURCE_* are deprecated as of Home Assistant 2022.2, use ConfigSource instead _DEPRECATED_SOURCE_DISCOVERED = DeprecatedConstantEnum( ConfigSource.DISCOVERED, "2025.1" @@ -1604,27 +1618,8 @@ class EventBus: raise HomeAssistantError( f"Event filter is required for event {event_type}" ) - # Special case for EVENT_STATE_REPORTED, we also want to listen to - # EVENT_STATE_CHANGED - self._listeners[EVENT_STATE_REPORTED].append(filterable_job) - self._listeners[EVENT_STATE_CHANGED].append(filterable_job) - return functools.partial( - self._async_remove_multiple_listeners, - (EVENT_STATE_REPORTED, EVENT_STATE_CHANGED), - filterable_job, - ) return self._async_listen_filterable_job(event_type, filterable_job) - @callback - def _async_remove_multiple_listeners( - self, - keys: Iterable[EventType[_DataT] | str], - filterable_job: _FilterableJobType[Any], - ) -> None: - """Remove multiple listeners for specific event_types.""" - for key in keys: - self._async_remove_listener(key, filterable_job) - @callback def _async_listen_filterable_job( self, @@ -2278,7 +2273,8 @@ class StateMachine: old_last_reported = old_state.last_reported # type: ignore[union-attr] old_state.last_reported = now # type: ignore[union-attr] old_state.last_reported_timestamp = timestamp # type: ignore[union-attr] - self._bus.async_fire_internal( + # Avoid creating an EventStateReportedData + self._bus.async_fire_internal( # type: ignore[misc] EVENT_STATE_REPORTED, { "entity_id": entity_id, diff --git a/tests/test_core.py b/tests/test_core.py index a1748638342..5e6b51cc39e 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -3385,24 +3385,24 @@ async def test_statemachine_report_state(hass: HomeAssistant) -> None: hass.states.async_set("light.bowl", "on", None, True) await hass.async_block_till_done() assert len(state_changed_events) == 1 - assert len(state_reported_events) == 2 + assert len(state_reported_events) == 1 hass.states.async_set("light.bowl", "off") await hass.async_block_till_done() assert len(state_changed_events) == 2 - assert len(state_reported_events) == 3 + assert len(state_reported_events) == 1 hass.states.async_remove("light.bowl") await hass.async_block_till_done() assert len(state_changed_events) == 3 - assert len(state_reported_events) == 4 + assert len(state_reported_events) == 1 unsub() hass.states.async_set("light.bowl", "on") await hass.async_block_till_done() assert len(state_changed_events) == 4 - assert len(state_reported_events) == 4 + assert len(state_reported_events) == 1 async def test_report_state_listener_restrictions(hass: HomeAssistant) -> None: