fix music navs
Deploy HEOS panel / deploy (push) Successful in 25s

This commit is contained in:
2026-09-15 23:19:11 +02:00
parent 7c19ff9096
commit 5b82a24ac4
9 changed files with 299 additions and 72 deletions
+35 -11
View File
@@ -378,20 +378,38 @@ class Controller:
reply = self.heos.command("player/get_play_state", pid=self.playback_pid(key))
return parse_message(reply["heos"]["message"]).get("state", "stop")
def on_spotify(self, key: str) -> bool:
"""Whether a room's now-playing is a Spotify stream, playing or
paused -- the only thing its play/pause and next buttons make sense
for. An idle player can refuse the query outright, which is "not
Spotify" too."""
def now_playing_media(self, key: str) -> dict:
"""HEOS's get_now_playing_media payload for a room. An idle player
can refuse the query outright, which is the same as nothing loaded."""
with self._lock:
self._fresh()
try:
reply = self.heos.command("player/get_now_playing_media", pid=self.playback_pid(key))
except HeosError:
return False
payload = reply.get("payload") or {}
return (str(payload.get("sid")) == self.SPOTIFY_SID
or str(payload.get("mid", "")).startswith("spotify:"))
return {}
return reply.get("payload") or {}
@classmethod
def _is_spotify(cls, media: dict) -> bool:
return (str(media.get("sid")) == cls.SPOTIFY_SID
or str(media.get("mid", "")).startswith("spotify:"))
@staticmethod
def _track(media: dict):
"""{"song", "artist", "image"} for a room's card, or None when there
is no song to show. An AVR input is not one: HEOS fills in its
"song" with the input's own name, which the input picker already
shows. Artist and cover are None when HEOS has nothing for them."""
song = media.get("song")
if not song or str(media.get("mid", "")).startswith("inputs/"):
return None
return {"song": song, "artist": media.get("artist") or None, "image": media.get("image_url") or None}
def on_spotify(self, key: str) -> bool:
"""Whether a room's now-playing is a Spotify stream, playing or
paused -- the only thing its play/pause and next buttons make sense
for."""
return self._is_spotify(self.now_playing_media(key))
def toggle_play(self, key: str, state: str = None) -> str:
"""Start or stop a room. With no state, flips whatever it is doing
@@ -506,13 +524,19 @@ class Controller:
"volume": None,
"play_state": None,
"spotify": False,
"now_playing": None,
"error": None,
}
try:
scope, obj_id = self._volume_handles(key)[0]
room["volume"] = self._read_volume(scope, obj_id)
room["play_state"] = self.get_play_state(key)
room["spotify"] = self.on_spotify(key)
media = self.now_playing_media(key)
room["spotify"] = self._is_spotify(media)
# Kept while paused, so the card does not jump about
# under the thumb that just pressed pause.
if room["play_state"] != "stop":
room["now_playing"] = self._track(media)
except (TargetError, HeosError, KeyError) as exc:
room["available"] = False
room["error"] = str(exc)
@@ -523,7 +547,7 @@ class Controller:
snapshot["rooms"] = [
{"key": key, "label": self.cfg.TARGETS[key]["label"], "available": False,
"grouped": False, "volume": None, "play_state": None, "spotify": False,
"error": str(exc)}
"now_playing": None, "error": str(exc)}
for key in self.cfg.ROOM_KEYS
]