From d007b175c5901adfd3d4c6e2091b48a1d6c13b4a Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Sun, 7 Apr 2024 12:51:59 -1000 Subject: [PATCH] Write timer entity state before firing events (#115151) --- homeassistant/components/timer/__init__.py | 12 ++++++------ tests/components/timer/test_init.py | 17 ++++++++++++----- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/homeassistant/components/timer/__init__.py b/homeassistant/components/timer/__init__.py index 72e93f5655ae46..5da68d99dd61b8 100644 --- a/homeassistant/components/timer/__init__.py +++ b/homeassistant/components/timer/__init__.py @@ -325,12 +325,12 @@ def async_start(self, duration: timedelta | None = None) -> None: self._end = start + self._remaining + self.async_write_ha_state() self.hass.bus.async_fire(event, {ATTR_ENTITY_ID: self.entity_id}) self._listener = async_track_point_in_utc_time( self.hass, self._async_finished, self._end ) - self.async_write_ha_state() @callback def async_change(self, duration: timedelta) -> None: @@ -351,11 +351,11 @@ def async_change(self, duration: timedelta) -> None: self._listener() self._end += duration self._remaining = self._end - dt_util.utcnow().replace(microsecond=0) + self.async_write_ha_state() self.hass.bus.async_fire(EVENT_TIMER_CHANGED, {ATTR_ENTITY_ID: self.entity_id}) self._listener = async_track_point_in_utc_time( self.hass, self._async_finished, self._end ) - self.async_write_ha_state() @callback def async_pause(self) -> None: @@ -368,8 +368,8 @@ def async_pause(self) -> None: self._remaining = self._end - dt_util.utcnow().replace(microsecond=0) self._state = STATUS_PAUSED self._end = None - self.hass.bus.async_fire(EVENT_TIMER_PAUSED, {ATTR_ENTITY_ID: self.entity_id}) self.async_write_ha_state() + self.hass.bus.async_fire(EVENT_TIMER_PAUSED, {ATTR_ENTITY_ID: self.entity_id}) @callback def async_cancel(self) -> None: @@ -381,10 +381,10 @@ def async_cancel(self) -> None: self._end = None self._remaining = None self._running_duration = self._configured_duration + self.async_write_ha_state() self.hass.bus.async_fire( EVENT_TIMER_CANCELLED, {ATTR_ENTITY_ID: self.entity_id} ) - self.async_write_ha_state() @callback def async_finish(self) -> None: @@ -400,11 +400,11 @@ def async_finish(self) -> None: self._end = None self._remaining = None self._running_duration = self._configured_duration + self.async_write_ha_state() self.hass.bus.async_fire( EVENT_TIMER_FINISHED, {ATTR_ENTITY_ID: self.entity_id, ATTR_FINISHED_AT: end.isoformat()}, ) - self.async_write_ha_state() @callback def _async_finished(self, time: datetime) -> None: @@ -418,11 +418,11 @@ def _async_finished(self, time: datetime) -> None: self._end = None self._remaining = None self._running_duration = self._configured_duration + self.async_write_ha_state() self.hass.bus.async_fire( EVENT_TIMER_FINISHED, {ATTR_ENTITY_ID: self.entity_id, ATTR_FINISHED_AT: end.isoformat()}, ) - self.async_write_ha_state() async def async_update_config(self, config: ConfigType) -> None: """Handle when the config is updated.""" diff --git a/tests/components/timer/test_init.py b/tests/components/timer/test_init.py index 5aca1625d1f13a..c1c9f56094bc24 100644 --- a/tests/components/timer/test_init.py +++ b/tests/components/timer/test_init.py @@ -45,7 +45,7 @@ EVENT_STATE_CHANGED, SERVICE_RELOAD, ) -from homeassistant.core import Context, CoreState, HomeAssistant, State +from homeassistant.core import Context, CoreState, Event, HomeAssistant, State, callback from homeassistant.exceptions import HomeAssistantError, Unauthorized from homeassistant.helpers import config_validation as cv, entity_registry as er from homeassistant.helpers.restore_state import StoredState, async_get @@ -156,11 +156,12 @@ async def test_methods_and_events(hass: HomeAssistant) -> None: assert state assert state.state == STATUS_IDLE - results = [] + results: list[tuple[Event, str]] = [] - def fake_event_listener(event): + @callback + def fake_event_listener(event: Event): """Fake event listener for trigger.""" - results.append(event) + results.append((event, hass.states.get("timer.test1").state)) hass.bus.async_listen(EVENT_TIMER_STARTED, fake_event_listener) hass.bus.async_listen(EVENT_TIMER_RESTARTED, fake_event_listener) @@ -262,7 +263,10 @@ def fake_event_listener(event): if step["event"] is not None: expected_events += 1 - assert results[-1].event_type == step["event"] + last_result = results[-1] + event, state = last_result + assert event.event_type == step["event"] + assert state == step["state"] assert len(results) == expected_events @@ -404,6 +408,7 @@ async def test_wait_till_timer_expires(hass: HomeAssistant) -> None: results = [] + @callback def fake_event_listener(event): """Fake event listener for trigger.""" results.append(event) @@ -580,6 +585,7 @@ async def test_timer_restarted_event(hass: HomeAssistant) -> None: results = [] + @callback def fake_event_listener(event): """Fake event listener for trigger.""" results.append(event) @@ -647,6 +653,7 @@ async def test_state_changed_when_timer_restarted(hass: HomeAssistant) -> None: results = [] + @callback def fake_event_listener(event): """Fake event listener for trigger.""" results.append(event)