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 <noreply@anthropic.com>
This commit is contained in:
Max Gramser
2026-09-14 13:15:09 +02:00
parent b9e1dfbd95
commit e3efbbaa06
12 changed files with 73 additions and 18 deletions
+4 -4
View File
@@ -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.
+5 -4
View File
@@ -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<int>(std::lround(std::sqrt(static_cast<double>(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; }
+6
View File
@@ -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)`,
+29
View File
@@ -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.
+4 -3
View File
@@ -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
+1 -1
View File
@@ -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.
+1 -1
View File
@@ -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.
+4 -3
View File
@@ -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
+5
View File
@@ -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.
+1 -1
View File
@@ -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'])
+1 -1
View File
@@ -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
+12
View File
@@ -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);