Skip to content

Commit 24755ff

Browse files
authoredFeb 24, 2025··
Ensure players refreshed after group event (#106)
2 parents 88c1b25 + 6b5949e commit 24755ff

File tree

3 files changed

+51
-4
lines changed

3 files changed

+51
-4
lines changed
 

‎pyheos/command/player.py

+10
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,16 @@ async def load_players(self) -> PlayerUpdateResult:
150150
self._players_loaded = True
151151
return result
152152

153+
async def _refresh_players_base_info(self) -> None:
154+
"""Refresh the attributes of all player's base information."""
155+
response = await self._connection.command(HeosCommand(c.COMMAND_GET_PLAYERS))
156+
payload = cast(Sequence[dict[str, str]], response.payload)
157+
for player_data in payload:
158+
player_id = int(player_data[c.ATTR_PLAYER_ID])
159+
player = self._players.get(player_id)
160+
if player:
161+
player._update_from_data(player_data)
162+
153163
async def player_get_play_state(self, player_id: int) -> PlayState:
154164
"""Get the state of the player.
155165

‎pyheos/heos.py

+8-4
Original file line numberDiff line numberDiff line change
@@ -235,17 +235,21 @@ async def _on_event_heos(self, event: HeosMessage) -> None:
235235
result: PlayerUpdateResult | None = None
236236
if event.command == const.EVENT_PLAYERS_CHANGED and self._players_loaded:
237237
result = await self.load_players()
238-
if event.command == const.EVENT_SOURCES_CHANGED and self._music_sources_loaded:
238+
elif (
239+
event.command == const.EVENT_SOURCES_CHANGED and self._music_sources_loaded
240+
):
239241
await self.get_music_sources(refresh=True)
240242
elif event.command == const.EVENT_USER_CHANGED:
241243
if c.ATTR_SIGNED_IN in event.message:
242244
self._signed_in_username = event.get_message_value(c.ATTR_USER_NAME)
243245
else:
244246
self._signed_in_username = None
245-
elif event.command == const.EVENT_GROUPS_CHANGED and self._groups_loaded:
247+
elif event.command == const.EVENT_GROUPS_CHANGED:
246248
if self._players_loaded:
247-
await self.get_players(refresh=True)
248-
await self.get_groups(refresh=True)
249+
# Ensure player group ID attributes (i.e. group_id) are update
250+
await self._refresh_players_base_info()
251+
if self._groups_loaded:
252+
await self.get_groups(refresh=True)
249253

250254
await self._dispatcher.wait_send(
251255
SignalType.CONTROLLER_EVENT, event.command, result, return_exceptions=True

‎tests/test_heos.py

+33
Original file line numberDiff line numberDiff line change
@@ -1096,6 +1096,39 @@ async def handler(event: str, data: dict[str, Any]) -> None:
10961096
assert not await heos.get_groups()
10971097

10981098

1099+
@calls_player_commands()
1100+
async def test_groups_changed_event_groups_not_loaded(
1101+
mock_device: MockHeosDevice, heos: Heos
1102+
) -> None:
1103+
"""Test groups changed fires dispatcher and updates players when groups not loaded."""
1104+
players = await heos.get_players()
1105+
assert all(player.group_id is not None for player in players.values())
1106+
signal = asyncio.Event()
1107+
1108+
async def handler(event: str, data: dict[str, Any]) -> None:
1109+
assert event == EVENT_GROUPS_CHANGED
1110+
signal.set()
1111+
1112+
heos.dispatcher.connect(SignalType.CONTROLLER_EVENT, handler)
1113+
1114+
# Write event through mock device
1115+
commands = [
1116+
mock_device.register(
1117+
c.COMMAND_GET_GROUPS, None, "group.get_groups_changed", replace=True
1118+
),
1119+
mock_device.register(
1120+
c.COMMAND_GET_PLAYERS, None, "player.get_players_no_groups", replace=True
1121+
),
1122+
]
1123+
await mock_device.write_event("event.groups_changed")
1124+
1125+
# Wait until the signal is set
1126+
await signal.wait()
1127+
map(lambda c: c.assert_called(), commands)
1128+
assert all(player.group_id is None for player in players.values())
1129+
assert not heos.groups
1130+
1131+
10991132
@calls_player_commands()
11001133
async def test_player_playback_error_event(
11011134
mock_device: MockHeosDevice, heos: Heos

0 commit comments

Comments
 (0)
Please sign in to comment.