PR-08: SNTP time, task watchdog & event logging#14
Merged
Conversation
Spec-kit artifacts for PR-08 (SNTP time + task watchdog + event logging), approved at Checkpoint 2. Records: reuse of PR-06 IDataStorage event log, the new IWallClock seam, CET/CEST TZ, watchdog excludes the WiFi task, WS_TASK_WDT_TIMEOUT_S=20s and se.pool.ntp.org defaults. No implementation yet. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ent, watchdog config Phase 1+2 of PR-08: - time component skeleton (linux-guarded CMake; header-only until US1 adds SRCS) - IWallClock pure interface (nowEpoch/isTimeSet) + FakeWallClock host fake + SyncStatus - Kconfig WS_SNTP_SERVER (se.pool.ntp.org) + WS_TASK_WDT_TIMEOUT_S (20s); sdkconfig CONFIG_ESP_TASK_WDT_INIT/PANIC (timeout reconfigured from Kconfig at init) - host time + event_logger suites registered (stubs) Verified: host tests 178/0, both board targets build + board-config verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t state Phase 3 / US1: - TimeService (pure): isPlausibleEpoch (>=2020) + formatLocal (localtime_r/strftime), host-tested for CET(+0100)/CEST(+0200) incl. the spring DST boundary - SystemWallClock (target): IWallClock over time(nullptr) - SntpClient (target): esp_netif_sntp against CONFIG_WS_SNTP_SERVER, step-set, sync callback updates SyncStatus; idempotent, non-blocking, non-fatal; TZ applied - diag console 'time' command + diag_console_register_time (app_main wiring deferred to US3) Verified: host 181/0 (+3), both board targets build + verified; SNTP links with PRIV_REQUIRES esp_netif. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ot reset reason Phase 4 / US2: - events component: EventLogger (pure, over IDataStorage + IWallClock) with typed producers (reset/wifi/pump start-stop/failsafe/ota), droppedEvents counter, resetReasonName mapping; reuses the PR-06 rotating event log (no interface change) - app_main: SystemWallClock + EventLogger; esp_reset_reason() -> logReset at boot - system_observer (main/): polls WifiManager snapshot + pump isRunning() from the 10 Hz loop, logs WiFi state changes + pump start/stop; null-guarded - 6 host tests (EventLogger producers/failure/resetReasonName) vs MockDataStorage - TODO(US3/T018): construct SntpClient + register the time console Verified: host 187/0 (+6), both board targets build + verified. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
… SNTP wiring Phase 5 / US3 + polish: - task_watchdog helper: reconfigure to WS_TASK_WDT_TIMEOUT_S (20s, panic->reboot), subscribe/feed. Subscribes ONLY the 10 Hz main loop + the 5 s sensor task; the WiFi task and console REPL are deliberately NOT subscribed (a network stall must not reboot the device - FR-014). Idle-task WDT from sdkconfig retained. - SNTP wiring: app_main constructs SntpClient + applyTimezone(); SystemObserver starts SNTP once on the first WifiState::Connected; diag console 'time' registered. - boot order verified: pumps_force_off() first -> esp_reset_reason()->logReset -> watchdog_init() -> tasks subscribe (a prior TASK_WDT reset shows in storage events). - firmware/CLAUDE.md feature-008 section; HIL checklist. Verified: host 187/0; rev1 1034400B (34% slot free) + rev2 build, both config-verified; dependencies.lock + esp-modbus pins unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addresses CP3 findings F1-F6 + polish (host 187/0, both boards green): - F1: SystemObserver surfaces EventLogger droppedEvents() via ESP_LOGW (was a dead counter — a failing event store went silent) - F2: task watchdog preserves idle-task watching on all cores (idle_core_mask = (1<<portNUM_PROCESSORS)-1) + corrected comment - F3: EventLogger::logReset(int) maps reason internally (dropped the dead, mismatchable reasonName param) - F4: SyncStatus.synced() derived from lastSyncEpoch (no redundant bool); SntpClient::start() returns bool; observer retries SNTP if init failed - F5: resetReasonName extended to IDF v6 values 11-15 (USB/JTAG/EFUSE/ PWR_GLITCH/CPU_LOCKUP) + corrected comment - F6: reset reason also ESP_LOGI'd at boot (serial trace independent of store) - polish: FakeWallClock threshold references TimeService::kMinPlausibleEpoch; SntpClient single-instance guard + benign-cross-task-read note; formatLocal guards localtime_r; corrected SystemWallClock 'IDF touchpoint' docs; softened reset-ordering comment Host tests (new cases) land in the next commit. pumps_force_off() still first; pure components remain esp-free. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…autumn, clock-step - logFailsafe/logOta producer tests (category + verbatim detail + epoch) - store-failure test extended to all six producers (droppedEvents==6) - resetReasonName total mapping 0..15 + unknown->UNKNOWN - multi-event clock-step: epoch stamped at emit time (not construction), getEvents newest-first - DST autumn (fall-back) boundary: CEST->CET flip at the last-Sunday-of-October instant Verified: host tests 191/0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR-08 — SNTP time, task watchdog & event logging
Completes the phase-2 exit criteria (FR10 + reliability/logging NFRs). Spec-kit artifacts in
specs/008-sntp-watchdog-logging/. Depends on PR-06 (littlefs event log) and PR-07 (WiFi), both merged.What it does
esp_netif_sntpagainst the Swedish pool (se.pool.ntp.org, Kconfig)starts once on the first WiFi
Connected; Europe/Stockholm CET/CEST (TZ=CET-1CEST,M3.5.0,M10.5.0/3);an explicit time-not-set state (year < 2020) that PR-11's scheduler gates on. Non-fatal if offline.
esp_task_wdt(reboot on hang) subscribes ONLY the watering-critical tasks — the10 Hz main loop (drives pump
update()) and the sensor task — plus the per-core idle tasks. The WiFitask and console REPL are deliberately excluded (a network stall must never reboot the device — PR-07
isolation). Replaces the ineffective legacy software watchdog (QUIRK 3). After a watchdog reset,
pumps_force_off()(unchanged, first action) keeps pumps OFF and the reset reason is persisted.EventLoggerwires producers (reset reason at boot, WiFi statechanges, pump start/stop) into the existing PR-06 rotating event log; readable via
storage events.Architecture
timecomponent: pureTimeService(plausibility + CET/CEST formatting) behind the newIWallClockseam; target-onlySntpClient(the sole IDF touchpoint) +SystemWallClock.eventscomponent: pureEventLogger(depends only oninterfaces; primitive args; a failedstore is counted, never throws — FR-014), reuses PR-06
IDataStorage(no interface change).main/glue:task_watchdog,system_observer(edge-detects WiFi/pump events, starts SNTP), bootreset-reason logging.
pumps_force_off()stays the firstapp_mainaction.Verification
(incl. failsafe/ota), reset-reason total mapping (0..15), store-failure/dropped counter, epoch-stamped-
at-emit clock-step.
dependencies.lock+ bothesp-modbuspins unchanged (only IDF built-ins added). No frozen-legacy edits.Review (CP3)
Five specialist agents; all core invariants PASS. Findings F1–F6 + polish fixed and re-verified (see
docs/checkpoints/cp3-008-sntp-watchdog-logging.md): dropped-event surfacing, watchdog idle-mask, amismatch-proof
logReset, SNTP retry/SyncStatuscleanup, full reset-reason mapping, and a boot serialtrace.
Deferred (by design)
ISntpseam to host-testSystemObserver's edge detection → a later PR.specs/008-sntp-watchdog-logging/checklists/hil.md) runs on the rev1 rig: correct Swedish timereset=TASK_WDTlogged, event-log power-cyclepersistence, WiFi-outage-does-not-reboot, non-fatal SNTP offline.
🤖 Generated with Claude Code