added timezone support

This commit is contained in:
Klaus K Wilting 2019-01-28 00:38:31 +01:00
parent 28bfae346e
commit 4341158fa3
8 changed files with 55 additions and 42 deletions

View File

@ -3,6 +3,7 @@
#include "globals.h" #include "globals.h"
#include <Time.h> #include <Time.h>
#include <Timezone.h>
#include <Wire.h> // must be included here so that Arduino library object file references work #include <Wire.h> // must be included here so that Arduino library object file references work
#include <RtcDS3231.h> #include <RtcDS3231.h>
@ -19,9 +20,9 @@ typedef enum {
} clock_state_t; } clock_state_t;
extern RtcDS3231<TwoWire> Rtc; // make RTC instance globally available extern RtcDS3231<TwoWire> Rtc; // make RTC instance globally available
extern Timezone myTZ; // make Timezone myTZ globally available
int rtc_init(void); int rtc_init(void);
void sync_rtctime(void);
int set_rtctime(uint32_t UTCTime); int set_rtctime(uint32_t UTCTime);
int set_rtctime(RtcDateTime now); int set_rtctime(RtcDateTime now);
void sync_rtctime(void); void sync_rtctime(void);

View File

@ -130,26 +130,23 @@ void do_timesync() {
gps.date.day(), gps.date.month(), gps.date.year()); gps.date.day(), gps.date.month(), gps.date.year());
// set RTC time to time source GPS, if RTC is present // set RTC time to time source GPS, if RTC is present
#ifdef HAS_RTC #ifdef HAS_RTC
RtcDateTime t = if (!set_rtctime(RtcDateTime(now())))
RtcDateTime(gps.date.year(), gps.date.month(), gps.date.day(), ESP_LOGE(TAG, "RTC set time failure");
gps.time.hour(), gps.time.minute(), gps.time.second());
set_rtctime(t);
#endif #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", 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)); month(tt), day(tt), year(tt), hour(tt), minute(tt), second(tt));
return; return;
} else { } else {
ESP_LOGI(TAG, "No valid GPS time"); ESP_LOGI(TAG, "No valid GPS time");
} }
#endif // HAS_GPS
// set system time to time source LoRa Network, if network supports DevTimeReq // set system time to time source LoRa Network, if network supports DevTimeReq
#ifdef LMIC_ENABLE_DeviceTimeReq #elif defined LMIC_ENABLE_DeviceTimeReq
// Schedule a network time sync request at the next possible time // Schedule a network time sync request at the next possible time
LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime); LMIC_requestNetworkTime(user_request_network_time_callback, &userUTCTime);
ESP_LOGI(TAG, "Network time request scheduled"); ESP_LOGI(TAG, "Network time request scheduled");
#endif #endif // HAS_GPS
#endif // TIME_SYNC_INTERVAL #endif // TIME_SYNC_INTERVAL
} // do_timesync() } // do_timesync()

View File

@ -209,7 +209,7 @@ void refreshtheDisplay() {
u8x8.printf("%-16s", display_line6); u8x8.printf("%-16s", display_line6);
#else #else
// update time/date display (line 6) // 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), u8x8.printf("%02d:%02d:%02d%c %2d.%3s", hour(t), minute(t), second(t),
timeStatus() == timeSet ? '*' : '?', day(t), timeStatus() == timeSet ? '*' : '?', day(t),
printmonth[month(t)]); printmonth[month(t)]);

View File

@ -140,7 +140,7 @@ void if482_loop(void *pvParameters) {
&wakeTime, // receives moment of call from isr &wakeTime, // receives moment of call from isr
portMAX_DELAY); // wait forever (missing error handling here...) portMAX_DELAY); // wait forever (missing error handling here...)
t = now(); t = myTZ.toLocal(now());
wakeTime -= startOffset; wakeTime -= startOffset;
// now we're synced to start of second t and wait // now we're synced to start of second t and wait

View File

