From 6d917f0242f35e487358fda4d2090501056bdc9e Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Mon, 24 Jun 2024 15:21:51 -0500 Subject: [PATCH] Don't run timer callbacks for delayed commands (#120367) * Don't send timer events for delayed commands * Don't run timer callbacks for delayed commands --- homeassistant/components/intent/timers.py | 28 +++++++++++------------ tests/components/intent/test_timers.py | 18 +++++---------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/homeassistant/components/intent/timers.py b/homeassistant/components/intent/timers.py index cddfce55b9f..40b55134e92 100644 --- a/homeassistant/components/intent/timers.py +++ b/homeassistant/components/intent/timers.py @@ -278,7 +278,7 @@ class TimerManager: name=f"Timer {timer_id}", ) - if timer.device_id in self.handlers: + if (not timer.conversation_command) and (timer.device_id in self.handlers): self.handlers[timer.device_id](TimerEventType.STARTED, timer) _LOGGER.debug( "Timer started: id=%s, name=%s, hours=%s, minutes=%s, seconds=%s, device_id=%s", @@ -317,7 +317,7 @@ class TimerManager: timer.cancel() - if timer.device_id in self.handlers: + if (not timer.conversation_command) and (timer.device_id in self.handlers): self.handlers[timer.device_id](TimerEventType.CANCELLED, timer) _LOGGER.debug( "Timer cancelled: id=%s, name=%s, seconds_left=%s, device_id=%s", @@ -346,7 +346,7 @@ class TimerManager: name=f"Timer {timer_id}", ) - if timer.device_id in self.handlers: + if (not timer.conversation_command) and (timer.device_id in self.handlers): self.handlers[timer.device_id](TimerEventType.UPDATED, timer) if seconds > 0: @@ -384,7 +384,7 @@ class TimerManager: task = self.timer_tasks.pop(timer_id) task.cancel() - if timer.device_id in self.handlers: + if (not timer.conversation_command) and (timer.device_id in self.handlers): self.handlers[timer.device_id](TimerEventType.UPDATED, timer) _LOGGER.debug( "Timer paused: id=%s, name=%s, seconds_left=%s, device_id=%s", @@ -410,7 +410,7 @@ class TimerManager: name=f"Timer {timer.id}", ) - if timer.device_id in self.handlers: + if (not timer.conversation_command) and (timer.device_id in self.handlers): self.handlers[timer.device_id](TimerEventType.UPDATED, timer) _LOGGER.debug( "Timer unpaused: id=%s, name=%s, seconds_left=%s, device_id=%s", @@ -426,15 +426,6 @@ class TimerManager: timer.finish() - if timer.device_id in self.handlers: - self.handlers[timer.device_id](TimerEventType.FINISHED, timer) - _LOGGER.debug( - "Timer finished: id=%s, name=%s, device_id=%s", - timer_id, - timer.name, - timer.device_id, - ) - if timer.conversation_command: # pylint: disable-next=import-outside-toplevel from homeassistant.components.conversation import async_converse @@ -451,6 +442,15 @@ class TimerManager: ), "timer assist command", ) + elif timer.device_id in self.handlers: + self.handlers[timer.device_id](TimerEventType.FINISHED, timer) + + _LOGGER.debug( + "Timer finished: id=%s, name=%s, device_id=%s", + timer_id, + timer.name, + timer.device_id, + ) def is_timer_device(self, device_id: str) -> bool: """Return True if device has been registered to handle timer events.""" diff --git a/tests/components/intent/test_timers.py b/tests/components/intent/test_timers.py index a884fd13de5..329db6e8b2b 100644 --- a/tests/components/intent/test_timers.py +++ b/tests/components/intent/test_timers.py @@ -1430,18 +1430,10 @@ async def test_start_timer_with_conversation_command( timer_name = "test timer" test_command = "turn on the lights" agent_id = "test_agent" - finished_event = asyncio.Event() - @callback - def handle_timer(event_type: TimerEventType, timer: TimerInfo) -> None: - if event_type == TimerEventType.FINISHED: - assert timer.conversation_command == test_command - assert timer.conversation_agent_id == agent_id - finished_event.set() + mock_handle_timer = MagicMock() + async_register_timer_handler(hass, device_id, mock_handle_timer) - async_register_timer_handler(hass, device_id, handle_timer) - - # Device id is required if no conversation command timer_manager = TimerManager(hass) with pytest.raises(ValueError): timer_manager.start_timer( @@ -1468,9 +1460,11 @@ async def test_start_timer_with_conversation_command( assert result.response_type == intent.IntentResponseType.ACTION_DONE - async with asyncio.timeout(1): - await finished_event.wait() + # No timer events for delayed commands + mock_handle_timer.assert_not_called() + # Wait for process service call to finish + await hass.async_block_till_done() mock_converse.assert_called_once() assert mock_converse.call_args.args[1] == test_command