Allow specifying SIP username for outgoing calls (#137059)

* Allow specifying SIP username for outgoing calls

Allow configuring a SIP username to be sent in outgoing call requests to
identify the home assistant source endpoint.

* Remove advanced options section

* Add test for removing user

* Allow unsetting SIP user

Make previous SIP user value a suggested value rather than default to
allow unsetting by submitting an empty value in the form.

* Remove unnecessary checks

Remove user check from main flow and remove none or empty check.
This commit is contained in:
Jamin 2025-02-10 18:24:59 -06:00 committed by GitHub
parent ba583cc669
commit 97a8f24f8e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 62 additions and 6 deletions

View File

@ -30,7 +30,15 @@ from homeassistant.config_entries import ConfigEntry
from homeassistant.core import Context, HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from .const import CHANNELS, CONF_SIP_PORT, DOMAIN, RATE, RTP_AUDIO_SETTINGS, WIDTH
from .const import (
CHANNELS,
CONF_SIP_PORT,
CONF_SIP_USER,
DOMAIN,
RATE,
RTP_AUDIO_SETTINGS,
WIDTH,
)
from .devices import VoIPDevice
from .entity import VoIPEntity
@ -199,7 +207,10 @@ class VoipAssistSatellite(VoIPEntity, AssistSatelliteEntity, RtpDatagramProtocol
# HA SIP server
source_ip = await async_get_source_ip(self.hass)
sip_port = self.config_entry.options.get(CONF_SIP_PORT, SIP_PORT)
source_endpoint = get_sip_endpoint(host=source_ip, port=sip_port)
sip_user = self.config_entry.options.get(CONF_SIP_USER)
source_endpoint = get_sip_endpoint(
host=source_ip, port=sip_port, username=sip_user
)
try:
# VoIP ID is SIP header

View File

@ -16,7 +16,7 @@ from homeassistant.config_entries import (
from homeassistant.core import callback
from homeassistant.helpers import config_validation as cv
from .const import CONF_SIP_PORT, DOMAIN
from .const import CONF_SIP_PORT, CONF_SIP_USER, DOMAIN
class VoIPConfigFlow(ConfigFlow, domain=DOMAIN):
@ -58,7 +58,15 @@ class VoipOptionsFlowHandler(OptionsFlow):
) -> ConfigFlowResult:
"""Manage the options."""
if user_input is not None:
return self.async_create_entry(title="", data=user_input)
if CONF_SIP_USER in user_input and not user_input[CONF_SIP_USER]:
del user_input[CONF_SIP_USER]
self.hass.config_entries.async_update_entry(
self.config_entry, options=user_input
)
return self.async_create_entry(
title="",
data=user_input,
)
return self.async_show_form(
step_id="init",
@ -70,7 +78,15 @@ class VoipOptionsFlowHandler(OptionsFlow):
CONF_SIP_PORT,
SIP_PORT,
),
): cv.port
): cv.port,
vol.Optional(
CONF_SIP_USER,
description={
"suggested_value": self.config_entry.options.get(
CONF_SIP_USER, None
)
},
): vol.Any(None, cv.string),
}
),
)

View File

@ -13,3 +13,4 @@ RTP_AUDIO_SETTINGS = {
}
CONF_SIP_PORT = "sip_port"
CONF_SIP_USER = "sip_user"

View File

@ -53,7 +53,8 @@
"step": {
"init": {
"data": {
"sip_port": "SIP port"
"sip_port": "SIP port",
"sip_user": "SIP user"
}
}
}

View File

@ -80,3 +80,30 @@ async def test_options_flow(hass: HomeAssistant) -> None:
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert config_entry.options == {"sip_port": 5061}
# Manual with user
result = await hass.config_entries.options.async_init(
config_entry.entry_id,
)
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={"sip_port": 5061, "sip_user": "HA"},
)
assert result["type"] is FlowResultType.CREATE_ENTRY
assert config_entry.options == {"sip_port": 5061, "sip_user": "HA"}
# Manual remove user
result = await hass.config_entries.options.async_init(
config_entry.entry_id,
)
assert config_entry.options == {"sip_port": 5061, "sip_user": "HA"}
result = await hass.config_entries.options.async_configure(
result["flow_id"],
user_input={"sip_port": 5060, "sip_user": ""},
)
await hass.async_block_till_done()
assert result["type"] is FlowResultType.CREATE_ENTRY
assert config_entry.options == {"sip_port": 5060}