parent
7fcf07c964
commit
f18056f0a4
|
@ -8,6 +8,7 @@ import logging
|
|||
|
||||
from voip_utils import SIP_PORT
|
||||
|
||||
from homeassistant.auth.const import GROUP_ID_USER
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import Platform
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
@ -43,6 +44,18 @@ class DomainData:
|
|||
|
||||
async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
||||
"""Set up VoIP integration from a config entry."""
|
||||
# Make sure there is a valid user ID for VoIP in the config entry
|
||||
if (
|
||||
"user" not in entry.data
|
||||
or (await hass.auth.async_get_user(entry.data["user"])) is None
|
||||
):
|
||||
voip_user = await hass.auth.async_create_system_user(
|
||||
"Voice over IP", group_ids=[GROUP_ID_USER]
|
||||
)
|
||||
hass.config_entries.async_update_entry(
|
||||
entry, data={**entry.data, "user": voip_user.id}
|
||||
)
|
||||
|
||||
devices = VoIPDevices(hass, entry)
|
||||
devices.async_setup()
|
||||
transport = await _create_sip_server(
|
||||
|
@ -87,3 +100,11 @@ async def async_remove_config_entry_device(
|
|||
) -> bool:
|
||||
"""Remove device from a config entry."""
|
||||
return True
|
||||
|
||||
|
||||
async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None:
|
||||
"""Remove VoIP entry."""
|
||||
if "user" in entry.data and (
|
||||
user := await hass.auth.async_get_user(entry.data["user"])
|
||||
):
|
||||
await hass.auth.async_remove_user(user)
|
||||
|
|
|
@ -2,16 +2,11 @@
|
|||
"config": {
|
||||
"step": {
|
||||
"user": {
|
||||
"data": {
|
||||
"ip_address": "IP Address"
|
||||
}
|
||||
"description": "Receive Voice over IP calls to interact with Assist."
|
||||
}
|
||||
},
|
||||
"abort": {
|
||||
"single_instance_allowed": "[%key:common::config_flow::abort::single_instance_allowed%]"
|
||||
},
|
||||
"error": {
|
||||
"invalid_ip_address": "Invalid IPv4 address."
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
|
|
|
@ -55,6 +55,7 @@ class HassVoipDatagramProtocol(VoipDatagramProtocol):
|
|||
hass,
|
||||
hass.config.language,
|
||||
devices.async_get_or_create(call_info),
|
||||
Context(user_id=devices.config_entry.data["user"]),
|
||||
),
|
||||
invalid_protocol_factory=lambda call_info: NotConfiguredRtpDatagramProtocol(
|
||||
hass,
|
||||
|
@ -77,6 +78,7 @@ class PipelineRtpDatagramProtocol(RtpDatagramProtocol):
|
|||
hass: HomeAssistant,
|
||||
language: str,
|
||||
voip_device: VoIPDevice,
|
||||
context: Context,
|
||||
pipeline_timeout: float = 30.0,
|
||||
audio_timeout: float = 2.0,
|
||||
listening_tone_enabled: bool = True,
|
||||
|
@ -94,7 +96,7 @@ class PipelineRtpDatagramProtocol(RtpDatagramProtocol):
|
|||
self.listening_tone_enabled = listening_tone_enabled
|
||||
|
||||
self._audio_queue: asyncio.Queue[bytes] = asyncio.Queue()
|
||||
self._context = Context()
|
||||
self._context = context
|
||||
self._conversation_id: str | None = None
|
||||
self._pipeline_task: asyncio.Task | None = None
|
||||
self._session_id: str | None = None
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# serializer version: 1
|
||||
# name: test_user_management
|
||||
list([
|
||||
dict({
|
||||
'id': 'system-users',
|
||||
'name': 'Users',
|
||||
'policy': dict({
|
||||
'entities': True,
|
||||
}),
|
||||
'system_generated': True,
|
||||
}),
|
||||
])
|
||||
# ---
|
|
@ -1,4 +1,6 @@
|
|||
"""Test VoIP init."""
|
||||
from syrupy.assertion import SnapshotAssertion
|
||||
|
||||
from homeassistant.core import HomeAssistant
|
||||
|
||||
|
||||
|
@ -9,3 +11,22 @@ async def test_unload_entry(
|
|||
) -> None:
|
||||
"""Test adding/removing VoIP."""
|
||||
assert await hass.config_entries.async_unload(config_entry.entry_id)
|
||||
|
||||
|
||||
async def test_user_management(
|
||||
hass: HomeAssistant, config_entry, setup_voip, snapshot: SnapshotAssertion
|
||||
) -> None:
|
||||
"""Test creating and removing voip user."""
|
||||
user = await hass.auth.async_get_user(config_entry.data["user"])
|
||||
assert user is not None
|
||||
assert user.is_active
|
||||
assert user.system_generated
|
||||
assert not user.is_admin
|
||||
assert user.name == "Voice over IP"
|
||||
assert user.groups == snapshot
|
||||
assert len(user.credentials) == 0
|
||||
assert len(user.refresh_tokens) == 0
|
||||
|
||||
await hass.config_entries.async_remove(config_entry.entry_id)
|
||||
|
||||
assert await hass.auth.async_get_user(user.id) is None
|
||||
|
|
|
@ -6,7 +6,7 @@ import async_timeout
|
|||
|
||||
from homeassistant.components import assist_pipeline, voip
|
||||
from homeassistant.components.voip.devices import VoIPDevice
|
||||
from homeassistant.core import HomeAssistant
|
||||
from homeassistant.core import Context, HomeAssistant
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
_ONE_SECOND = 16000 * 2 # 16Khz 16-bit
|
||||
|
@ -86,6 +86,7 @@ async def test_pipeline(
|
|||
hass,
|
||||
hass.config.language,
|
||||
voip_device,
|
||||
Context(),
|
||||
listening_tone_enabled=False,
|
||||
)
|
||||
rtp_protocol.transport = Mock()
|
||||
|
@ -133,6 +134,7 @@ async def test_pipeline_timeout(hass: HomeAssistant, voip_device: VoIPDevice) ->
|
|||
hass,
|
||||
hass.config.language,
|
||||
voip_device,
|
||||
Context(),
|
||||
pipeline_timeout=0.001,
|
||||
listening_tone_enabled=False,
|
||||
)
|
||||
|
@ -170,6 +172,7 @@ async def test_stt_stream_timeout(hass: HomeAssistant, voip_device: VoIPDevice)
|
|||
hass,
|
||||
hass.config.language,
|
||||
voip_device,
|
||||
Context(),
|
||||
audio_timeout=0.001,
|
||||
listening_tone_enabled=False,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue