mirror of
https://github.com/home-assistant/core.git
synced 2025-07-25 14:17:45 +00:00
Fix sonos overloading the executor when there are many devices (#112482)
This commit is contained in:
parent
7096701cab
commit
0f3838e7a8
@ -8,7 +8,7 @@ import datetime
|
|||||||
from functools import partial
|
from functools import partial
|
||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
from typing import Any, cast
|
from typing import TYPE_CHECKING, Any, cast
|
||||||
|
|
||||||
import defusedxml.ElementTree as ET
|
import defusedxml.ElementTree as ET
|
||||||
from soco.core import SoCo
|
from soco.core import SoCo
|
||||||
@ -64,6 +64,9 @@ from .helpers import soco_error
|
|||||||
from .media import SonosMedia
|
from .media import SonosMedia
|
||||||
from .statistics import ActivityStatistics, EventStatistics
|
from .statistics import ActivityStatistics, EventStatistics
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from . import SonosData
|
||||||
|
|
||||||
NEVER_TIME = -1200.0
|
NEVER_TIME = -1200.0
|
||||||
RESUB_COOLDOWN_SECONDS = 10.0
|
RESUB_COOLDOWN_SECONDS = 10.0
|
||||||
EVENT_CHARGING = {
|
EVENT_CHARGING = {
|
||||||
@ -97,6 +100,7 @@ class SonosSpeaker:
|
|||||||
) -> None:
|
) -> None:
|
||||||
"""Initialize a SonosSpeaker."""
|
"""Initialize a SonosSpeaker."""
|
||||||
self.hass = hass
|
self.hass = hass
|
||||||
|
self.data: SonosData = hass.data[DATA_SONOS]
|
||||||
self.soco = soco
|
self.soco = soco
|
||||||
self.websocket: SonosWebsocket | None = None
|
self.websocket: SonosWebsocket | None = None
|
||||||
self.household_id: str = soco.household_id
|
self.household_id: str = soco.household_id
|
||||||
@ -183,7 +187,7 @@ class SonosSpeaker:
|
|||||||
)
|
)
|
||||||
dispatch_pairs: tuple[tuple[str, Callable[..., Any]], ...] = (
|
dispatch_pairs: tuple[tuple[str, Callable[..., Any]], ...] = (
|
||||||
(SONOS_CHECK_ACTIVITY, self.async_check_activity),
|
(SONOS_CHECK_ACTIVITY, self.async_check_activity),
|
||||||
(SONOS_SPEAKER_ADDED, self.update_group_for_uid),
|
(SONOS_SPEAKER_ADDED, self.async_update_group_for_uid),
|
||||||
(f"{SONOS_REBOOTED}-{self.soco.uid}", self.async_rebooted),
|
(f"{SONOS_REBOOTED}-{self.soco.uid}", self.async_rebooted),
|
||||||
(f"{SONOS_SPEAKER_ACTIVITY}-{self.soco.uid}", self.speaker_activity),
|
(f"{SONOS_SPEAKER_ACTIVITY}-{self.soco.uid}", self.speaker_activity),
|
||||||
(f"{SONOS_VANISHED}-{self.soco.uid}", self.async_vanished),
|
(f"{SONOS_VANISHED}-{self.soco.uid}", self.async_vanished),
|
||||||
@ -272,12 +276,12 @@ class SonosSpeaker:
|
|||||||
@property
|
@property
|
||||||
def alarms(self) -> SonosAlarms:
|
def alarms(self) -> SonosAlarms:
|
||||||
"""Return the SonosAlarms instance for this household."""
|
"""Return the SonosAlarms instance for this household."""
|
||||||
return self.hass.data[DATA_SONOS].alarms[self.household_id]
|
return self.data.alarms[self.household_id]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def favorites(self) -> SonosFavorites:
|
def favorites(self) -> SonosFavorites:
|
||||||
"""Return the SonosFavorites instance for this household."""
|
"""Return the SonosFavorites instance for this household."""
|
||||||
return self.hass.data[DATA_SONOS].favorites[self.household_id]
|
return self.data.favorites[self.household_id]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_coordinator(self) -> bool:
|
def is_coordinator(self) -> bool:
|
||||||
@ -496,9 +500,7 @@ class SonosSpeaker:
|
|||||||
"x-rincon:"
|
"x-rincon:"
|
||||||
):
|
):
|
||||||
new_coordinator_uid = av_transport_uri.split(":")[-1]
|
new_coordinator_uid = av_transport_uri.split(":")[-1]
|
||||||
if new_coordinator_speaker := self.hass.data[DATA_SONOS].discovered.get(
|
if new_coordinator_speaker := self.data.discovered.get(new_coordinator_uid):
|
||||||
new_coordinator_uid
|
|
||||||
):
|
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"Media update coordinator (%s) received for %s",
|
"Media update coordinator (%s) received for %s",
|
||||||
new_coordinator_speaker.zone_name,
|
new_coordinator_speaker.zone_name,
|
||||||
@ -657,7 +659,7 @@ class SonosSpeaker:
|
|||||||
|
|
||||||
await self.async_unsubscribe()
|
await self.async_unsubscribe()
|
||||||
|
|
||||||
self.hass.data[DATA_SONOS].discovery_known.discard(self.soco.uid)
|
self.data.discovery_known.discard(self.soco.uid)
|
||||||
|
|
||||||
async def async_vanished(self, reason: str) -> None:
|
async def async_vanished(self, reason: str) -> None:
|
||||||
"""Handle removal of speaker when marked as vanished."""
|
"""Handle removal of speaker when marked as vanished."""
|
||||||
@ -784,15 +786,16 @@ class SonosSpeaker:
|
|||||||
"""Update group topology when polling."""
|
"""Update group topology when polling."""
|
||||||
self.hass.add_job(self.create_update_groups_coro())
|
self.hass.add_job(self.create_update_groups_coro())
|
||||||
|
|
||||||
def update_group_for_uid(self, uid: str) -> None:
|
@callback
|
||||||
|
def async_update_group_for_uid(self, uid: str) -> None:
|
||||||
"""Update group topology if uid is missing."""
|
"""Update group topology if uid is missing."""
|
||||||
if uid not in self._group_members_missing:
|
if uid not in self._group_members_missing:
|
||||||
return
|
return
|
||||||
missing_zone = self.hass.data[DATA_SONOS].discovered[uid].zone_name
|
missing_zone = self.data.discovered[uid].zone_name
|
||||||
_LOGGER.debug(
|
_LOGGER.debug(
|
||||||
"%s was missing, adding to %s group", missing_zone, self.zone_name
|
"%s was missing, adding to %s group", missing_zone, self.zone_name
|
||||||
)
|
)
|
||||||
self.update_groups()
|
self.hass.async_create_task(self.create_update_groups_coro(), eager_start=True)
|
||||||
|
|
||||||
@callback
|
@callback
|
||||||
def async_update_groups(self, event: SonosEvent) -> None:
|
def async_update_groups(self, event: SonosEvent) -> None:
|
||||||
@ -866,7 +869,7 @@ class SonosSpeaker:
|
|||||||
sonos_group_entities = []
|
sonos_group_entities = []
|
||||||
|
|
||||||
for uid in group:
|
for uid in group:
|
||||||
speaker = self.hass.data[DATA_SONOS].discovered.get(uid)
|
speaker = self.data.discovered.get(uid)
|
||||||
if speaker:
|
if speaker:
|
||||||
self._group_members_missing.discard(uid)
|
self._group_members_missing.discard(uid)
|
||||||
sonos_group.append(speaker)
|
sonos_group.append(speaker)
|
||||||
@ -894,10 +897,7 @@ class SonosSpeaker:
|
|||||||
self.async_write_entity_states()
|
self.async_write_entity_states()
|
||||||
|
|
||||||
for joined_uid in group[1:]:
|
for joined_uid in group[1:]:
|
||||||
joined_speaker: SonosSpeaker = self.hass.data[
|
if joined_speaker := self.data.discovered.get(joined_uid):
|
||||||
DATA_SONOS
|
|
||||||
].discovered.get(joined_uid)
|
|
||||||
if joined_speaker:
|
|
||||||
joined_speaker.coordinator = self
|
joined_speaker.coordinator = self
|
||||||
joined_speaker.sonos_group = sonos_group
|
joined_speaker.sonos_group = sonos_group
|
||||||
joined_speaker.sonos_group_entities = sonos_group_entities
|
joined_speaker.sonos_group_entities = sonos_group_entities
|
||||||
@ -908,13 +908,13 @@ class SonosSpeaker:
|
|||||||
async def _async_handle_group_event(event: SonosEvent | None) -> None:
|
async def _async_handle_group_event(event: SonosEvent | None) -> None:
|
||||||
"""Get async lock and handle event."""
|
"""Get async lock and handle event."""
|
||||||
|
|
||||||
async with self.hass.data[DATA_SONOS].topology_condition:
|
async with self.data.topology_condition:
|
||||||
group = await _async_extract_group(event)
|
group = await _async_extract_group(event)
|
||||||
|
|
||||||
if self.soco.uid == group[0]:
|
if self.soco.uid == group[0]:
|
||||||
_async_regroup(group)
|
_async_regroup(group)
|
||||||
|
|
||||||
self.hass.data[DATA_SONOS].topology_condition.notify_all()
|
self.data.topology_condition.notify_all()
|
||||||
|
|
||||||
return _async_handle_group_event(event)
|
return _async_handle_group_event(event)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user