feat(companion): clock tools — alarm, countdown timer, stopwatch

Add a Clock Tools screen (Enter on the home Clock page) with three time
utilities, plus the engine that drives them from UITask::loop() so they
work regardless of the current screen / display state:

- Alarm: a single one-shot wake alarm. Persisted in NodePrefs as a local
  time-of-day; UITask schedules it as an ABSOLUTE fire instant recomputed
  from that time, so it survives RTC re-syncs (mesh/app/GPS/CLI all jump
  the clock) — small corrections still fire on time, a jump over the
  target still fires (late, up to 6 h). Disarms after firing. A bell
  icon signals an armed alarm on the clock face and the top status bar.
- Timer: a millis-based countdown (sync-immune), big HH:MM:SS readout,
  rings even when off-screen.
- Stopwatch: millis-based, keeps running in the background.

Numeric fields use the shared framework DigitEditor (digit-by-digit,
min/max enforced). The alarm/timer/ring engine lives in UITask alongside
the locator/live-share engines (no screen-cast for time-critical logic).

E-ink: live readouts refresh coarsely (and on any key); timing is exact
regardless, and the countdown's buzzer fires on time. Rings override mute
and are dismissed by any key (auto-stop after 1 min). Cannot wake from a
full Shutdown (CPU/RAM powered down).

NodePrefs: +alarm_on/alarm_hour/alarm_min (fit existing tail padding,
sizeof unchanged 2488), SCHEMA_SENTINEL 0xC0DE0016 -> 0xC0DE0017,
DataStore read/clamp/write in lockstep.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
MarekZegare4
2026-06-30 09:01:03 +02:00
co-authored by Claude Opus 4.8
parent 59d1722207
commit 9ce04835da
7 changed files with 509 additions and 2 deletions
+8
View File
@@ -150,6 +150,14 @@ MINI_ICON(ICON_ADVERT, 6, // broadcast mast + radiating waves (auto-advert)
packRow(".####."),
packRow(".####."));
MINI_ICON(ICON_ALARM, 5, // bell — an alarm is armed
packRow("..#.."),
packRow(".###."),
packRow(".###."),
packRow(".###."),
packRow("#####"),
packRow("..#.."));
MINI_ICON(ICON_TRAIL, 6, // map pin / location marker (GPS trail logging)
packRow(".####."),
packRow("######"),