Add offline and ntfy alerts
Co-authored-by: Copilot <[email protected]>
This commit is contained in:
@@ -1009,21 +1009,49 @@ the remaining readings. The endpoint exposes structured current and historical f
|
||||
without overflow or new console errors. Also fixed disconnected OBD speed showing `undefined`
|
||||
and deferred offline map tiles until a real GPS fix, avoiding irrelevant placeholder requests.
|
||||
|
||||
### Phase 20: Alerts/notifications — 🚧 PLANNED
|
||||
**New phase - depends on Phases 13/17/19 existing first**, since it needs real data sources to
|
||||
alert on. Right now, finding out about a problem (check-engine light on, dashcam SD card nearly
|
||||
full, upload backlog growing unbounded, Pi overheating, GPS fix lost for a long stretch) requires
|
||||
manually opening the web UI. Add a lightweight push-notification integration - no new
|
||||
infrastructure needed, just an outbound webhook to something like `ntfy.sh` or a Telegram bot -
|
||||
fired on a handful of conditions:
|
||||
- DTC/MIL status changes to "on" (from Phase 13's expanded OBD data).
|
||||
- Dashcam USB storage or local `dash/videos/` disk usage crossing a configurable threshold.
|
||||
- Upload backlog (pending tracking rows or dashcam files) growing past a configurable size,
|
||||
suggesting the Pi's been offline/uploading too slowly for a while.
|
||||
- Pi CPU temperature crossing a configurable threshold (from Phase 19).
|
||||
- GPS fix lost for longer than a configurable duration while the car appears to be moving
|
||||
(OBD speed > 0 with no fix - needs Phase 13's data).
|
||||
Webhook target/thresholds configurable via the Phase 21 Settings page rather than hardcoded.
|
||||
### Phase 20: Alerts/notifications — ✅ DONE
|
||||
Added an offline-first notification system. A shared bell in the top bar on every web page shows
|
||||
active local alerts with no modem, SIM card, or internet connection. Optional ntfy delivery mirrors
|
||||
the same conditions only when explicitly enabled and configured; it defaults off until Phase 21
|
||||
exposes its topic URL, optional access token, and thresholds.
|
||||
|
||||
Monitored conditions:
|
||||
- MIL/check-engine state and DTC codes.
|
||||
- Pi filesystem pressure and the physical dashcam USB filesystem, checked read-only and cached for
|
||||
five minutes to avoid repeated mounts.
|
||||
- Pending tracking-row or local dashcam-video upload backlog.
|
||||
- Pi CPU temperature and Raspberry Pi firmware undervoltage/throttling flags.
|
||||
- GPS fix loss for a configured duration while fresh OBD wheel speed confirms movement.
|
||||
|
||||
The alert engine runs independently every minute and persists active state, first-active time,
|
||||
last attempt/success, delivery errors, recovery state, and last value in SQLite. It sends once on a
|
||||
transition, repeats only after the configured cooldown, retries failed deliveries after five
|
||||
minutes, and sends a recovery notification after a delivered condition clears. GPS cold starts
|
||||
must remain lost for the full duration before alerting, and stale MIL/DTC values are suppressed
|
||||
after OBD communication stops. Firmware current flags alert immediately; new historical bits
|
||||
remain visible for five minutes, and cleared bits are reconciled so the same fault can alert again
|
||||
after reboot. Failed transient deliveries retry every minute during that window. The bell
|
||||
explicitly reports a dead/stale monitor instead of silently showing old conditions.
|
||||
`/api/alerts/status` exposes sanitized diagnostics without the ntfy URL, token, or request errors
|
||||
that could contain a private topic URL.
|
||||
|
||||
**Implemented and verified 2026-08-09:**
|
||||
- Thirteen focused alert tests cover ntfy request shape/authentication/error redaction, transition
|
||||
deduplication, cooldown repeats, recovery, failed-delivery retry, disabled delivery, GPS
|
||||
duration/reset, firmware-event recurrence, diagnostic freshness, and dashcam-usage caching. The
|
||||
combined targeted suite is 33 tests.
|
||||
- Deployed uncommitted code and verified the alert thread, state table, status API, and service on
|
||||
the Pi. `enabled=false` and `configured=false` produced no external attempt while local alerts
|
||||
continued working.
|
||||
- Tested the ntfy transport against a temporary HTTP receiver bound only to `127.0.0.1` on the Pi:
|
||||
path, UTF-8 body, title, priority, tags, and bearer Authorization header all arrived correctly;
|
||||
no third-party request or real token was used.
|
||||
- The real read-only physical-dashcam check found 96.1% usage/1.23GB free, unmounted afterward, and
|
||||
the original library remained exactly 87 files/29,615,111,758 bytes. The live bell correctly
|
||||
showed that storage alert alongside the real Pi undervoltage/throttling alert.
|
||||
- Browser-tested the real local bell/dropdown at 390x844 on the dashboard and trip-history page:
|
||||
badge counts, alert titles/details, no-alert state, synthetic monitor-failure state, shared-shell
|
||||
availability, and no-horizontal-overflow behavior passed with no new console errors.
|
||||
|
||||
### Phase 21: Settings page — 🚧 PLANNED
|
||||
**New phase - depends on Phase 15's shared components, and benefits from Phases 17/20 existing**
|
||||
|
||||
Reference in New Issue
Block a user