From d515a7f0634641a6aa4990d86621542f249cf175 Mon Sep 17 00:00:00 2001 From: Michael Hansen Date: Wed, 26 Jun 2024 07:20:11 -0500 Subject: [PATCH] Add created_seconds to timer info and pass to ESPHome devices (#120364) --- .../components/esphome/voice_assistant.py | 2 +- homeassistant/components/intent/timers.py | 17 +++++++++++ .../esphome/test_voice_assistant.py | 29 +++++++++++++++++-- tests/components/intent/test_timers.py | 7 +++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/esphome/voice_assistant.py b/homeassistant/components/esphome/voice_assistant.py index 10358d871ca..a6cedee30ab 100644 --- a/homeassistant/components/esphome/voice_assistant.py +++ b/homeassistant/components/esphome/voice_assistant.py @@ -467,7 +467,7 @@ def handle_timer_event( native_event_type, timer_info.id, timer_info.name, - timer_info.seconds, + timer_info.created_seconds, timer_info.seconds_left, timer_info.is_active, ) diff --git a/homeassistant/components/intent/timers.py b/homeassistant/components/intent/timers.py index 82f6121da53..a8576509a4b 100644 --- a/homeassistant/components/intent/timers.py +++ b/homeassistant/components/intent/timers.py @@ -93,6 +93,13 @@ class TimerInfo: This agent will be used to execute the conversation command. """ + _created_seconds: int = 0 + """Number of seconds on the timer when it was created.""" + + def __post_init__(self) -> None: + """Post initialization.""" + self._created_seconds = self.seconds + @property def seconds_left(self) -> int: """Return number of seconds left on the timer.""" @@ -103,6 +110,15 @@ class TimerInfo: seconds_running = int((now - self.updated_at) / 1e9) return max(0, self.seconds - seconds_running) + @property + def created_seconds(self) -> int: + """Return number of seconds on the timer when it was created. + + This value is increased if time is added to the timer, exceeding its + original created_seconds. + """ + return self._created_seconds + @cached_property def name_normalized(self) -> str: """Return normalized timer name.""" @@ -131,6 +147,7 @@ class TimerInfo: Seconds may be negative to remove time instead. """ self.seconds = max(0, self.seconds_left + seconds) + self._created_seconds = max(self._created_seconds, self.seconds) self.updated_at = time.monotonic_ns() def finish(self) -> None: diff --git a/tests/components/esphome/test_voice_assistant.py b/tests/components/esphome/test_voice_assistant.py index bcd49f91c03..c347c3dc7d3 100644 --- a/tests/components/esphome/test_voice_assistant.py +++ b/tests/components/esphome/test_voice_assistant.py @@ -836,6 +836,7 @@ async def test_timer_events( connections={(dr.CONNECTION_NETWORK_MAC, mock_device.entry.unique_id)} ) + total_seconds = (1 * 60 * 60) + (2 * 60) + 3 await intent_helper.async_handle( hass, "test", @@ -853,8 +854,32 @@ async def test_timer_events( VoiceAssistantTimerEventType.VOICE_ASSISTANT_TIMER_STARTED, ANY, "test timer", - 3723, - 3723, + total_seconds, + total_seconds, + True, + ) + + # Increase timer beyond original time and check total_seconds has increased + mock_client.send_voice_assistant_timer_event.reset_mock() + + total_seconds += 5 * 60 + await intent_helper.async_handle( + hass, + "test", + intent_helper.INTENT_INCREASE_TIMER, + { + "name": {"value": "test timer"}, + "minutes": {"value": 5}, + }, + device_id=dev.id, + ) + + mock_client.send_voice_assistant_timer_event.assert_called_with( + VoiceAssistantTimerEventType.VOICE_ASSISTANT_TIMER_UPDATED, + ANY, + "test timer", + total_seconds, + ANY, True, ) diff --git a/tests/components/intent/test_timers.py b/tests/components/intent/test_timers.py index c2efe5d39e2..d194d532513 100644 --- a/tests/components/intent/test_timers.py +++ b/tests/components/intent/test_timers.py @@ -54,6 +54,7 @@ async def test_start_finish_timer(hass: HomeAssistant, init_components) -> None: assert timer.start_minutes is None assert timer.start_seconds == 0 assert timer.seconds_left == 0 + assert timer.created_seconds == 0 if event_type == TimerEventType.STARTED: timer_id = timer.id @@ -218,6 +219,7 @@ async def test_increase_timer(hass: HomeAssistant, init_components) -> None: timer_name = "test timer" timer_id: str | None = None original_total_seconds = -1 + seconds_added = 0 @callback def handle_timer(event_type: TimerEventType, timer: TimerInfo) -> None: @@ -238,12 +240,14 @@ async def test_increase_timer(hass: HomeAssistant, init_components) -> None: + (60 * timer.start_minutes) + timer.start_seconds ) + assert timer.created_seconds == original_total_seconds started_event.set() elif event_type == TimerEventType.UPDATED: assert timer.id == timer_id # Timer was increased assert timer.seconds_left > original_total_seconds + assert timer.created_seconds == original_total_seconds + seconds_added updated_event.set() elif event_type == TimerEventType.CANCELLED: assert timer.id == timer_id @@ -270,6 +274,7 @@ async def test_increase_timer(hass: HomeAssistant, init_components) -> None: await started_event.wait() # Adding 0 seconds has no effect + seconds_added = 0 result = await intent.async_handle( hass, "test", @@ -288,6 +293,7 @@ async def test_increase_timer(hass: HomeAssistant, init_components) -> None: assert not updated_event.is_set() # Add 30 seconds to the timer + seconds_added = (1 * 60 * 60) + (5 * 60) + 30 result = await intent.async_handle( hass, "test", @@ -357,6 +363,7 @@ async def test_decrease_timer(hass: HomeAssistant, init_components) -> None: # Timer was decreased assert timer.seconds_left <= (original_total_seconds - 30) + assert timer.created_seconds == original_total_seconds updated_event.set() elif event_type == TimerEventType.CANCELLED: