ADR-0068: Favourite playlists in the music popup — names pushed by the blueprint, links kept in Home Assistant, played on an Apple TV through the YouTube app¶
Page en anglais
Cette page n'existe qu'en anglais.
Status: Proposed (2026-10-18, asked for by the author; not tried on a tablet when written). Extends the music popup of ADR-0050. Date: 2026-10-18
Context¶
The author asked for « une liste de playlists dans HA + des boutons sur la tablette »: touch one of his favourite YouTube / YouTube Music playlists in the Music popup and have it play on his Apple TV, which sends the sound to his speakers over AirPlay. The house screen is the Waveshare ESP32-P4 7B (1024×600); the Tab5 (1280×720) is away for repair: both boards must stay right (ADR-0061).
Constraints: push-only and events-only (ADR-0001, ADR-0025) — the firmware names no entity, calls no action and must not receive a link it could be made to play; nothing of a real home in the public HA files (ADR-0024); one swipe mechanism for popups with pages (ADR-0046); colours from the palette; every icon in its font's glyphs: (code rule 9); instant transitions.
Verified on the author's Apple TV 4K (tvOS, apple_tv integration / pyatv) on 2026-10-18, camera in front of the TV and Home Assistant's history (11:17 – 11:19 for the timings):
- tvOS has no YouTube Music app: YouTube Music plays in the YouTube app.
media_player.play_mediawithmedia_content_type: urlandmedia_content_id: youtube://www.youtube.com/watch?list=<L>(Home Assistant calls pyatv'slaunch_app) starts the playlist at its first track, andmedia_next_trackfollows the playlist; withv=<V>&list=<L>it starts at that track. Anhttps://…link is refused by tvOS (« Open URL failed »);youtube://watch/<id>withoutlistplays one track, then YouTube's autoplay.- After the link the state goes to
paused(what was playing) in about 1 s, then toplayingwith the new track about 2-3 s after the call — from YouTube playing, from the Apple TV home screen and from standby (off). - The tvOS dialog « Ouvrir dans « YouTube » ? » (Open selected, nothing starts without OK) appeared on the first two links of the morning and never again (4 tries out of 4 without): handled, not assumed. A
selectsent with no dialog only shows YouTube's controls; playback goes on. - In standby,
media_player.turn_on: the state leavesoffin 5 to 10 s; a link sent right after starts in 2 to 3 s, with no extra delay (7.8 s from the tap on a sleeping Apple TV, through the script). Woken 4 s after it went to sleep, the Apple TV ignoredturn_onfor 20 s and refused the link (« Open URL failed »).
Decision¶
- Written in the blueprint. A new input of « Tab5 — emplacements », « Playlists favorites · Favourite playlists » (
playlists, multi-line text, empty by default, section « TV, téléphone »): one playlist per line, « Name | link » (the name is what precedes the last « | »; a line with the link alone gets « Playlist N »; empty lines, lines without a link and lines starting with « # » are skipped), the link copied in YouTube or YouTube Music (Share → Copy link), eight at most. One template,playlists, reads the lines; the push and the command read the same list, so a rank means the same line on both sides. - Only the names reach the tablet. A key of
tab5_maj_emplacements, pushed with every state liketelecommandes(ADR-0056):playlists|name|name|…;, « | » and « ; » replaced in the names, 40 characters each at most, pushed even empty (playlists|;removes the page). Read in pure C++ byplaylists_lire()(Tab5/socle/tab5_parse.*, section 16; cases intools/test_parse.cpp, fuzzed bytools/fuzz/fuzz_parse.cpp): fields kept in place, empty names included (the screen writes « Playlist N »), the rest ignored past eight. Nothing in NVS: until Home Assistant pushes, no Playlists page. - A page of the Music popup, « Playlists », only when at least one playlist was pushed. The page change is the shared brick (
PagesPopup+pages_brancher(), left / right swipe, no second gesture handler); the popup always opens on « Lecture ». Since the merge with ADR-0067 (2026-10-18), one brick serves the popup's four pages, in this order: Lecture, Playlists, Pièces, Bibliothèque (tab5_musique.cpp, which askslecteur_playlists_nb()); their names sit on the title line against the ×, each as wide as its name (96 to 200 px),pages_onglet.yamlbuttons (musique_onglet_0..3) andchoix_peindre():pages_onglets()places names on the modal card, and the music card (940 × 536, the same on both boards) is not that card. The application chip moves to their left and the player's name loses the same width (cut with « … »). On the Playlists page the cover and the player chips stay; the right column (508 × 360, the cover's height) shows one button per playlist (lecteur_playlist.yaml, eight): one column of four rows up to four playlists, two columns beyond, theplaylist-musicicon and the name cut with « … ». - A tap sends the rank, nothing else: the existing event
esphome.tab5_lecteurwithaction: playlist,lecteur: "-1",valeur: "<rank>". The button turns to the accent colour at once (and stays so for 30 s), and the popup comes back to « Lecture » 600 ms later (musique_retour_lecture(), cancelled by a page change). - The blueprint resolves the rank (an
if« La tablette lance une playlist favorite » at the start of the music branch, whose single conditiontrigger.id == 'lecteur'letstools/contrat_api.pytie the fields read to their event): the link of the line of that rank in its own input, never a link or an entity from the event; a rank outside the list does nothing. It startsscript.tab5_lecteur_playlist(packages/tab5_lecteur.yaml) withlien.script.tab5_lecteur_commande(viatab5_evenements.yaml) has no branch forplaylist: it does nothing. script.tab5_lecteur_playlist(mode: restart):list=andv=read from the link (music.youtube.com, www / m.youtube.com, youtu.be;si=and other parameters ignored),youtube://www.youtube.com/watch?[v=V&]list=L; nolist=→ a persistent notification that says what to fix, and stop. The target: the shown player (sensor.tab5_lecteur_montre) if it belongs tointegration_entities('apple_tv')and itssource_listhas « YouTube », otherwise the first player of « Tab5 · lecteurs de musique » that does; its remote is theremote.*of the same device; none → a notification, stop;unavailable→ a notification, stop. Then, the sequence measured above:input_text.tab5_lecteur_actif= the Apple TV at the start (the popup shows it at once instead of 3 to 30 s later);off/standby→media_player.turn_on, then wait up to 10 s for it to leave those states, else a secondturn_onand up to 15 s more (an Apple TV woken 4 s after it went to sleep ignored the first one, 18/10/2026);play_media; wait up to 6 s forplayingwith alast_changedafter the call; otherwiseremote.send_command: select(the tvOS dialog, or a track loaded paused), wait up to 5 s, thenmedia_player.media_play. Every player and remote action hascontinue_on_error.
Rejected¶
- Links on the tablet, or an entity in the event: against ADR-0025 — another ESPHome device could send any link; the tablet would need the links to send them back.
- A « Tab5 · » list or an
input_textper playlist: a list's options are entity IDs, not links, and eight helpers are eight things to create by hand; the blueprint input is one text box the author fills once. pages_onglets()for the page names: it places names on the modal card (from 1148 px on the Tab5), the music card is 940 px wide; a second set of constants for one popup would be a copy, not a reuse.- An
https://link or the YouTube Music app: refused by tvOS / does not exist on tvOS. - Other players (Chromecast, a smart TV, Spotify): not asked for and not tried; one more player = one more branch of the script.
Consequences¶
- API contract unchanged (1.3.0): no action or field added;
tab5_maj_emplacementscarries one more key, which an older firmware ignores, andesphome.tab5_lecteurone moreactionvalue, which an older blueprint ignores. Both orders work: a new firmware with an older blueprint shows no Playlists page; an older firmware with the new blueprint shows none either. The script needs the package and the blueprint of the same version. - Without playlists the popup has no Playlists page. Since the merge with ADR-0067 the page brick (which stops the swipe at the popup) is wired at the popup's first opening, playlists or not: a swipe on the popup no longer reaches the forecasts behind it, as in every other popup with pages, and does nothing below two pages.
- Three screen texts in six languages (« lecteur|Lecture », « Playlists », « Playlist {n} »); the
playlist-musicglyph (F0CB8) inmdi_font_32. - The off-device render captures the page names on « Lecture » and the Playlists page (
musique-avec-playlists,musique-playlists); the demo has no music player and pushes none. - Not checked on a tablet when written: the page names next to a long player name and an application chip, the swipe on the cover, the grid on the 7B, the whole chain from a tap to the Apple TV (
tests/test_playlists.pyrenders the blueprint and the script's templates; the sequence's timings come from the author's Apple TV, not from this script running).