mirror of
https://github.com/home-assistant/core.git
synced 2025-07-08 22:07:10 +00:00
Ignore Sonos Boost devices during discovery v2 (#53358)
This commit is contained in:
parent
268ade6b76
commit
214920f486
@ -12,7 +12,7 @@ from urllib.parse import urlparse
|
|||||||
from soco import events_asyncio
|
from soco import events_asyncio
|
||||||
import soco.config as soco_config
|
import soco.config as soco_config
|
||||||
from soco.core import SoCo
|
from soco.core import SoCo
|
||||||
from soco.exceptions import SoCoException
|
from soco.exceptions import NotSupportedException, SoCoException
|
||||||
import voluptuous as vol
|
import voluptuous as vol
|
||||||
|
|
||||||
from homeassistant import config_entries
|
from homeassistant import config_entries
|
||||||
@ -87,6 +87,7 @@ class SonosData:
|
|||||||
self.alarms: dict[str, SonosAlarms] = {}
|
self.alarms: dict[str, SonosAlarms] = {}
|
||||||
self.topology_condition = asyncio.Condition()
|
self.topology_condition = asyncio.Condition()
|
||||||
self.hosts_heartbeat = None
|
self.hosts_heartbeat = None
|
||||||
|
self.discovery_ignored: set[str] = set()
|
||||||
self.discovery_known: set[str] = set()
|
self.discovery_known: set[str] = set()
|
||||||
self.boot_counts: dict[str, int] = {}
|
self.boot_counts: dict[str, int] = {}
|
||||||
|
|
||||||
@ -137,21 +138,6 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _create_soco(ip_address: str, source: SoCoCreationSource) -> SoCo | None:
|
|
||||||
"""Create a soco instance and return if successful."""
|
|
||||||
try:
|
|
||||||
soco = SoCo(ip_address)
|
|
||||||
# Ensure that the player is available and UID is cached
|
|
||||||
_ = soco.uid
|
|
||||||
_ = soco.volume
|
|
||||||
return soco
|
|
||||||
except (OSError, SoCoException) as ex:
|
|
||||||
_LOGGER.warning(
|
|
||||||
"Failed to connect to %s player '%s': %s", source.value, ip_address, ex
|
|
||||||
)
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
class SonosDiscoveryManager:
|
class SonosDiscoveryManager:
|
||||||
"""Manage sonos discovery."""
|
"""Manage sonos discovery."""
|
||||||
|
|
||||||
@ -165,6 +151,26 @@ class SonosDiscoveryManager:
|
|||||||
self.hosts = hosts
|
self.hosts = hosts
|
||||||
self.discovery_lock = asyncio.Lock()
|
self.discovery_lock = asyncio.Lock()
|
||||||
|
|
||||||
|
def _create_soco(self, ip_address: str, source: SoCoCreationSource) -> SoCo | None:
|
||||||
|
"""Create a soco instance and return if successful."""
|
||||||
|
if ip_address in self.data.discovery_ignored:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
soco = SoCo(ip_address)
|
||||||
|
# Ensure that the player is available and UID is cached
|
||||||
|
uid = soco.uid
|
||||||
|
_ = soco.volume
|
||||||
|
return soco
|
||||||
|
except NotSupportedException as exc:
|
||||||
|
_LOGGER.debug("Device %s is not supported, ignoring: %s", uid, exc)
|
||||||
|
self.data.discovery_ignored.add(ip_address)
|
||||||
|
except (OSError, SoCoException) as ex:
|
||||||
|
_LOGGER.warning(
|
||||||
|
"Failed to connect to %s player '%s': %s", source.value, ip_address, ex
|
||||||
|
)
|
||||||
|
return None
|
||||||
|
|
||||||
async def _async_stop_event_listener(self, event: Event) -> None:
|
async def _async_stop_event_listener(self, event: Event) -> None:
|
||||||
await asyncio.gather(
|
await asyncio.gather(
|
||||||
*(speaker.async_unsubscribe() for speaker in self.data.discovered.values()),
|
*(speaker.async_unsubscribe() for speaker in self.data.discovered.values()),
|
||||||
@ -213,7 +219,7 @@ class SonosDiscoveryManager:
|
|||||||
if known_uid:
|
if known_uid:
|
||||||
dispatcher_send(self.hass, f"{SONOS_SEEN}-{known_uid}")
|
dispatcher_send(self.hass, f"{SONOS_SEEN}-{known_uid}")
|
||||||
else:
|
else:
|
||||||
soco = _create_soco(ip_addr, SoCoCreationSource.CONFIGURED)
|
soco = self._create_soco(ip_addr, SoCoCreationSource.CONFIGURED)
|
||||||
if soco and soco.is_visible:
|
if soco and soco.is_visible:
|
||||||
self._discovered_player(soco)
|
self._discovered_player(soco)
|
||||||
|
|
||||||
@ -222,7 +228,7 @@ class SonosDiscoveryManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
def _discovered_ip(self, ip_address):
|
def _discovered_ip(self, ip_address):
|
||||||
soco = _create_soco(ip_address, SoCoCreationSource.DISCOVERED)
|
soco = self._create_soco(ip_address, SoCoCreationSource.DISCOVERED)
|
||||||
if soco and soco.is_visible:
|
if soco and soco.is_visible:
|
||||||
self._discovered_player(soco)
|
self._discovered_player(soco)
|
||||||
|
|
||||||
@ -238,7 +244,7 @@ class SonosDiscoveryManager:
|
|||||||
if boot_seqnum and boot_seqnum > self.data.boot_counts[uid]:
|
if boot_seqnum and boot_seqnum > self.data.boot_counts[uid]:
|
||||||
self.data.boot_counts[uid] = boot_seqnum
|
self.data.boot_counts[uid] = boot_seqnum
|
||||||
if soco := await self.hass.async_add_executor_job(
|
if soco := await self.hass.async_add_executor_job(
|
||||||
_create_soco, discovered_ip, SoCoCreationSource.REBOOTED
|
self._create_soco, discovered_ip, SoCoCreationSource.REBOOTED
|
||||||
):
|
):
|
||||||
async_dispatcher_send(self.hass, f"{SONOS_REBOOTED}-{uid}", soco)
|
async_dispatcher_send(self.hass, f"{SONOS_REBOOTED}-{uid}", soco)
|
||||||
else:
|
else:
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
"name": "Sonos",
|
"name": "Sonos",
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
"documentation": "https://www.home-assistant.io/integrations/sonos",
|
"documentation": "https://www.home-assistant.io/integrations/sonos",
|
||||||
"requirements": ["soco==0.23.1"],
|
"requirements": ["soco==0.23.2"],
|
||||||
"dependencies": ["ssdp"],
|
"dependencies": ["ssdp"],
|
||||||
"after_dependencies": ["plex", "zeroconf"],
|
"after_dependencies": ["plex", "zeroconf"],
|
||||||
"zeroconf": ["_sonos._tcp.local."],
|
"zeroconf": ["_sonos._tcp.local."],
|
||||||
|
@ -2148,7 +2148,7 @@ smhi-pkg==1.0.15
|
|||||||
snapcast==2.1.3
|
snapcast==2.1.3
|
||||||
|
|
||||||
# homeassistant.components.sonos
|
# homeassistant.components.sonos
|
||||||
soco==0.23.1
|
soco==0.23.2
|
||||||
|
|
||||||
# homeassistant.components.solaredge_local
|
# homeassistant.components.solaredge_local
|
||||||
solaredge-local==0.2.0
|
solaredge-local==0.2.0
|
||||||
|
@ -1177,7 +1177,7 @@ smarthab==0.21
|
|||||||
smhi-pkg==1.0.15
|
smhi-pkg==1.0.15
|
||||||
|
|
||||||
# homeassistant.components.sonos
|
# homeassistant.components.sonos
|
||||||
soco==0.23.1
|
soco==0.23.2
|
||||||
|
|
||||||
# homeassistant.components.solaredge
|
# homeassistant.components.solaredge
|
||||||
solaredge==0.0.2
|
solaredge==0.0.2
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
"""Tests for the Sonos Media Player platform."""
|
"""Tests for the Sonos Media Player platform."""
|
||||||
|
from unittest.mock import PropertyMock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from soco.exceptions import NotSupportedException
|
||||||
|
|
||||||
from homeassistant.components.sonos import DATA_SONOS, DOMAIN, media_player
|
from homeassistant.components.sonos import DATA_SONOS, DOMAIN, media_player
|
||||||
from homeassistant.const import STATE_IDLE
|
from homeassistant.const import STATE_IDLE
|
||||||
@ -40,6 +43,16 @@ async def test_async_setup_entry_discover(hass, config_entry, discover):
|
|||||||
assert media_player.state == STATE_IDLE
|
assert media_player.state == STATE_IDLE
|
||||||
|
|
||||||
|
|
||||||
|
async def test_discovery_ignore_unsupported_device(hass, config_entry, soco, caplog):
|
||||||
|
"""Test discovery setup."""
|
||||||
|
message = f"GetVolume not supported on {soco.ip_address}"
|
||||||
|
type(soco).volume = PropertyMock(side_effect=NotSupportedException(message))
|
||||||
|
await setup_platform(hass, config_entry, {})
|
||||||
|
|
||||||
|
assert message in caplog.text
|
||||||
|
assert not hass.data[DATA_SONOS].discovered
|
||||||
|
|
||||||
|
|
||||||
async def test_services(hass, config_entry, config, hass_read_only_user):
|
async def test_services(hass, config_entry, config, hass_read_only_user):
|
||||||
"""Test join/unjoin requires control access."""
|
"""Test join/unjoin requires control access."""
|
||||||
await setup_platform(hass, config_entry, config)
|
await setup_platform(hass, config_entry, config)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user