From b863e2ef05af07e95f3bc3bd62e0c4edb45db588 Mon Sep 17 00:00:00 2001 From: Marcel van der Veldt Date: Thu, 24 Oct 2024 15:55:14 +0200 Subject: [PATCH] Better handling of unavailable players --- music_assistant/server/controllers/players.py | 25 +++++++++++++++++++ .../server/providers/player_group/__init__.py | 9 +++++++ 2 files changed, 34 insertions(+) diff --git a/music_assistant/server/controllers/players.py b/music_assistant/server/controllers/players.py index 0d7e94c1..1e783174 100644 --- a/music_assistant/server/controllers/players.py +++ b/music_assistant/server/controllers/players.py @@ -859,6 +859,10 @@ class PlayerController(CoreController): if skip_forward and not force_update: return + # handle player becoming unavailable + if "available" in changed_values and not player.available: + self._handle_player_unavailable(player) + # update/signal group player(s) child's when group updates for child_player in self.iter_group_members(player, exclude_self=True): self.update(child_player.player_id, skip_forward=True) @@ -1072,6 +1076,27 @@ class PlayerController(CoreController): group_volume = group_volume / active_players return int(group_volume) + def _handle_player_unavailable(self, player: Player) -> None: + """Handle a player becoming unavailable.""" + if player.synced_to: + self.mass.create_task(self.cmd_unsync(player.player_id)) + # also set this optimistically because the above command will most likely fail + player.synced_to = None + return + for group_child_id in player.group_childs: + if group_child_id == player.player_id: + continue + if child_player := self.get(group_child_id): + self.mass.create_task(self.cmd_power(group_child_id, False, True)) + # also set this optimistically because the above command will most likely fail + child_player.synced_to = None + player.group_childs = set() + if player.active_group and (group_player := self.get(player.active_group)): + # remove player from group if its part of a group + group_player = self.get(player.active_group) + if player.player_id in group_player.group_childs: + group_player.group_childs.remove(player.player_id) + async def _play_announcement( self, player: Player, diff --git a/music_assistant/server/providers/player_group/__init__.py b/music_assistant/server/providers/player_group/__init__.py index 4fa9cef0..064767ad 100644 --- a/music_assistant/server/providers/player_group/__init__.py +++ b/music_assistant/server/providers/player_group/__init__.py @@ -511,6 +511,13 @@ class PlayerGroupProvider(PlayerProvider): if 'needs_poll' is set to True in the player object. """ if group_player := self.mass.players.get(player_id): + # dynamically change the poll interval + if group_player.state == PlayerState.PLAYING: + group_player.poll_interval = 5 + elif group_player.powered: + group_player.poll_interval = 20 + else: + group_player.poll_interval = 60 self._update_attributes(group_player) async def create_group(self, group_type: str, name: str, members: list[str]) -> Player: @@ -682,6 +689,8 @@ class PlayerGroupProvider(PlayerProvider): supported_features=tuple(player_features), group_childs=set(members), active_source=group_player_id, + needs_poll=True, + poll_interval=5, ) await self.mass.players.register_or_update(player) -- 2.34.1