From 956de5a52bbb92a6e3d6b34e6cbd72b4ad28b571 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 11:20:07 +0200 Subject: [PATCH 01/20] TimeService: Add connected() method to check connection status --- src/utility/time/TimeService.cpp | 9 +++++++++ src/utility/time/TimeService.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 112745d06..a229de29b 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -192,6 +192,15 @@ unsigned long TimeService::getTimeFromString(const String& input) * PRIVATE MEMBER FUNCTIONS **************************************************************************************/ +bool TimeService::connected() +{ + if(_con_hdl == nullptr) { + return false; + } else { + return _con_hdl->getStatus() == NetworkConnectionState::CONNECTED; + } +} + unsigned long TimeService::getRemoteTime() { #include "../../AIoTC_Config.h" diff --git a/src/utility/time/TimeService.h b/src/utility/time/TimeService.h index fbe81986d..8d8862287 100644 --- a/src/utility/time/TimeService.h +++ b/src/utility/time/TimeService.h @@ -64,6 +64,7 @@ class TimeService unsigned long _timezone_dst_until; unsigned long getRemoteTime(); + bool connected(); static bool isTimeValid(unsigned long const time); }; From 398bef817d477e79cea3eb207bbe1eb3df9c60b4 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 11:23:21 +0200 Subject: [PATCH 02/20] Check if board is connected before trying to get time from network/NTP --- src/utility/time/TimeService.cpp | 35 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index a229de29b..88c60a1a2 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -206,27 +206,26 @@ unsigned long TimeService::getRemoteTime() #include "../../AIoTC_Config.h" #ifndef HAS_LORA - if(_con_hdl == nullptr) - return EPOCH_AT_COMPILE_TIME; - - /* At first try to see if a valid time can be obtained - * using the network time available via the connection - * handler. - */ - unsigned long const connection_time = _con_hdl->getTime(); - if(isTimeValid(connection_time)) { - return connection_time; - } + if(connected()) { + /* At first try to see if a valid time can be obtained + * using the network time available via the connection + * handler. + */ + unsigned long const connection_time = _con_hdl->getTime(); + if(isTimeValid(connection_time)) { + return connection_time; + } #ifndef __AVR__ - /* If no valid network time is available try to obtain the - * time via NTP next. - */ - unsigned long const ntp_time = NTPUtils::getTime(_con_hdl->getUDP()); - if(isTimeValid(ntp_time)) { - return ntp_time; - } + /* If no valid network time is available try to obtain the + * time via NTP next. + */ + unsigned long const ntp_time = NTPUtils::getTime(_con_hdl->getUDP()); + if(isTimeValid(ntp_time)) { + return ntp_time; + } #endif + } #endif /* ifndef HAS_LORA */ From 4f798840d9fb196c0a8511a48096b2a14860b1ca Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 11:43:42 +0200 Subject: [PATCH 03/20] Add HAS_RTC define in config file for boards with RTC support --- src/AIoTC_Config.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/AIoTC_Config.h b/src/AIoTC_Config.h index af76df907..a0637a90e 100644 --- a/src/AIoTC_Config.h +++ b/src/AIoTC_Config.h @@ -119,21 +119,25 @@ defined (ARDUINO_NANO_RP2040_CONNECT) #define BOARD_HAS_ECCX08 #define HAS_TCP + #define HAS_RTC #endif #if defined(ARDUINO_NICLA_VISION) #define BOARD_HAS_SE050 #define HAS_TCP + #define HAS_RTC #endif #if defined(ARDUINO_AVR_UNO_WIFI_REV2) || \ defined(ARDUINO_SAMD_MKRWIFI1010) || defined(ARDUINO_SAMD_NANO_33_IOT) #define BOARD_HAS_OFFLOADED_ECCX08 #define HAS_TCP + #define HAS_RTC #endif #if defined(ARDUINO_SAMD_MKRWAN1300) || defined(ARDUINO_SAMD_MKRWAN1310) #define HAS_LORA + #define HAS_RTC #endif #if defined(ARDUINO_ESP8266_ESP12) || defined(ARDUINO_ARCH_ESP32) || defined(ESP8266) || defined(ESP32) From bd8ec23e568c76a1afeb486c1be511b14cfd11df Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 12:07:04 +0200 Subject: [PATCH 04/20] Fix includes to make HAS_RTC macro available in TimeService code --- src/utility/time/TimeService.cpp | 1 - src/utility/time/TimeService.h | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 88c60a1a2..3d56d7fac 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -203,7 +203,6 @@ bool TimeService::connected() unsigned long TimeService::getRemoteTime() { -#include "../../AIoTC_Config.h" #ifndef HAS_LORA if(connected()) { diff --git a/src/utility/time/TimeService.h b/src/utility/time/TimeService.h index 8d8862287..6a714a9b1 100644 --- a/src/utility/time/TimeService.h +++ b/src/utility/time/TimeService.h @@ -24,6 +24,9 @@ #include +#include "../../AIoTC_Config.h" + +#ifdef HAS_RTC #ifdef ARDUINO_ARCH_SAMD #include #endif @@ -31,6 +34,7 @@ #ifdef ARDUINO_ARCH_MBED #include #endif +#endif /* HAS_RTC */ /************************************************************************************** * CLASS DECLARATION From 947c9c6a0d9258f04c6a31754f05d29124c061f1 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 12:10:10 +0200 Subject: [PATCH 05/20] Add internal interface functions to RTC --- src/utility/time/TimeService.cpp | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 3d56d7fac..638ced93c 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -38,6 +38,11 @@ RTCZero rtc; **************************************************************************************/ time_t cvt_time(char const * time); +#ifdef HAS_RTC +void rtc_begin(); +void rtc_set(unsigned long time); +unsigned long rtc_get(); +#endif /************************************************************************************** * CONSTANTS @@ -275,6 +280,38 @@ time_t cvt_time(char const * time) return mktime(&t); } +#ifdef HAS_RTC +void rtc_begin() { +#ifdef ARDUINO_ARCH_SAMD + rtc.begin(); +#elif ARDUINO_ARCH_MBED + +#else + +#endif +} + +void rtc_set(unsigned long time) { +#ifdef ARDUINO_ARCH_SAMD + rtc.setEpoch(time); +#elif ARDUINO_ARCH_MBED + set_time(time); +#else + +#endif +} + +unsigned long rtc_get() { +#ifdef ARDUINO_ARCH_SAMD + return rtc.getEpoch(); +#elif ARDUINO_ARCH_MBED + return time(NULL); +#else + return EPOCH; +#endif +} +#endif /* HAS_RTC */ + TimeService & ArduinoIoTCloudTimeService() { static TimeService _timeService_instance; return _timeService_instance; From e837afbd806694df75febc4e7ca25d77c018afaf Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 12:11:37 +0200 Subject: [PATCH 06/20] Add getRTC() and configureRTC private methods --- src/utility/time/TimeService.cpp | 22 ++++++++++++++++++++++ src/utility/time/TimeService.h | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 638ced93c..caad702a0 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -241,6 +241,28 @@ unsigned long TimeService::getRemoteTime() return EPOCH_AT_COMPILE_TIME; } +#ifdef HAS_RTC +unsigned long TimeService::getRTC() { + if(!_is_rtc_configured) { + configureRTC(); + } + return rtc_get(); +} + +void TimeService::configureRTC() { +#ifdef HAS_LORA + rtc_set(EPOCH_AT_COMPILE_TIME); + _is_rtc_configured = true; +#else + unsigned long remote_time = getRemoteTime(); + if(isTimeValid(remote_time)) { + rtc_set(remote_time); + _is_rtc_configured = true; + } +#endif +} +#endif /* HAS_RTC */ + bool TimeService::isTimeValid(unsigned long const time) { return (time >= EPOCH_AT_COMPILE_TIME); diff --git a/src/utility/time/TimeService.h b/src/utility/time/TimeService.h index 6a714a9b1..1f349ce37 100644 --- a/src/utility/time/TimeService.h +++ b/src/utility/time/TimeService.h @@ -69,6 +69,10 @@ class TimeService unsigned long getRemoteTime(); bool connected(); +#ifdef HAS_RTC + void configureRTC(); + unsigned long getRTC(); +#endif static bool isTimeValid(unsigned long const time); }; From ccc88def2e79670e59eaa6c8dca7851de829197d Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 12:13:48 +0200 Subject: [PATCH 07/20] Use internal RTC interface function to initialize RTC hardware --- src/utility/time/TimeService.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index caad702a0..727ccb19b 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -74,8 +74,8 @@ TimeService::TimeService() void TimeService::begin(ConnectionHandler * con_hdl) { _con_hdl = con_hdl; -#ifdef ARDUINO_ARCH_SAMD - rtc.begin(); +#ifdef HAS_RTC + rtc_begin(); #endif } From c1d5a85b4854998843a1ec5be597add814f6520d Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 12:15:15 +0200 Subject: [PATCH 08/20] TimeService::getTime rework to simplify logic If board has RTC use getRTC() to retrive time, otherwise always use getRemoteTime() Check for valid time before return, if not valid return EPOCH_AT_COMPILE_TIME --- src/utility/time/TimeService.cpp | 34 ++++++++++---------------------- 1 file changed, 10 insertions(+), 24 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 727ccb19b..0febd4a39 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -81,33 +81,19 @@ void TimeService::begin(ConnectionHandler * con_hdl) unsigned long TimeService::getTime() { -#ifdef ARDUINO_ARCH_SAMD - if(!_is_rtc_configured) - { - unsigned long utc = getRemoteTime(); - if(EPOCH_AT_COMPILE_TIME != utc) - { - rtc.setEpoch(utc); - _is_rtc_configured = true; - } - return utc; - } - return rtc.getEpoch(); -#elif ARDUINO_ARCH_MBED - if(!_is_rtc_configured) - { - unsigned long utc = getRemoteTime(); - if(EPOCH_AT_COMPILE_TIME != utc) - { - set_time(utc); - _is_rtc_configured = true; - } - return utc; +#ifdef HAS_RTC + unsigned long rtc_time = getRTC(); + if(isTimeValid(rtc_time)) { + return rtc_time; } - return time(NULL); #else - return getRemoteTime(); + unsigned long remote_time = getRemoteTime(); + if(isTimeValid(remote_time)) { + return remote_time; + } #endif + + return EPOCH_AT_COMPILE_TIME; } void TimeService::setTimeZoneData(long offset, unsigned long dst_until) From 1f5722dea0ce839040cf5de774b52a489312eeee Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 12:20:32 +0200 Subject: [PATCH 09/20] Fix isTimeValid() > EPOCH_AT_COMPILE_TIME TCP BOARDS: During RTC configuration we don't want to store EPOCH_AT_COMPILE_TIME into RTC register otherwise internal time will be wrong and scheduler wont work. LORA BOARDS: This check is not performed for LORA BOARDS since we don't have a valid timesource --- src/utility/time/TimeService.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 0febd4a39..3f1989296 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -251,7 +251,7 @@ void TimeService::configureRTC() { bool TimeService::isTimeValid(unsigned long const time) { - return (time >= EPOCH_AT_COMPILE_TIME); + return (time > EPOCH_AT_COMPILE_TIME); } /************************************************************************************** From 4b7e17a3cd6ddbece3c6a8115ba0412b906ae3be Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 12:38:29 +0200 Subject: [PATCH 10/20] Substitute missing build options with HAS_RTC define --- src/utility/time/TimeService.cpp | 2 +- src/utility/time/TimeService.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 3f1989296..0e4bb6afb 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -57,7 +57,7 @@ static time_t const EPOCH = 0; TimeService::TimeService() : _con_hdl(nullptr) -#if defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_MBED) +#ifdef HAS_RTC , _is_rtc_configured(false) #endif , _is_tz_configured(false) diff --git a/src/utility/time/TimeService.h b/src/utility/time/TimeService.h index 1f349ce37..5b240f13c 100644 --- a/src/utility/time/TimeService.h +++ b/src/utility/time/TimeService.h @@ -60,7 +60,7 @@ class TimeService private: ConnectionHandler * _con_hdl; -#if defined (ARDUINO_ARCH_SAMD) || defined (ARDUINO_ARCH_MBED) +#ifdef HAS_RTC bool _is_rtc_configured; #endif bool _is_tz_configured; From 8afe84346a031a9526ef932ce376728be476ae41 Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 12:39:30 +0200 Subject: [PATCH 11/20] getRemoteTime() and connected() methods are meaningful only if TCP is available --- src/utility/time/TimeService.cpp | 6 ++---- src/utility/time/TimeService.h | 4 ++++ 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 0e4bb6afb..0d57fbece 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -183,6 +183,7 @@ unsigned long TimeService::getTimeFromString(const String& input) * PRIVATE MEMBER FUNCTIONS **************************************************************************************/ +#ifdef HAS_TCP bool TimeService::connected() { if(_con_hdl == nullptr) { @@ -194,8 +195,6 @@ bool TimeService::connected() unsigned long TimeService::getRemoteTime() { -#ifndef HAS_LORA - if(connected()) { /* At first try to see if a valid time can be obtained * using the network time available via the connection @@ -217,8 +216,6 @@ unsigned long TimeService::getRemoteTime() #endif } -#endif /* ifndef HAS_LORA */ - /* Return the epoch timestamp at compile time as a last * line of defense. Otherwise the certificate expiration * date is wrong and we'll be unable to establish a connection @@ -226,6 +223,7 @@ unsigned long TimeService::getRemoteTime() */ return EPOCH_AT_COMPILE_TIME; } +#endif /* HAS_TCP */ #ifdef HAS_RTC unsigned long TimeService::getRTC() { diff --git a/src/utility/time/TimeService.h b/src/utility/time/TimeService.h index 5b240f13c..b53d295e8 100644 --- a/src/utility/time/TimeService.h +++ b/src/utility/time/TimeService.h @@ -67,12 +67,16 @@ class TimeService long _timezone_offset; unsigned long _timezone_dst_until; +#ifdef HAS_TCP unsigned long getRemoteTime(); bool connected(); +#endif + #ifdef HAS_RTC void configureRTC(); unsigned long getRTC(); #endif + static bool isTimeValid(unsigned long const time); }; From 52f19f66026d633382cb62f96faab73b40c02afc Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 3 Feb 2022 15:49:43 +0100 Subject: [PATCH 12/20] TimeService::setTimeZoneData: change timezone prints from DEBUG_DEBUG to DEBUG_VERBOSE --- src/utility/time/TimeService.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 0d57fbece..9f2935119 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -99,11 +99,11 @@ unsigned long TimeService::getTime() void TimeService::setTimeZoneData(long offset, unsigned long dst_until) { if(_timezone_offset != offset) - DEBUG_DEBUG("ArduinoIoTCloudTCP::%s tz_offset: [%d]", __FUNCTION__, offset); + DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s tz_offset: [%d]", __FUNCTION__, offset); _timezone_offset = offset; if(_timezone_dst_until != dst_until) - DEBUG_DEBUG("ArduinoIoTCloudTCP::%s tz_dst_unitl: [%ul]", __FUNCTION__, dst_until); + DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s tz_dst_unitl: [%ul]", __FUNCTION__, dst_until); _timezone_dst_until = dst_until; _is_tz_configured = true; From 0f3511ad687043537e8ccb88a123cd271d3f0442 Mon Sep 17 00:00:00 2001 From: pennam Date: Thu, 3 Feb 2022 16:02:29 +0100 Subject: [PATCH 13/20] TimeService::setTimeZoneData: add braces around single statement if --- src/utility/time/TimeService.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 9f2935119..5860b55dd 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -98,12 +98,14 @@ unsigned long TimeService::getTime() void TimeService::setTimeZoneData(long offset, unsigned long dst_until) { - if(_timezone_offset != offset) + if(_timezone_offset != offset) { DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s tz_offset: [%d]", __FUNCTION__, offset); + } _timezone_offset = offset; - if(_timezone_dst_until != dst_until) + if(_timezone_dst_until != dst_until) { DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s tz_dst_unitl: [%ul]", __FUNCTION__, dst_until); + } _timezone_dst_until = dst_until; _is_tz_configured = true; From 2597a796eb705d18c3e61057ca3347f263c1761d Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 13:36:18 +0200 Subject: [PATCH 14/20] TimeService::setTimeZoneData print timezone updates in one row --- src/utility/time/TimeService.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 5860b55dd..4600a40e1 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -98,17 +98,12 @@ unsigned long TimeService::getTime() void TimeService::setTimeZoneData(long offset, unsigned long dst_until) { - if(_timezone_offset != offset) { - DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s tz_offset: [%d]", __FUNCTION__, offset); + if(_timezone_offset != offset || _timezone_dst_until != dst_until) { + DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s offset: %d dst_unitl %ul", __FUNCTION__, offset, dst_until); + _timezone_offset = offset; + _timezone_dst_until = dst_until; + _is_tz_configured = true; } - _timezone_offset = offset; - - if(_timezone_dst_until != dst_until) { - DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s tz_dst_unitl: [%ul]", __FUNCTION__, dst_until); - } - _timezone_dst_until = dst_until; - - _is_tz_configured = true; } unsigned long TimeService::getLocalTime() From 6c7b163cc0ead388bb44bcfdf156c03f3bb9b31e Mon Sep 17 00:00:00 2001 From: pennam Date: Tue, 24 May 2022 13:37:51 +0200 Subject: [PATCH 15/20] TimeService: other cosmetics changes --- src/utility/time/TimeService.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 4600a40e1..05d14b881 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -137,16 +137,14 @@ unsigned long TimeService::getTimeFromString(const String& input) static const int expected_length = 20; static const int expected_parameters = 6; - if(input == nullptr || input.length() != expected_length) - { + if(input == nullptr || input.length() != expected_length) { DEBUG_ERROR("ArduinoIoTCloudTCP::%s invalid input length", __FUNCTION__); return 0; } int scanned_parameters = sscanf(input.c_str(), "%d %s %d %d:%d:%d", &year, s_month, &day, &hour, &min, &sec); - if(scanned_parameters != expected_parameters) - { + if(scanned_parameters != expected_parameters) { DEBUG_ERROR("ArduinoIoTCloudTCP::%s invalid input parameters number", __FUNCTION__); return 0; } @@ -223,14 +221,16 @@ unsigned long TimeService::getRemoteTime() #endif /* HAS_TCP */ #ifdef HAS_RTC -unsigned long TimeService::getRTC() { +unsigned long TimeService::getRTC() +{ if(!_is_rtc_configured) { configureRTC(); } return rtc_get(); } -void TimeService::configureRTC() { +void TimeService::configureRTC() +{ #ifdef HAS_LORA rtc_set(EPOCH_AT_COMPILE_TIME); _is_rtc_configured = true; From 5bbec5857d0905715852c116ff1d7f0d223ea4b0 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 25 May 2022 08:55:08 +0200 Subject: [PATCH 16/20] Fix debug prints reporting the wrong class name --- src/utility/time/TimeService.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 05d14b881..01bccb874 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -99,7 +99,7 @@ unsigned long TimeService::getTime() void TimeService::setTimeZoneData(long offset, unsigned long dst_until) { if(_timezone_offset != offset || _timezone_dst_until != dst_until) { - DEBUG_VERBOSE("ArduinoIoTCloudTCP::%s offset: %d dst_unitl %ul", __FUNCTION__, offset, dst_until); + DEBUG_VERBOSE("TimeService::%s offset: %d dst_unitl %ul", __FUNCTION__, offset, dst_until); _timezone_offset = offset; _timezone_dst_until = dst_until; _is_tz_configured = true; @@ -138,21 +138,21 @@ unsigned long TimeService::getTimeFromString(const String& input) static const int expected_parameters = 6; if(input == nullptr || input.length() != expected_length) { - DEBUG_ERROR("ArduinoIoTCloudTCP::%s invalid input length", __FUNCTION__); + DEBUG_ERROR("TimeService::%s invalid input length", __FUNCTION__); return 0; } int scanned_parameters = sscanf(input.c_str(), "%d %s %d %d:%d:%d", &year, s_month, &day, &hour, &min, &sec); if(scanned_parameters != expected_parameters) { - DEBUG_ERROR("ArduinoIoTCloudTCP::%s invalid input parameters number", __FUNCTION__); + DEBUG_ERROR("TimeService::%s invalid input parameters number", __FUNCTION__); return 0; } char * s_month_position = strstr(month_names, s_month); if(s_month_position == nullptr || strlen(s_month) != 3) { - DEBUG_ERROR("ArduinoIoTCloudTCP::%s invalid month name, use %s", __FUNCTION__, month_names); + DEBUG_ERROR("TimeService::%s invalid month name, use %s", __FUNCTION__, month_names); return 0; } @@ -160,7 +160,7 @@ unsigned long TimeService::getTimeFromString(const String& input) if(month < 0 || month > 11 || day < 1 || day > 31 || year < 1900 || hour < 0 || hour > 24 || min < 0 || min > 60 || sec < 0 || sec > 60) { - DEBUG_ERROR("ArduinoIoTCloudTCP::%s invalid date values", __FUNCTION__); + DEBUG_ERROR("TimeService::%s invalid date values", __FUNCTION__); return 0; } From 4ea05aa9558fe282c0bd0ec970b94a3a91669da3 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 25 May 2022 09:13:45 +0200 Subject: [PATCH 17/20] Make explicit that timezone support is not available for devices without TCP connection --- src/utility/time/TimeService.cpp | 11 +++++++++++ src/utility/time/TimeService.h | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 01bccb874..c9d813045 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -60,9 +60,11 @@ TimeService::TimeService() #ifdef HAS_RTC , _is_rtc_configured(false) #endif +#ifdef HAS_TCP , _is_tz_configured(false) , _timezone_offset(0) , _timezone_dst_until(0) +#endif { } @@ -98,22 +100,31 @@ unsigned long TimeService::getTime() void TimeService::setTimeZoneData(long offset, unsigned long dst_until) { +#ifdef HAS_TCP if(_timezone_offset != offset || _timezone_dst_until != dst_until) { DEBUG_VERBOSE("TimeService::%s offset: %d dst_unitl %ul", __FUNCTION__, offset, dst_until); _timezone_offset = offset; _timezone_dst_until = dst_until; _is_tz_configured = true; } +#else + DEBUG_WARNING("TimeService::%s Timezone support not available without TCP connection"); +#endif } unsigned long TimeService::getLocalTime() { +#ifdef HAS_TCP unsigned long utc = getTime(); if(_is_tz_configured) { return utc + _timezone_offset; } else { return EPOCH; } +#else + DEBUG_WARNING("TimeService::%s Timezone support not available without TCP connection"); + return EPOCH; +#endif } unsigned long TimeService::getTimeFromString(const String& input) diff --git a/src/utility/time/TimeService.h b/src/utility/time/TimeService.h index b53d295e8..44ea0049f 100644 --- a/src/utility/time/TimeService.h +++ b/src/utility/time/TimeService.h @@ -63,11 +63,12 @@ class TimeService #ifdef HAS_RTC bool _is_rtc_configured; #endif + +#ifdef HAS_TCP bool _is_tz_configured; long _timezone_offset; unsigned long _timezone_dst_until; -#ifdef HAS_TCP unsigned long getRemoteTime(); bool connected(); #endif From 2d7c0cf262f9646017879418b0045b96ce1dd884 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 25 May 2022 09:43:14 +0200 Subject: [PATCH 18/20] Fix getTime() flow and add comments to describe it --- src/utility/time/TimeService.cpp | 33 +++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index c9d813045..4627012bd 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -83,18 +83,31 @@ void TimeService::begin(ConnectionHandler * con_hdl) unsigned long TimeService::getTime() { + /* If RTC is available try to get current time from + * there as first choice. RTC configuration is managed + * runtime by checking _is_rtc_configured flag. + */ #ifdef HAS_RTC unsigned long rtc_time = getRTC(); if(isTimeValid(rtc_time)) { return rtc_time; } -#else +#endif + + /* Without RTC support, but with TCP connection available + * try to get time from connection handler or NTP server. + */ +#ifdef HAS_TCP unsigned long remote_time = getRemoteTime(); if(isTimeValid(remote_time)) { return remote_time; } #endif + /* If none of the previous methods is supported or returns + * a valid time return the epoch at compile time as we do + * in TimeService::getRemoteTime(). + */ return EPOCH_AT_COMPILE_TIME; } @@ -235,6 +248,9 @@ unsigned long TimeService::getRemoteTime() unsigned long TimeService::getRTC() { if(!_is_rtc_configured) { + /* If RTC is not yet configured try to get a valid time value + * from the network. + */ configureRTC(); } return rtc_get(); @@ -242,15 +258,22 @@ unsigned long TimeService::getRTC() void TimeService::configureRTC() { -#ifdef HAS_LORA - rtc_set(EPOCH_AT_COMPILE_TIME); - _is_rtc_configured = true; -#else +#ifdef HAS_TCP + /* For devices with a TCP connection we can try to get a valid + * time value from connection handler or from NTP server. + */ unsigned long remote_time = getRemoteTime(); if(isTimeValid(remote_time)) { rtc_set(remote_time); _is_rtc_configured = true; } +#else + /* For devices without a TCP connection (LoRa) we cannot + * retrieve current time, so we store the epoch at compile time + * inside the RTC. + */ + rtc_set(EPOCH_AT_COMPILE_TIME); + _is_rtc_configured = true; #endif } #endif /* HAS_RTC */ From e9e0434742e4eae9345b064cd7ddbe7cf8241ac1 Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 25 May 2022 11:41:54 +0200 Subject: [PATCH 19/20] Rename TimeService into TimeServiceClass and use a more standard way to instantiate it --- extras/test/src/test_CloudSchedule.cpp | 12 ++++++--- extras/test/src/util/PropertyTestUtil.cpp | 5 ---- src/ArduinoIoTCloud.cpp | 2 +- src/ArduinoIoTCloud.h | 2 +- src/property/types/CloudSchedule.h | 3 +-- src/utility/time/TimeService.cpp | 31 ++++++++++++----------- src/utility/time/TimeService.h | 12 ++++++--- 7 files changed, 36 insertions(+), 31 deletions(-) diff --git a/extras/test/src/test_CloudSchedule.cpp b/extras/test/src/test_CloudSchedule.cpp index 53b582aef..04ecbad7a 100644 --- a/extras/test/src/test_CloudSchedule.cpp +++ b/extras/test/src/test_CloudSchedule.cpp @@ -13,16 +13,22 @@ unsigned long time_now = 1; /************************************************************************************** - * TimeService Fake CTOR/DTOR + * TimeService Fake CTOR **************************************************************************************/ -TimeService::TimeService() {} +TimeServiceClass::TimeServiceClass() {} /************************************************************************************** * TimeService Fake Methods **************************************************************************************/ -unsigned long TimeService::getLocalTime() {return time_now;} +unsigned long TimeServiceClass::getLocalTime() {return time_now;} + +/************************************************************************************** + * TimeService Fake local instance + **************************************************************************************/ + +TimeServiceClass TimeService; /************************************************************************************** TEST CODE diff --git a/extras/test/src/util/PropertyTestUtil.cpp b/extras/test/src/util/PropertyTestUtil.cpp index ca71cd765..1bf41c437 100644 --- a/extras/test/src/util/PropertyTestUtil.cpp +++ b/extras/test/src/util/PropertyTestUtil.cpp @@ -18,8 +18,3 @@ unsigned long getTime() { return 0; } - -TimeService & ArduinoIoTCloudTimeService() { - static TimeService _timeService_instance; - return _timeService_instance; -} diff --git a/src/ArduinoIoTCloud.cpp b/src/ArduinoIoTCloud.cpp index 0b2794ade..8ba86ff74 100644 --- a/src/ArduinoIoTCloud.cpp +++ b/src/ArduinoIoTCloud.cpp @@ -28,7 +28,7 @@ ArduinoIoTCloudClass::ArduinoIoTCloudClass() : _connection{nullptr} , _last_checked_property_index{0} -, _time_service(ArduinoIoTCloudTimeService()) +, _time_service{TimeService} , _tz_offset{0} , _tz_dst_until{0} , _thing_id{""} diff --git a/src/ArduinoIoTCloud.h b/src/ArduinoIoTCloud.h index 8be318b25..d09fca600 100644 --- a/src/ArduinoIoTCloud.h +++ b/src/ArduinoIoTCloud.h @@ -170,7 +170,7 @@ class ArduinoIoTCloudClass PropertyContainer _device_property_container; PropertyContainer _thing_property_container; unsigned int _last_checked_property_index; - TimeService & _time_service; + TimeServiceClass & _time_service; int _tz_offset; unsigned int _tz_dst_until; String _thing_id; diff --git a/src/property/types/CloudSchedule.h b/src/property/types/CloudSchedule.h index 47827c59c..3d2c598fd 100644 --- a/src/property/types/CloudSchedule.h +++ b/src/property/types/CloudSchedule.h @@ -115,7 +115,7 @@ class Schedule { bool isActive() { - ScheduleTimeType now = _schedule_time_service.getLocalTime(); + ScheduleTimeType now = TimeService.getLocalTime(); if(checkTimeValid(now)) { /* We have to wait RTC configuration and Timezone setting from the cloud */ @@ -201,7 +201,6 @@ class Schedule { return !(operator==(aSchedule)); } private: - TimeService & _schedule_time_service = ArduinoIoTCloudTimeService(); ScheduleUnit getScheduleUnit(ScheduleConfigurationType msk) { return static_cast((msk & SCHEDULE_UNIT_MASK) >> SCHEDULE_UNIT_SHIFT); diff --git a/src/utility/time/TimeService.cpp b/src/utility/time/TimeService.cpp index 4627012bd..a10556f7c 100644 --- a/src/utility/time/TimeService.cpp +++ b/src/utility/time/TimeService.cpp @@ -55,7 +55,7 @@ static time_t const EPOCH = 0; * CTOR/DTOR **************************************************************************************/ -TimeService::TimeService() +TimeServiceClass::TimeServiceClass() : _con_hdl(nullptr) #ifdef HAS_RTC , _is_rtc_configured(false) @@ -73,7 +73,7 @@ TimeService::TimeService() * PUBLIC MEMBER FUNCTIONS **************************************************************************************/ -void TimeService::begin(ConnectionHandler * con_hdl) +void TimeServiceClass::begin(ConnectionHandler * con_hdl) { _con_hdl = con_hdl; #ifdef HAS_RTC @@ -81,7 +81,7 @@ void TimeService::begin(ConnectionHandler * con_hdl) #endif } -unsigned long TimeService::getTime() +unsigned long TimeServiceClass::getTime() { /* If RTC is available try to get current time from * there as first choice. RTC configuration is managed @@ -111,7 +111,7 @@ unsigned long TimeService::getTime() return EPOCH_AT_COMPILE_TIME; } -void TimeService::setTimeZoneData(long offset, unsigned long dst_until) +void TimeServiceClass::setTimeZoneData(long offset, unsigned long dst_until) { #ifdef HAS_TCP if(_timezone_offset != offset || _timezone_dst_until != dst_until) { @@ -125,7 +125,7 @@ void TimeService::setTimeZoneData(long offset, unsigned long dst_until) #endif } -unsigned long TimeService::getLocalTime() +unsigned long TimeServiceClass::getLocalTime() { #ifdef HAS_TCP unsigned long utc = getTime(); @@ -140,7 +140,7 @@ unsigned long TimeService::getLocalTime() #endif } -unsigned long TimeService::getTimeFromString(const String& input) +unsigned long TimeServiceClass::getTimeFromString(const String& input) { struct tm t = { @@ -203,7 +203,7 @@ unsigned long TimeService::getTimeFromString(const String& input) **************************************************************************************/ #ifdef HAS_TCP -bool TimeService::connected() +bool TimeServiceClass::connected() { if(_con_hdl == nullptr) { return false; @@ -212,7 +212,7 @@ bool TimeService::connected() } } -unsigned long TimeService::getRemoteTime() +unsigned long TimeServiceClass::getRemoteTime() { if(connected()) { /* At first try to see if a valid time can be obtained @@ -245,7 +245,7 @@ unsigned long TimeService::getRemoteTime() #endif /* HAS_TCP */ #ifdef HAS_RTC -unsigned long TimeService::getRTC() +unsigned long TimeServiceClass::getRTC() { if(!_is_rtc_configured) { /* If RTC is not yet configured try to get a valid time value @@ -256,7 +256,7 @@ unsigned long TimeService::getRTC() return rtc_get(); } -void TimeService::configureRTC() +void TimeServiceClass::configureRTC() { #ifdef HAS_TCP /* For devices with a TCP connection we can try to get a valid @@ -278,7 +278,7 @@ void TimeService::configureRTC() } #endif /* HAS_RTC */ -bool TimeService::isTimeValid(unsigned long const time) +bool TimeServiceClass::isTimeValid(unsigned long const time) { return (time > EPOCH_AT_COMPILE_TIME); } @@ -349,7 +349,8 @@ unsigned long rtc_get() { } #endif /* HAS_RTC */ -TimeService & ArduinoIoTCloudTimeService() { - static TimeService _timeService_instance; - return _timeService_instance; -} +/****************************************************************************** + * EXTERN DEFINITION + ******************************************************************************/ + +TimeServiceClass TimeService; diff --git a/src/utility/time/TimeService.h b/src/utility/time/TimeService.h index 44ea0049f..7f3787739 100644 --- a/src/utility/time/TimeService.h +++ b/src/utility/time/TimeService.h @@ -40,13 +40,13 @@ * CLASS DECLARATION **************************************************************************************/ -class TimeService +class TimeServiceClass { public: - TimeService(); - + TimeServiceClass(); + virtual ~TimeServiceClass() { } void begin (ConnectionHandler * con_hdl); unsigned long getTime(); @@ -82,6 +82,10 @@ class TimeService }; -TimeService & ArduinoIoTCloudTimeService(); +/****************************************************************************** + * EXTERN DECLARATION + ******************************************************************************/ + +extern TimeServiceClass TimeService; #endif /* ARDUINO_IOT_CLOUD_TIME_SERVICE_H_ */ From 5132d2be035d100ab51a07eab1244227d359811a Mon Sep 17 00:00:00 2001 From: pennam Date: Wed, 25 May 2022 13:54:00 +0200 Subject: [PATCH 20/20] Fix build for esp8226 --- src/ArduinoIoTCloud.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ArduinoIoTCloud.cpp b/src/ArduinoIoTCloud.cpp index 8ba86ff74..2475b5621 100644 --- a/src/ArduinoIoTCloud.cpp +++ b/src/ArduinoIoTCloud.cpp @@ -28,7 +28,7 @@ ArduinoIoTCloudClass::ArduinoIoTCloudClass() : _connection{nullptr} , _last_checked_property_index{0} -, _time_service{TimeService} +, _time_service(TimeService) , _tz_offset{0} , _tz_dst_until{0} , _thing_id{""}