Fix zeroconf with sonos v1 firmware (#59460)
This commit is contained in:
parent
f8f060b72b
commit
cab9f821a1
4 changed files with 63 additions and 2 deletions
|
@ -30,7 +30,7 @@ class SonosDiscoveryFlowHandler(DiscoveryFlowHandler):
|
||||||
) -> FlowResult:
|
) -> FlowResult:
|
||||||
"""Handle a flow initialized by zeroconf."""
|
"""Handle a flow initialized by zeroconf."""
|
||||||
hostname = discovery_info["hostname"]
|
hostname = discovery_info["hostname"]
|
||||||
if hostname is None or not hostname.startswith("Sonos-"):
|
if hostname is None or not hostname.lower().startswith("sonos"):
|
||||||
return self.async_abort(reason="not_sonos_device")
|
return self.async_abort(reason="not_sonos_device")
|
||||||
await self.async_set_unique_id(self._domain, raise_on_progress=False)
|
await self.async_set_unique_id(self._domain, raise_on_progress=False)
|
||||||
host = discovery_info[CONF_HOST]
|
host = discovery_info[CONF_HOST]
|
||||||
|
|
|
@ -44,5 +44,10 @@ def soco_error(errorcodes: list[str] | None = None) -> Callable:
|
||||||
|
|
||||||
def hostname_to_uid(hostname: str) -> str:
|
def hostname_to_uid(hostname: str) -> str:
|
||||||
"""Convert a Sonos hostname to a uid."""
|
"""Convert a Sonos hostname to a uid."""
|
||||||
baseuid = hostname.split("-")[1].replace(".local.", "")
|
if hostname.startswith("Sonos-"):
|
||||||
|
baseuid = hostname.split("-")[1].replace(".local.", "")
|
||||||
|
elif hostname.startswith("sonos"):
|
||||||
|
baseuid = hostname[5:].replace(".local.", "")
|
||||||
|
else:
|
||||||
|
raise ValueError(f"{hostname} is not a sonos device.")
|
||||||
return f"{UID_PREFIX}{baseuid}{UID_POSTFIX}"
|
return f"{UID_PREFIX}{baseuid}{UID_POSTFIX}"
|
||||||
|
|
|
@ -75,6 +75,56 @@ async def test_zeroconf_form(hass: core.HomeAssistant):
|
||||||
assert len(mock_manager.mock_calls) == 2
|
assert len(mock_manager.mock_calls) == 2
|
||||||
|
|
||||||
|
|
||||||
|
async def test_zeroconf_sonos_v1(hass: core.HomeAssistant):
|
||||||
|
"""Test we pass sonos devices to the discovery manager with v1 firmware devices."""
|
||||||
|
|
||||||
|
mock_manager = hass.data[DATA_SONOS_DISCOVERY_MANAGER] = MagicMock()
|
||||||
|
result = await hass.config_entries.flow.async_init(
|
||||||
|
DOMAIN,
|
||||||
|
context={"source": config_entries.SOURCE_ZEROCONF},
|
||||||
|
data={
|
||||||
|
"host": "192.168.1.107",
|
||||||
|
"port": 1443,
|
||||||
|
"hostname": "sonos5CAAFDE47AC8.local.",
|
||||||
|
"type": "_sonos._tcp.local.",
|
||||||
|
"name": "Sonos-5CAAFDE47AC8._sonos._tcp.local.",
|
||||||
|
"properties": {
|
||||||
|
"_raw": {
|
||||||
|
"info": b"/api/v1/players/RINCON_5CAAFDE47AC801400/info",
|
||||||
|
"vers": b"1",
|
||||||
|
"protovers": b"1.18.9",
|
||||||
|
},
|
||||||
|
"info": "/api/v1/players/RINCON_5CAAFDE47AC801400/info",
|
||||||
|
"vers": "1",
|
||||||
|
"protovers": "1.18.9",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert result["type"] == "form"
|
||||||
|
assert result["errors"] is None
|
||||||
|
|
||||||
|
with patch(
|
||||||
|
"homeassistant.components.sonos.async_setup",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup, patch(
|
||||||
|
"homeassistant.components.sonos.async_setup_entry",
|
||||||
|
return_value=True,
|
||||||
|
) as mock_setup_entry:
|
||||||
|
result2 = await hass.config_entries.flow.async_configure(
|
||||||
|
result["flow_id"],
|
||||||
|
{},
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
assert result2["type"] == "create_entry"
|
||||||
|
assert result2["title"] == "Sonos"
|
||||||
|
assert result2["data"] == {}
|
||||||
|
|
||||||
|
assert len(mock_setup.mock_calls) == 1
|
||||||
|
assert len(mock_setup_entry.mock_calls) == 1
|
||||||
|
assert len(mock_manager.mock_calls) == 2
|
||||||
|
|
||||||
|
|
||||||
async def test_zeroconf_form_not_sonos(hass: core.HomeAssistant):
|
async def test_zeroconf_form_not_sonos(hass: core.HomeAssistant):
|
||||||
"""Test we abort on non-sonos devices."""
|
"""Test we abort on non-sonos devices."""
|
||||||
mock_manager = hass.data[DATA_SONOS_DISCOVERY_MANAGER] = MagicMock()
|
mock_manager = hass.data[DATA_SONOS_DISCOVERY_MANAGER] = MagicMock()
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
"""Test the sonos config flow."""
|
"""Test the sonos config flow."""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
from homeassistant.components.sonos.helpers import hostname_to_uid
|
from homeassistant.components.sonos.helpers import hostname_to_uid
|
||||||
|
|
||||||
|
|
||||||
async def test_uid_to_hostname():
|
async def test_uid_to_hostname():
|
||||||
"""Test we can convert a hostname to a uid."""
|
"""Test we can convert a hostname to a uid."""
|
||||||
assert hostname_to_uid("Sonos-347E5C0CF1E3.local.") == "RINCON_347E5C0CF1E301400"
|
assert hostname_to_uid("Sonos-347E5C0CF1E3.local.") == "RINCON_347E5C0CF1E301400"
|
||||||
|
assert hostname_to_uid("sonos5CAAFDE47AC8.local.") == "RINCON_5CAAFDE47AC801400"
|
||||||
|
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
assert hostname_to_uid("notsonos5CAAFDE47AC8.local.")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue