Add EU DST<->STD time change to gateway

pull/142/head
Jeff Lehman 1 year ago
parent 56af9918c9
commit d9083d0d75

@ -70,10 +70,12 @@
//#define MQTT_PASS "Your MQTT Password"
// NTP Time settings
#define USDST
// #define EUDST
#define TIME_SERVER "0.us.pool.ntp.org" // NTP time server to use. If FQDN at least one DNS server is required to resolve name
#define STD_OFFSET (-6) // Local standard time offset in hours from UTC - if unsure, check https://time.is
#define DST_OFFSET (STD_OFFSET + 1) // Local savings time offset in hours from UTC - if unsure, check https://time.is
#define TIME_FETCHNTP 15 // Time, in minutes, between fetching time from NTP server
#define TIME_PRINTTIME 1 // Time, in minutes, between printing local time to debug
#define TIME_SEND_INTERVAL 1 // Time, in minutes, between sending out time to remote devices
#define TIME_PRINTTIME 10 // Time, in minutes, between printing local time to debug
#define TIME_SEND_INTERVAL 15 // Time, in minutes, between sending out time to remote devices

@ -70,9 +70,11 @@
//#define MQTT_PASS "Your MQTT Password"
// NTP Time settings
#define USDST
// #define EUDST
#define TIME_SERVER "0.us.pool.ntp.org" // NTP time server to use. If FQDN at least one DNS server is required to resolve name
#define STD_OFFSET (-6) // Local standard time offset in hours from UTC - if unsure, check https://time.is
#define DST_OFFSET (STD_OFFSET + 1) // Local savings time offset in hours from UTC - if unsure, check https://time.is
#define TIME_FETCHNTP 15 // Time, in minutes, between fetching time from NTP server
#define TIME_PRINTTIME 1 // Time, in minutes, between printing local time to debug
#define TIME_SEND_INTERVAL 1 // Time, in minutes, between sending out time to remote devices
#define TIME_PRINTTIME 10 // Time, in minutes, between printing local time to debug
#define TIME_SEND_INTERVAL 15 // Time, in minutes, between sending out time to remote devices

@ -70,9 +70,11 @@
//#define MQTT_PASS "Your MQTT Password"
// NTP Time settings
#define USDST
// #define EUDST
#define TIME_SERVER "0.us.pool.ntp.org" // NTP time server to use. If FQDN at least one DNS server is required to resolve name
#define STD_OFFSET (-6) // Local standard time offset in hours from UTC - if unsure, check https://time.is
#define DST_OFFSET (STD_OFFSET + 1) // Local savings time offset in hours from UTC - if unsure, check https://time.is
#define TIME_FETCHNTP 15 // Time, in minutes, between fetching time from NTP server
#define TIME_PRINTTIME 1 // Time, in minutes, between printing local time to debug
#define TIME_SEND_INTERVAL 1 // Time, in minutes, between sending out time to remote devices
#define TIME_PRINTTIME 10 // Time, in minutes, between printing local time to debug
#define TIME_SEND_INTERVAL 15 // Time, in minutes, between sending out time to remote devices

@ -70,9 +70,11 @@
//#define MQTT_PASS "Your MQTT Password"
// NTP Time settings
#define USDST
// #define EUDST
#define TIME_SERVER "0.us.pool.ntp.org" // NTP time server to use. If FQDN at least one DNS server is required to resolve name
#define STD_OFFSET (-6) // Local standard time offset in hours from UTC - if unsure, check https://time.is
#define DST_OFFSET (STD_OFFSET + 1) // Local savings time offset in hours from UTC - if unsure, check https://time.is
#define TIME_FETCHNTP 15 // Time, in minutes, between fetching time from NTP server
#define TIME_PRINTTIME 1 // Time, in minutes, between printing local time to debug
#define TIME_SEND_INTERVAL 1 // Time, in minutes, between sending out time to remote devices
#define TIME_PRINTTIME 10 // Time, in minutes, between printing local time to debug
#define TIME_SEND_INTERVAL 15 // Time, in minutes, between sending out time to remote devices

@ -71,9 +71,11 @@
// NTP Time settings
#define USDST
// #define EUDST
#define TIME_SERVER "0.us.pool.ntp.org" // NTP time server to use. If FQDN at least one DNS server is required to resolve name
#define STD_OFFSET (-6) // Local standard time offset in hours from UTC - if unsure, check https://time.is
#define DST_OFFSET (STD_OFFSET + 1) // Local savings time offset in hours from UTC - if unsure, check https://time.is
#define TIME_FETCHNTP 15 // Time, in minutes, between fetching time from NTP server
#define TIME_PRINTTIME 1 // Time, in minutes, between printing local time to debug
#define TIME_SEND_INTERVAL 1 // Time, in minutes, between sending out time to remote devices
#define TIME_PRINTTIME 10 // Time, in minutes, between printing local time to debug
#define TIME_SEND_INTERVAL 15 // Time, in minutes, between sending out time to remote devices

