Add timer support to VoIP (#139763)
parent
7fb949dff7
commit
c51a2317e1
|
@ -3,6 +3,7 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
from datetime import timedelta
|
||||
from enum import IntFlag
|
||||
from functools import partial
|
||||
import io
|
||||
|
@ -16,7 +17,7 @@ import wave
|
|||
from voip_utils import SIP_PORT, RtpDatagramProtocol
|
||||
from voip_utils.sip import SipDatagramProtocol, SipEndpoint, get_sip_endpoint
|
||||
|
||||
from homeassistant.components import tts
|
||||
from homeassistant.components import intent, tts
|
||||
from homeassistant.components.assist_pipeline import PipelineEvent, PipelineEventType
|
||||
from homeassistant.components.assist_satellite import (
|
||||
AssistSatelliteAnnouncement,
|
||||
|
@ -25,6 +26,7 @@ from homeassistant.components.assist_satellite import (
|
|||
AssistSatelliteEntityDescription,
|
||||
AssistSatelliteEntityFeature,
|
||||
)
|
||||
from homeassistant.components.intent import TimerEventType, TimerInfo
|
||||
from homeassistant.components.network import async_get_source_ip
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import Context, HomeAssistant, callback
|
||||
|
@ -161,6 +163,13 @@ class VoipAssistSatellite(VoIPEntity, AssistSatelliteEntity, RtpDatagramProtocol
|
|||
await super().async_added_to_hass()
|
||||
self.voip_device.protocol = self
|
||||
|
||||
assert self.device_entry is not None
|
||||
self.async_on_remove(
|
||||
intent.async_register_timer_handler(
|
||||
self.hass, self.device_entry.id, self.async_handle_timer_event
|
||||
)
|
||||
)
|
||||
|
||||
async def async_will_remove_from_hass(self) -> None:
|
||||
"""Run when entity will be removed from hass."""
|
||||
await super().async_will_remove_from_hass()
|
||||
|
@ -174,6 +183,29 @@ class VoipAssistSatellite(VoIPEntity, AssistSatelliteEntity, RtpDatagramProtocol
|
|||
"""Get the current satellite configuration."""
|
||||
raise NotImplementedError
|
||||
|
||||
@callback
|
||||
def async_handle_timer_event(
|
||||
self,
|
||||
event_type: TimerEventType,
|
||||
timer_info: TimerInfo,
|
||||
) -> None:
|
||||
"""Handle timer event."""
|
||||
if event_type != TimerEventType.FINISHED:
|
||||
return
|
||||
|
||||
if timer_info.name:
|
||||
message = f"{timer_info.name} finished"
|
||||
else:
|
||||
message = f"{timedelta(seconds=timer_info.created_seconds)} timer finished"
|
||||
|
||||
async def announce_message():
|
||||
announcement = await self._resolve_announcement_media_id(message, None)
|
||||
await self.async_announce(announcement)
|
||||
|
||||
self.config_entry.async_create_background_task(
|
||||
self.hass, announce_message(), "voip_announce_timer"
|
||||
)
|
||||
|
||||
async def async_set_configuration(
|
||||
self, config: AssistSatelliteConfiguration
|
||||
) -> None:
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Voice over IP",
|
||||
"codeowners": ["@balloob", "@synesthesiam"],
|
||||
"config_flow": true,
|
||||
"dependencies": ["assist_pipeline", "assist_satellite", "network"],
|
||||
"dependencies": ["assist_pipeline", "assist_satellite", "intent", "network"],
|
||||
"documentation": "https://www.home-assistant.io/integrations/voip",
|
||||
"iot_class": "local_push",
|
||||
"quality_scale": "internal",
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
"""Test the Assist Satellite platform."""
|
||||
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.voip.devices import VoIPDevice
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.helpers import intent as intent_helper
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("intent_args", "message"),
|
||||
[
|
||||
(
|
||||
{},
|
||||
"0:02:00 timer finished",
|
||||
),
|
||||
(
|
||||
{"name": {"value": "pizza"}},
|
||||
"pizza finished",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_timer_events(
|
||||
hass: HomeAssistant, voip_device: VoIPDevice, intent_args: dict, message: str
|
||||
) -> None:
|
||||
"""Test for timer events."""
|
||||
|
||||
await intent_helper.async_handle(
|
||||
hass,
|
||||
"test",
|
||||
intent_helper.INTENT_START_TIMER,
|
||||
{
|
||||
"minutes": {"value": 2},
|
||||
}
|
||||
| intent_args,
|
||||
device_id=voip_device.device_id,
|
||||
)
|
||||
|
||||
with (
|
||||
patch(
|
||||
"homeassistant.components.voip.assist_satellite.VoipAssistSatellite._resolve_announcement_media_id",
|
||||
) as mock_resolve,
|
||||
patch(
|
||||
"homeassistant.components.voip.assist_satellite.VoipAssistSatellite.async_announce",
|
||||
) as mock_announce,
|
||||
):
|
||||
await intent_helper.async_handle(
|
||||
hass,
|
||||
"test",
|
||||
intent_helper.INTENT_DECREASE_TIMER,
|
||||
{
|
||||
"minutes": {"value": 2},
|
||||
},
|
||||
device_id=voip_device.device_id,
|
||||
)
|
||||
await hass.async_block_till_done(wait_background_tasks=True)
|
||||
|
||||
assert len(mock_resolve.mock_calls) == 1
|
||||
assert len(mock_announce.mock_calls) == 1
|
||||
assert mock_resolve.mock_calls[0][1][0] == message
|
Loading…
Reference in New Issue