feat(media-player): flatten now-playing into separate attributes and name the tier
The user reads attributes as YAML — "These could do with being separate attributes rather than an object in one?" — so the nested `media_dag_now_playing` object is gone and every field it carried is its own top-level attribute: now_playing_via, now_playing_state, now_playing_title, now_playing_artist, now_playing_album, now_playing_media_type, now_playing_series, now_playing_season, now_playing_episode, now_playing_duration, now_playing_position, now_playing_position_updated_at, now_playing_thumbnail, now_playing_media_info Rules the surface now holds to: - an unknown field is OMITTED, never published as None (`title: null` inside the object was exactly the noise this removes); 0 and False are real values - a device reading `off` publishes no now-playing row at all — a Jellyfin session that has gone stale must not put a title beside a device that is off — and `on` (nothing reported) publishes none either, because there is no reading - `now_playing_state` IS the entity's own state, so the ladder stays the single answer even while the foreground tier's last-known bridge serves a title - the tier indicator is `now_playing_via` (`jellyfin` / `media_session` / `app`), NOT `source`: on a media_player `source`/`source_list` mean the selected app input (`Netflix`, `TiviMate`, …) and they still do — a tier named `source` is what made the reading look like media metadata from somewhere else. The internal reading key is renamed `via` as well, and the Jellyfin tier now names itself too - every published name is declared unrecorded (G12): these change every poll COMPATIBILITY: `media_dag_now_playing` is removed, not deprecated, and no alias is kept — a nested copy would double every poll's payload. README documents the exact names, these rules, the sensor's own flat set and a one-line template migration. sensor.py: the Jellyfin now-playing sensor follows the same no-None rule (`title` and `media_type` used to be published as null there). Tests: 17 new cases pin the flattening, the tier rename, the five states, the off/on gate, the playing->idle transition, the last-known bridge, privacy mode and agreement with the Current App sensor; the tier-dict tests follow `via`.
This commit is contained in:
1 parent
46738063aa
commit
a1ce28996e
4 files changed
+543
-47
No files matched your search
@@ -299,23 +299,24 @@ class NvidiaShieldNowPlayingSensor(NvidiaShieldSensorBase):
|
||||
return {"playback_state": "idle"}
|
||||
|
||||
attrs = state.attributes
|
||||
result = {
|
||||
"playback_state": state.state,
|
||||
"title": attrs.get("media_title"),
|
||||
"media_type": attrs.get("media_content_type"),
|
||||
}
|
||||
|
||||
if attrs.get("media_series_title"):
|
||||
result["series"] = attrs["media_series_title"]
|
||||
if attrs.get("media_season") is not None:
|
||||
result["season"] = attrs["media_season"]
|
||||
if attrs.get("media_episode") is not None:
|
||||
result["episode"] = attrs["media_episode"]
|
||||
if attrs.get("media_duration") is not None:
|
||||
result["duration"] = attrs["media_duration"]
|
||||
if attrs.get("media_position") is not None:
|
||||
result["position"] = attrs["media_position"]
|
||||
if attrs.get("entity_picture"):
|
||||
result["thumbnail"] = attrs["entity_picture"]
|
||||
# t65: the same "no None rows" rule the media player's flattened surface
|
||||
# follows — an attribute that reads `title: null` in the template editor
|
||||
# is noise, so a field the Jellyfin entity did not answer is OMITTED
|
||||
# rather than published. Zero stays: 0 s of position is a real reading.
|
||||
result = {"playback_state": state.state}
|
||||
for key, source in (
|
||||
("title", "media_title"),
|
||||
("media_type", "media_content_type"),
|
||||
("series", "media_series_title"),
|
||||
("season", "media_season"),
|
||||
("episode", "media_episode"),
|
||||
("duration", "media_duration"),
|
||||
("position", "media_position"),
|
||||
("thumbnail", "entity_picture"),
|
||||
):
|
||||
value = attrs.get(source)
|
||||
if value is None or value == "":
|
||||
continue
|
||||
result[key] = value
|
||||
|
||||
return result
|
||||
Reference in new issue
Block a user