better handling of chromecast group players
authorMarcel van der Veldt <m.vanderveldt@outlook.com>
Thu, 4 Mar 2021 20:12:23 +0000 (21:12 +0100)
committerMarcel van der Veldt <m.vanderveldt@outlook.com>
Thu, 4 Mar 2021 20:12:23 +0000 (21:12 +0100)
music_assistant/constants.py
music_assistant/managers/players.py
music_assistant/providers/chromecast/__init__.py
music_assistant/providers/chromecast/models.py
music_assistant/providers/chromecast/player.py

index 389d110d6e1e00bd9eb3055fbc1dea0808b8f964..d599ff2089b456a578f50b846a00ed732d0aa5d2 100755 (executable)
@@ -1,6 +1,6 @@
 """All constants for Music Assistant."""
 
-__version__ = "0.1.4"
+__version__ = "0.1.5"
 REQUIRED_PYTHON_VER = "3.8"
 
 # configuration keys/attributes
index 2bd93d6a449f9c311d76dc6ad2dce3811d9ae490..bcb964c4657d488346457be94f16beeb9054f9ac 100755 (executable)
@@ -103,6 +103,18 @@ class PlayerManager:
         """Return Player by player_id or None if player does not exist."""
         return self._players.get(player_id)
 
+    @callback
+    def get_player_by_name(
+        self, name: str, provider_id: Optional[str] = None
+    ) -> Optional[Player]:
+        """Return Player by name."""
+        for player in self:
+            if provider_id is not None and player.provider_id != provider_id:
+                continue
+            if player.name == name or player.player_state.name == name:
+                return player
+        return None
+
     @callback
     def get_player_provider(self, player_id: str) -> PlayerProvider:
         """Return provider by player_id or None if player does not exist."""
index f1f5939c28ec6658c26fc95dea8bfbb03facfdcf..a0041392526cb987c6761f069fb17319af8a78aa 100644 (file)
@@ -73,9 +73,6 @@ class ChromecastProvider(PlayerProvider):
     def __chromecast_add_update_callback(self, cast_uuid, cast_service_name):
         """Handle zeroconf discovery of a new or updated chromecast."""
         # pylint: disable=unused-argument
-        if cast_uuid is None:
-            return  # Discovered chromecast without uuid?
-
         service = self._listener.services[cast_uuid]
         cast_info = ChromecastInfo(
             services=service[0],
@@ -86,11 +83,18 @@ class ChromecastProvider(PlayerProvider):
             port=service[5],
         )
         cast_info.fill_out_missing_chromecast_info(self.mass.zeroconf)
+        if cast_info.uuid is None:
+            return  # Discovered chromecast without uuid?
         player_id = cast_info.uuid
         LOGGER.debug(
             "Chromecast discovered: %s (%s)", cast_info.friendly_name, player_id
         )
         player = self.mass.players.get_player(player_id)
+        if not player and cast_info.is_audio_group:
+            # audio groups may reappear with new uuid, try to handle that
+            player = self.mass.players.get_player_by_name(
+                cast_info.friendly_name, PROV_ID
+            )
         if not player:
             player = ChromecastPlayer(self.mass, cast_info)
         # if player was already added, the player will take care of reconnects itself.
index 2c08064f52b30b3d98f127fa8f04e04ab6af1885..a96ae10e7ed3d4d59b53748c5b140c978f24c69f 100644 (file)
@@ -59,7 +59,7 @@ class ChromecastInfo:
             http_group_status = None
             if self.uuid:
                 http_group_status = dial.get_multizone_status(
-                    self.host,
+                    None,
                     services=self.services,
                     zconf=zconf,
                 )
@@ -71,10 +71,10 @@ class ChromecastInfo:
         else:
             # Fill out some missing information (friendly_name, uuid) via HTTP dial.
             http_device_status = dial.get_device_status(
-                self.host, services=self.services, zconf=zconf
+                None, services=self.services, zconf=zconf
             )
-        if not self.uuid and http_device_status:
-            self.uuid = http_device_status.uuid
+        if http_device_status:
+            self.uuid = str(http_device_status.uuid)
         if not self.friendly_name and http_device_status:
             self.friendly_name = http_device_status.friendly_name
         if not self.model_name and http_device_status:
index ee1ea31d75faf5806c147080bbc9863190e1f7ed..442ebf4619e901fc1475b759ef147db0fc000e9a 100644 (file)
@@ -76,9 +76,15 @@ class ChromecastPlayer(Player):
     @property
     def powered(self) -> bool:
         """Return power state of this player."""
+        if not self._chromecast or not self.cast_status:
+            return False
         if self.is_group_player:
-            return self._chromecast.is_idle
-        return not self.cast_status.volume_muted if self.cast_status else False
+            return (
+                self.media_status.player_is_playing
+                or self.media_status.player_is_paused
+                or self.media_status.player_is_idle
+            )
+        return not self.cast_status.volume_muted and not self.cast_status.is_stand_by
 
     @property
     def should_poll(self) -> bool:
@@ -88,6 +94,8 @@ class ChromecastPlayer(Player):
     @property
     def state(self) -> PlaybackState:
         """Return the state of the player."""
+        if self.cast_status and self.cast_status.is_stand_by:
+            return PlaybackState.Off
         if self.media_status is None:
             return PlaybackState.Stopped
         if self.media_status.player_is_playing:
@@ -192,10 +200,11 @@ class ChromecastPlayer(Player):
         self._available = False
         self.cast_status = chromecast.status
         self.media_status = chromecast.media_controller.status
-        mz_controller = MultizoneController(chromecast.uuid)
-        chromecast.register_handler(mz_controller)
-        chromecast.mz_controller = mz_controller
-        chromecast.start()
+        if self._cast_info.is_audio_group:
+            mz_controller = MultizoneController(chromecast.uuid)
+            chromecast.register_handler(mz_controller)
+            chromecast.mz_controller = mz_controller
+        self._chromecast.start()
 
     def set_cast_info(self, cast_info: ChromecastInfo) -> None:
         """Set (or update) the cast discovery info."""