@ -456,9 +456,10 @@ void user_request_network_time_callback(void *pVoidUserUTCTime,
// Update system time with time read from the network // Update system time with time read from the network
setTime(*pUserUTCTime); setTime(*pUserUTCTime);
#ifdef HAS_RTC #ifdef HAS_RTC
set_rtctime(*pUserUTCTime); if (!set_rtctime(*pUserUTCTime))
ESP_LOGE(TAG, "RTC set time failure");
#endif #endif
time_t t = now(); time_t t = myTZ.toLocal(now());
ESP_LOGI(TAG, ESP_LOGI(TAG,
"LORA Network has set system time to %02d/%02d/%d %02d:%02d:%02d", "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)); month(t), day(t), year(t), hour(t), minute(t), second(t));

View File

@ -173,7 +173,7 @@ void setup() {
#if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED) #if (HAS_LED != NOT_A_PIN) || defined(HAS_RGB_LED)
// start led loop // start led loop
ESP_LOGI(TAG, "Starting LEDloop..."); ESP_LOGI(TAG, "Starting LED Controller...");
xTaskCreatePinnedToCore(ledLoop, // task function xTaskCreatePinnedToCore(ledLoop, // task function
"ledloop", // name of task "ledloop", // name of task
1024, // stack size of task 1024, // stack size of task
@ -190,18 +190,17 @@ void setup() {
sync_rtctime(); sync_rtctime();
#ifdef HAS_IF482 #ifdef HAS_IF482
strcat_P(features, " IF482"); strcat_P(features, " IF482");
if (if482_init()) { assert(if482_init());
ESP_LOGI(TAG, "Starting IF482loop..."); ESP_LOGI(TAG, "Starting IF482 Generator...");
xTaskCreatePinnedToCore(if482_loop, // task function xTaskCreatePinnedToCore(if482_loop, // task function
"if482loop", // name of task "if482loop", // name of task
2048, // stack size of task 2048, // stack size of task
(void *)1, // parameter of the task (void *)1, // parameter of the task
3, // priority of the task 3, // priority of the task
&IF482Task, // task handle &IF482Task, // task handle
0); // CPU core 0); // CPU core
} #endif // HAS_IF482
#endif // HAS_IF482 #endif // HAS_RTC
#endif // HAS_RTC
// initialize wifi antenna // initialize wifi antenna
#ifdef HAS_ANTENNA_SWITCH #ifdef HAS_ANTENNA_SWITCH
@ -265,7 +264,7 @@ void setup() {
#ifdef HAS_GPS #ifdef HAS_GPS
strcat_P(features, " GPS"); strcat_P(features, " GPS");
if (gps_init()) { if (gps_init()) {
ESP_LOGI(TAG, "Starting GPSloop..."); ESP_LOGI(TAG, "Starting GPS Feed...");
xTaskCreatePinnedToCore(gps_loop, // task function xTaskCreatePinnedToCore(gps_loop, // task function
"gpsloop", // name of task "gpsloop", // name of task
2048, // stack size of task 2048, // stack size of task
@ -359,7 +358,7 @@ void setup() {
get_salt(); // get new 16bit for salting hashes get_salt(); // get new 16bit for salting hashes
// start state machine // start state machine
ESP_LOGI(TAG, "Starting IRQ Handler..."); ESP_LOGI(TAG, "Starting Interrupt Handler...");
xTaskCreatePinnedToCore(irqHandler, // task function xTaskCreatePinnedToCore(irqHandler, // task function
"irqhandler", // name of task "irqhandler", // name of task
4096, // stack size of task 4096, // stack size of task
@ -382,7 +381,7 @@ void setup() {
#ifdef HAS_BME #ifdef HAS_BME
strcat_P(features, " BME"); strcat_P(features, " BME");
if (bme_init()) { if (bme_init()) {
ESP_LOGI(TAG, "Starting BMEloop..."); ESP_LOGI(TAG, "Starting Bluetooth sniffer...");
xTaskCreatePinnedToCore(bme_loop, // task function xTaskCreatePinnedToCore(bme_loop, // task function
"bmeloop", // name of task "bmeloop", // name of task
2048, // stack size of task 2048, // stack size of task
@ -393,7 +392,8 @@ void setup() {
} }
#endif #endif
// start timer triggered interrupts assert(irqHandlerTask != NULL); // has interrupt handler task started?
// start timer triggered interrupts
ESP_LOGI(TAG, "Starting Interrupts..."); ESP_LOGI(TAG, "Starting Interrupts...");
#ifdef HAS_DISPLAY #ifdef HAS_DISPLAY
timerAlarmEnable(displaytimer); timerAlarmEnable(displaytimer);
@ -414,8 +414,9 @@ void setup() {
// start RTC interrupt // start RTC interrupt
#if defined HAS_IF482 && defined HAS_RTC #if defined HAS_IF482 && defined HAS_RTC
// setup external interupt for active low RTC INT pin // setup external interupt for active low RTC INT pin
if (IF482IRQ != NULL) // has if482loop task started? assert(IF482Task != NULL); // has if482loop task started?
attachInterrupt(digitalPinToInterrupt(RTC_INT), IF482IRQ, FALLING); ESP_LOGI(TAG, "Starting IF482 output...");
attachInterrupt(digitalPinToInterrupt(RTC_INT), IF482IRQ, FALLING);
#endif #endif
} // setup() } // setup()

View File

@ -82,9 +82,12 @@
#define RESPONSE_TIMEOUT_MS 60000 // firmware binary server connection timeout [milliseconds] #define RESPONSE_TIMEOUT_MS 60000 // firmware binary server connection timeout [milliseconds]
// settings for syncing time of node and external time sources // 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 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 #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 // LMIC settings
// moved to src/lmic_config.h // moved to src/lmic_config.h

View File

@ -5,7 +5,12 @@
// Local logging tag // Local logging tag
static const char TAG[] = "main"; static const char TAG[] = "main";
RtcDS3231<TwoWire> Rtc(Wire); RtcDS3231<TwoWire> 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 // initialize RTC
int rtc_init(void) { int rtc_init(void) {
@ -34,7 +39,7 @@ int rtc_init(void) {
RtcDateTime now = Rtc.GetDateTime(); RtcDateTime now = Rtc.GetDateTime();
if (now < compiled) { 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); Rtc.SetDateTime(compiled);
} }
@ -80,12 +85,12 @@ int set_rtctime(RtcDateTime t) {
} // set_rtctime() } // set_rtctime()
time_t get_rtctime(void) { 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; time_t tt = 0;
// block i2c bus access // block i2c bus access
if (I2C_MUTEX_LOCK()) { if (I2C_MUTEX_LOCK()) {
if (!Rtc.IsDateTimeValid()) { if (!Rtc.IsDateTimeValid()) {
ESP_LOGW(TAG, "RTC lost confidence in the DateTime"); ESP_LOGW(TAG, "RTC has no confident time");
} else { } else {
RtcDateTime t = Rtc.GetDateTime(); RtcDateTime t = Rtc.GetDateTime();
tt = t.Epoch32Time(); tt = t.Epoch32Time();
@ -99,16 +104,21 @@ time_t get_rtctime(void) {
void sync_rtctime(void) { void sync_rtctime(void) {
if (timeStatus() != timeSet) { // do we need time sync? if (timeStatus() != timeSet) { // do we need time sync?
time_t t = get_rtctime(); 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); setTime(t);
time_t tt = myTZ.toLocal(t);
ESP_LOGI(TAG, "RTC has set system time to %02d/%02d/%d %02d:%02d:%02d", 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 } else
ESP_LOGE(TAG, "RTC has no confident time, not synced"); ESP_LOGW(TAG, "System time was not synced");
} }
#ifdef TIME_SYNC_INTERVAL_RTC #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); setSyncInterval(TIME_SYNC_INTERVAL_RTC);
#endif #endif