@ -377,8 +377,6 @@ esp_err_t sendESPNowTempPeer(uint8_t *dest) {
}
void recvTimeEspNow() {
time_t previousTime = now;
now = theCmd.param;
setTime(previousTime);
setTime(theCmd.param);
DBG("Received time via ESP-NOW from 0x" + String(incMAC[5],HEX));
}

@ -40,9 +40,7 @@ void getSerial() {
else if(obj.containsKey("cmd")) { // SystemPacket
cmd_t c = doc[0]["cmd"];
if(c == cmd_time) {
time_t previousTime = now;
now = doc[0]["param"];
setTime(previousTime);
setTime(doc[0]["param"]);
DBG("Incoming Serial: time");
}
else {

@ -21,8 +21,11 @@
#define FDRS_DST_OFFSET GLOBAL_DST_OFFSET
#endif // DST_OFFSET
#define USDSTSTART (timeinfo.tm_mon == 2; timeinfo.tm_wday == 0 && timeinfo.tm_mday > 7 && timeinfo.tm_mday < 15 && timeinfo.tm_hour == 2)
#define USDSTEND (timeinfo.tm_mon == 10 && timeinfo.tm_wday == 0 && timeinfo.tm_mday < 8 && timeinfo.tm_hour == 2)
// US DST Start - 2nd Sunday in March - 02:00 local time
// US DST End - 1st Sunday in November - 02:00 local time
// EU DST Start - last Sunday in March - 01:00 UTC
// EU DST End - last Sunday in October - 01:00 UTC
time_t now; // Current time in UTC- number of seconds since Jan 1 1970 (epoch)
struct tm timeinfo; // Structure containing time elements
@ -71,7 +74,7 @@ void printTime() {
time_t local = time(NULL) + (isDST?dstOffset:stdOffset);
localtime_r(&local, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
DBG("The current local date/time is: " + String(strftime_buf) + (isDST?" DST":" STD"));
DBG("Local date/time is: " + String(strftime_buf) + (isDST?" DST":" STD"));
}
}
@ -84,16 +87,30 @@ void checkDST() {
struct tm dstBegin;
dstBegin.tm_year = timeinfo.tm_year;
dstBegin.tm_mon = 2;
#ifdef USDST
dstBegin.tm_mday = 8;
dstBegin.tm_hour = 2;
dstBegin.tm_min = 0;
dstBegin.tm_sec = 0;
mktime(&dstBegin); // calculate tm_dow
mktime(&dstBegin); // calculate tm_wday
dstBegin.tm_mday = dstBegin.tm_mday + ((7 - dstBegin.tm_wday) % 7);
// mktime(&dstBegin); // recalculate tm_dow
// mktime(&dstBegin); // recalculate tm_wday
// strftime(buf, sizeof(buf), "%c", &dstBegin);
// DBG("DST Begins: " + String(buf) + " local");
time_t tdstBegin = mktime(&dstBegin) - stdOffset;
#endif // USDST
#ifdef EUDST
dstBegin.tm_mday = 25;
dstBegin.tm_hour = 1;
dstBegin.tm_min = 0;
dstBegin.tm_sec = 0;
mktime(&dstBegin); // calculate tm_wday
dstBegin.tm_mday = dstBegin.tm_mday + ((7 - dstBegin.tm_wday) % 7);
// mktime(&dstBegin); // recalculate tm_wday
// strftime(buf, sizeof(buf), "%c", &dstBegin);
// DBG("DST Begins: " + String(buf) + " local");
time_t tdstBegin = mktime(&dstBegin);
#endif // EUDST
if(tdstBegin != -1 && (time(NULL) - tdstBegin >= 0) && isDST == false) { // STD -> DST
dstFlag = 1;
}
@ -101,7 +118,36 @@ void checkDST() {
dstFlag = 0;
}
}
else if(timeinfo.tm_mon == 9) {
#ifdef EUDST
struct tm dstEnd;
dstEnd.tm_year = timeinfo.tm_year;
dstEnd.tm_mon = 9;
dstEnd.tm_mday = 25;
dstEnd.tm_hour = 1;
dstEnd.tm_min = 0;
dstEnd.tm_sec = 0;
mktime(&dstEnd); // calculate tm_dow
dstEnd.tm_mday = dstEnd.tm_mday + ((7 - dstEnd.tm_wday) % 7);
// mktime(&dstEnd); // recalculate tm_dow
// strftime(buf, sizeof(buf), "%c", &dstEnd);
// DBG("DST Ends: " + String(buf) + " local");
time_t tdstEnd = mktime(&dstEnd);
if(tdstEnd != -1 && (time(NULL) - tdstEnd >= 0) && isDST == true) { // DST -> STD
dstFlag = 0;
}
else if(tdstEnd != -1 && (time(NULL) - tdstEnd < 0) && isDST == false) { // STD -> DST
dstFlag = 1;
}
#endif //EUDST
#ifdef USDST
if(isDST == false) {
dstFlag = 1;
}
#endif // USDST
}
else if(timeinfo.tm_mon == 10) {
#ifdef USDST
struct tm dstEnd;
dstEnd.tm_year = timeinfo.tm_year;
dstEnd.tm_mon = 10;
@ -121,11 +167,17 @@ void checkDST() {
else if(tdstEnd != -1 && (time(NULL) - tdstEnd < 0) && isDST == false) { // STD -> DST
dstFlag = 1;
}
#endif //USDST
#ifdef EUDST
if(isDST == true) {
dstFlag = 0;
}
#endif // EUDST
}
else if((timeinfo.tm_mon == 11 || timeinfo.tm_mon == 0 || timeinfo.tm_mon == 1) && isDST == true) {
dstFlag = 0;
}
else if(timeinfo.tm_mon >= 3 && timeinfo.tm_mon <= 9 && isDST == false) {
else if(timeinfo.tm_mon >= 3 && timeinfo.tm_mon <= 8 && isDST == false) {
dstFlag = 1;
}
if(dstFlag == 1) {
@ -136,17 +188,19 @@ void checkDST() {
isDST = false;
// Since we are potentially moving back an hour we need to prevent flip flopping back and forth
// 2AM -> 1AM, wait 70 minutes -> 2:10AM then start DST checks again.
lastDstCheck += (70 * 60); // skip checks for another 70 minutes
lastDstCheck += ((65-timeinfo.tm_min) * 60); // skip checks until after beginning of next hour
DBG("Time change from DST -> STD");
}
}
return;
}
bool setTime(time_t previousTime) {
bool setTime(time_t currentTime) {
slewSecs = 0;
time_t previousTime = now;
if(previousTime != 0) {
if(currentTime != 0) {
now = currentTime;
slewSecs = now - previousTime;
DBG("Time adjust " + String(slewSecs) + " secs");
}

@ -1,11 +1,19 @@
#include <sys/time.h>
// select Local Offset from UTC configuration
#if defined(LOCAL_OFFSET)
#define FDRS_LOCAL_OFFSET LOCAL_OFFSET
// select Local Standard time Offset from UTC configuration
#if defined(STD_OFFSET)
#define FDRS_STD_OFFSET STD_OFFSET
#else
#define FDRS_LOCAL_OFFSET GLOBAL_LOCAL_OFFSET
#endif // LOCAL_OFFSET
#define FDRS_STD_OFFSET GLOBAL_STD_OFFSET
#endif // STD_OFFSET
// select Local savings time Offset from UTC configuration
#if defined(DST_OFFSET)
#define FDRS_DST_OFFSET DST_OFFSET
#else
#define FDRS_DST_OFFSET GLOBAL_DST_OFFSET
#endif // DST_OFFSET
#define DSTSTART (timeinfo.tm_mon == 2 && timeinfo.tm_wday == 0 && timeinfo.tm_mday > 7 && timeinfo.tm_mday < 15 && timeinfo.tm_hour == 2)
#define DSTEND (timeinfo.tm_mon == 10 && timeinfo.tm_wday == 0 && timeinfo.tm_mday < 8 && timeinfo.tm_hour == 2)
@ -19,6 +27,9 @@ time_t lastTimeSetEvent = 0;
bool isDST;
time_t previousTime = 0;
long slewSecs = 0;
double stdOffset = (FDRS_STD_OFFSET * 60 * 60); // UTC -> Local time, in Seconds, offset from UTC in Standard Time
double dstOffset = (FDRS_DST_OFFSET * 60 * 60); // DST offset from standard time (in seconds)
time_t lastDstCheck = 0;
// Function prototypes
void loadFDRS(float, uint8_t, uint16_t);
@ -59,24 +70,77 @@ void printTime() {
// now += localOffset;
// Local time
time_t local = time(NULL) + (isDST?dstOffset:stdOffset);
localtime_r(&now, &timeinfo);
strftime(strftime_buf, sizeof(strftime_buf), "%c", &timeinfo);
DBG("Local date/time: " + String(strftime_buf));
DBG("Local date/time: " + String(strftime_buf) + (isDST?" DST":" STD"));
}
// Checks for DST or STD and adjusts time if there is a change
void checkDST() {
// DST -> STD - subtract one hour (3600 seconds)
if(validTimeFlag && isDST && (DSTEND || timeinfo.tm_isdst == 1)) {
isDST = false;
now -= 3600;
DBG("Time change from DST -> STD");
}
// STD -> DST - add one hour (3600 seconds)
else if(validTimeFlag && !isDST && (DSTSTART || timeinfo.tm_isdst == 0)) {
isDST = true;
now += 3600;
DBG("Time change from STD -> DST");
if(validTime() && (time(NULL) - lastDstCheck > 5)) {
lastDstCheck = time(NULL);
int dstFlag = -1;
localtime_r(&now, &timeinfo);
if(timeinfo.tm_mon == 2) {
struct tm dstBegin;
dstBegin.tm_year = timeinfo.tm_year;
dstBegin.tm_mon = 2;
dstBegin.tm_mday = 8;
dstBegin.tm_hour = 2;
dstBegin.tm_min = 0;
dstBegin.tm_sec = 0;
mktime(&dstBegin); // calculate tm_dow
dstBegin.tm_mday = dstBegin.tm_mday + ((7 - dstBegin.tm_wday) % 7);
// mktime(&dstBegin); // recalculate tm_dow
// strftime(buf, sizeof(buf), "%c", &dstBegin);
// DBG("DST Begins: " + String(buf) + " local");
time_t tdstBegin = mktime(&dstBegin) - stdOffset;
if(tdstBegin != -1 && (time(NULL) - tdstBegin >= 0) && isDST == false) { // STD -> DST
dstFlag = 1;
}
else if(tdstBegin != -1 && (time(NULL) - tdstBegin < 0) && isDST == true) { // DST -> STD
dstFlag = 0;
}
}
else if(timeinfo.tm_mon == 10) {
struct tm dstEnd;
dstEnd.tm_year = timeinfo.tm_year;
dstEnd.tm_mon = 10;
dstEnd.tm_mday = 1;
dstEnd.tm_hour = 2;
dstEnd.tm_min = 0;
dstEnd.tm_sec = 0;
mktime(&dstEnd); // calculate tm_dow
dstEnd.tm_mday = dstEnd.tm_mday + ((7 - dstEnd.tm_wday) % 7);
// mktime(&dstEnd); // recalculate tm_dow
// strftime(buf, sizeof(buf), "%c", &dstEnd);
// DBG("DST Ends: " + String(buf) + " local");
time_t tdstEnd = mktime(&dstEnd) - dstOffset;
if(tdstEnd != -1 && (time(NULL) - tdstEnd >= 0) && isDST == true) { // DST -> STD
dstFlag = 0;
}
else if(tdstEnd != -1 && (time(NULL) - tdstEnd < 0) && isDST == false) { // STD -> DST
dstFlag = 1;
}
}
else if((timeinfo.tm_mon == 11 || timeinfo.tm_mon == 0 || timeinfo.tm_mon == 1) && isDST == true) {
dstFlag = 0;
}
else if(timeinfo.tm_mon >= 3 && timeinfo.tm_mon <= 9 && isDST == false) {
dstFlag = 1;
}
if(dstFlag == 1) {
isDST = true;
DBG("Time change from STD -> DST");
}
else if(dstFlag == 0) {
isDST = false;
// Since we are potentially moving back an hour we need to prevent flip flopping back and forth
// 2AM -> 1AM, wait 70 minutes -> 2:10AM then start DST checks again.
lastDstCheck += ((65-timeinfo.tm_min) * 60); // skip checks until after the next hour
DBG("Time change from DST -> STD");
}
}
return;
}
@ -84,18 +148,23 @@ void checkDST() {
// Sets the time and calculates time time difference, in seconds, of the time change
// Returns true if time is valid otherwise false
bool setTime(time_t previousTime) {
slewSecs = now - previousTime;
DBG("Time adjust " + String(slewSecs) + " secs");
slewSecs = 0;
if(previousTime != 0) {
slewSecs = now - previousTime;
DBG("Time adjust " + String(slewSecs) + " secs");
}
// time(&now);
tv.tv_sec = now;
settimeofday(&tv,NULL);
localtime_r(&now, &timeinfo);
localtime_r(&now, &timeinfo); // write to timeinfo struct
mktime(&timeinfo); // set tm_isdst flag
// Check for DST/STD time and adjust accordingly
checkDST();
loadFDRS(now, STATUS_T, READING_ID);
loadFDRS(slewSecs, STATUS_T, READING_ID);
tv.tv_sec = now;
settimeofday(&tv,NULL); // set the RTC time
// loadFDRS(now, STATUS_T, READING_ID);
// loadFDRS(slewSecs, STATUS_T, READING_ID);
// DO NOT CALL sendFDRS here. Will not work for some reason ?????????
if(validTime()) {
lastTimeSetEvent = millis();

Loading…
Cancel
Save