Refactor time sync messages

This commit is contained in:
Theo Arends 2022-02-27 16:09:32 +01:00
parent f240c5d68c
commit 45a0b7cc84
5 changed files with 50 additions and 47 deletions

View File

@ -471,10 +471,10 @@ void RtcSecond(void)
mutex = false; mutex = false;
} }
void RtcSync(void) { void RtcSync(const char* source) {
Rtc.time_synced = true; Rtc.time_synced = true;
RtcSecond(); RtcSecond();
// AddLog(LOG_LEVEL_DEBUG, PSTR("RTC: Synced")); AddLog(LOG_LEVEL_INFO, PSTR("RTC: Synced by %s"), source);
} }
void RtcSetTime(uint32_t epoch) { void RtcSetTime(uint32_t epoch) {
@ -483,7 +483,9 @@ void RtcSetTime(uint32_t epoch) {
TasmotaGlobal.ntp_force_sync = true; TasmotaGlobal.ntp_force_sync = true;
} else { } else {
Rtc.user_time_entry = true; Rtc.user_time_entry = true;
Rtc.utc_time = epoch -1; // Will be corrected by RtcSecond // Rtc.utc_time = epoch -1; // Will be corrected by RtcSecond
Rtc.utc_time = epoch;
RtcSync("Time");
} }
} }

View File

