Fix bluesound_group attribute in bluesound integration (#130815)
Co-authored-by: Robert Resch <robert@resch.dev>pull/131696/head
parent
507bb4a685
commit
96eae1221c
|
@ -292,14 +292,6 @@ class BluesoundPlayer(MediaPlayerEntity):
|
|||
self._last_status_update = dt_util.utcnow()
|
||||
self._status = status
|
||||
|
||||
group_name = status.group_name
|
||||
if group_name != self._group_name:
|
||||
_LOGGER.debug("Group name change detected on device: %s", self.id)
|
||||
self._group_name = group_name
|
||||
|
||||
# rebuild ordered list of entity_ids that are in the group, master is first
|
||||
self._group_list = self.rebuild_bluesound_group()
|
||||
|
||||
self.async_write_ha_state()
|
||||
except PlayerUnreachableError:
|
||||
self._attr_available = False
|
||||
|
@ -323,6 +315,8 @@ class BluesoundPlayer(MediaPlayerEntity):
|
|||
|
||||
self._sync_status = sync_status
|
||||
|
||||
self._group_list = self.rebuild_bluesound_group()
|
||||
|
||||
if sync_status.master is not None:
|
||||
self._is_master = False
|
||||
master_id = f"{sync_status.master.ip}:{sync_status.master.port}"
|
||||
|
@ -619,21 +613,32 @@ class BluesoundPlayer(MediaPlayerEntity):
|
|||
|
||||
def rebuild_bluesound_group(self) -> list[str]:
|
||||
"""Rebuild the list of entities in speaker group."""
|
||||
if self._group_name is None:
|
||||
if self.sync_status.master is None and self.sync_status.slaves is None:
|
||||
return []
|
||||
|
||||
device_group = self._group_name.split("+")
|
||||
player_entities: list[BluesoundPlayer] = self.hass.data[DATA_BLUESOUND]
|
||||
|
||||
sorted_entities: list[BluesoundPlayer] = sorted(
|
||||
self.hass.data[DATA_BLUESOUND],
|
||||
key=lambda entity: entity.is_master,
|
||||
reverse=True,
|
||||
)
|
||||
return [
|
||||
entity.sync_status.name
|
||||
for entity in sorted_entities
|
||||
if entity.bluesound_device_name in device_group
|
||||
leader_sync_status: SyncStatus | None = None
|
||||
if self.sync_status.master is None:
|
||||
leader_sync_status = self.sync_status
|
||||
else:
|
||||
required_id = f"{self.sync_status.master.ip}:{self.sync_status.master.port}"
|
||||
for x in player_entities:
|
||||
if x.sync_status.id == required_id:
|
||||
leader_sync_status = x.sync_status
|
||||
break
|
||||
|
||||
if leader_sync_status is None or leader_sync_status.slaves is None:
|
||||
return []
|
||||
|
||||
follower_ids = [f"{x.ip}:{x.port}" for x in leader_sync_status.slaves]
|
||||
follower_names = [
|
||||
x.sync_status.name
|
||||
for x in player_entities
|
||||
if x.sync_status.id in follower_ids
|
||||
]
|
||||
follower_names.insert(0, leader_sync_status.name)
|
||||
return follower_names
|
||||
|
||||
async def async_unjoin(self) -> None:
|
||||
"""Unjoin the player from a group."""
|
||||
|
|
|
@ -325,17 +325,17 @@ async def test_attr_bluesound_group(
|
|||
setup_config_entry_secondary: None,
|
||||
player_mocks: PlayerMocks,
|
||||
) -> None:
|
||||
"""Test the media player grouping."""
|
||||
"""Test the media player grouping for leader."""
|
||||
attr_bluesound_group = hass.states.get(
|
||||
"media_player.player_name1111"
|
||||
).attributes.get("bluesound_group")
|
||||
assert attr_bluesound_group is None
|
||||
|
||||
updated_status = dataclasses.replace(
|
||||
player_mocks.player_data.status_long_polling_mock.get(),
|
||||
group_name="player-name1111+player-name2222",
|
||||
updated_sync_status = dataclasses.replace(
|
||||
player_mocks.player_data.sync_status_long_polling_mock.get(),
|
||||
slaves=[PairedPlayer("2.2.2.2", 11000)],
|
||||
)
|
||||
player_mocks.player_data.status_long_polling_mock.set(updated_status)
|
||||
player_mocks.player_data.sync_status_long_polling_mock.set(updated_sync_status)
|
||||
|
||||
# give the long polling loop a chance to update the state; this could be any async call
|
||||
await hass.async_block_till_done()
|
||||
|
@ -347,6 +347,45 @@ async def test_attr_bluesound_group(
|
|||
assert attr_bluesound_group == ["player-name1111", "player-name2222"]
|
||||
|
||||
|
||||
async def test_attr_bluesound_group_for_follower(
|
||||
hass: HomeAssistant,
|
||||
setup_config_entry: None,
|
||||
setup_config_entry_secondary: None,
|
||||
player_mocks: PlayerMocks,
|
||||
) -> None:
|
||||
"""Test the media player grouping for follower."""
|
||||
attr_bluesound_group = hass.states.get(
|
||||
"media_player.player_name2222"
|
||||
).attributes.get("bluesound_group")
|
||||
assert attr_bluesound_group is None
|
||||
|
||||
updated_sync_status = dataclasses.replace(
|
||||
player_mocks.player_data.sync_status_long_polling_mock.get(),
|
||||
slaves=[PairedPlayer("2.2.2.2", 11000)],
|
||||
)
|
||||
player_mocks.player_data.sync_status_long_polling_mock.set(updated_sync_status)
|
||||
|
||||
# give the long polling loop a chance to update the state; this could be any async call
|
||||
await hass.async_block_till_done()
|
||||
|
||||
updated_sync_status = dataclasses.replace(
|
||||
player_mocks.player_data_secondary.sync_status_long_polling_mock.get(),
|
||||
master=PairedPlayer("1.1.1.1", 11000),
|
||||
)
|
||||
player_mocks.player_data_secondary.sync_status_long_polling_mock.set(
|
||||
updated_sync_status
|
||||
)
|
||||
|
||||
# give the long polling loop a chance to update the state; this could be any async call
|
||||
await hass.async_block_till_done()
|
||||
|
||||
attr_bluesound_group = hass.states.get(
|
||||
"media_player.player_name2222"
|
||||
).attributes.get("bluesound_group")
|
||||
|
||||
assert attr_bluesound_group == ["player-name1111", "player-name2222"]
|
||||
|
||||
|
||||
async def test_volume_up_from_6_to_7(
|
||||
hass: HomeAssistant,
|
||||
setup_config_entry: None,
|
||||
|
|
Loading…
Reference in New Issue