feat: NTP time sync writing to DS3231 (by IP, DNS-independent)
This LAN's router does not resolve external hostnames, so NTP uses hard-coded Cloudflare/Google anycast IPs instead of names. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -55,6 +55,10 @@ void setup() {
|
|||||||
displaySplash("WiFi", "Connect / portal");
|
displaySplash("WiFi", "Connect / portal");
|
||||||
if (netBegin()) {
|
if (netBegin()) {
|
||||||
Serial.printf("WiFi connected: %s\n", netIP().c_str());
|
Serial.printf("WiFi connected: %s\n", netIP().c_str());
|
||||||
|
if (ntpSync(settings.tzOffsetMin))
|
||||||
|
Serial.println(F("RTC synced from NTP"));
|
||||||
|
else
|
||||||
|
Serial.println(F("NTP sync failed"));
|
||||||
} else {
|
} else {
|
||||||
Serial.println(F("WiFi not connected - running offline"));
|
Serial.println(F("WiFi not connected - running offline"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,5 +30,5 @@ static const float DEFAULT_LAT = 54.9870f;
|
|||||||
static const float DEFAULT_LON = 82.8730f;
|
static const float DEFAULT_LON = 82.8730f;
|
||||||
|
|
||||||
// ---- Network ----
|
// ---- Network ----
|
||||||
#define NTP_SERVER "pool.ntp.org"
|
// NTP is done by hard-coded IP in rtc_time.cpp (this LAN's DNS is unreliable).
|
||||||
#define AP_NAME "WeatherPredictor-Setup"
|
#define AP_NAME "WeatherPredictor-Setup"
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
#include <RTClib.h>
|
#include <RTClib.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include "config.h"
|
||||||
#include "rtc_time.h"
|
#include "rtc_time.h"
|
||||||
|
|
||||||
static RTC_DS3231 rtc;
|
static RTC_DS3231 rtc;
|
||||||
@@ -18,3 +21,22 @@ void rtcSet(const RtcTime& t) {
|
|||||||
uint32_t rtcEpoch() {
|
uint32_t rtcEpoch() {
|
||||||
return rtc.now().unixtime();
|
return rtc.now().unixtime();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ntpSync(int tzOffsetMin) {
|
||||||
|
// NTP servers by IP to bypass DNS (this network doesn't resolve names reliably).
|
||||||
|
// Cloudflare (162.159.200.123) and Google (216.239.35.0/.4) are stable anycast.
|
||||||
|
configTime(tzOffsetMin * 60, 0, "162.159.200.123", "216.239.35.0", "216.239.35.4");
|
||||||
|
time_t now = time(nullptr);
|
||||||
|
int tries = 0;
|
||||||
|
while (now < 1700000000 && tries < 120) { // up to ~30 s
|
||||||
|
delay(250);
|
||||||
|
now = time(nullptr);
|
||||||
|
tries++;
|
||||||
|
}
|
||||||
|
if (now < 1700000000) return false;
|
||||||
|
struct tm* lt = localtime(&now);
|
||||||
|
rtcSet(RtcTime{ (uint16_t)(lt->tm_year + 1900), (uint8_t)(lt->tm_mon + 1),
|
||||||
|
(uint8_t)lt->tm_mday, (uint8_t)lt->tm_hour,
|
||||||
|
(uint8_t)lt->tm_min, (uint8_t)lt->tm_sec });
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,3 +11,4 @@ bool rtcLostPower();
|
|||||||
RtcTime rtcNow();
|
RtcTime rtcNow();
|
||||||
void rtcSet(const RtcTime& t);
|
void rtcSet(const RtcTime& t);
|
||||||
uint32_t rtcEpoch();
|
uint32_t rtcEpoch();
|
||||||
|
bool ntpSync(int tzOffsetMin); // true if synced and RTC updated
|
||||||
|
|||||||
Reference in New Issue
Block a user