c09e4e333f
Docs only, no version change: the add-on update and the OTA to firmware 0.2.64, the media card with a real Sonos cover, and an alert with a camera over it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
9.7 KiB
9.7 KiB
Test results app 0.2.77 / firmware 0.2.64 (2026-09-18)
Max asked for a media card "like Spotify or Apple Music now playing" instead of the plain card with three text keys
and a thin volume slider, with the album cover through the camera-image route, working as the card behind a media
tile, as a tile over the whole page, and in the light and the dark look. Then: the CYD gets the new card without the
picture ("te risky"), a player does not always have a picture, and renders first so he could approve the look.
See CHANGELOG 0.2.77. Built on 0.2.76 (bdb1f12).
What changed
components/smart_display/media_card.h(new): the card's geometry and words, free of LVGL. A tall area (the Guition's card) stacks cover, title, artist · album, the bar row (elapsed | bar | total on one line), the keys (previous 52, play or pause 64 on the accent, next) and the volume row. A wide area (the CYD's card, a tile over the whole page) puts the cover at the left with the column beside it; what does not fit goes in order: the artist line, the times, then the cover shrinks.tests/test_media_card.cppchecks every shape for overlaps and order.runtime_tiles.h:render_media_detail(the card),render_media_full(the tile over the whole page, parts inw.extra),media_actionshared by both (20 play/pause, 21 previous, 22 next, 23 mute, 24 turn on), the card's key handler pulled out ofdetail_buttonintodetail_command,media_progressmoved bytick()once a second, and the cover:cover_want/cover_ready/cover_tick/cover_offeraround onecamera_view::Feedthat loads a link once (once,loaded), owned by the card or by a tile slot and dropped when the owner goes; a camera full screen takes the shared image buffer and the cover comes back after. The camera answer parser acceptst: cover. The palette pass leaves the media tile's parts alone (it painted them the card's grey). A player's state falls back to the screen's own word ("Playing") when Home Assistant sent none.- One picture at a time (asked by Max after approving the renders: "two images at once, is that too much?"). An
alert already closes every card (
wake_displayrunsclose_cards), so the card's cover is dropped with it. A media tile over the whole page stays under the alert:alert_image_due()holds its cover while the alert's picture is announced, loading or due for a retry, and an alert picture that arrives while a cover is on its way (or while a dropped cover's download is still being closed) waits for it (alert_retry_at, started bycamera_tick). Memory was never the limit: the pictures live in PSRAM (cover ~70 KB, alert 172 KB); the rule keeps the main loop, where touch waits, to one download. runtime_model.h:Extracarries artist, album, picture mark, duration, position and its moment.camera_view.h:open(entity, once),loaded; an empty answer to a one-time feed stops the asking.theme.h:theme::of(lv_color_t)(the 24-bit value of a drawn colour, for the cover's corner colour).tile_controls.h:feature::MEDIA_TURN_ON.- App:
core.media_extras(x: artist, album, dur, pos, at, pic),COVER_MIN_FIRMWARE = 0.2.64;camera_feed.cover_supported/can_show_cover/cover_request/encode_cover,CameraFeed.cover()(fetched when the picture address changed),Link.cover;server.HomeAssistant.media_picture/media_image,Manager.cover_message,answer_cameraserves covers to a Guition on 0.2.64+ for players on its layout. - Both profiles: firmware 0.2.64. Docs: CHANGELOG, README rows, docs/CAMERA.md "The album cover on the media card".
Checks
tests/test_media_card.cpp(geometry, progress, clock text, subtitle),tests/test_camera_view.cpp(one-time feed), all 18 C++ suites: pass.tests/test_media_card.py(14): extras, firmware wiring, cover encoding (corners, square crop, transparency), fetch-on-change and links, the app's answer throughManager.answer_camera(Guition 0.2.64 gets a link, a stream an empty one, a stranger nothing, older firmware and a CYD nothing). Whole Python suite: 409 + 14, pass.- Host harness (
.esphome/readme-render/media/media_host.py, real ESPHome API, virtual finger, the app's ownanswer_camerabehind/dev/cover): Guition 64/64, CYD 42/42. Covered: the card of a playing player (title, artist · album, elapsed from the reported position and running on, keys enabled, slider at 32 %, bar track and fill), the cover asked for with size and page colour and loaded once over the placeholder, pause →media_play_pausewith the keys faded during the wait and back after, next, mute (is_volume_muted: true), the slider drag →volume_set≈ 0.8, closing drops the cover; a stream (no times, no cover request); a paused muted TV with few features (play key, muted key, "Muted", next and mute faded, previous not, a still bar, its cover); an off player ("Off", no times); dark mode (dark keys, the cover asked again with the dark page colour); a tile over the whole page (track beside the cover, keys, slider, "48 %", times, cover at the tile's size and colour, the bar running, the tile's pause key acting on the study speaker without opening the card, the tile's slider →volume_set≈ 0.2, a new picture in Home Assistant → new mark → the tile asks again and loads the new cover, holding the tile opens the card which takes the cover at its own size, closing gives it back to the tile); a stream over the page (no times, no cover, the study cover dropped); an idle player ("Not playing"); a wide media tile with a volume control keeps its panel; no errors in the firmware log. The CYD asks for no cover anywhere. Alerts with a camera (Guition): an alert closes the open media card and drops its cover, and its picture loads alone; under a full-page media tile whose cover is not loaded yet, the cover waits until the alert's picture is shown and loads after it; a cover on its way (a link that answers after 1.5 s) finishes first and the alert's picture ("waits for the cover") follows. The firmware log shows the downloads one after the other in all three. - Renders (
render_media.py, both boards, light and dark): card of a playing player, a stream, a paused TV, an off player, tiles over the page (study, radio, idle). Sent to Max for approval. - ESP32 builds of both Easy Setup profiles: see the sizes below.
- Hardware: Studio 1 (Guition, this network's Home Assistant) — see below.
Sizes
Both Easy Setup profiles compile with ESPHome 2026.6.2, no warnings (see the pitfalls for this Mac's Python).
| Build | Flash | RAM |
|---|---|---|
| Guition (easy-guition-device) | 1,971,975 B, 24.3 % of 8 MB | 76,852 B, 23.5 % |
| CYD (easy-cyd-device) | 1,582,183 B, 86.2 % of the 1.835 MB update slot | 71,276 B, 21.8 % |
Hardware (Studio 1, Guition on the studio's Home Assistant, 2026-09-18 17:20)
- Released as
079ffcf, tagscreens-v0.2.77. The add-on on the studio's Home Assistant went 0.2.75 → 0.2.77 from the store; Studio 1 got firmware 0.2.64 over OTA, built from GitHub main (so the published package and its fonts and components resolve; both packages also passesphome configfrom an empty folder). It came back on the same address, Home Assistant reports firmware 0.2.64 and the tile settings read Synced. - Two Sonos tiles were added through the
esp_screens_add_tileevent:media_player.office_rukbunkeras a full-page tile on page 4 andmedia_player.keuken_baras a single tile on page 5 (the Sonos group plays in the studio). - The card of the Keuken Bar tile (opened with
preview_runtime_card): the app answered one cover request (the screen asked a second time after 10 s, its normal retry, because the first event arrived while the app reconnected), the real Spotify cover (69 KB BMP) loaded in one download and showed with the title, the artist, the running bar, the keys and the muted volume row. - Media card open with its cover, then
esp_screens_show_alertwithcamera.amcrest_camera: the card closed, the alert's picture (182 KB) loaded alone and showed 2.2 s after the event; the alert timed out by itself. - Heap after these tests: 96 KB free, 55 KB largest block, lowest free 91 KB (0.2.63 before the update: 86 / 32 / 61 KB).
- Not tested on hardware: the full-page tile (a page change needs a finger) and the keys and slider on a real player (they play music in the studio): Max checks those himself.
Pitfalls
render_timeon a host build freezes the clock, and the progress bar with it: the harness shifts the demo's report moments to now instead.- LVGL's
LV_LABEL_LONG_DOTwrites the dots into the label's text: a probe sees "Miles Davis · Kin...". tick()re-enables every object indetail_actionsafter a wait: a key the player lacks must stay out of it.- The tile palette pass paints every custom part; a mode that paints its own parts must be skipped there.
- Homebrew's python@3.14.7 on this Mac has a broken
pyexpat(it loads macOS's/usr/lib/libexpat.1.dylib, which lacks_XML_SetAllocTrackerActivationThreshold), soplatform.mac_ver()returns '' and pip's truststore anduvrefuse the interpreter. The pioarduino platform then cannot rebuild~/.platformio/penv("Failed to install Python dependencies into penv"). SettingDYLD_LIBRARY_PATH=/opt/homebrew/opt/expat/libis not enough, because pioarduino startsuvwithout it. What works: ESPHome 2026.6.2 in a venv on PlatformIO's own bundled Python 3.11 (~/.platformio/python3), wheremac_ver()is fine. Every session must build with that same Python: pioarduino recreates the penv whenever the Python version changes, so a build on another Python breaks the next one elsewhere.brew reinstall python@3.14(or expat) is the real fix. Never run two ESPHome builds at once.