Fix what a full test round of today's releases found: a ticking single clock, a switch that works in standby, no taps from a swipe (0.2.78)
A test and code-analysis round of 0.2.72 to 0.2.76 (suites at every tag, sanitizers, ESP32 and GitHub builds, host harnesses on both boards, the editor in a browser, best practice checked against ESPHome, LVGL, Home Assistant and Vue) found these, fixed here with Max's choices for the product questions: - Firmware 0.2.65: the second hand of a single analog clock moves again; on a page that is one full on/off tile the waking push also switches it; on the Guition a flick is never a tap and a finger that slides off a tile doesn't tap it; Previous/Next react to a firm press; the same Go to page tile may sit on several pages; a layout the screen has no memory for is refused instead of crashing; 64-bit redraw mask for 48 tiles; Montserrat 14 no longer built. - App: Save refuses a layout too long for one message or too big for eight pages; an offline screen keeps its firmware version from the device registry; HA refusals reach the editor; 128 KB requests; changelog out of the live stream; cached hashed assets; tini as init and a clean stop; changelog parsing without asterisks or crashes. - Editor: clicking the open screen keeps unsaved edits, edits during a save stay unsaved, a Page row and phone dragging to other pages, repeated page tiles, limits from the server, HA's error messages, a type-checked build. - tools/check.sh + GitHub Actions + a CYD flash budget; docs match 48 tiles and the new editor. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+23
-21
@@ -38,9 +38,9 @@ Use the GitHub version for updates; a local test add-on is a separate app.
|
||||
1. Connect the screen with a **USB data cable** to the machine running Home
|
||||
Assistant. With multiple boards: connect them one at a time for the first
|
||||
installation, or check which port belongs to this screen.
|
||||
2. Open **Settings** at the top right of ESP Screens and click **New screen**. Choose CYD or Guition and give the screen a name,
|
||||
for example `Kitchen`. The device name (`kitchen`) follows from that; use
|
||||
**customize** to choose a different one.
|
||||
2. Click **New screen** in the sidebar of ESP Screens, under your screens. Choose CYD
|
||||
or Guition and give the screen a name, for example `Kitchen`. The device name
|
||||
(`kitchen`) follows from that; use **customize** to choose a different one.
|
||||
3. Wi-Fi: if `wifi_ssid` and `wifi_password` are already in the ESPHome `secrets.yaml`,
|
||||
the screen uses them automatically. If they're missing, or the file doesn't
|
||||
exist yet, the window asks for them once and ESP Screens only adds the
|
||||
@@ -93,7 +93,7 @@ USB, see [CALIBRATING.md](CALIBRATING.md).
|
||||
## 3. Pair the screen with Home Assistant
|
||||
|
||||
This happens in Home Assistant itself, outside ESP Screens. As long as a profile
|
||||
hasn't been added to Home Assistant yet, it appears on the left under **My screens**
|
||||
hasn't been added to Home Assistant yet, it appears in the sidebar under **Screens**
|
||||
as a *not yet in Home Assistant* card, with an **Open Devices & services**
|
||||
button and **Copy API key**; the done screen of **New screen** has the same
|
||||
button. The card disappears once the screen is in the list.
|
||||
@@ -115,8 +115,10 @@ Tip: in your ESPHome YAML, add the line `power_save_mode: none` under `wifi:` (n
|
||||
wizard YAMLs already have it); the screen is mains-powered, so this keeps it responding to
|
||||
Home Assistant without Wi-Fi sleep delay.
|
||||
|
||||
Select your screen, fill in the title, and search for entities. The picker has
|
||||
domain filters with colored icons. You can add up to twenty tiles.
|
||||
Select your screen, tap the bar at the top of a page to give the screen its name,
|
||||
and search for entities in the **Library** on the right. It has domain filters with
|
||||
colored icons. You can add up to 48 tiles, one for every slot
|
||||
(firmware 0.2.62+; see below for older firmware).
|
||||
The screen preview shows their placement: two columns, six slots per page,
|
||||
up to eight pages. Every tile has a fixed slot that only changes if
|
||||
you drag it; empty slots stay empty, wherever you leave them. Drag a tile
|
||||
@@ -125,27 +127,27 @@ swap (the other tile takes the freed-up slot, or otherwise the nearest free
|
||||
slot); everything else stays put. While dragging, the preview already shows where
|
||||
everything will land; an empty page then stands ready below the last page. **Add
|
||||
page** creates an empty page that's kept; an empty page gets
|
||||
**Remove page**. Click an empty slot to place the next tile from the picker
|
||||
**Remove page**. Click an empty slot to place the next tile from the library
|
||||
there. Use the arrow keys to move a focused tile.
|
||||
Click a tile for a custom name and **Configure control & display**:
|
||||
click behavior, a mini-slider, a large value, a graph (sensors), a
|
||||
weather forecast (weather), or the **Double-width** setting. A double-width tile for
|
||||
a climate, switch, light, fan, vacuum, cover, media player,
|
||||
number, select, timer, scene, script, or button gets **direct
|
||||
Click a tile and its settings open in a drawer on the right, with the preview
|
||||
still in view: a custom name, click behavior, a mini-slider, a large value, a graph
|
||||
(sensors), a weather forecast (weather), or the size: **Double-width** or **Full
|
||||
page** (firmware 0.2.62+). A double-width tile for a climate, switch, light, fan,
|
||||
vacuum, cover, media player, number, select, timer, scene, script, or button gets **direct
|
||||
control** on the right, like the rows in Home Assistant (for example temperature − / +,
|
||||
open/stop/close, volume with mute, a toggle); under **Direct control
|
||||
on the tile**, choose which set, or **None** (firmware 0.2.19+). **Open control** on
|
||||
a weather tile shows the weather card with the coming hours and days (rain included);
|
||||
on a climate tile, the card with an on/off button and the mode, fan, and
|
||||
swing settings. The built-in **Clock**
|
||||
sits at the top of the picker; find sun, timers, and people via the filters. Under
|
||||
sits at the top of the library; find sun, timers, and people via the filters. Under
|
||||
**Pastel background**, choose a custom color with dark text; **Default** restores
|
||||
the normal look, and **None** drops the card, so the content sits the same size
|
||||
directly on the screen background (firmware 0.2.16+). This requires firmware 0.2.10+.
|
||||
Adding without a chosen slot fills the first free slot. Fixed slots and empty
|
||||
slots work on the screen from firmware 0.2.26 on; older firmware shifts the
|
||||
tiles up to the first free slot, and the editor notes that below the preview.
|
||||
The preview shows the layout, not live sensor values.
|
||||
The preview shows the values Home Assistant reports right now (app 0.2.73+).
|
||||
Click **Save & send** to send your changes.
|
||||
|
||||
- Light, switch, input_boolean, and fan: tap to turn on/off.
|
||||
@@ -164,11 +166,11 @@ Click **Save & send** to send your changes.
|
||||
shows 1, 6, or 24 hours.
|
||||
- Select/input_select: open the picker menu.
|
||||
|
||||
From firmware 0.2.7, twenty tiles fit across up to four pages. Older
|
||||
firmware keeps the limit of ten until you update. Under **General settings
|
||||
→ Swipe between pages**, you can enable swiping. On the Guition (firmware
|
||||
0.2.24+), you then swipe inward from the left or right edge, like the
|
||||
back-swipe gesture on a phone; slow or fast, and a swipe starting in the
|
||||
From firmware 0.2.62, 48 tiles fit across up to eight pages. Firmware 0.2.7 to
|
||||
0.2.61 keeps the limit of twenty (four pages) and older firmware ten, until you
|
||||
update. In the **Screen settings** tab, **Swipe between pages** turns on swiping.
|
||||
On the Guition (firmware 0.2.24+), you then swipe inward from the left or right
|
||||
edge, like the back-swipe gesture on a phone; slow or fast, and a swipe starting in the
|
||||
middle of the screen does nothing, so tapping and dragging tiles never
|
||||
accidentally changes pages. On the CYD, it stays a quick swipe across the screen. Sliders
|
||||
only control their value; detail menus and standby don't change pages.
|
||||
@@ -263,8 +265,8 @@ HA mechanisms used: [Ingress](https://developers.home-assistant.io/docs/apps/pre
|
||||
|
||||
Update ESP Screen Manager to 0.1.2 and install the new firmware once
|
||||
via your **existing** ESPHome device → Install → Wirelessly. Keep your own YAML
|
||||
with Wi-Fi and keys. Then open the screen in ESP Screen Manager and expand
|
||||
**Screen settings**. After adjusting, click **Save & send**.
|
||||
with Wi-Fi and keys. Then open the screen in ESP Screen Manager and its
|
||||
**Screen settings** tab. A change there applies at once; there is nothing to save.
|
||||
After this, changes to these settings don't need a new firmware flash.
|
||||
|
||||
| Setting | Options | Default |
|
||||
|
||||
+11
-10
@@ -27,10 +27,10 @@ carry over `calibration.yaml` or the XPT2046 correction.
|
||||
### Mounting and screen rotation (runtime 0.2.9+)
|
||||
|
||||
Install Guition firmware 0.2.9 and ESP Screen Manager 0.2.9. Open the screen
|
||||
in the management page, go to **Screen settings**, and choose 0°, 90°, 180°,
|
||||
or 270° (clockwise) under **Rotate screen**. Click save. After that, a
|
||||
firmware flash is no longer needed to change the angle. The setting is kept
|
||||
in the app data and on the screen after a restart.
|
||||
in the management page, open the **Screen settings** tab, and choose 0°, 90°,
|
||||
180°, or 270° (clockwise) under **Rotation**. It applies at once; there is
|
||||
nothing to save. After that, a firmware flash is no longer needed to change the
|
||||
angle. The setting is kept in the app data and on the screen after a restart.
|
||||
|
||||
This uses native ESPHome/LVGL rotation for both display and touch, with no changes
|
||||
to the panel initialization or GT911 mirroring. After mounting, physically check the
|
||||
@@ -39,18 +39,19 @@ only visible for the Guition once its new firmware has been discovered by HA.
|
||||
The CYD stays on its existing orientation with its own calibration.
|
||||
|
||||
Six tiles of **218 × 108 pixels** per page, 12px spacing, and a
|
||||
separate navigation strip. In ESP Screen Manager, twenty tiles fit across up to
|
||||
four pages; navigation disappears at six or fewer. The current interface has a
|
||||
light gray background, white cards, and colored domain icons. From 0.2.10, you
|
||||
can choose a pastel background with dark text per tile. Standby starts
|
||||
after ten minutes without touch by default and is adjustable in the management page.
|
||||
separate navigation strip. In ESP Screen Manager, up to 48 tiles fit across up to
|
||||
eight pages (firmware 0.2.62+; twenty over four pages before); navigation disappears
|
||||
at six or fewer. The current interface has a light gray background, white cards,
|
||||
and colored domain icons. From 0.2.10, you can choose a pastel background with
|
||||
dark text per tile. Standby starts after ten minutes without touch by default and
|
||||
is adjustable in the management page.
|
||||
The backlight dims through ESPHome's own light transition (1.5 s to standby, 80 ms to
|
||||
wake). Firmware 0.2.13-0.2.56 used the LEDC hardware fader (`backlight_fade.h`) instead;
|
||||
0.2.57 went back to ESPHome's transition, because that fader reached into ESPHome's LEDC
|
||||
output, which ESPHome 2026.8 no longer allows.
|
||||
|
||||
The existing tile actions, climate control, and vacuum card are preserved.
|
||||
Every card type works in all twenty positions.
|
||||
Every card type works in all 48 positions.
|
||||
|
||||
## New installation
|
||||
|
||||
|
||||
+78
-9
@@ -23,16 +23,42 @@
|
||||
The editor is the Vue app in `web/`: after a change under `web/src`, run
|
||||
`cd web && npm ci && npm test && npm run check && npm run build` and commit
|
||||
`screen_manager/app/static` with it (that folder is the build output; never edit it by hand).
|
||||
2. Run all Python tests with aiohttp installed, all `tests/*.cpp`, the
|
||||
generator with `--check`, and compile both Easy Setup profiles. Do that
|
||||
sequentially: profiles with the same `DEVICE_NAME` share one build folder, and a
|
||||
parallel build can make an upload pick the wrong `firmware.bin`. Check that no
|
||||
secrets are in Git.
|
||||
2. Run `tools/check.sh` (with `PYTHON=.venv-portal/bin/python` on a development machine). It runs all
|
||||
Python tests with aiohttp, PyYAML, Pillow and fontTools installed, every `tests/*.cpp` with
|
||||
`clang++ -std=c++17 -Wall -Wextra -Werror -I.`, both generators with `--check`, and the editor's
|
||||
`npm ci`, `npm test`, `npm run check` and `npm run build`, and fails when that fresh build differs from the
|
||||
`screen_manager/app/static` in Git (committed or staged). For a firmware change, `tools/check.sh --firmware`
|
||||
compiles both board profiles with placeholder secrets from a temporary folder (never the real `secrets.yaml`) and
|
||||
applies the flash budget below; `--all` does both. CI (`.github/workflows/ci.yml`) runs the same script on every
|
||||
push and pull request to main. Compile sequentially: profiles with the same `DEVICE_NAME` share one build folder,
|
||||
and a parallel build can make an upload pick the wrong `firmware.bin` (the check builds are called `check-cyd` and
|
||||
`check-guition` and build under `.esphome/check`, apart from the bench profiles). Check that no secrets are in Git.
|
||||
|
||||
**Flash budget of the CYD** (Max's rule, app 0.2.78). The CYD has 4 MB of flash and two update slots of
|
||||
1,835,008 bytes; the Guition's 16 MB leave it far from any limit. Measure the CYD on the build users get: the YAML
|
||||
`core.installation_yaml()` writes has the Wi-Fi fallback access point (`wifi: ap:`) and `captive_portal:`, about
|
||||
84 KB more than a profile without them. The board profiles carry both, so `tools/check.sh --firmware` measures
|
||||
that shape; it reads the slot from the build's `partitions.csv` (`app0`, `ota_0`) and the image from
|
||||
`firmware.ota.bin`, and `--baseline <bytes>` prints the delta against the last release. The check-profile tables
|
||||
in earlier test results left both out and read about 84 KB low (0.2.72: 1,453,647 bytes, 79.2 %, where the
|
||||
user-shaped build was 1,538,032 bytes, 83.8 %). Build with the add-on's pinned ESPHome (`screen_manager/Dockerfile`)
|
||||
and, when the ESPHome Device Builder ships a newer ESPHome, with that one too (`ESPHOME=<its esphome command>`),
|
||||
because users build their updates there.
|
||||
|
||||
| CYD image, share of 1,835,008 bytes | Rule |
|
||||
|---|---|
|
||||
| up to 90 % | normal |
|
||||
| 90-93 % | tight: every release states its flash delta; a delta over 8 KB needs a matching saving or Max's OK |
|
||||
| 93-95 % | only fixes ship |
|
||||
| over 95 % | never: that keeps about 90 KB for ESPHome upgrades and users' own overrides |
|
||||
3. Test app start, saving, restarting/updating with existing layouts,
|
||||
reconnecting to HA, and an ESP restart. Test a new card on real
|
||||
hardware. A good build doesn't replace physical touch acceptance.
|
||||
4. Bump the app version and firmware project version; write the CHANGELOG and concrete
|
||||
test results. Only publish compatible changes directly to main.
|
||||
test results. Only publish compatible changes directly to main. `tests/test_release_lint.py`
|
||||
(part of `tools/check.sh`) holds `config.yaml`'s version, the first CHANGELOG heading and its
|
||||
firmware against `FIRMWARE_VERSION`, keeps the CHANGELOG headings unique and newest first, and checks
|
||||
that every `fonts/...` file the packages fetch from GitHub is in the tree.
|
||||
5. Commit and push main (the only release branch). Create an immutable tag
|
||||
`screens-vX.Y.Z` from the same commit. Test the remote YAML in an empty folder:
|
||||
all components/fonts must be fetchable via GitHub.
|
||||
@@ -52,7 +78,7 @@ For backend tests on a development machine:
|
||||
|
||||
```sh
|
||||
python3 -m venv .venv-portal
|
||||
.venv-portal/bin/pip install aiohttp PyYAML
|
||||
.venv-portal/bin/pip install aiohttp PyYAML Pillow fonttools
|
||||
.venv-portal/bin/python -m unittest discover -s tests
|
||||
```
|
||||
|
||||
@@ -189,6 +215,34 @@ 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.78 / firmware 0.2.65
|
||||
|
||||
Repeated navigation tiles: the same `screen.page_<n>` may sit on several pages of one screen. Firmware 0.2.65 accepts
|
||||
repeats of `screen.page_*` only (`Model::set_layout`, `page_entity()`); every Home Assistant entity still appears once.
|
||||
The app sends a repeat only to 0.2.65+ (`PAGE_TILE_REPEAT_MIN_FIRMWARE` in `min_firmware`); an older screen gets
|
||||
"Install screen firmware 0.2.65 or newer first". Tile events from Claude in HA pick a copy by `slot`/`page` (move:
|
||||
`from_slot`/`from_page`); without one they act on the first copy in slot order, and the answer names its page and slot.
|
||||
|
||||
- Firmware: `dirty_tiles` is 64 bits (`tile_bit`, `mark_tile`, `static_assert(MAX_TILES <= 64)`). `set_layout` refuses a
|
||||
layout whose tile list does not fit the largest free block (`tile_room`, ESP32 only) and reports it through
|
||||
`Model::refusal`; `TileAllocator` logs and aborts on a null block instead of writing through it. The second hand
|
||||
moves on `analog` and `calendar` dials while part 18 is an `lv_line` (`lv_obj_check_type`). Guition: an
|
||||
`LV_EVENT_GESTURE` handler on `home_page` consumes the contact (no page flip; LVGL needs speed and 50 px), and
|
||||
`runtime_tiles::event` drops a tap or hold released outside the tile (`lv_obj_hit_test`); LVGL's `PRESS_LOCK` stays so
|
||||
a finger that slides on to a slider never drags it. `dim_wake_overlay` calls `runtime_tiles::wake_tap()` after
|
||||
`wake_display`: on a page that is one full tile whose tap is `<domain>.toggle`, the waking push also taps it. Page
|
||||
bars (tile pages and the settings page) react to `on_click`/`LV_EVENT_CLICKED`. `lvgl: default_font` is a Roboto font
|
||||
of each board, so ESPHome no longer builds Montserrat 14 (CYD -13.9 KB).
|
||||
- App: `Manager.save` encodes the real layout message and refuses one over 4096 bytes; `core.packed_slots` refuses tiles
|
||||
that don't fit eight pages. `discover_screens` adds `firmware_known`: the "Screen firmware" sensor when it holds a
|
||||
strict X.Y.Z, else the device registry's `sw_version` in the form `X.Y.Z (ESPHome …)`. Every screen in the inventory
|
||||
carries `firmware_known`, `tile_limit`, `full_page` and `page_tiles_repeat`; the changelog moved from the update
|
||||
summary (and the live stream) to the full inventory's top-level `changelog`. HA refusals answer 400 and an unreachable
|
||||
HA 503, both JSON `{"error"}`. `client_max_size` 128 KB. Hashed `/assets/` files get `private, max-age=31536000,
|
||||
immutable`; the page and `/api` keep `no-store`. `config.yaml` drops `init: false` (tini is PID 1 again) and the server
|
||||
uses aiohttp's `handle_signals`.
|
||||
- Editor: `npm run build` type-checks first (`vue-tsc --noEmit`), `devEngines` pins Node. Storage unchanged.
|
||||
|
||||
### Compatibility 0.2.74 / firmware 0.2.62
|
||||
|
||||
Forty-eight tiles per screen, a tile over the whole page (`size: full`) and navigation tiles (`screen.page_1` to
|
||||
@@ -196,6 +250,11 @@ Forty-eight tiles per screen, a tile over the whole page (`size: full`) and navi
|
||||
gets "Install screen firmware 0.2.62 or newer first". Older apps keep working with this firmware: they never send
|
||||
`full` or a page tile, and the firmware still packs `wide` as before.
|
||||
|
||||
Downgrade: an app older than 0.2.74 stops at startup on a stored layout with more than 20 tiles or a page tile
|
||||
(`validate_layout` raises "Choose at most 20 tiles." or "This entity isn't supported." even with `stored=True`);
|
||||
`screens.json` stays untouched. Before going back, trim the layout to 20 normal tiles, or restore the app backup (the
|
||||
Supervisor restores the version and its data together).
|
||||
|
||||
- Firmware: `MAX_TILES` is `MAX_SLOTS` (48). `Model::tiles` is a `std::vector` sized to the layout (a `TileAllocator`
|
||||
over ESPHome's `RAMAllocator`, so a Guition keeps the list in PSRAM; the CYD's falls back to its heap); nothing may
|
||||
index `tiles` beyond `count`. A `Tile` has `full` next to `wide` (a full tile is also wide) and `cells()`; `pack()`
|
||||
@@ -227,6 +286,9 @@ storage or editor change, and an older app drives this firmware as before.
|
||||
the Guition), a contact that moved, a contact that already counted, and a tap within 150 ms of the last accepted
|
||||
tap on the same button (bounce). `show_page` already drops a fill still under way when the next page is asked for,
|
||||
so nothing else changed. `tests/test_cyd_ui.cpp` covers the page buttons.
|
||||
- On the CYD a lift-off bounce is stopped first by the XPT2046 filter (`components/xpt2046/touchscreen/touch_filter.h`:
|
||||
three matching samples start a contact, two empty samples release it, one empty sample is ignored); the 40 ms
|
||||
minimum and the 150 ms same-button gap of `accept_repeat` are backup nets behind it (noted 2026-09-18).
|
||||
- The settings page's own pager (`settings_screen.h`) never used the guard and is unchanged. Tile taps, cards, keys,
|
||||
chips and sliders keep `accept()` and its window.
|
||||
|
||||
@@ -1138,8 +1200,15 @@ rotation mapping, `update()`, `end()`); the indev callback is gone. Otherwise un
|
||||
### Compatibility 0.2.33 / firmware 0.2.28
|
||||
|
||||
Firmware only. `TouchGuard::configure(0, ...)` disables the movement limit
|
||||
(`moved_` is then never set; LVGL's press-lost decides whether a tap goes through). The
|
||||
Guition profile sets `TOUCH_MOVE_LIMIT_PX` to 0, the CYD keeps 56. Otherwise unchanged.
|
||||
(`moved_` is then never set). The Guition profile sets `TOUCH_MOVE_LIMIT_PX` to 0, the
|
||||
CYD keeps 56. Otherwise unchanged.
|
||||
|
||||
Correction (2026-09-18): this note said LVGL's press-lost then decides whether a tap goes
|
||||
through. It doesn't: a tile keeps LVGL's `LV_OBJ_FLAG_PRESS_LOCK` (on by default), so a
|
||||
finger that slides off never sends `LV_EVENT_PRESS_LOST`, and on the Guition a release
|
||||
outside the tile still counted as a tap. From firmware 0.2.65 a tile without a movement limit
|
||||
checks it itself (`runtime_tiles::event`): a tap or hold whose finger lets go outside the tile
|
||||
does nothing. PRESS_LOCK stays on.
|
||||
|
||||
### Compatibility 0.2.32 / firmware 0.2.27
|
||||
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
# Testresultaten app 0.2.33 / firmware 0.2.28 (2026-09-14)
|
||||
|
||||
Alleen firmware: op de Guition beslist LVGL of een tik doorgaat (loslaten binnen de tegel
|
||||
telt), de verplaatsingsgrens van de tap-guard staat daar uit. Max koos dit na een live
|
||||
geweigerde druk van 73 px op Studio 1.
|
||||
Alleen firmware: op de Guition zou LVGL beslissen of een tik doorgaat (loslaten binnen de
|
||||
tegel telt; zie de correctie hieronder), de verplaatsingsgrens van de tap-guard staat daar
|
||||
uit. Max koos dit na een live geweigerde druk van 73 px op Studio 1.
|
||||
|
||||
## Wat veranderde
|
||||
|
||||
- `TouchGuard::configure(move_limit_px, ...)` met 0 betekent geen grens: `moved_` wordt nooit
|
||||
gezet, `accept()` en `accept_repeat()` kijken alleen nog naar duur, dubbel gebruik en
|
||||
dender. LVGL's press-lost (vinger verlaat het object) bepaalt of de klik doorgaat.
|
||||
dender. LVGL's press-lost (vinger verlaat het object) zou bepalen of de klik doorgaat.
|
||||
- Guition-profiel `TOUCH_MOVE_LIMIT_PX: "0"`; CYD blijft 56 (resistief paneel springt).
|
||||
- Correctie (2026-09-18): LVGL beslist dat niet. Een tegel houdt LVGL's `LV_OBJ_FLAG_PRESS_LOCK`
|
||||
(standaard aan), dus een vinger die van de tegel schuift stuurt nooit `LV_EVENT_PRESS_LOST`, en
|
||||
loslaten buiten de tegel telde op de Guition nog steeds als tik. Vanaf firmware 0.2.65 controleert
|
||||
de tegel dat zelf (`runtime_tiles::event`): een tik of vasthouden waarbij de vinger buiten de tegel
|
||||
loslaat, doet niets. PRESS_LOCK blijft aan.
|
||||
|
||||
## Geautomatiseerd
|
||||
|
||||
@@ -24,6 +29,7 @@ geweigerde druk van 73 px op Studio 1.
|
||||
## Nog te controleren op Studio 1
|
||||
|
||||
- Een stevige, schuivende druk op een tegel voert de actie uit zolang je binnen de tegel
|
||||
loslaat; over de rand van de tegel loslaten doet niets (LVGL press-lost).
|
||||
loslaat; over de rand van de tegel loslaten doet niets (zo bedoeld; waar vanaf firmware 0.2.65,
|
||||
zie de correctie hierboven).
|
||||
- De randveeg (0.2.27) na een update zonder eerst een kaart te sluiten, en de eerste veeg
|
||||
na een paginawissel; het log meldt `randveeg niet gevuurd: …` als hij te kort was.
|
||||
|
||||
@@ -72,5 +72,8 @@ the sizes differ from the bench profiles by the length of those strings; the cod
|
||||
|
||||
- Real hardware: neither bench screen ran this firmware before the release. Max's own screens get it through Update;
|
||||
the tap that started this is the one to try there, on the Guition and on the CYD.
|
||||
- A resistive panel's lift-off bounce on the CYD is covered by the 40 ms minimum contact and the 150 ms gap, the same
|
||||
net the -/+ keys have had since 0.2.25 (physically tested then), not by a new measurement.
|
||||
- A resistive panel's lift-off bounce on the CYD, not measured again. Correction (2026-09-18, touch analysis): the
|
||||
first net for that bounce is the XPT2046 filter (`components/xpt2046/touchscreen/touch_filter.h`), which starts a
|
||||
contact only after three matching samples, ignores one empty sample and releases after two, so a bounce never
|
||||
reaches LVGL as a new tap. `accept_repeat`'s 40 ms minimum contact and 150 ms same-button gap are backup nets
|
||||
behind it, the same the -/+ keys have had since 0.2.25 (physically tested then).
|
||||
|
||||
@@ -24,7 +24,8 @@ CHANGELOG 0.2.74 and the compatibility note in docs/RELEASING.md. Built on 0.2.7
|
||||
|
||||
- Python (`.venv-portal`): 396 tests OK, including the new `tests/test_full_page_tiles.py` (sizes and footprints,
|
||||
in-order packing, free slots, validation of full and page tiles, the firmware they need, the layout sensor, the wire
|
||||
form of built-in tiles, tile events for Claude in Home Assistant, the 48 limit).
|
||||
form of built-in tiles, tile events for Claude in Home Assistant, the 48 limit). Correction: the committed 0.2.74
|
||||
runs 409 tests; 396 was counted on the branch before the rebase onto the Vue editor.
|
||||
- C++ (`c++ -std=c++17 -Wall -Wextra -pedantic`): 17/17 PASS. `tests/test_runtime_model.cpp` now covers 48 tiles, a
|
||||
list sized to the layout, `screen.page_<n>` validation and page targets, and full tiles in `pack()` and `place()`
|
||||
(a page of their own, snapping to the page start, the page count).
|
||||
@@ -77,7 +78,9 @@ the harness follows each board's demo layout). What the checks cover:
|
||||
Both bench boards were OTA-flashed with firmware 0.2.62 from the Mac (`esphome upload easy-<board>-device.yaml
|
||||
--device <ip>`), the Guition first, and report 0.2.62 in Home Assistant. Heap right after boot (HA sensors): Guition
|
||||
89 KB free / 60 KB minimum / 45 KB largest block (0.2.59: 76 / 57 / 33), CYD 116 KB / 107 KB / 59 KB (0.2.59: 106 /
|
||||
96 / 51).
|
||||
96 / 51). Correction: the after-boot figures are not the steady state. With 48 populated tiles the CYD has about
|
||||
97 KB free, a 49 KB largest block and a 78.6 KB minimum; a 13-tile steady state is about 98 KB free / 49 KB largest
|
||||
block, so compare against those, not against 116 / 59.
|
||||
|
||||
- `hw_push.py <scene> [cyd]` pushes one full-page scene straight to a board's `screen_message` action and, on the
|
||||
Guition, snapshots the LVGL render through `ui_snapshot`: the big button (lit amber, in Max's dark look a brown
|
||||
|
||||
@@ -33,8 +33,11 @@ Measured by compiling the same profile twice at the same commit (0.2.72, `9f5694
|
||||
| 4 bpp (this release) | 1 632 736 bytes | 89.0 % |
|
||||
| difference | +94 704 bytes | +5.2 points |
|
||||
|
||||
On 0.2.74 (`bb25353`, which added the 40 px full-page font and the 48-tile code) the release build is 1 655 568 bytes,
|
||||
90.2 % of the slot, static RAM 21.7 % (71 188 of 327 680 bytes); about 180 KB stay free for later rounds.
|
||||
Correction (after the release): that table was measured at 0.2.72, before 0.2.74's 40 px full-page icon font, which
|
||||
also went to 4 bpp. The released CYD build of this commit (`261fa82`) is 1 655 584 bytes, 90.2 % of the 1 835 008-byte
|
||||
slot: +107 744 bytes against 0.2.74 (1 547 840 bytes, 84.4 %), matching ESPHome's own glyph count (+107 756 bytes).
|
||||
So the release costs 108 KB, not 95 KB, and the slot is 90 % full, not 89 %. Static RAM 21.7 % (71 188 of 327 680
|
||||
bytes); about 180 KB stay free for later rounds.
|
||||
|
||||
The glyph bitmaps alone grow by 108 KB (309 icons at three sizes plus the big font, counted with freetype); the
|
||||
linker's alignment takes a little of that back. Fonts live in flash, so RAM does not move (24.1 % static in both
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# Test results app 0.2.78 / firmware 0.2.65 (2026-09-18)
|
||||
|
||||
Max: "ga eens je ultra best doen om de commits van vandaag lokaal 100% te testen", then "gedegen code analyse en check op
|
||||
internet of dit best practise is", and after the report "can you address them?". This release fixes what that test round
|
||||
of 0.2.72 to 0.2.76 found, with Max's choices for the product questions: a swipe is never a tap, the waking push also
|
||||
switches a full-page switch, and the same page tile may sit on several pages. See CHANGELOG 0.2.78 and the compatibility
|
||||
note in docs/RELEASING.md.
|
||||
|
||||
## The test round of 0.2.72 to 0.2.76 (before the fixes)
|
||||
|
||||
- Python suite at every release point: 386 (2cb3479, 9f5694b), 398 (1ed42dc), 409 (bb25353, 261fa82), 0 skips, no
|
||||
order dependence over 43 runs (reverse, shuffled, `-X dev`). Only the older test_camera.Feed timing flake failed.
|
||||
- C++: 17/17 at every tag with the project's flags, ASan + UBSan, libc++ hardening, g++ 16 with `_GLIBCXX_DEBUG`, plus
|
||||
594 new runtime_model checks, 20,022 comparisons with the add-on's packing and 200,000 fuzz rounds, all clean.
|
||||
- Editor: Vitest 46/46, vue-tsc clean, and the committed bundle rebuilt byte for byte at 1ed42dc, bb25353 and 261fa82.
|
||||
- ESP32 builds of both boards, also fetched from GitHub the way users get them; the add-on image built and started.
|
||||
- Host harnesses: full page 37/37 per board, page buttons 12/12 per board (the 0.2.71 rule fails 3/12 and 4/12, as it
|
||||
should), wake/sleep, settings, cover and history on the Guition without regressions; 4 bpp icons measured (2 grey
|
||||
levels became 15 to 16).
|
||||
- Found and fixed here: the frozen second hand of a single analog clock (since 0.2.74), unsaved edits lost when clicking
|
||||
the open screen, dragging to page 2+ on a phone, Identify and Try it answering 500, a 48-tile layout too long for one
|
||||
message saving anyway, packing past slot 47, an offline screen counted as very old firmware, the 32-bit redraw mask,
|
||||
a crash instead of a refusal when memory runs out, a firm press on Previous/Next doing nothing, python as PID 1
|
||||
(every stop took 10 s), the 16 KB request limit, asterisks in What's new, docs that still said twenty tiles.
|
||||
|
||||
## Automated (this release)
|
||||
|
||||
- `tools/check.sh` (new; the same script runs in GitHub Actions), on this release rebased onto 0.2.77 (the media card):
|
||||
Python 454 tests OK, C++ 18/18 with `-Wall -Wextra -Werror`, packages and icons current, Vitest green, vue-tsc clean, build, and the committed editor bundle
|
||||
equal to a fresh build.
|
||||
- `tools/check.sh --firmware` with ESPHome 2026.6.2, on copies of both board profiles with the fallback access point and
|
||||
captive portal users get:
|
||||
|
||||
| Board | firmware.bin | of the app slot | vs 0.2.75 |
|
||||
|---|---|---|---|
|
||||
| CYD | 1,652,384 B | 90.0 % of 1,835,008 B (183 KB free) | -3,200 B (Montserrat 14 no longer built: -13,936 B; the 0.2.77 media card adds the rest) |
|
||||
| Guition | 2,026,608 B | 24.9 % of 8,126,464 B | |
|
||||
|
||||
The CYD sits at the edge of the new budget's "tight" band (90-93 %): the next release states its flash delta.
|
||||
|
||||
## Firmware on the Mac (host builds, virtual finger)
|
||||
|
||||
- Full-page harness (`fullpage_host.py`, 37 checks: taps, holds, drags, keys, page jumps, 48 tiles, six forecast/clock
|
||||
flips), on the fixes before the rebase onto 0.2.77: Guition 37/37, CYD 37/37. The CYD's first run gave 36/37: the
|
||||
harness repeats a tap when the host loop stretches the contact past 350 ms, and the firmware had already counted the
|
||||
first one (two light.toggle calls 0.7 s apart); the rerun without that stall passed 37/37.
|
||||
|
||||
## Not tested
|
||||
|
||||
- On real hardware: nothing of this release has run on a bench screen yet. To check on the glass: a single analog clock
|
||||
ticks; a flick across a full-page light on the Guition does nothing while a tap and a hold still work; one push on a
|
||||
dimmed screen with a full-page light switches it; a firm press on Next turns the page.
|
||||
- Unit tests cover the repeated page tiles (tests/test_runtime_model.cpp and the Python suite), the memory refusal (a
|
||||
stand-in for the free block size on the host), a consumed contact after a flick and the 300 ms page-bar case. The
|
||||
gesture handler, the slide-off check and the waking push run inside LVGL and have code review only, no host harness
|
||||
run with a finger.
|
||||
- Build machine note: Homebrew's Python 3.14.7 cannot load pyexpat on macOS 26.2 (system libexpat lacks
|
||||
`XML_SetAllocTrackerActivationThreshold`), which breaks PlatformIO's penv; the builds here ran with ESPHome 2026.6.2 in a
|
||||
Python 3.11 venv.
|
||||
Reference in New Issue
Block a user