ADR-0051: The zone left of the clock shows a content chosen in the blueprint — the voice controls, a chart of the coming hours or a compact music player, the next one by a tap on the second temperature¶
Page en anglais
Cette page n'existe qu'en anglais.
Status: Accepted (2026-10-10, asked for by the author; not tried on a tablet when written). Completed the same day by a second lot: the compact music player and a restyled chart (sections « Lot 2 » below). Date: 2026-10-10
Context¶
On the home page, the column left of the clock (x 20–425, above the « Ok Nabu » frame at y 236, ADR-0041) always showed the voice controls: the microphone (icon_mic_status, tap to talk, long press for the assistant popup) and the Domo / Discu buttons (hidden without a discussion pipeline, zone discussion).
The author asked (2026-10-10) to choose what this zone shows: the voice controls, an audio player, or a chart — « very beautiful, light » — and to handle it like the other zones (« Ok Nabu » panel, row under the clock, − / + tile): the next content by a tap on a given area of the screen (for now the second temperature, whose tap opened the Arcade), and the same action among the gesture choices.
A music player is being built at the same time by another lot (ADR-0050, popup and mini bar, not merged when this was written).
Decision¶
- Three contents.
ZoneGauche(Tab5/socle/tab5_parse.h, pure C++):VOCAL(the screen from before),GRAPHIQUE(the chart below),LECTEUR(the compact music player, lot 2 below, built on ADR-0050's data). In the first lot the firmware read, kept and skippedlecteur, and the blueprint accepted the code without offering it; the second lot added its case indisponible(), its widgets and the option.tests/test_zone_gauche.pykeeps the options equal to what the screen can show. - The voice controls do not change. The four widgets go into one transparent container,
zone_vocal, at the corner of the screen, without padding or border: their screen coordinates, look, gestures and thediscussionmasking stay the same (the container is hidden or shown as a whole; the per-widget hidden flags are untouched). - The chart: the coming hours, from data already on the tablet.
cal_heures_data(15 slots, pushed bytab5_maj_previsions_heures_bulk; nothing new from Home Assistant, contract unchanged): the monotone curve of the temperatures (the Weather popup's own smoothing, moved toui_courbe_lisse(), ADR-0043) in the colour of their mean, a dot and its value at the warmest and the coldest hour (one only when flat), rain bars in mm in the rain colours, three hour labels (now, then every 4 slots) and the rain total on the same line. About 30 objects (lv_line+lv_obj:lv_chartis disabled), built at its first appearance, repainted only when new hourly forecasts arrive or the theme changes — at once if shown, at its next appearance otherwise. Colours from the palette (UIColor, no new role), fonts already compiled (roboto_22), no new screen text (« En attente de Home Assistant » exists). The card iszone_graphique(405 × 184 at x 20, y 42: 8 px under the status bar's ink, 10 px above the « Ok Nabu » frame), in the glass of the column's buttons (style_clim_btn_page); its sides keep 22 px for a pill-shaped frame (Capsule theme). A tap on it opens the Weather popup. - The next content: the second temperature's tap, and a gesture.
btn_serre_games(its id kept: docs, tests and the render cite it) now callszone_gauche_suivante()on a tap; its long press (history, ADR-0032) does not change. Without a second sensor, the icon at its place was a gamepad (« the Arcade is here »); it is nowview-carousel(U+F056C), the icon of the new gesture codezone_gauche_suivante(index 23, at the end ofkCodesGestes: NVS keeps the index;mdi_font_26,mdi_font_45,mdi_font_70), selectable on any of the twelve home gestures (ADR-0039). The Arcade stays one touch away: the tap of the gamepad button (« auto ») and « Jeux » in the navigation wheel (ADR-0042). - Chosen in the blueprint, like the other zones. A section « Zone à gauche de l'horloge » (
zone_gauche): the content at start and the contents the tap goes through (a multiple select). One key oftab5_maj_emplacements,gauche|start|c1|c2…;, pushed with the gestures (all states: connection, reload, « MAJ Écran », HA start); an older firmware ignores it. Read byzone_gauche_lire()(tab5_parse.cpp; cases intools/test_parse.cpp, called by the libFuzzer harness): an unknown start isvocal, unknown codes are left out, the start is always in the cycle (alone, the tap changes nothing). Without the key (a blueprint from before):vocalat start,vocalandgraphiqueon tap — the screen from before until the first tap. - Kept in NVS (« zgau », « ZGA1 »: current, start, cycle), so the content shown survives a restart. A new start from the blueprint shows at once; the same choices pushed again change nothing; a current content no longer offered falls back to the start. The order of the cycle is the enum's (vocal, chart, player).
- Instant change, no animation (the author's preference).
Lot 2 (2026-10-10): the compact music player¶
- What it shows: in a card with the chart's footprint and glass (
zone_lecteur,Tab5/ui_components/lecteur_zone.yaml, x 20, y 42, 405 × 184,style_clim_btn_page), the cover on the left (the Music popup'sonline_image, the same decoded pixels: no second download, no second buffer), and on the right the title, the artist, a thin position bar (4 px,lv_bar, no knob: seeking stays in the popup) and previous / play-pause / next centred under them. Nothing playing: the popup's own sentence (« Rien en lecture », « Lecteur éteint », « Lecteur indisponible », « En attente de Home Assistant »: no new screen text) and the player's name, centred when no button applies. A button shows only when the player offers it (supported_features), at its place. The volume is left out: a slider in a 205 px column would be cramped, and the popup is one tap away. - Same data, same commands: the widgets are bound by
tab5_lecteur_lier(also run at boot bytab5_zones_apply, so the player can be the start content before any push) and painted bytab5_lecteur.cpp(peindre_zone()), from the state oftab5_maj_lecteur; the buttons calllecteur_appui(), i.e. theesphome.tab5_lecteurevent with the popup's actions. Nothing new from Home Assistant, no entity named, the contract unchanged. A tap elsewhere on the card opens the popup (Ecran::MUSIQUE). - Theme-aware geometry: the border and radius of the card are read at paint time; the cover's corner radius is the card's inner radius minus the margin (concentric corners, a near-circle in the Capsule theme), and the text and bar widths stop before the card's rounded corner.
- Painted only when shown:
lecteur_zone_montrer()(called byzone_gauche_appliquer()); while hidden, a push only marks it « dirty » and it is repainted at its next appearance. The position bar moves once a second while playing (lecteur_tic()), only while shown. - The « now playing » bar (ADR-0050) stays on the Ok Nabu frame, but hides while the zone shows the player (the author's choice) and comes back when the zone changes.
- Skipped when no player is chosen: once Home Assistant has pushed an empty state (its list « Tab5 · lecteurs de musique » is empty),
disponible()skipslecteurin the cycle and in the fallback; a list filled again brings it back (lecteur_recu()callszone_gauche_appliquer()when this changes). Before any push it shows (« En attente de Home Assistant »), so a start on the player does not flicker at boot. The stored current content is not overwritten, so the player comes back by itself. - Blueprint: the option « Lecteur de musique · Music player » in both lists, and in the default cycle (
[vocal, graphique, lecteur]): skipped anyway without players. The firmware's default without the key stays voice and chart (a blueprint from before). - Built at boot in YAML, not lazily in C++ (about 15 objects): every MDI glyph then sits on a YAML label with its font (code rule 9 can check it), the theme's glass and accent styles apply as role styles (code rule 1), and the off-device render needs nothing more. The chart stays lazy (its 30 objects have no MDI glyph nor role style).
Lot 2 (2026-10-10): the chart restyled¶
Asked by the author on the render's capture (line too thin, the « 16° » label touching the first point, weak rain shown as a row of dots):
- the curve is 5 px wide with round caps, over a faint gradient in its colour (about 33 % under the line down to 0 at the rain baseline).
lv_canvas,lv_chartand the drawing of A8 images are disabled in the build (lv_conf.h), so it is one ARGB8888lv_imagewhose pixels are computed when the chart is painted (new hourly forecasts or a theme, about 36 000 pixels, at most once an hour); its buffer (363 × 110 × 4 bytes, 156 KiB: the curve's span in the card) is taken once in PSRAM. One object; blending it costs a redraw of that area only when the card is redrawn; - the warmest and coldest dots are 12 px with a 3 px ring in the background colour; each value goes to the first free place around its dot (above first for the warmest, below for the coldest, then diagonals, sides, the other side): never over the curve (its line plus 3 px), a rain bar, the other value or dot, nor outside the card;
- rain bars readable even when weak: any forecast rain above 0 gets a bar at least 8 px high, the strongest 26 px, on a square-root scale (a light rain next to a shower does not fall back to the minimum); no rain, no bar.
Rejected¶
- Building the player in this lot: the other lot is writing the player (state, commands, popup) right now; a second player here would be a copy to merge later (rule 5). The compact player will read its data.
- Leaving
lecteurout of the enum until the second lot: the NVS and the key would then need a second format; reserving it now costs one value and one code. - Offering
lecteurin the blueprint already (first lot): a choice that showed nothing on the screen. Done in lot 2. - Removing the « now playing » bar once the player can sit left of the clock (lot 2): the author keeps it for the other contents.
- The volume in the compact player (lot 2): it does not fit cleanly in the column; the popup has it.
- A service variable or an event: a key of
tab5_maj_emplacementsis what the gestures,defiland the solar icon already use; the contract between versions does not change (contrat/contrat.yamluntouched). - Rain probabilities:
cal_heures_datacarries the quantity (mm) only; bars in mm, like the Weather popup. - Switching back to the voice controls during a voice session: not asked; with the chart shown, the listening state is not visible on the home page (the assistant popup and the voice reply still are). Left to the author.
Consequences¶
- The tap on the second temperature no longer opens the Arcade (
docs/arcade.md, the user manual anddocs/screens.mdsay so); the render opens the Arcade through the gamepad button (tools/rendu/ecrans.py) and captures the chart (accueil-zone-graphique, and in the Capsule theme). - A new content: its value at the end of
ZoneGaucheand its code (tab5_parse.h), its case indisponible()andzone_gauche_appliquer(), its option in the blueprint;tests/test_zone_gauche.pycompares. - Lot 2: three more render captures (
accueil-zone-lecteur,accueil-zone-lecteur-vide,accueil-zone-lecteur-gelule); the chart's captures change (gradient, labels, rain bars). - Not tried on a tablet when written: the author judges the look and the touch.