2d343a450f
A tap on the On/off switch of a wide or full-page tile moved the knob to on and back, and the light stayed off. Since firmware 0.2.59 control_event drew the new position first (Tile::optimistic writes it into state) and then asked key_action for the action, which read that new position: an off light got light.turn_off, an on light light.turn_on. A tap on the tile itself was never affected. tile_controls::press_key chooses the action first and then shows the new position; control_event uses it. Unit tests cover a light, a fan, a sensor and a cover key. Checked with tools/check.sh (471 Python tests, 19/19 C++) and compiled for both boards: CYD 1,677,504 B (91.4 %, +16 B), Guition 2,054,640 B (25.3 %). On Max's Guition Wallbox (OTA from this branch) every tap on the switch sent the right action and Home Assistant's logbook followed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
74 lines
4.1 KiB
Markdown
74 lines
4.1 KiB
Markdown
# Test results app 0.2.86 / firmware 0.2.72 (2026-09-19)
|
|
|
|
Max reported that a tap on the on/off switch at the right of a wide tile went "from off to on to off in one click",
|
|
as if it registered a double click. A tap on the tile itself worked. The tile was `light.badkamer_3` on his Guition
|
|
Wallbox, a wide tile with the control *On/off switch*.
|
|
|
|
## Cause
|
|
|
|
No double tap: the switch sent the opposite of what it showed. `runtime_tiles::control_event` did two things in the
|
|
wrong order since firmware 0.2.59 (app 0.2.70, the "tap looks instant" round):
|
|
|
|
1. `Tile::optimistic(t.state != "on")` draws the new position at once. Since 0.2.59 it writes that position into
|
|
`Tile::state` (before, a separate `optimistic_on` field held it and `state` stayed as it was).
|
|
2. `tile_controls::key_action(t, TOGGLE)` then chose `turn_off` when `state` was "on", which it now always was for a
|
|
light that had been off.
|
|
|
|
So an off light got `light.turn_off`. Home Assistant answered "it worked" without a new state, the wait ended 800 ms
|
|
after that answer, `end_wait` undid the optimistic position, and the knob slid back to off. An on light got
|
|
`light.turn_on` the same way. The other three callers of `optimistic()` (the tile's own tap, the light card's switch,
|
|
a slider on an off light) choose their action before they call it, or don't read `state` afterwards.
|
|
|
|
Evidence before the fix:
|
|
|
|
- The two lines of `control_event`, run against the released headers (origin/main 311fa2a), print
|
|
`light off -> knob shows on, sends light.turn_off` and `light on -> knob shows off, sends light.turn_on`.
|
|
- Home Assistant's logbook for `light.badkamer_3` only had `light.toggle` state changes from the screen (taps on
|
|
the tile). A `turn_off` sent to a light that is off changes nothing, so it leaves no line in the logbook.
|
|
|
|
## What changed
|
|
|
|
- `tile_controls::press_key(Tile &, command, arg)`: chooses the action with `key_action` first, then shows a toggle's
|
|
new position with `optimistic()`, and only when there is an action to send.
|
|
- `runtime_tiles::control_event` calls `press_key` instead of the two lines.
|
|
- `tests/test_tile_controls.cpp`: an off light sends `light.turn_on` and shows on, and undoing that brings back off;
|
|
an on fan sends `fan.turn_off` and shows off; a toggle on a sensor sends nothing and leaves its state alone; a
|
|
cover's open key leaves the state alone.
|
|
|
|
## Automated
|
|
|
|
- `tools/check.sh`: Python 471 tests, C++ 19/19, packages, icons, Vitest, vue-tsc, the editor build and the bundle
|
|
in Git: all pass.
|
|
- `tools/check.sh --firmware --baseline 1677488` (ESPHome 2026.6.2): CYD 1,677,504 B = 91.4 % of the 1,835,008 B
|
|
slot, +16 B against 0.2.85 (tight band, well under the 8 KB rule); Guition 2,054,640 B = 25.3 %, the same as 0.2.85.
|
|
Built before the version bump, which only changes the version text (same length).
|
|
|
|
## On the screen
|
|
|
|
With Max's OK the fix went over the air to his Guition Wallbox (192.168.146.136). The YAML was the one his ESPHome
|
|
Device Builder holds for it, with the packages and components of this branch instead of GitHub. That build still says
|
|
0.2.71, so ESP Screens offers the released 0.2.72 afterwards. `device_info` read back the build's compile time
|
|
(2026-09-19 08:10:24).
|
|
|
|
Max then tapped the switch and the tile, and the screen's log and Home Assistant's logbook agree on every tap:
|
|
|
|
| Time | Where | Sent | Light after |
|
|
|---|---|---|---|
|
|
| 08:13:12.9 | switch (light on) | `light.turn_off` | off |
|
|
| 08:13:14.5 | switch | `light.turn_on` | on |
|
|
| 08:13:15.8 | switch | `light.turn_off` | off |
|
|
| 08:13:16.5 | tile | `light.toggle` | on |
|
|
| 08:13:17.1 | tile | `light.toggle` | off |
|
|
| 08:13:17.6 | switch | `light.turn_on` | on |
|
|
| 08:13:19.2 | switch | `light.turn_off` | off |
|
|
|
|
Home Assistant reported each new state 220-430 ms after the send. One tap at 08:13:18.1, 526 ms after the one
|
|
before, was dropped by the 600 ms same-control debounce (`TouchGuard::accept`), as before. Max: "werkt super!".
|
|
|
|
## Not tested
|
|
|
|
- The switch of a switch, an input boolean or a fan on real hardware: they go through the same `press_key` line
|
|
and the unit tests.
|
|
- The CYD: the fix is the same shared code. Its screen has no tile with a switch now, and it gets 0.2.72 through
|
|
**Update**.
|