Cleanup regroup handling in Sonos (#53241)
Check event before creating coroutine Remove unnecessary regrouping dispatcher Update typing to reflect actual behavior Add optimizations for polling mode
This commit is contained in:
parent
8c43e5c736
commit
a2fbc4218d
3 changed files with 22 additions and 39 deletions
|
@ -19,11 +19,7 @@ from homeassistant import config_entries
|
|||
from homeassistant.components import ssdp
|
||||
from homeassistant.components.media_player import DOMAIN as MP_DOMAIN
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import (
|
||||
CONF_HOSTS,
|
||||
EVENT_HOMEASSISTANT_START,
|
||||
EVENT_HOMEASSISTANT_STOP,
|
||||
)
|
||||
from homeassistant.const import CONF_HOSTS, EVENT_HOMEASSISTANT_STOP
|
||||
from homeassistant.core import Event, HomeAssistant, callback
|
||||
from homeassistant.helpers import config_validation as cv
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_send, dispatcher_send
|
||||
|
@ -35,7 +31,6 @@ from .const import (
|
|||
DISCOVERY_INTERVAL,
|
||||
DOMAIN,
|
||||
PLATFORMS,
|
||||
SONOS_GROUP_UPDATE,
|
||||
SONOS_REBOOTED,
|
||||
SONOS_SEEN,
|
||||
UPNP_ST,
|
||||
|
@ -226,10 +221,6 @@ class SonosDiscoveryManager:
|
|||
DISCOVERY_INTERVAL.total_seconds(), self._manual_hosts
|
||||
)
|
||||
|
||||
@callback
|
||||
def _async_signal_update_groups(self, _event):
|
||||
async_dispatcher_send(self.hass, SONOS_GROUP_UPDATE)
|
||||
|
||||
def _discovered_ip(self, ip_address):
|
||||
soco = _create_soco(ip_address, SoCoCreationSource.DISCOVERED)
|
||||
if soco and soco.is_visible:
|
||||
|
@ -290,11 +281,6 @@ class SonosDiscoveryManager:
|
|||
for platform in PLATFORMS
|
||||
)
|
||||
)
|
||||
self.entry.async_on_unload(
|
||||
self.hass.bus.async_listen_once(
|
||||
EVENT_HOMEASSISTANT_START, self._async_signal_update_groups
|
||||
)
|
||||
)
|
||||
self.entry.async_on_unload(
|
||||
self.hass.bus.async_listen_once(
|
||||
EVENT_HOMEASSISTANT_STOP, self._async_stop_event_listener
|
||||
|
|
|
@ -140,7 +140,6 @@ SONOS_CREATE_BATTERY = "sonos_create_battery"
|
|||
SONOS_CREATE_MEDIA_PLAYER = "sonos_create_media_player"
|
||||
SONOS_ENTITY_CREATED = "sonos_entity_created"
|
||||
SONOS_POLL_UPDATE = "sonos_poll_update"
|
||||
SONOS_GROUP_UPDATE = "sonos_group_update"
|
||||
SONOS_ALARMS_UPDATED = "sonos_alarms_updated"
|
||||
SONOS_FAVORITES_UPDATED = "sonos_favorites_updated"
|
||||
SONOS_STATE_UPDATED = "sonos_state_updated"
|
||||
|
|
|
@ -46,7 +46,6 @@ from .const import (
|
|||
SONOS_CREATE_BATTERY,
|
||||
SONOS_CREATE_MEDIA_PLAYER,
|
||||
SONOS_ENTITY_CREATED,
|
||||
SONOS_GROUP_UPDATE,
|
||||
SONOS_POLL_UPDATE,
|
||||
SONOS_REBOOTED,
|
||||
SONOS_SEEN,
|
||||
|
@ -206,11 +205,6 @@ class SonosSpeaker:
|
|||
f"{SONOS_ENTITY_CREATED}-{self.soco.uid}",
|
||||
self.async_handle_new_entity,
|
||||
)
|
||||
self._group_dispatcher = dispatcher_connect(
|
||||
self.hass,
|
||||
SONOS_GROUP_UPDATE,
|
||||
self.async_update_groups,
|
||||
)
|
||||
self._seen_dispatcher = dispatcher_connect(
|
||||
self.hass, f"{SONOS_SEEN}-{self.soco.uid}", self.async_seen
|
||||
)
|
||||
|
@ -612,22 +606,18 @@ class SonosSpeaker:
|
|||
#
|
||||
# Group management
|
||||
#
|
||||
def update_groups(self, event: SonosEvent | None = None) -> None:
|
||||
"""Handle callback for topology change event."""
|
||||
coro = self.create_update_groups_coro(event)
|
||||
if coro:
|
||||
self.hass.add_job(coro) # type: ignore
|
||||
def update_groups(self) -> None:
|
||||
"""Update group topology when polling."""
|
||||
self.hass.add_job(self.create_update_groups_coro())
|
||||
|
||||
@callback
|
||||
def async_update_groups(self, event: SonosEvent | None = None) -> None:
|
||||
def async_update_groups(self, event: SonosEvent) -> None:
|
||||
"""Handle callback for topology change event."""
|
||||
coro = self.create_update_groups_coro(event)
|
||||
if coro:
|
||||
self.hass.async_add_job(coro) # type: ignore
|
||||
if not hasattr(event, "zone_player_uui_ds_in_group"):
|
||||
return None
|
||||
self.hass.async_add_job(self.create_update_groups_coro(event))
|
||||
|
||||
def create_update_groups_coro(
|
||||
self, event: SonosEvent | None = None
|
||||
) -> Coroutine | None:
|
||||
def create_update_groups_coro(self, event: SonosEvent | None = None) -> Coroutine:
|
||||
"""Handle callback for topology change event."""
|
||||
|
||||
def _get_soco_group() -> list[str]:
|
||||
|
@ -646,7 +636,7 @@ class SonosSpeaker:
|
|||
|
||||
return [coordinator_uid] + slave_uids
|
||||
|
||||
async def _async_extract_group(event: SonosEvent) -> list[str]:
|
||||
async def _async_extract_group(event: SonosEvent | None) -> list[str]:
|
||||
"""Extract group layout from a topology event."""
|
||||
group = event and event.zone_player_uui_ds_in_group
|
||||
if group:
|
||||
|
@ -658,6 +648,10 @@ class SonosSpeaker:
|
|||
@callback
|
||||
def _async_regroup(group: list[str]) -> None:
|
||||
"""Rebuild internal group layout."""
|
||||
if group == [self.soco.uid] and self.sonos_group == [self]:
|
||||
# Skip updating existing single speakers in polling mode
|
||||
return
|
||||
|
||||
entity_registry = ent_reg.async_get(self.hass)
|
||||
sonos_group = []
|
||||
sonos_group_entities = []
|
||||
|
@ -671,6 +665,11 @@ class SonosSpeaker:
|
|||
)
|
||||
sonos_group_entities.append(entity_id)
|
||||
|
||||
if self.sonos_group_entities == sonos_group_entities:
|
||||
# Useful in polling mode for speakers with stereo pairs or surrounds
|
||||
# as those "invisible" speakers will bypass the single speaker check
|
||||
return
|
||||
|
||||
self.coordinator = None
|
||||
self.sonos_group = sonos_group
|
||||
self.sonos_group_entities = sonos_group_entities
|
||||
|
@ -684,7 +683,9 @@ class SonosSpeaker:
|
|||
slave.sonos_group_entities = sonos_group_entities
|
||||
slave.async_write_entity_states()
|
||||
|
||||
async def _async_handle_group_event(event: SonosEvent) -> None:
|
||||
_LOGGER.debug("Regrouped %s: %s", self.zone_name, self.sonos_group_entities)
|
||||
|
||||
async def _async_handle_group_event(event: SonosEvent | None) -> None:
|
||||
"""Get async lock and handle event."""
|
||||
|
||||
async with self.hass.data[DATA_SONOS].topology_condition:
|
||||
|
@ -695,9 +696,6 @@ class SonosSpeaker:
|
|||
|
||||
self.hass.data[DATA_SONOS].topology_condition.notify_all()
|
||||
|
||||
if event and not hasattr(event, "zone_player_uui_ds_in_group"):
|
||||
return None
|
||||
|
||||
return _async_handle_group_event(event)
|
||||
|
||||
@soco_error()
|
||||
|
|
Loading…
Add table
Reference in a new issue