Fix zeroconf with sonos v1 firmware (#59460)

pull/59530/head
J. Nick Koston 2021-11-11 00:31:08 -06:00 committed by GitHub
parent f8f060b72b
commit cab9f821a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 2 deletions

View File

@ -30,7 +30,7 @@ class SonosDiscoveryFlowHandler(DiscoveryFlowHandler):
) -> FlowResult:
"""Handle a flow initialized by zeroconf."""
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")
await self.async_set_unique_id(self._domain, raise_on_progress=False)
host = discovery_info[CONF_HOST]

View File

@ -44,5 +44,10 @@ def soco_error(errorcodes: list[str] | None = None) -> Callable:
def hostname_to_uid(hostname: str) -> str:
"""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}"

View File

@ -75,6 +75,56 @@ async def test_zeroconf_form(hass: core.HomeAssistant):
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):
"""Test we abort on non-sonos devices."""
mock_manager = hass.data[DATA_SONOS_DISCOVERY_MANAGER] = MagicMock()

View File

@ -1,9 +1,15 @@
"""Test the sonos config flow."""
from __future__ import annotations
import pytest
from homeassistant.components.sonos.helpers import hostname_to_uid
async def test_uid_to_hostname():
"""Test we can convert a hostname to a uid."""
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.")