From 4341158fa3e440000926732020ec1ca365df3dd8 Mon Sep 17 00:00:00 2001 From: Klaus K Wilting Date: Mon, 28 Jan 2019 00:38:31 +0100 Subject: [PATCH] added timezone support --- include/rtctime.h | 3 ++- src/cyclic.cpp | 15 ++++++--------- src/display.cpp | 2 +- src/if482.cpp | 2 +- src/lorawan.cpp | 5 +++-- src/main.cpp | 39 ++++++++++++++++++++------------------- src/paxcounter.conf | 5 ++++- src/rtctime.cpp | 26 ++++++++++++++++++-------- 8 files changed, 55 insertions(+), 42 deletions(-) diff --git a/include/rtctime.h b/include/rtctime.h index 09c86492..e308ec20 100644 --- a/include/rtctime.h +++ b/include/rtctime.h @@ -3,6 +3,7 @@ #include "globals.h" #include +#include #include // must be included here so that Arduino library object file references work #include @@ -19,9 +20,9 @@ typedef enum { } clock_state_t; extern RtcDS3231 Rtc; // make RTC instance globally available +extern Timezone myTZ; // make Timezone myTZ globally available int rtc_init(void); -void sync_rtctime(void); int set_rtctime(uint32_t UTCTime); int set_rtctime(RtcDateTime now); void sync_rtctime(void); diff --git a/src/cyclic.cpp b/src/cyclic.cpp index 312d3aa0..dc9fe12f 100644 --- a/src/cyclic.cpp +++ b/src/cyclic.cpp @@ -130,26 +130,23 @@ void do_timesync() { gps.date.day(), gps.date.month(), gps.date.year()); // set RTC time to time source GPS, if RTC is present #ifdef HAS_RTC - RtcDateTime t = - RtcDateTime(gps.date.year(), gps.date.month(), gps.date.day(), - gps.time.hour(), gps.time.minute(), gps.time.second()); - set_rtctime(t); + if (!set_rtctime(RtcDateTime(now()))) + ESP_LOGE(TAG, "RTC set time failure"); #endif - time_t tt = now(); + time_t tt = myTZ.toLocal(now()); ESP_LOGI(TAG, "GPS has set system time to %02d/%02d/%d %02d:%02d:%02d", month(tt), day(tt), year(tt), hour(tt), minute(tt), second(tt)); return; } else { ESP_LOGI(TAG, "No valid GPS time"); } -#endif // HAS_GPS -// set system time to time source LoRa Network, if network supports DevTimeReq -#ifdef LMIC_ENABLE_DeviceTimeReq + // set system time to time source LoRa Network, if network supports DevTimeReq +#elif defined LMIC_ENABLE_DeviceTimeReq // Schedule a network time sync request at the next possible time LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime); ESP_LOGI(TAG, "Network time request scheduled"); -#endif +#endif // HAS_GPS #endif // TIME_SYNC_INTERVAL } // do_timesync() diff --git a/src/display.cpp b/src/display.cpp index f52286ec..7f9adbea 100644 --- a/src/display.cpp +++ b/src/display.cpp @@ -209,7 +209,7 @@ void refreshtheDisplay() { u8x8.printf("%-16s", display_line6); #else // update time/date display (line 6) - time_t t = now(); + time_t t = myTZ.toLocal(now()); u8x8.printf("%02d:%02d:%02d%c %2d.%3s", hour(t), minute(t), second(t), timeStatus() == timeSet ? '*' : '?', day(t), printmonth[month(t)]); diff --git a/src/if482.cpp b/src/if482.cpp index 76e59755..48d98a47 100644 --- a/src/if482.cpp +++ b/src/if482.cpp @@ -140,7 +140,7 @@ void if482_loop(void *pvParameters) { &wakeTime, // receives moment of call from isr portMAX_DELAY); // wait forever (missing error handling here...) - t = now(); + t = myTZ.toLocal(now()); wakeTime -= startOffset; // now we're synced to start of second t and wait diff --git a/src/lorawan.cpp b/src/lorawan.cpp index 437a7e61..dd200c89 100644 --- a/src/lorawan.cpp +++ b/src/lorawan.cpp @@ -456,9 +456,10 @@ void user_request_network_time_callback(void *pVoidUserUTCTime, // Update system time with time read from the network setTime(*pUserUTCTime); #ifdef HAS_RTC - set_rtctime(*pUserUTCTime); + if (!set_rtctime(*pUserUTCTime)) + ESP_LOGE(TAG, "RTC set time failure"); #endif - time_t t = now(); + time_t t = myTZ.toLocal(now()); ESP_LOGI(TAG, "LORA Network has set system time to %02d/%02d/%d %02d:%02d:%02d", month(t), day(t), year(t), hour(t), minute(t), second(t)); diff --git a/src/main.cpp b/src/main.cpp index 5c6cf814..57350e70 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -173,7 +173,7 @@ void setup() { #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) // start led loop - ESP_LOGI(TAG, "Starting LEDloop..."); + ESP_LOGI(TAG, "Starting LED Controller..."); xTaskCreatePinnedToCore(ledLoop, // task function "ledloop", // name of task 1024, // stack size of task @@ -190,18 +190,17 @@ void setup() { sync_rtctime(); #ifdef HAS_IF482 strcat_P(features, " IF482"); - if (if482_init()) { - ESP_LOGI(TAG, "Starting IF482loop..."); - xTaskCreatePinnedToCore(if482_loop, // task function - "if482loop", // name of task - 2048, // stack size of task - (void *)1, // parameter of the task - 3, // priority of the task - &IF482Task, // task handle - 0); // CPU core - } -#endif // HAS_IF482 -#endif // HAS_RTC + assert(if482_init()); + ESP_LOGI(TAG, "Starting IF482 Generator..."); + xTaskCreatePinnedToCore(if482_loop, // task function + "if482loop", // name of task + 2048, // stack size of task + (void *)1, // parameter of the task + 3, // priority of the task + &IF482Task, // task handle + 0); // CPU core +#endif // HAS_IF482 +#endif // HAS_RTC // initialize wifi antenna #ifdef HAS_ANTENNA_SWITCH @@ -265,7 +264,7 @@ void setup() { #ifdef HAS_GPS strcat_P(features, " GPS"); if (gps_init()) { - ESP_LOGI(TAG, "Starting GPSloop..."); + ESP_LOGI(TAG, "Starting GPS Feed..."); xTaskCreatePinnedToCore(gps_loop, // task function "gpsloop", // name of task 2048, // stack size of task @@ -359,7 +358,7 @@ void setup() { get_salt(); // get new 16bit for salting hashes // start state machine - ESP_LOGI(TAG, "Starting IRQ Handler..."); + ESP_LOGI(TAG, "Starting Interrupt Handler..."); xTaskCreatePinnedToCore(irqHandler, // task function "irqhandler", // name of task 4096, // stack size of task @@ -382,7 +381,7 @@ void setup() { #ifdef HAS_BME strcat_P(features, " BME"); if (bme_init()) { - ESP_LOGI(TAG, "Starting BMEloop..."); + ESP_LOGI(TAG, "Starting Bluetooth sniffer..."); xTaskCreatePinnedToCore(bme_loop, // task function "bmeloop", // name of task 2048, // stack size of task @@ -393,7 +392,8 @@ void setup() { } #endif - // start timer triggered interrupts + assert(irqHandlerTask != NULL); // has interrupt handler task started? + // start timer triggered interrupts ESP_LOGI(TAG, "Starting Interrupts..."); #ifdef HAS_DISPLAY timerAlarmEnable(displaytimer); @@ -414,8 +414,9 @@ void setup() { // start RTC interrupt #if defined HAS_IF482 && defined HAS_RTC // setup external interupt for active low RTC INT pin - if (IF482IRQ != NULL) // has if482loop task started? - attachInterrupt(digitalPinToInterrupt(RTC_INT), IF482IRQ, FALLING); + assert(IF482Task != NULL); // has if482loop task started? + ESP_LOGI(TAG, "Starting IF482 output..."); + attachInterrupt(digitalPinToInterrupt(RTC_INT), IF482IRQ, FALLING); #endif } // setup() diff --git a/src/paxcounter.conf b/src/paxcounter.conf index 1b1875e3..050fe655 100644 --- a/src/paxcounter.conf +++ b/src/paxcounter.conf @@ -82,9 +82,12 @@ #define RESPONSE_TIMEOUT_MS 60000 // firmware binary server connection timeout [milliseconds] // settings for syncing time of node and external time sources -//#define TIME_SYNC_INTERVAL 60 // sync time each ... minutes with external source [default = 60], comment out means off +#define TIME_SYNC_INTERVAL 60 // sync time each ... minutes with external source [default = 60], comment out means off #define TIME_SYNC_INTERVAL_RTC 5 // sync time each ... minutes with RTC [default = 5], comment out means off #define IF482_OFFSET 984 // 1sec minus IF482 serial transmit time [ms]: e.g. 9 bits * 17 bytes * 1/9600 bps = 16ms +// time zone, see https://github.com/JChristensen/Timezone/blob/master/examples/WorldClock/WorldClock.ino +#define DAYLIGHT_TIME {"CEST", Last, Sun, Mar, 2, 120} // Central European Summer Time +#define STANDARD_TIME {"CET ", Last, Sun, Oct, 3, 60} // Central European Standard Time // LMIC settings // moved to src/lmic_config.h \ No newline at end of file diff --git a/src/rtctime.cpp b/src/rtctime.cpp index d826a5cf..4262b25e 100644 --- a/src/rtctime.cpp +++ b/src/rtctime.cpp @@ -5,7 +5,12 @@ // Local logging tag static const char TAG[] = "main"; -RtcDS3231 Rtc(Wire); +RtcDS3231 Rtc(Wire); // RTC hardware i2c interface + +// set Time Zone, fetch user setting from paxcounter.conf +TimeChangeRule myDST = DAYLIGHT_TIME; +TimeChangeRule mySTD = STANDARD_TIME; +Timezone myTZ(myDST, mySTD); // initialize RTC int rtc_init(void) { @@ -34,7 +39,7 @@ int rtc_init(void) { RtcDateTime now = Rtc.GetDateTime(); if (now < compiled) { - ESP_LOGI(TAG, "RTC date/time is older than compilation date, updating)"); + ESP_LOGI(TAG, "RTC date/time is older than compilation date, updating"); Rtc.SetDateTime(compiled); } @@ -80,12 +85,12 @@ int set_rtctime(RtcDateTime t) { } // set_rtctime() time_t get_rtctime(void) { - // never call now() in this function, would cause recursion! + // never call now() in this function, this would cause a recursion! time_t tt = 0; // block i2c bus access if (I2C_MUTEX_LOCK()) { if (!Rtc.IsDateTimeValid()) { - ESP_LOGW(TAG, "RTC lost confidence in the DateTime"); + ESP_LOGW(TAG, "RTC has no confident time"); } else { RtcDateTime t = Rtc.GetDateTime(); tt = t.Epoch32Time(); @@ -99,16 +104,21 @@ time_t get_rtctime(void) { void sync_rtctime(void) { if (timeStatus() != timeSet) { // do we need time sync? time_t t = get_rtctime(); - if (t) { // do we have valid time by RTC? + if (t) { // have we got a valid time from RTC? setTime(t); + time_t tt = myTZ.toLocal(t); ESP_LOGI(TAG, "RTC has set system time to %02d/%02d/%d %02d:%02d:%02d", - month(t), day(t), year(t), hour(t), minute(t), second(t)); + month(tt), day(tt), year(tt), hour(tt), minute(tt), second(tt)); } else - ESP_LOGE(TAG, "RTC has no confident time, not synced"); + ESP_LOGW(TAG, "System time was not synced"); } #ifdef TIME_SYNC_INTERVAL_RTC - setSyncProvider(&get_rtctime); + setSyncProvider(&get_rtctime); // does not sync if callback function returns 0 + if (timeStatus() != timeSet) + ESP_LOGI("Unable to sync with the RTC"); + else + ESP_LOGI("RTC has set the system time"); setSyncInterval(TIME_SYNC_INTERVAL_RTC); #endif