Let a tap look instant and keep the spinner for a command that really takes a while (0.2.70)
Home Assistant answered every command in 342-599 ms on a real installation, yet a tile was busy for at least a second and up to six without a confirming state. Now nothing is drawn for the first 400 ms, a tap that switches shows the new stand at once as Home Assistant's own switch does, and the sheet appears only for a slow command. Home Assistant's "it worked" answer ends the wait 800 ms later, which covers a stop on a cover that already stands still, and a wait without any answer ends after three seconds instead of six. The cards' keys, sliders, chips and the -/+ edit now ask for an answer too, so a refusal shows wherever a finger presses. Firmware 0.2.59. A 200 ms LVGL timer runs only while a command is under way. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -176,6 +176,30 @@ 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.70 / firmware 0.2.59
|
||||
|
||||
Firmware only (`runtime_model.h`, `runtime_tiles.h`, `tile_controls.h`); the app raises `FIRMWARE_VERSION`. No
|
||||
protocol, storage or editor change, and an older app drives this firmware as before.
|
||||
|
||||
- `Tile::waiting(now)` replaces `awaiting_action`: pending, not confirmed, not `local_feedback`, and within `BUSY_CAP`
|
||||
(3000 ms), or within `BUSY_AFTER_ANSWER` (800 ms) of Home Assistant's "it worked" answer (`answered_at`, set by the
|
||||
action-response callback). It guards what a finger may do: a second tap, a slider, a key, a chip, the -/+ edit.
|
||||
- `Tile::loading(now)` is what gets drawn: `waiting` once `BUSY_GRACE` (400 ms) has passed. Home Assistant answered
|
||||
every command in 342-599 ms on Max's installation, so a command that lands shows nothing at all; the busy sheet, the
|
||||
card's "Command sent..." and its greyed keys only appear for a slow one. The old rule (always busy for 1000 ms,
|
||||
150 ms for a switch, then up to 6000 ms without confirmation) is gone, and with it the switch's own window.
|
||||
- `Tile::optimistic(on)` writes the new stand into `state` and keeps the old one in `optimistic_prev_on`, as Home
|
||||
Assistant's `ha-control-switch` flips before the command goes out. A tap that sends `<domain>.toggle` on a light,
|
||||
switch, input boolean or fan uses it, and so does a card's switch. `observe` clears the flag, so a state message
|
||||
always wins; `undo_optimistic` puts the old stand back on a refusal or when the wait runs out (`end_wait`, which
|
||||
also drops a chip's sent value).
|
||||
- Between the manager's messages nothing redraws a card, so `watch_busy` creates one 200 ms LVGL timer while any tile
|
||||
waits: it brings the sheet up after the grace, ends waits that ran out, and deletes itself. `Widgets::busy_drawn`
|
||||
keeps a card from being drawn again for nothing.
|
||||
- `action()` asks for an answer by default now, so the cards' keys, sliders, chips and the -/+ edit get the same
|
||||
refusal and "it worked" handling a tap has had since 0.2.67. At most four answers are watched at a time, as before.
|
||||
- Firmware before 0.2.59 keeps its own timing; the app sends nothing new, so any app drives either firmware.
|
||||
|
||||
### Compatibility 0.2.67 / firmware 0.2.58
|
||||
|
||||
App (new `ha_catalogue.py`, `core.py`, `server.py`, `header_bar.py`, `history_card.py`, `tile_icons.py`, the editor and
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# Test results app 0.2.70 / firmware 0.2.59 (2026-09-17)
|
||||
|
||||
Max, after the 0.2.67 update round on his own screens: "ik vind sws alle busy heel lang duren" - every busy state feels
|
||||
longer than it needs to be. This release makes a tap look instant and keeps the spinner for commands that really take a
|
||||
while. See CHANGELOG 0.2.70 and the compatibility note in docs/RELEASING.md. Built on 0.2.69 (`45fcbdd`).
|
||||
|
||||
## What the old rule did, measured
|
||||
|
||||
- `Tile::loading()` held a tile busy for at least 1000 ms (150 ms for a switch) and then, without a confirming state,
|
||||
up to 6000 ms. The 1000 ms came from the first runtime tiles; nothing measured it.
|
||||
- The bench screens' own logs during the 0.2.67 hardware round, against Max's Home Assistant: a tap was answered with a
|
||||
new state in 342, 399, 404, 417, 434, 467, 550 and 599 ms. Eight of eight under 600 ms, so the sheet always outlived
|
||||
the command.
|
||||
- `cover.stop_cover` on a cover that already stands still brings no new state at all: Max pressed the middle key in the
|
||||
cover card and the sheet stayed the full six seconds. The log shows the command going out at 21:43:31 with no state
|
||||
after it.
|
||||
- Home Assistant itself shows no spinner: `ha-control-switch._toggle()` flips the switch before the command goes out
|
||||
(180 ms CSS transition) and the state that follows confirms it.
|
||||
|
||||
## Automated
|
||||
|
||||
- Python (`.venv-portal`): 386 tests OK, the same set as 0.2.69 (this release is firmware only; the app just raises
|
||||
`FIRMWARE_VERSION`).
|
||||
- C++ (`clang++ -std=c++17 -Wall -Wextra -Werror -I.`): 17/17 PASS. `tests/test_action_feedback.cpp` now holds the new
|
||||
rules: nothing drawn in the first 400 ms while a second finger is still ignored, the sheet from 400 ms, the cap at
|
||||
3000 ms, an "it worked" answer ending the wait 800 ms later, a tap that opens a card drawing no sheet at all, the
|
||||
clock wrapping around, a switch confirming at 250 ms without ever drawing a sheet, and the optimistic stand with its
|
||||
undo and a state message overruling it.
|
||||
- `generate_packages.py --check` and `generate_icons.py --check` green.
|
||||
|
||||
## Firmware on the Mac (host builds, driven over the ESPHome API)
|
||||
|
||||
`tap_host.py`, now with the busy sheet in its probe (`busy=`) and the probed slot in every line, so the host's
|
||||
one-to-two-second log lag cannot be read as another card's answer. **Guition 34/34, CYD 34/34.** The eight new checks:
|
||||
|
||||
| Check | Guition | CYD |
|
||||
|---|---|---|
|
||||
| A tap on a lamp shows the new stand at once | pass | pass |
|
||||
| and draws no sheet yet | pass | pass |
|
||||
| The sheet comes when Home Assistant takes longer | pass | pass |
|
||||
| An answer that brings no new state lets go in a moment | pass | pass |
|
||||
| and the tile shows Home Assistant's own stand again | pass | pass |
|
||||
| A command without an answer keeps the sheet | pass | pass |
|
||||
| and lets go after three seconds | pass | pass |
|
||||
| A refused switch says Refused, then the old stand is back | pass | pass |
|
||||
|
||||
The 26 checks of 0.2.67 (On / off, Perform action with its data, a refusal, holding, an unanswered call, Home
|
||||
Assistant's words) pass unchanged.
|
||||
|
||||
## Max's own screen
|
||||
|
||||
The Guition at his desk got firmware 0.2.59 over the air from this tree (`esphome upload`, own name, keys and Wi-Fi;
|
||||
Home Assistant kept the device and the app reported Synced again within half a minute). His verdict after tapping:
|
||||
"wauw dit is perfect, werkt veel fijner."
|
||||
|
||||
## Builds (ESPHome 2026.6.2)
|
||||
|
||||
Check profiles with the generated packages and local components; no errors or compiler warnings.
|
||||
|
||||
| Profile | RAM | Flash | vs 0.2.69 |
|
||||
|---|---|---|---|
|
||||
| CYD | 23.9% (78,396 B) | 79.2% (1,453,351 B) | +112 B RAM, +1,060 B flash |
|
||||
| Guition | 25.6% (83,972 B) | 21.0% (1,708,627 B) | +112 B RAM, +1,024 B flash |
|
||||
|
||||
The RAM is the answer timestamp and the two optimistic flags per tile, plus one LVGL timer while a command is under way.
|
||||
|
||||
## Not tested
|
||||
|
||||
- The CYD on real hardware: it kept firmware 0.2.58 until the release, so its Update round follows the push.
|
||||
- A refusal on Max's own screen: it needs a tile whose action Home Assistant rejects, which the 0.2.67 round already
|
||||
showed there ("value must be at most 100 at 'brightness_pct'").
|
||||
Reference in New Issue
Block a user