Simplify EVENT_STATE_REPORTED (#120508)

pull/120541/head
Erik Montnemery 2024-06-26 11:23:26 +02:00 committed by GitHub
parent 2c48843739
commit d589eaf440
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 23 additions and 27 deletions

View File

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

View File

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

View File

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