diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 8bec60e..f0f4080 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -176,6 +176,25 @@ icons sit off-center in the browser); run `generate_packages.py` afterward. The `MDI_GLYPH_*` substitutions are retired: `TILEn_ICON` in manual profiles must come from the set. No changed preferences or keys. +### Compatibility 0.2.64 / firmware 0.2.55 + +Both board profiles, the Claude skill and the editor's alert tips; the app raises `FIRMWARE_VERSION`. Storage, tile +protocol, preferences and keys are unchanged. + +- `alert_title` gets `height: ${ALERT_TITLE_H}`, one line of its `headline` font: 32 px on the Guition, 21 px on the CYD. + That is FreeType's size height of Roboto 500 at 27 and 18 px (`hhea` ascender minus descender, scaled and rounded), + which ESPHome 2026.6.2 hands to `lv_font_t.line_height`. LVGL 9.5's `lv_label_refr_text` only puts the dots of + `long_mode: DOT` on a label whose wrapped text is taller than the label, and a label without a height is as tall as + its wrapped text, so a long title wrapped and ran into `alert_subtitle` (y 68 / 44). With one line of height LVGL + breaks that line anywhere and ends it with "...". A title that fits draws the same pixels as before. +- `tests/test_alert.py` computes the line height from the font file and fails when `ALERT_TITLE_H` differs from it or + the title reaches the subtitle: a new `headline` size needs a new `ALERT_TITLE_H` on that board. +- Older firmware keeps wrapping a long title over the subtitle. +- `claude_skill.text()` and the alert tips in `static/index.html` said the CYD shows about forty characters of a title. + FreeType's advances of Roboto 500 give 20-23 characters before the "..." on the Guition (304 px at 27 px) and 24-25 + on the CYD (212 px at 18 px), so both now say about twenty. An installed skill shows as outdated until it is + installed again. + ### Compatibility 0.2.63 / firmware 0.2.54 Firmware (`components/smart_display`, new `theme.h`), both board profiles and the app's settings. The tile protocol diff --git a/docs/TEST_RESULTS_0264.md b/docs/TEST_RESULTS_0264.md new file mode 100644 index 0000000..65fbd26 --- /dev/null +++ b/docs/TEST_RESULTS_0264.md @@ -0,0 +1,73 @@ +# Test results app 0.2.64 / firmware 0.2.55 (2026-09-17) + +An alert with a long title (`show_alert` with title "Washing machine is done" and subtitle "Empty it before the laundry +smells") showed the title on two lines on the Guition, the second line on top of the subtitle, although the comment on +`ALERT_TITLE_MAX` and README_EXTENDED promise one line that ends in an ellipsis. See CHANGELOG 0.2.64 and the +compatibility note in docs/RELEASING.md. Built on 0.2.62 while Dark mode was under way in another session, rebased +onto 0.2.63 when it was released, and tested again there (only the version lines, CHANGELOG and RELEASING conflicted). + +## Cause + +LVGL 9.5.0 (`src/widgets/label/lv_label.c`, as ESPHome 2026.6.2 builds it): `lv_label_refr_text` only puts the dots of +`LV_LABEL_LONG_MODE_DOTS` on a label whose wrapped text is taller than its content area. `alert_title` had a width but +no height, so `LV_EVENT_GET_SELF_SIZE` made it exactly as tall as its wrapped text and the dots never came. With a +height of one line, `lv_label_get_letter_on` finds the letter on that line (which it breaks anywhere, since it is the +last one that shows) and the text ends in "...". + +ESPHome's `lv_font_t.line_height` is FreeType's size height. The generated code builds `headline` (Roboto 500) as +`font::Font(..., 26, 32, 7, ...)` at 27 px and `font::Font(..., 17, 21, 5, ...)` at 18 px (baseline, height, descender), +and freetype-py (FreeType 2.13.2) gives the same 32 and 21 px. + +## Automated + +- Python (`.venv-portal`): 312 tests OK on 0.2.63 (302 on 0.2.62). New in `tests/test_alert.py`: in both profiles and + both packages the title has `height: ${ALERT_TITLE_H}` and the `headline` font, `ALERT_TITLE_H` equals the line + height computed from the font file (`head` and `hhea`, rounded as FreeType does: 32 and 21), and the title ends above + the subtitle. The test fails on 0.2.62 before the fix. +- C++ (`clang++ -std=c++17 -Wall -Wextra -Werror -I. -I components/smart_display`): 16/16 PASS on 0.2.63 (15/15 on + 0.2.62). +- `generate_packages.py --check` green. + +## Builds (ESPHome 2026.6.2) + +Check profiles with the generated packages and local components, as for 0.2.62, built for this release and for 0.2.63 +(the same check profiles from `bc2a754`). All compile without errors. + +| Profile | RAM | Flash | vs 0.2.63 | +|---|---|---|---| +| CYD | 23.7% (77,500 B) | 77.4% (1,420,991 B) | +0 B RAM, -8 B flash | +| Guition | 24.7% (80,852 B) | 18.8% (1,524,647 B) | +0 B RAM, +8 B flash | + +## Firmware on the Mac (host builds, driven over the ESPHome API) + +`show_alert` on host builds of both packages over a demo page, before and after the change, with a probe that logs the +title's and subtitle's position and height as LVGL laid them out and the text the title shows: + +| Board | Title | Before: title height, bottom | After | +|---|---|---|---| +| Guition | Washing machine is done | 64 px (2 lines), y 90, over the subtitle at y 68 | 32 px, y 58: "Washing machine is d..." | +| Guition | Door open | 32 px, y 58 | the same pixels | +| Guition | a title of 64 bytes | 96 px (3 lines), y 122 | 32 px, y 58: "The dishwasher in the ..." | +| CYD | Washing machine is done | 21 px (fits), y 37 | the same pixels | +| CYD | Door open | 21 px, y 37 | the same pixels | +| CYD | a title of 48 bytes | 42 px (2 lines), y 58, over the subtitle at y 44 | 21 px, y 37: "The dishwasher in the ki..." | + +Comparing the renders pixel by pixel: no difference for the three titles that fit, and for the others only inside the +title and subtitle area. The "g" of "Washing" keeps its descender in the one-line box, which is as high as the label +of a title that fits always was. + +On 0.2.63 (rebased, firmware reporting 0.2.55) the probe gives the same numbers and texts for all six, in the light +look and with the Dark mode switch on; the light card is pixel-identical to the render before the rebase, and the dark +card shows the same single line with its ellipsis. + +## How long a title can be + +The Claude skill and the editor's alert tips said the CYD shows about forty characters of a title. Measured with +FreeType's advances of Roboto 500 at the label widths, on seven typical titles: 20-23 characters before the "..." on +the Guition, 24-25 on the CYD, which matches the cuts LVGL made in the renders above ("Washing machine is d" and "The +dishwasher in the ki"). Both now say about twenty. The editor, served from this tree on a demo home, shows the new tip +in Settings → Alerts → Tips without console errors, and `claude_skill.text()` carries the new sentence. + +## Not tested + +- Physical screens: not flashed in this round. diff --git a/guition-4848s040.yaml b/guition-4848s040.yaml index 9ff9522..b7937e2 100644 --- a/guition-4848s040.yaml +++ b/guition-4848s040.yaml @@ -2,7 +2,7 @@ # Source profile for packages/guition.yaml (tools/generate_packages.py); see docs/GUITION.md. # A screen gets its tiles from the ESP Screen Manager add-on while it runs. The CYD is its own profile. substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.54" + SCREEN_FIRMWARE_VERSION: "0.2.55" # 0: no drift limit; LVGL decides, releasing inside the tile is a tap, leaving it is not # (like iOS). The CYD keeps a limit because its resistive panel jumps. TOUCH_MOVE_LIMIT_PX: "0" @@ -60,6 +60,7 @@ substitutions: ALERT_TEXT_X: "90" ALERT_TEXT_W: "304" ALERT_TITLE_Y: "26" + ALERT_TITLE_H: "32" # one line of headline; a DOT label only ends in an ellipsis with a height ALERT_SUBTITLE_Y: "68" ALERT_SUBTITLE_H: "150" ALERT_BUTTON_W: "150" @@ -1524,6 +1525,7 @@ lvgl: x: ${ALERT_TEXT_X} y: ${ALERT_TITLE_Y} width: ${ALERT_TEXT_W} + height: ${ALERT_TITLE_H} long_mode: DOT text: "Notification" text_font: headline diff --git a/home-like-2432s028.yaml b/home-like-2432s028.yaml index 27aa4c1..d3d128d 100644 --- a/home-like-2432s028.yaml +++ b/home-like-2432s028.yaml @@ -17,7 +17,7 @@ ############################################################ substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.54" + SCREEN_FIRMWARE_VERSION: "0.2.55" # A tap survives a finger that drifts up to this far (320 px over 58 mm: 1 cm); further is a swipe. TOUCH_MOVE_LIMIT_PX: "56" # Shortest contact that counts as a tap; a resistive panel bounces, a capacitive one does not. @@ -94,6 +94,7 @@ substitutions: ALERT_TEXT_X: "62" ALERT_TEXT_W: "212" ALERT_TITLE_Y: "16" + ALERT_TITLE_H: "21" # one line of headline; a DOT label only ends in an ellipsis with a height ALERT_SUBTITLE_Y: "44" ALERT_SUBTITLE_H: "88" ALERT_BUTTON_W: "100" @@ -1621,6 +1622,7 @@ lvgl: x: ${ALERT_TEXT_X} y: ${ALERT_TITLE_Y} width: ${ALERT_TEXT_W} + height: ${ALERT_TITLE_H} long_mode: DOT text: "Notification" text_font: headline diff --git a/packages/cyd.yaml b/packages/cyd.yaml index 2be84fe..c6b4ea4 100644 --- a/packages/cyd.yaml +++ b/packages/cyd.yaml @@ -18,7 +18,7 @@ ############################################################ substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.54" + SCREEN_FIRMWARE_VERSION: "0.2.55" # A tap survives a finger that drifts up to this far (320 px over 58 mm: 1 cm); further is a swipe. TOUCH_MOVE_LIMIT_PX: "56" # Shortest contact that counts as a tap; a resistive panel bounces, a capacitive one does not. @@ -95,6 +95,7 @@ substitutions: ALERT_TEXT_X: "62" ALERT_TEXT_W: "212" ALERT_TITLE_Y: "16" + ALERT_TITLE_H: "21" # one line of headline; a DOT label only ends in an ellipsis with a height ALERT_SUBTITLE_Y: "44" ALERT_SUBTITLE_H: "88" ALERT_BUTTON_W: "100" @@ -1610,6 +1611,7 @@ lvgl: x: ${ALERT_TEXT_X} y: ${ALERT_TITLE_Y} width: ${ALERT_TEXT_W} + height: ${ALERT_TITLE_H} long_mode: DOT text: "Notification" text_font: headline diff --git a/packages/guition.yaml b/packages/guition.yaml index d118f24..4b9750b 100644 --- a/packages/guition.yaml +++ b/packages/guition.yaml @@ -3,7 +3,7 @@ # Source profile for packages/guition.yaml (tools/generate_packages.py); see docs/GUITION.md. # A screen gets its tiles from the ESP Screen Manager add-on while it runs. The CYD is its own profile. substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.54" + SCREEN_FIRMWARE_VERSION: "0.2.55" # 0: no drift limit; LVGL decides, releasing inside the tile is a tap, leaving it is not # (like iOS). The CYD keeps a limit because its resistive panel jumps. TOUCH_MOVE_LIMIT_PX: "0" @@ -61,6 +61,7 @@ substitutions: ALERT_TEXT_X: "90" ALERT_TEXT_W: "304" ALERT_TITLE_Y: "26" + ALERT_TITLE_H: "32" # one line of headline; a DOT label only ends in an ellipsis with a height ALERT_SUBTITLE_Y: "68" ALERT_SUBTITLE_H: "150" ALERT_BUTTON_W: "150" @@ -1513,6 +1514,7 @@ lvgl: x: ${ALERT_TEXT_X} y: ${ALERT_TITLE_Y} width: ${ALERT_TEXT_W} + height: ${ALERT_TITLE_H} long_mode: DOT text: "Notification" text_font: headline diff --git a/screen_manager/CHANGELOG.md b/screen_manager/CHANGELOG.md index 6adb3c9..5b75f7e 100644 --- a/screen_manager/CHANGELOG.md +++ b/screen_manager/CHANGELOG.md @@ -1,3 +1,11 @@ +## 0.2.64 (firmware 0.2.55) + +A long alert title stays on its own line. + +- **An alert's title no longer runs into the text below it.** A title too long for one line, such as "Washing machine is done" on a Guition, wrapped onto a second line on top of the subtitle. It now ends in an ellipsis on one line, as the alert documentation says: "Washing machine is d...". A title that fits looks exactly as before; put the details in the subtitle. +- **Claude knows how long a title can be.** The Claude skill and the alert tips in ESP Screens said the CYD shows about forty characters of a title; both screens show about twenty. Install the skill again from Settings → Claude to get it. +- Needs firmware 0.2.55: press **Update** on the screen. Includes everything from 0.2.63. + ## 0.2.63 (firmware 0.2.54) Dark mode, for a screen beside the bed. diff --git a/screen_manager/app/claude_skill.py b/screen_manager/app/claude_skill.py index 0b1639f..b5160b8 100644 --- a/screen_manager/app/claude_skill.py +++ b/screen_manager/app/claude_skill.py @@ -181,7 +181,7 @@ actions: |---|---|---|---| {fields} -Text limits are in bytes; an accented letter takes two. Keep the title short, the CYD shows about forty characters on one line, and put details in the subtitle. +Text limits are in bytes; an accented letter takes two. Keep the title short: a screen shows about twenty characters of it on one line and ends a longer title with an ellipsis. Put details in the subtitle. ## Colors diff --git a/screen_manager/app/core.py b/screen_manager/app/core.py index 26cc9af..7517f1f 100644 --- a/screen_manager/app/core.py +++ b/screen_manager/app/core.py @@ -17,7 +17,7 @@ WEEKDAYS = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'] REPO = 'https://github.com/MaxGramser/homeassistant_espscreen' REFS = {'cyd': 'main', 'guition': 'main'} # Firmware shipped with this app release; screens below it get an update offer. -FIRMWARE_VERSION = '0.2.54' +FIRMWARE_VERSION = '0.2.55' # The Auto standby switch a screen offers Home Assistant automations. AUTO_STANDBY_MIN_FIRMWARE = '0.2.41' # The settings page the screen opens itself, and the screen.settings tile that opens it. diff --git a/screen_manager/app/static/index.html b/screen_manager/app/static/index.html index 772b40b..579205c 100644 --- a/screen_manager/app/static/index.html +++ b/screen_manager/app/static/index.html @@ -570,8 +570,8 @@