Skip to content

Track last SNTP sync time to flag a stale clock on the Services tile#1221

Draft
gskjold wants to merge 1 commit into
mainfrom
ntp-sync-freshness
Draft

Track last SNTP sync time to flag a stale clock on the Services tile#1221
gskjold wants to merge 1 commit into
mainfrom
ntp-sync-freshness

Conversation

@gskjold

@gskjold gskjold commented Jun 25, 2026

Copy link
Copy Markdown
Member

Summary

The NTP entry on the new Services status tile only checks whether the system clock has ever been set (time() > BuildEpoch in AmsWebServer.cpp). That misses the failure mode behind #1191: a clock that synced once and then silently stopped resyncing keeps ticking from millis(), so the tile stays green even while the clock drifts and day-boundary energy accounting gets corrupted (and the GUI shows the wrong time).

This adds a real freshness signal.

Changes

  • New src/NtpStatus.{h,cpp} — registers a platform SNTP sync-notification callback that records millis64() at each successful sync, exposed via ntpLastSyncMillis():
    • ESP8266: settimeofday_cb(void(*)(bool from_sntp)) — the from_sntp flag lets us ignore the meter-timestamp settimeofday() at AmsToMqttBridge.cpp:1734, so only real SNTP syncs count.
    • ESP32: sntp_set_time_sync_notification_cb(void(*)(struct timeval*)).
  • AmsToMqttBridge.cpp — register the callback once in setup().
  • AmsWebServer.cpp — the Services tile NTP status is now yellow when there has been no SNTP sync since boot or the last sync is older than 3h (NTP_STALE_AFTER_SECONDS), and green only on a recent sync. Maps onto the existing bcol() colors; no UI changes needed.

Diagnostic only — no change to the accounting logic.

Why draft

Investigating #1191. The reporter notes the GUI is exactly 1 hour off, which looks more like a DST/meter-timestamp-deviation issue than NTP drift. This PR is the diagnostic that will tell us whether NTP is actually still syncing on affected devices; root cause may turn out to be elsewhere (the meter-timestamp decode / tz DST handling). Waiting on a data dump from the reporter before deciding whether more is needed here.

Testing

  • pio run -e esp8266dev → SUCCESS (confirms settimeofday_cb(bool) overload)
  • pio run -e esp32dev → SUCCESS (confirms esp_sntp.h / sntp_set_time_sync_notification_cb)

Related: #1191

🤖 Generated with Claude Code

The NTP entry on the Services status tile only checked whether the
system clock had ever been set (time() > BuildEpoch). A clock that was
synced once and then silently stopped resyncing — which corrupts
day-boundary energy accounting and shows up as a wrong GUI time — kept
reporting green because the clock keeps ticking from millis().

Register a platform SNTP sync-notification callback that records
millis64() at each successful sync:
- ESP8266: settimeofday_cb(void(*)(bool from_sntp)) — the from_sntp flag
  lets us ignore the meter-timestamp settimeofday() so only real SNTP
  syncs count.
- ESP32: sntp_set_time_sync_notification_cb(void(*)(struct timeval*)).

The Services tile now reports NTP as degraded (yellow) when there has
been no SNTP sync since boot or the last sync is older than 3h, and OK
(green) only on a recent sync.

Diagnostic only; no change to the accounting logic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown

🔧 PR Build Artifacts

Version: dcdac45

All environments built successfully. Download the zip files:

Artifacts expire after 7 days. View workflow run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant