Put ESP Screens in English and keep layouts when entity IDs change (0.2.40)

Everything a user sees or reads is now English: both boards' labels,
status replies and logs, the ESP Screens editor and Alerts cheatsheet,
and the README and guides (docs/TILES.md, CALIBRATING.md, ACCEPTANCE.md
and TROUBLESHOOTING.md replace the Dutch file names). Labels follow
Home Assistant's own English names (Heat/Cool modes, Heating/Cooling
actions, Away, Returning to dock, weather conditions), dates use English
abbreviations and the top bar writes numbers the English way. Docs use
HA 2026.9's menu names (Settings -> Apps, App store, Settings -> Tools).
Unused legacy files (home-like.yaml, buttons.yaml, a.out) are removed.

Firmware 0.2.34 names its entities in English. Home Assistant registers
a renamed ESPHome entity under a new entity ID, so the inbox
text.<screen>_tegelinstellingen becomes text.<screen>_tile_settings and
the layout stored under the old ID would be lost. The manager now
recognises the screen by its device, during a run or after a restart,
and moves its layout and update history along; the Update button and
the nightly round follow the screen through the rename. Screens that
still run 0.2.33 or older keep working: both languages are matched.

Main is the only release branch from now on.

Tested on a Home Assistant Yellow (HA 2026.9.1) with both bench boards:
see docs/TEST_RESULTS_0240.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Max Gramser
2026-09-15 02:08:43 +02:00
parent f60eed3ff6
commit 3e959b3df9
87 changed files with 5049 additions and 11167 deletions
+85 -85
View File
@@ -1,60 +1,60 @@
> Historisch onderzoek aan één paneel. Voor een nieuw scherm: [README.md](README.md)
> en [de vijfpuntskalibratie](docs/CALIBREREN.md); neem geen meetwaarden over.
> Historical investigation on a single panel. For a new screen, see [README.md](README.md)
> and [the five-point calibration](docs/CALIBRATING.md); don't reuse these measurements.
# ESP32-2432S028: stabiele bediening
# ESP32-2432S028: stable operation
Gebruik **home-like-2432s028.yaml** voor de aangesloten 2,8-inch CYD met
ILI9341 en XPT2046. `home-like.yaml` hoort bij het andere ST7789V/GT911-bord.
De wifi-, API- en OTA-geheimen blijven in `secrets.yaml`.
Use **home-like-2432s028.yaml** for the connected 2.8-inch CYD with
ILI9341 and XPT2046. The Wi-Fi, API, and OTA secrets stay in `secrets.yaml`.
## Bediening
## Operation
- Stel `TILE_COUNT` in op het aantal gebruikte tegels (1–10). Bij maximaal
zes tegels verdwijnen beide paginaknoppen en de pagina-aanduiding; hogere
tegelnummers zijn verborgen.
- Pagina 1 bevat tegels 1–6; pagina 2 bevat 7–10. Gebruik de knoppen
**Vorige** en **Volgende** onderaan. Slepen is uitgeschakeld.
- Kort tikken voert de bestaande tegelactie uit. Lang indrukken opent de
bestaande licht-, climate- of vacuumkaart, of de ingestelde lange actie.
- Standby begint na tien minuten zonder aanraking (`AUTO_DIM_TIMEOUT: "600"`).
- De eerste tik op het gedimde scherm maakt het scherm wakker.
- Contacten korter dan `TOUCH_MIN_PRESS_MS` (60 ms op de CYD, 20 ms op de
Guition) worden genegeerd. Eén aanraking kan maximaal één tegelactie geven;
een verplaatsing groter dan `TOUCH_MOVE_LIMIT_PX` (56 px, circa 1 cm, op de CYD;
0 op de Guition: geen grens, LVGL beslist en loslaten binnen de tegel telt) ten
opzichte van het gesettelde eerste contactpunt annuleert de tik; alleen het eerste
contact telt; dezelfde tegel wordt 600 ms tegen contactdender beschermd. Een geweigerde tik staat met reden in het log (tag `touch`).
- De thermostaat verstuurt de afgeronde, begrensde temperatuur die hij toont.
Een lokale temperatuur- of moduskeuze krijgt drie seconden om met HA te
synchroniseren. Een ingedrukte bediening voorkomt automatisch dimmen.
- Pippa gebruikt de echte `vacuum.s8`-status, zodat docken, schoonmaken,
pauzeren en terugkeren onderscheiden worden. Ontbrekende HA-statussen
worden als `Niet beschikbaar` getoond.
- Set `TILE_COUNT` to the number of tiles in use (1–10). With six tiles or
fewer, both page buttons and the page indicator disappear; higher
tile numbers stay hidden.
- Page 1 holds tiles 1–6; page 2 holds 7–10. Use the **Previous**
and **Next** buttons at the bottom. Swiping is disabled.
- A short tap runs the tile's existing action. A long press opens the
existing light, climate, or vacuum card, or the configured long-press action.
- Standby starts after ten minutes without touch (`AUTO_DIM_TIMEOUT: "600"`).
- The first tap on the dimmed screen wakes the screen.
- Contacts shorter than `TOUCH_MIN_PRESS_MS` (60 ms on the CYD, 20 ms on the
Guition) are ignored. One touch can produce at most one tile action;
a movement greater than `TOUCH_MOVE_LIMIT_PX` (56 px, about 1 cm, on the CYD;
0 on the Guition: no limit, LVGL decides and releasing inside the tile counts)
relative to the settled first contact point cancels the tap; only the first
contact counts; the same tile is protected against contact bounce for 600 ms.
A rejected tap is logged with its reason (tag `touch`).
- The thermostat sends the rounded, clamped temperature it displays.
A local temperature or mode choice gets three seconds to sync with HA.
An active control press prevents automatic dimming.
- Pippa uses the real `vacuum.s8` status, so docking, cleaning,
pausing, and returning are distinguished. Missing HA states
are shown as `Unavailable`.
## Technische keuzes
## Technical choices
ESPHome 2026.6.2 met ESP-IDF; er zijn geen Arduino-componenten nodig.
De displaybus draait op 40 MHz, zoals ESPHome's standaard CYD-profiel.
XPT2046 wordt elke 20 ms uitgelezen zonder GPIO36-interrupt. De drukdrempel
is 800, na een verdachte hoekmeting bij druk 422. Een lokale XPT2046-driver
vereist drie consistente ADC-samples voor een nieuwe aanraking, negeert losse
uitschieters en wacht twee drukloze samples af voor loslaten. Dit voegt circa
40–60 ms toe bij aanraken en voorkomt dat een onstabiele eerste meting meteen
als een andere knop wordt geïnterpreteerd. De driver staat onder `components/`. De geïnstalleerde
interruptdriver probeert op die input-only pin een niet-beschikbare interne
pull-up te activeren; de oude firmware logde hiervoor een GPIO-fout.
ESPHome 2026.6.2 with ESP-IDF; no Arduino components are needed.
The display bus runs at 40 MHz, like ESPHome's standard CYD profile.
XPT2046 is polled every 20 ms without the GPIO36 interrupt. The pressure
threshold is 800, after a suspect corner reading at pressure 422. A local XPT2046
driver requires three consistent ADC samples for a new touch, ignores isolated
outliers, and waits for two pressure-free samples before release. This adds about
40–60 ms on touch and prevents an unstable first reading from being immediately
interpreted as a different button. The driver lives under `components/`. The stock
interrupt driver tries to enable an unavailable internal pull-up on that
input-only pin; the old firmware logged a GPIO error for this.
LVGL krijgt 12% tekenbuffer. Geen scrollanimaties en geen extra flitspuls na
elke tik. Tegelachtergronden zijn ondoorzichtig. Updates binnen 100 ms worden
samengevoegd; ongewijzigde tegellabels en kleuren worden niet opnieuw gezet.
De UI-initialisatie draait pas nadat LVGL is gestart. De klok ververst direct
bij tijdsynchronisatie. Roboto staat lokaal in `fonts/`, inclusief OFL-licentie.
LVGL gets a 12% draw buffer. No scroll animations and no extra flash pulse after
each tap. Tile backgrounds are opaque. Updates within 100 ms are
coalesced; unchanged tile labels and colors are not redrawn.
UI initialization only runs after LVGL has started. The clock refreshes immediately
on time sync. Roboto is bundled locally in `fonts/`, including the OFL license.
De actieve indeling is 320×240. De oude, uitgecommentarieerde portretpresets
zijn nog geen aangepaste paginalay-outs: reserveer bij een andere oriëntatie
ook onderaan 34 pixels voor de navigatie en controleer de tegelposities.
The active layout is 320×240. The old, commented-out portrait presets
are not adapted page layouts yet: with a different orientation, also reserve
34 pixels at the bottom for navigation and check the tile positions.
## Bouwen en flashen
## Building and flashing
```sh
esphome compile home-like-2432s028.yaml
@@ -62,12 +62,12 @@ esphome upload home-like-2432s028.yaml --device /dev/cu.usbserial-130
esphome logs home-like-2432s028.yaml --device /dev/cu.usbserial-130
```
Sluit een lopende seriële loglezer voordat je flasht. De vorige configuratie
staat lokaal in `diagnostics/before-2432s028.yaml.bak`; de bijbehorende vorige
factorybinary in `diagnostics/before-2432s028.factory.bin`. Deze lokale backups
worden niet in Git opgenomen. Teruggaan kan door de backup als configuratie
te herstellen en opnieuw te bouwen/flashen; herstel de oude Arduino-toolchain
als je de oude configuratie bouwt.
Close any running serial log reader before flashing. The previous configuration
is stored locally in `diagnostics/before-2432s028.yaml.bak`; the corresponding previous
factory binary is in `diagnostics/before-2432s028.factory.bin`. These local backups
are not included in Git. You can roll back by restoring the backup as the configuration
and rebuilding/flashing; restore the old Arduino toolchain
if you build the old configuration.
## Tests
@@ -79,46 +79,46 @@ clang++ -std=c++17 -Wall -Wextra -Werror tests/test_touch_filter.cpp -o /tmp/tes
/tmp/test_touch_filter
```
De C++-test controleert contactdender, korte ruispulsen, opeenvolgende tegels,
herhaling binnen één aanraking, `millis()`-overflow en temperatuurafronding.
De indelingstest controleert overlap, schermgrenzen, ruimte voor navigatie
en het filter vóór beide handlers van alle tien tegels.
The C++ test checks contact bounce, short noise pulses, consecutive tiles,
repetition within a single touch, `millis()` overflow, and temperature rounding.
The layout test checks overlap, screen bounds, space for navigation,
and the filter ahead of both handlers for all ten tiles.
Met de Python-omgeving van ESPHome (met aioesphomeapi, PyYAML en pyserial):
With ESPHome's Python environment (with aioesphomeapi, PyYAML, and pyserial):
```sh
python diagnostics/capture_serial.py --reset --seconds 120 > diagnostics/runtime.log
python diagnostics/run_ui_test.py --host cyd-2432s028.local
```
De API-test leest de encryptiesleutel intern uit `secrets.yaml` en drukt deze
niet af. Hij wisselt tien keer van pagina en tekent de vijf overlays in elke
ronde. Hij roept geen Home Assistant-acties aan. Raak het scherm tijdens
deze circa 11 seconden niet aan. Dit is een teken-/geheugentest; hij vervangt
geen fysieke toets van de touchkalibratie of een test van HA-service-effecten.
The API test reads the encryption key internally from `secrets.yaml` and doesn't
print it. It switches pages ten times and draws the five overlays on each
round. It doesn't call any Home Assistant actions. Don't touch the screen during
these roughly 11 seconds. This is a rendering/memory test; it doesn't replace
a physical check of the touch calibration or a test of HA service effects.
Diagnostiek logt iedere 30 seconden vrije heap en grootste vrije geheugenblok.
`DEBUG` is tijdelijk nuttig voor touch- en verbindingsdiagnose. Voor dagelijks
gebruik kan `logger.level` op `INFO` zodra de fysieke bediening goed is.
Diagnostics logs free heap and the largest free memory block every 30 seconds.
`DEBUG` is useful temporarily for touch and connection diagnostics. For everyday
use, `logger.level` can go back to `INFO` once physical operation is confirmed good.
## Touchdiagnose
## Touch diagnostics
`python diagnostics/control_ui.py touch_diagnostics` opent een apart scherm
met vier kruizen. Tijdens deze meting kunnen aanrakingen geen tegelactie
uitvoeren. Tik nauwkeurig achtereenvolgens linksboven, rechtsboven,
rechtsonder en linksonder. De ruwe en genormaliseerde coördinaten staan in
de seriële logs met tag `touch`. Sluit af met
`python diagnostics/control_ui.py end_touch_diagnostics`. De kruizen staan
op (20,20), (299,20), (299,219) en (20,219) voor landschap 320×240.
`python diagnostics/control_ui.py touch_diagnostics` opens a separate screen
with four crosshairs. During this measurement, touches can't trigger a tile
action. Tap accurately, in order: top-left, top-right,
bottom-right, and bottom-left. The raw and normalized coordinates appear in
the serial logs with tag `touch`. Exit with
`python diagnostics/control_ui.py end_touch_diagnostics`. The crosshairs sit
at (20,20), (299,20), (299,219), and (20,219) for 320×240 landscape.
De huidige kalibratie (X 225–3800, Y 274–3609) is afgeleid uit de drie
herhaalde metingen rechtsboven en linksonder op dit fysieke bord. De eerdere
metingen linksboven waren onstabiel en zijn bewust niet gebruikt om het
hele scherm naar een verkeerde positie te verschuiven.
The current calibration (X 225–3800, Y 274–3609) is derived from the three
repeated measurements at top-right and bottom-left on this physical board. The earlier
top-left measurements were unstable and were deliberately not used, to avoid
shifting the entire screen to the wrong position.
Daarbovenop corrigeert `set_raw_correction(...)` in `on_boot` de gemeten
scheefstand. De fit gebruikt de gefilterde hoekmedianen (830,556), (544,3461),
(3410,3391) en (3492,372). De vier medianen vallen na correctie binnen vijf
pixels van hun meetdoel in de regressietest. Dit zijn bord-specifieke
coëfficiënten; neem ze niet blind over op een ander paneel. De `raw=`-logs
blijven de fysieke, gefilterde ADC-metingen tonen.
On top of that, `set_raw_correction(...)` in `on_boot` corrects the measured
skew. The fit uses the filtered corner medians (830,556), (544,3461),
(3410,3391), and (3492,372). After correction, the four medians land within five
pixels of their measurement target in the regression test. These are board-specific
coefficients; don't carry them over blindly to another panel. The `raw=` logs
still show the physical, filtered ADC readings.