From e3efbbaa061be871fe4d49ca092ada9a1162815e Mon Sep 17 00:00:00 2001 From: Max Gramser Date: Mon, 14 Sep 2026 13:15:09 +0200 Subject: [PATCH] Let LVGL decide a tap on the Guition: release inside the tile counts (0.2.33) A firm press on Studio 1 that drifted 73 px was still refused by the touch guard's movement limit. On a capacitive panel that limit has no job left: the edge swipe consumes its own tap, sliders capture their own drag, and LVGL already drops the click when the finger leaves the tile. The guard's limit can now be 0 (no limit); the Guition profile sets it so, the CYD keeps 56 px because its resistive panel jumps. Firmware 0.2.28 for both boards; the app only moves its target version. Co-Authored-By: Claude Fable 5.1 --- CYD_STABILITY.md | 8 ++++---- components/smart_display/cyd_ui.h | 9 +++++---- docs/RELEASING.md | 6 ++++++ docs/TEST_RESULTS_0233.md | 29 +++++++++++++++++++++++++++++ guition-4848s040.yaml | 7 ++++--- home-like-2432s028.yaml | 2 +- packages/cyd.yaml | 2 +- packages/guition.yaml | 7 ++++--- screen_manager/CHANGELOG.md | 5 +++++ screen_manager/app/core.py | 2 +- screen_manager/config.yaml | 2 +- tests/test_cyd_ui.cpp | 12 ++++++++++++ 12 files changed, 73 insertions(+), 18 deletions(-) create mode 100644 docs/TEST_RESULTS_0233.md diff --git a/CYD_STABILITY.md b/CYD_STABILITY.md index 7f69012..3e8fd31 100644 --- a/CYD_STABILITY.md +++ b/CYD_STABILITY.md @@ -20,10 +20,10 @@ De wifi-, API- en OTA-geheimen blijven in `secrets.yaml`. - 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` (circa 1 cm: 56 px CYD, - 67 px Guition) 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`). + 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. diff --git a/components/smart_display/cyd_ui.h b/components/smart_display/cyd_ui.h index e8abb31..54b52d1 100644 --- a/components/smart_display/cyd_ui.h +++ b/components/smart_display/cyd_ui.h @@ -28,9 +28,10 @@ inline int quantize_temperature(int value, int minimum, int maximum, int step) { class TouchGuard { public: enum Reject { NONE, MOVED, TOO_SHORT, USED, BOUNCE }; - // Board tuning, set from the profile on boot: how far the finger may drift (pixels, about - // one centimetre) before a tap is dropped, and the shortest contact that counts. A resistive - // panel (CYD) bounces on landing and lift-off; a capacitive one (Guition) does not. + // Board tuning, set from the profile on boot: how far the finger may drift (pixels) before + // a tap is dropped, 0 for no limit at all (LVGL then decides: releasing inside the tile is a + // tap, leaving it is not), and the shortest contact that counts. A resistive panel (CYD) + // bounces on landing and lift-off and needs both; a capacitive one (Guition) needs neither. void configure(int move_limit_px, uint32_t min_press_ms) { move_limit_ = move_limit_px; min_press_ = min_press_ms; @@ -64,7 +65,7 @@ class TouchGuard { const long dx = x - anchor_x_, dy = y - anchor_y_; const int distance = static_cast(std::lround(std::sqrt(static_cast(dx * dx + dy * dy)))); distance_ = std::max(distance_, distance); - if (distance > move_limit_) moved_ = true; + if (move_limit_ > 0 && distance > move_limit_) moved_ = true; } int distance() const { return distance_; } void consume() { accepted_ = true; moved_ = true; } diff --git a/docs/RELEASING.md b/docs/RELEASING.md index 5ca19e5..d7e2a7b 100644 --- a/docs/RELEASING.md +++ b/docs/RELEASING.md @@ -177,6 +177,12 @@ staan iconen in de browser uit het midden); draai daarna `generate_packages.py`. De substituties `MDI_GLYPH_*` zijn vervallen: `TILEn_ICON` in handmatige profielen moet uit de set komen. Geen gewijzigde preferences of sleutels. +### Compatibiliteit 0.2.33 / firmware 0.2.28 + +Alleen firmware. `TouchGuard::configure(0, ...)` schakelt de verplaatsingsgrens uit +(`moved_` wordt dan nooit gezet; LVGL's press-lost bepaalt of een tik doorgaat). Het +Guition-profiel zet `TOUCH_MOVE_LIMIT_PX` op 0, de CYD houdt 56. Verder ongewijzigd. + ### Compatibiliteit 0.2.32 / firmware 0.2.27 Alleen firmware. `cyd::EdgeSwipe` werkt op LVGL-pointercoördinaten: `configure(band, travel)`, diff --git a/docs/TEST_RESULTS_0233.md b/docs/TEST_RESULTS_0233.md new file mode 100644 index 0000000..19840e8 --- /dev/null +++ b/docs/TEST_RESULTS_0233.md @@ -0,0 +1,29 @@ +# 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. + +## 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. +- Guition-profiel `TOUCH_MOVE_LIMIT_PX: "0"`; CYD blijft 56 (resistief paneel springt). + +## Geautomatiseerd + +- C++ (clang++ -std=c++17 -Wall -Wextra -Werror -I.): 11/11 PASS; `test_cyd_ui` dekt + `configure(0, 20)`: 200 px drift blijft een tik, ook voor de −/+ toetsen. +- Python: 91 tests OK (`FIRMWARE_VERSION` 0.2.28 in app, profielen en pakketten). + `generate_packages.py --check` groen; bench-kopieën opnieuw gegenereerd. +- ESPHome 2026.6.2 compile: `easy-guition-device.yaml` SUCCESS in 40 s (RAM 32,0%, flash + 18,3%), `easy-cyd-device.yaml` SUCCESS in 36 s (RAM 31,0%, flash 76,1%); geen nieuwe + waarschuwingen. + +## 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). +- 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. diff --git a/guition-4848s040.yaml b/guition-4848s040.yaml index b977ef1..2ab514e 100644 --- a/guition-4848s040.yaml +++ b/guition-4848s040.yaml @@ -1,9 +1,10 @@ # Guition ESP32-S3-4848S040 / 4-inch EU wallbox, 480x480 IPS + GT911. # Use guition-device.yaml; see docs/GUITION.md. CYD hardware is a separate profile. substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.27" - # A tap survives a finger that drifts up to this far (480 px over 72 mm: 1 cm); further is a swipe. - TOUCH_MOVE_LIMIT_PX: "67" + SCREEN_FIRMWARE_VERSION: "0.2.28" + # 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" # Shortest contact that counts as a tap; a resistive panel bounces, a capacitive one does not. TOUCH_MIN_PRESS_MS: "20" # Page swipe starts in this band along the left or right edge (about 5 mm) and needs diff --git a/home-like-2432s028.yaml b/home-like-2432s028.yaml index 220b2f4..fbee4ef 100644 --- a/home-like-2432s028.yaml +++ b/home-like-2432s028.yaml @@ -58,7 +58,7 @@ ############################################################ substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.27" + SCREEN_FIRMWARE_VERSION: "0.2.28" # 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. diff --git a/packages/cyd.yaml b/packages/cyd.yaml index 51fd964..bc96bc2 100644 --- a/packages/cyd.yaml +++ b/packages/cyd.yaml @@ -59,7 +59,7 @@ ############################################################ substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.27" + SCREEN_FIRMWARE_VERSION: "0.2.28" # 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. diff --git a/packages/guition.yaml b/packages/guition.yaml index 49e87e6..15c4652 100644 --- a/packages/guition.yaml +++ b/packages/guition.yaml @@ -2,9 +2,10 @@ # Guition ESP32-S3-4848S040 / 4-inch EU wallbox, 480x480 IPS + GT911. # Use guition-device.yaml; see docs/GUITION.md. CYD hardware is a separate profile. substitutions: - SCREEN_FIRMWARE_VERSION: "0.2.27" - # A tap survives a finger that drifts up to this far (480 px over 72 mm: 1 cm); further is a swipe. - TOUCH_MOVE_LIMIT_PX: "67" + SCREEN_FIRMWARE_VERSION: "0.2.28" + # 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" # Shortest contact that counts as a tap; a resistive panel bounces, a capacitive one does not. TOUCH_MIN_PRESS_MS: "20" # Page swipe starts in this band along the left or right edge (about 5 mm) and needs diff --git a/screen_manager/CHANGELOG.md b/screen_manager/CHANGELOG.md index 2d128ad..44f60e7 100644 --- a/screen_manager/CHANGELOG.md +++ b/screen_manager/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.2.33 (firmware 0.2.28) + +- **Guition: loslaten binnen de tegel telt.** De verplaatsingsgrens voor een tik staat op de Guition uit (`TOUCH_MOVE_LIMIT_PX: "0"`); LVGL beslist, zoals iOS: laat je los binnen de tegel waarop je begon, dan is het een tik, verlaat je vinger de tegel, dan niet. Een stevige druk die een centimeter verschoof (73 px op Studio 1) werd anders nog geweigerd. De randveeg neemt zijn eigen tik weg en sliders vangen hun eigen sleep, dus de grens had daar geen taak meer. De CYD houdt zijn 56 px, omdat het resistieve paneel kan springen. +- Firmware 0.2.28 voor beide borden; de app biedt de update aan. Alleen de doelversie verandert in de app. + ## 0.2.32 (firmware 0.2.27) - **Randveeg die nooit pakte, opgelost.** Live meegelezen op een Guition: de veeg werd herkend maar geblokkeerd door de voorwaarde "kaart open". De lichtkaart, klimaatkaart en stofzuigerkaart wisten bij sluiten (kruisje, tik naast de kaart) en bij wakker worden uit standby de interne "actieve kaart" niet, dus na één keer een kaart openen bleef vegen stil geblokkeerd tot de indeling veranderde. Dat gold ook voor de oude veeg over het hele scherm en voor de CYD. Beide borden sluiten kaarten nu via één script (`close_cards`) dat alles verbergt én die toestand wist; wakker worden gebruikt hetzelfde pad. diff --git a/screen_manager/app/core.py b/screen_manager/app/core.py index 75b1926..909997b 100644 --- a/screen_manager/app/core.py +++ b/screen_manager/app/core.py @@ -16,7 +16,7 @@ WEEKDAYS = ['ma', 'di', 'wo', 'do', 'vr', 'za', 'zo'] 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.27' +FIRMWARE_VERSION = '0.2.28' ATTRS = frozenset('brightness percentage current_position current_temperature temperature current_humidity min_temp max_temp target_temp_step supported_color_modes hvac_modes hvac_action hs_color color_temp_kelvin min_color_temp_kelvin max_color_temp_kelvin fan_speed_list unit_of_measurement battery_level fan_speed volume_level is_volume_muted media_title options min max step temperature_unit supported_features device_class next_rising next_setting finishes_at duration remaining humidity wind_speed wind_speed_unit apparent_temperature fan_modes swing_modes fan_mode swing_mode'.split()) # Attributes whose boolean value the screen needs; every other bool stays behind. BOOL_ATTRS = frozenset(['is_volume_muted']) diff --git a/screen_manager/config.yaml b/screen_manager/config.yaml index 6377992..15af6f6 100644 --- a/screen_manager/config.yaml +++ b/screen_manager/config.yaml @@ -1,5 +1,5 @@ name: ESP Screen Manager -version: "0.2.32" +version: "0.2.33" slug: esp_screen_manager description: Kies tegels voor je CYD en Guition touchscreen, zonder opnieuw flashen. url: https://github.com/MaxGramser/homeassistant_espscreen diff --git a/tests/test_cyd_ui.cpp b/tests/test_cyd_ui.cpp index 32c2aa1..ca81c9b 100644 --- a/tests/test_cyd_ui.cpp +++ b/tests/test_cyd_ui.cpp @@ -76,6 +76,18 @@ int main() { wide.begin(3200, 200, 200, 3); assert(!wide.accept(3260, 2)); // same tile within 600 ms assert(wide.reason() == "dezelfde knop binnen de dendertijd"); + // No movement limit (0): a capacitive board leaves the drift decision to LVGL's press-lost. + cyd::TouchGuard free; + free.configure(0, 20); + free.begin(100, 200, 200, 3); + free.update(205, 200, 3); free.update(205, 200, 3); free.update(205, 200, 3); // settled + free.update(400, 260, 3); + assert(free.distance() > 200); + assert(free.accept(180, 1)); // 200 px of drift, still a tap + free.begin(1000, 200, 200, 3); + free.update(205, 200, 3); free.update(205, 200, 3); free.update(205, 200, 3); + free.update(400, 200, 3); + assert(free.accept_repeat(1060, 7)); // -/+ keys follow the same rule cyd::TouchGuard resistive; resistive.configure(56, 60); resistive.begin(100, 50, 50);