mirror of
https://github.com/home-assistant/core.git
synced 2025-04-24 09:17:53 +00:00
Fix Sonos races related to grouping and startup (#71026)
This commit is contained in:
parent
7e8c6d563f
commit
1f1932d224
@ -258,6 +258,15 @@ class SonosMediaPlayerEntity(SonosEntity, MediaPlayerEntity):
|
||||
if self.coordinator.uid == uid:
|
||||
self.async_write_ha_state()
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return if the media_player is available."""
|
||||
return (
|
||||
self.speaker.available
|
||||
and self.speaker.sonos_group_entities
|
||||
and self.media.playback_status
|
||||
)
|
||||
|
||||
@property
|
||||
def coordinator(self) -> SonosSpeaker:
|
||||
"""Return the current coordinator SonosSpeaker."""
|
||||
|
@ -189,7 +189,12 @@ class SonosSpeaker:
|
||||
|
||||
def setup(self, entry: ConfigEntry) -> None:
|
||||
"""Run initial setup of the speaker."""
|
||||
self.set_basic_info()
|
||||
self.media.play_mode = self.soco.play_mode
|
||||
self.update_volume()
|
||||
self.update_groups()
|
||||
if self.is_coordinator:
|
||||
self.media.poll_media()
|
||||
|
||||
future = asyncio.run_coroutine_threadsafe(
|
||||
self.async_setup_dispatchers(entry), self.hass.loop
|
||||
)
|
||||
@ -247,11 +252,6 @@ class SonosSpeaker:
|
||||
"""Write states for associated SonosEntity instances."""
|
||||
async_dispatcher_send(self.hass, f"{SONOS_STATE_UPDATED}-{self.soco.uid}")
|
||||
|
||||
def set_basic_info(self) -> None:
|
||||
"""Set basic information when speaker is reconnected."""
|
||||
self.media.play_mode = self.soco.play_mode
|
||||
self.update_volume()
|
||||
|
||||
#
|
||||
# Properties
|
||||
#
|
||||
@ -456,6 +456,34 @@ class SonosSpeaker:
|
||||
@callback
|
||||
def async_dispatch_media_update(self, event: SonosEvent) -> None:
|
||||
"""Update information about currently playing media from an event."""
|
||||
# The new coordinator can be provided in a media update event but
|
||||
# before the ZoneGroupState updates. If this happens the playback
|
||||
# state will be incorrect and should be ignored. Switching to the
|
||||
# new coordinator will use its media. The regrouping process will
|
||||
# be completed during the next ZoneGroupState update.
|
||||
av_transport_uri = event.variables.get("av_transport_uri", "")
|
||||
current_track_uri = event.variables.get("current_track_uri", "")
|
||||
if av_transport_uri == current_track_uri and av_transport_uri.startswith(
|
||||
"x-rincon:"
|
||||
):
|
||||
new_coordinator_uid = av_transport_uri.split(":")[-1]
|
||||
if new_coordinator_speaker := self.hass.data[DATA_SONOS].discovered.get(
|
||||
new_coordinator_uid
|
||||
):
|
||||
_LOGGER.debug(
|
||||
"Media update coordinator (%s) received for %s",
|
||||
new_coordinator_speaker.zone_name,
|
||||
self.zone_name,
|
||||
)
|
||||
self.coordinator = new_coordinator_speaker
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"Media update coordinator (%s) for %s not yet available",
|
||||
new_coordinator_uid,
|
||||
self.zone_name,
|
||||
)
|
||||
return
|
||||
|
||||
if crossfade := event.variables.get("current_crossfade_mode"):
|
||||
self.cross_fade = bool(int(crossfade))
|
||||
|
||||
@ -774,6 +802,7 @@ class SonosSpeaker:
|
||||
self.zone_name,
|
||||
uid,
|
||||
)
|
||||
return
|
||||
|
||||
if self.sonos_group_entities == sonos_group_entities:
|
||||
# Useful in polling mode for speakers with stereo pairs or surrounds
|
||||
|
@ -120,6 +120,7 @@ def soco_fixture(
|
||||
mock_soco.get_battery_info.return_value = battery_info
|
||||
mock_soco.all_zones = {mock_soco}
|
||||
mock_soco.visible_zones = {mock_soco}
|
||||
mock_soco.group.coordinator = mock_soco
|
||||
yield mock_soco
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user