@ -737,7 +737,7 @@ void WifiPollNtp() {
TasmotaGlobal.ntp_force_sync = false; TasmotaGlobal.ntp_force_sync = false;
AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NTP: Synch time...")); AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("NTP: Sync time..."));
ntp_run_time = millis(); ntp_run_time = millis();
uint32_t ntp_time = WifiGetNtp(); uint32_t ntp_time = WifiGetNtp();
ntp_run_time = (millis() - ntp_run_time) / 1000; ntp_run_time = (millis() - ntp_run_time) / 1000;
@ -747,8 +747,7 @@ void WifiPollNtp() {
if (ntp_time > START_VALID_TIME) { if (ntp_time > START_VALID_TIME) {
Rtc.utc_time = ntp_time; Rtc.utc_time = ntp_time;
ntp_sync_minute = 60; // Sync so block further requests ntp_sync_minute = 60; // Sync so block further requests
RtcSync(); RtcSync("NTP");
AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: Synched"));
} else { } else {
ntp_sync_minute++; // Try again in next minute ntp_sync_minute++; // Try again in next minute
} }
@ -839,7 +838,7 @@ uint32_t WifiGetNtp(void) {
if ((packet_buffer[0] & 0b11000000) == 0b11000000) { if ((packet_buffer[0] & 0b11000000) == 0b11000000) {
// Leap-Indicator: unknown (clock unsynchronized) // Leap-Indicator: unknown (clock unsynchronized)
// See: https://github.com/letscontrolit/ESPEasy/issues/2886#issuecomment-586656384 // See: https://github.com/letscontrolit/ESPEasy/issues/2886#issuecomment-586656384
AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: IP %_I unsynched"), (uint32_t)time_server_ip); AddLog(LOG_LEVEL_DEBUG, PSTR("NTP: IP %_I unsynced"), (uint32_t)time_server_ip);
ntp_server_id++; // Next server next time ntp_server_id++; // Next server next time
return 0; return 0;
} }

View File

@ -118,7 +118,7 @@ void CB_MESHDataReceived(uint8_t *MAC, uint8_t *packet, uint8_t len) {
Rtc.user_time_entry = true; Rtc.user_time_entry = true;
MESH.lastMessageFromBroker = millis(); MESH.lastMessageFromBroker = millis();
if (MESH.flags.nodeGotTime == 0) { if (MESH.flags.nodeGotTime == 0) {
RtcSync(); RtcSync("Mesh");
TasmotaGlobal.rules_flag.system_boot = 1; // for now we consider the node booted and let trigger system#boot on RULES TasmotaGlobal.rules_flag.system_boot = 1; // for now we consider the node booted and let trigger system#boot on RULES
} }
MESH.flags.nodeGotTime = 1; MESH.flags.nodeGotTime = 1;

View File

@ -20,17 +20,17 @@
#ifdef USE_I2C #ifdef USE_I2C
#ifdef USE_DS3231 #ifdef USE_DS3231
/*********************************************************************************************\ /*********************************************************************************************\
DS3231 - its a accurate RTC that used in the SONOFF for get time when you not have internet connection DS3231 - its a accurate RTC that used in the SONOFF for get time when you not have internet connection
This is minimal library that use only for read/write time ! This is minimal library that use only for read/write time !
We store UTC time in the DS3231 , so we can use the standart functions. We store UTC time in the DS3231 , so we can use the standart functions.
HOWTO Use : first time, you must to have internet connection (use your mobile phone or try in other location). HOWTO Use : first time, you must to have internet connection (use your mobile phone or try in other location).
once you have ntp connection , the DS3231 internal clock will be updated automatically. once you have ntp connection , the DS3231 internal clock will be updated automatically.
you can now power off the device, from now and on the time is stored in the module and will you can now power off the device, from now and on the time is stored in the module and will
be restored when the is no connection to NTP. be restored when the is no connection to NTP.
Source: Guy Elgabsi with special thanks to Jack Christensen Source: Guy Elgabsi with special thanks to Jack Christensen
I2C Address: 0x68 I2C Address: 0x68
\*********************************************************************************************/ \*********************************************************************************************/
#define XSNS_33 33 #define XSNS_33 33
#define XI2C_26 26 // See I2CDEVICES.md #define XI2C_26 26 // See I2CDEVICES.md
@ -67,10 +67,13 @@
#define HR1224 6 //Hours register 12 or 24 hour mode (24 hour mode==0) #define HR1224 6 //Hours register 12 or 24 hour mode (24 hour mode==0)
#define CENTURY 7 //Century bit in Month register #define CENTURY 7 //Century bit in Month register
#define DYDT 6 //Day/Date flag bit in alarm Day/Date registers #define DYDT 6 //Day/Date flag bit in alarm Day/Date registers
bool ds3231ReadStatus = false; bool ds3231ReadStatus = false;
bool ds3231WriteStatus = false; //flag, we want to read/write to DS3231 only once bool ds3231WriteStatus = false; //flag, we want to read/write to DS3231 only once
bool DS3231chipDetected = false; bool DS3231chipDetected = false;
/*********************************************************************************************/
#ifdef DS3231_NTP_SERVER #ifdef DS3231_NTP_SERVER
#include "NTPServer.h" #include "NTPServer.h"
#include "NTPPacket.h" #include "NTPPacket.h"
@ -93,9 +96,9 @@ struct NTP_t {
} NTP; } NTP;
#endif // DS3231_NTP_SERVER #endif // DS3231_NTP_SERVER
/*----------------------------------------------------------------------* /*----------------------------------------------------------------------*\
Detect the DS3231 Chip * Detect the DS3231 Chip
----------------------------------------------------------------------*/ \*----------------------------------------------------------------------*/
void DS3231Detect(void) { void DS3231Detect(void) {
if (!I2cSetDevice(USE_RTC_ADDR)) { return; } if (!I2cSetDevice(USE_RTC_ADDR)) { return; }
@ -105,23 +108,23 @@ void DS3231Detect(void) {
} }
} }
/*----------------------------------------------------------------------* /*----------------------------------------------------------------------*\
BCD-to-Decimal conversion * BCD-to-Decimal conversion
----------------------------------------------------------------------*/ \*----------------------------------------------------------------------*/
uint8_t bcd2dec(uint8_t n) { uint8_t bcd2dec(uint8_t n) {
return n - 6 * (n >> 4); return n - 6 * (n >> 4);
} }
/*----------------------------------------------------------------------* /*----------------------------------------------------------------------*\
Decimal-to-BCD conversion * Decimal-to-BCD conversion
----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
uint8_t dec2bcd(uint8_t n) { uint8_t dec2bcd(uint8_t n) {
return n + 6 * (n / 10); return n + 6 * (n / 10);
} }
/*----------------------------------------------------------------------* /*----------------------------------------------------------------------*\
Read time from DS3231 and return the epoch time (second since 1-1-1970 00:00) * Read time from DS3231 and return the epoch time (second since 1-1-1970 00:00)
----------------------------------------------------------------------*/ \*----------------------------------------------------------------------*/
uint32_t ReadFromDS3231(void) { uint32_t ReadFromDS3231(void) {
TIME_T tm; TIME_T tm;
tm.second = bcd2dec(I2cRead8(USE_RTC_ADDR, RTC_SECONDS)); tm.second = bcd2dec(I2cRead8(USE_RTC_ADDR, RTC_SECONDS));
@ -133,9 +136,10 @@ uint32_t ReadFromDS3231(void) {
tm.year = bcd2dec(I2cRead8(USE_RTC_ADDR, RTC_YEAR)); tm.year = bcd2dec(I2cRead8(USE_RTC_ADDR, RTC_YEAR));
return MakeTime(tm); return MakeTime(tm);
} }
/*----------------------------------------------------------------------*
Get time as TIME_T and set the DS3231 time to this value /*----------------------------------------------------------------------*\
----------------------------------------------------------------------*/ * Get time as TIME_T and set the DS3231 time to this value
/*----------------------------------------------------------------------*/
void SetDS3231Time (uint32_t epoch_time) { void SetDS3231Time (uint32_t epoch_time) {
TIME_T tm; TIME_T tm;
BreakTime(epoch_time, tm); BreakTime(epoch_time, tm);
@ -146,25 +150,24 @@ void SetDS3231Time (uint32_t epoch_time) {
I2cWrite8(USE_RTC_ADDR, RTC_DATE, dec2bcd(tm.day_of_month)); I2cWrite8(USE_RTC_ADDR, RTC_DATE, dec2bcd(tm.day_of_month));
I2cWrite8(USE_RTC_ADDR, RTC_MONTH, dec2bcd(tm.month)); I2cWrite8(USE_RTC_ADDR, RTC_MONTH, dec2bcd(tm.month));
I2cWrite8(USE_RTC_ADDR, RTC_YEAR, dec2bcd(tm.year)); I2cWrite8(USE_RTC_ADDR, RTC_YEAR, dec2bcd(tm.year));
I2cWrite8(USE_RTC_ADDR, RTC_STATUS, I2cRead8(USE_RTC_ADDR, RTC_STATUS) & ~_BV(OSF)); //clear the Oscillator Stop Flag I2cWrite8(USE_RTC_ADDR, RTC_STATUS, I2cRead8(USE_RTC_ADDR, RTC_STATUS) & ~_BV(OSF)); // Clear the Oscillator Stop Flag
} }
void DS3231EverySecond(void) { void DS3231EverySecond(void) {
if (!ds3231ReadStatus && (Rtc.utc_time < START_VALID_TIME)) { // We still did not sync with NTP (time not valid) , so, read time from DS3231 if (!ds3231ReadStatus && (Rtc.utc_time < START_VALID_TIME)) { // We still did not sync with NTP (time not valid) , so, read time from DS3231
uint32_t ds3231_time = ReadFromDS3231(); // Read UTC TIME from DS3231
uint32_t ds3231_time = ReadFromDS3231(); // Read UTC TIME from DS3231
if (ds3231_time > START_VALID_TIME) { if (ds3231_time > START_VALID_TIME) {
Rtc.utc_time = ds3231_time; Rtc.utc_time = ds3231_time;
RtcSync(); RtcSync("DS3231");
AddLog(LOG_LEVEL_DEBUG, PSTR("DS3: Synched")); // Rtc.user_time_entry = true; // Stop NTP sync and DS3231 time write
// Rtc.user_time_entry = true; // Stop NTP sync and DS3231 time write ds3231ReadStatus = true; // As time in DS3231 is valid, do not update again
ds3231ReadStatus = true; // if time in DS3231 is valid, do not update again
} }
} }
else if (!ds3231WriteStatus && (Rtc.utc_time > START_VALID_TIME) && (abs((int32_t)(Rtc.utc_time - ReadFromDS3231())) > 10)) { // If time is valid and has drifted from RTC more than 10 seconds else if ((!ds3231WriteStatus || (!(TasmotaGlobal.uptime % 3600))) && // After restart or every hour
AddLog(LOG_LEVEL_INFO, PSTR("DS3: Write Time from NTP (" D_UTC_TIME ") %s"), GetDateAndTime(DT_UTC).c_str()); (Rtc.utc_time > START_VALID_TIME) && // Valid UTC time
SetDS3231Time(Rtc.utc_time); // Update the DS3231 time (abs((int32_t)(Rtc.utc_time - ReadFromDS3231())) > 4)) { // Time has drifted from RTC more than 4 seconds
SetDS3231Time(Rtc.utc_time); // Update the DS3231 time
AddLog(LOG_LEVEL_DEBUG, PSTR("DS3: Re-synced (" D_UTC_TIME ") %s"), GetDateAndTime(DT_UTC).c_str());
ds3231WriteStatus = true; ds3231WriteStatus = true;
} }
#ifdef DS3231_NTP_SERVER #ifdef DS3231_NTP_SERVER

View File

@ -680,8 +680,7 @@ void UBXHandleTIME()
if (UBX.mode.forceUTCupdate || Rtc.user_time_entry == false) { if (UBX.mode.forceUTCupdate || Rtc.user_time_entry == false) {
// AddLog(LOG_LEVEL_INFO, PSTR("UBX: UTC-Time is valid, set system time")); // AddLog(LOG_LEVEL_INFO, PSTR("UBX: UTC-Time is valid, set system time"));
Rtc.utc_time = UBX.rec_buffer.values.time; Rtc.utc_time = UBX.rec_buffer.values.time;
RtcSync(); RtcSync("UBX");
AddLog(LOG_LEVEL_DEBUG, PSTR("UBX: Synched"));
} }
Rtc.user_time_entry = true; Rtc.user_time_entry = true;
} }