From 786a94b448c98d207d30354020a10f61bccecb0f Mon Sep 17 00:00:00 2001 From: MichaelDvP Date: Tue, 29 Mar 2022 15:30:39 +0200 Subject: [PATCH] try to fix #408 and #412 --- lib/framework/NTPSettingsService.cpp | 7 +++++++ lib/framework/NTPSettingsService.h | 2 ++ lib/framework/NTPStatus.cpp | 3 ++- src/devices/thermostat.cpp | 11 +++++++---- src/system.cpp | 1 + src/system.h | 14 ++++++++++++++ 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/lib/framework/NTPSettingsService.cpp b/lib/framework/NTPSettingsService.cpp index efd5132ee..672f0b496 100644 --- a/lib/framework/NTPSettingsService.cpp +++ b/lib/framework/NTPSettingsService.cpp @@ -46,8 +46,10 @@ void NTPSettingsService::WiFiEvent(WiFiEvent_t event) { // https://werner.rothschopf.net/microcontroller/202103_arduino_esp32_ntp_en.htm void NTPSettingsService::configureNTP() { + emsesp::EMSESP::system_.ntp_connected(false); if (connected_ && _state.enabled) { emsesp::EMSESP::logger().info(F("Starting NTP")); + sntp_set_time_sync_notification_cb(ntp_received); configTzTime(_state.tzFormat.c_str(), _state.server.c_str()); } else { setenv("TZ", _state.tzFormat.c_str(), 1); @@ -75,3 +77,8 @@ void NTPSettingsService::configureTime(AsyncWebServerRequest * request, JsonVari AsyncWebServerResponse * response = request->beginResponse(400); request->send(response); } + +void NTPSettingsService::ntp_received(struct timeval * tv) { + // emsesp::EMSESP::logger().info(F("NTP sync to %d sec"), tv->tv_sec); + emsesp::EMSESP::system_.ntp_connected(true); +} diff --git a/lib/framework/NTPSettingsService.h b/lib/framework/NTPSettingsService.h index e6af2831d..69125628a 100644 --- a/lib/framework/NTPSettingsService.h +++ b/lib/framework/NTPSettingsService.h @@ -57,6 +57,7 @@ class NTPSettingsService : public StatefulService { NTPSettingsService(AsyncWebServer * server, FS * fs, SecurityManager * securityManager); void begin(); + static void ntp_received(struct timeval * tv); private: HttpEndpoint _httpEndpoint; @@ -67,6 +68,7 @@ class NTPSettingsService : public StatefulService { void WiFiEvent(WiFiEvent_t event); void configureNTP(); void configureTime(AsyncWebServerRequest * request, JsonVariant & json); + }; #endif diff --git a/lib/framework/NTPStatus.cpp b/lib/framework/NTPStatus.cpp index 217345d44..4f026c77f 100644 --- a/lib/framework/NTPStatus.cpp +++ b/lib/framework/NTPStatus.cpp @@ -1,4 +1,5 @@ #include +#include "../../src/emsesp_stub.hpp" // proddy added using namespace std::placeholders; // for `_1` etc @@ -35,7 +36,7 @@ void NTPStatus::ntpStatus(AsyncWebServerRequest * request) { time_t now = time(nullptr); // only provide enabled/disabled status for now - root["status"] = sntp_enabled() ? 1 : 0; + root["status"] = sntp_enabled() && emsesp::EMSESP::system_.ntp_connected() ? 1 : 0; // the current time in UTC root["utc_time"] = toUTCTimeString(gmtime(&now)); diff --git a/src/devices/thermostat.cpp b/src/devices/thermostat.cpp index d4de33b66..432817d41 100644 --- a/src/devices/thermostat.cpp +++ b/src/devices/thermostat.cpp @@ -1235,7 +1235,7 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { // check clock time_t now = time(nullptr); tm * tm_ = localtime(&now); - bool ntp_ = tm_->tm_year > 110; // year 2010 and up, time is valid + bool tset_ = tm_->tm_year > 110; // year 2010 and up, time is valid tm_->tm_year = telegram->message_data[0] + 100; tm_->tm_mon = telegram->message_data[1] - 1; tm_->tm_mday = telegram->message_data[3]; @@ -1244,7 +1244,7 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { tm_->tm_sec = telegram->message_data[5]; tm_->tm_isdst = telegram->message_data[7] & 0x01; time_t ttime = mktime(tm_); // thermostat time - if (ntp_ && has_command(&dateTime_)) { // have NTP time and command + if (tset_ && EMSESP::system_.ntp_connected() && has_command(&dateTime_)) { // have NTP time and command double difference = difftime(now, ttime); if (difference > 15 || difference < -15) { set_datetime("ntp", -1); // set from NTP @@ -1252,7 +1252,7 @@ void Thermostat::process_RCTime(std::shared_ptr telegram) { } } #ifndef EMSESP_STANDALONE - if (!ntp_ && tm_->tm_year > 110) { // emsesp clock not set, but thermostat clock + if (!tset_ && tm_->tm_year > 110) { // emsesp clock not set, but thermostat clock struct timeval newnow = {.tv_sec = ttime}; settimeofday(&newnow, nullptr); LOG_INFO(F("ems-esp time set from thermostat")); @@ -1797,9 +1797,12 @@ bool Thermostat::set_datetime(const char * value, const int8_t id) { if (dt == "ntp") { time_t now = time(nullptr); tm * tm_ = localtime(&now); - if (tm_->tm_year < 110) { // no NTP time + if (tm_->tm_year < 110) { // no valid time return false; } + if (!EMSESP::system_.ntp_connected()) { + LOG_WARNING(F("Set date: no valid NTP data, setting from ESP Clock")); + } data[0] = tm_->tm_year - 100; // Bosch counts from 2000 data[1] = tm_->tm_mon + 1; diff --git a/src/system.cpp b/src/system.cpp index bf8f9ec26..630936548 100644 --- a/src/system.cpp +++ b/src/system.cpp @@ -1080,6 +1080,7 @@ bool System::command_info(const char * value, const int8_t id, JsonObject & outp node["version"] = EMSESP_APP_VERSION; node["uptime"] = uuid::log::format_timestamp_ms(uuid::get_uptime_ms(), 3); node["uptime (seconds)"] = uuid::get_uptime_sec(); + node["network time"] = EMSESP::system_.ntp_connected() ? "connected" : "disconnected"; #ifndef EMSESP_STANDALONE node["freemem"] = ESP.getFreeHeap() / 1000L; // kilobytes diff --git a/src/system.h b/src/system.h index 970b77731..83576b5a8 100644 --- a/src/system.h +++ b/src/system.h @@ -154,6 +154,17 @@ class System { ethernet_connected_ = b; } + void ntp_connected(bool b) { + ntp_connected_ = b; + ntp_last_check_ = b ? uuid::get_uptime_sec() : 0; + } + + bool ntp_connected() { + // timeout 2 hours, ntp sync is normally every hour. + ntp_connected_ = (uuid::get_uptime_sec() - ntp_last_check_ > 7201) ? false : ntp_connected_; + return ntp_connected_; + } + bool network_connected() { #ifndef EMSESP_STANDALONE return (ethernet_connected() || WiFi.isConnected()); @@ -218,6 +229,9 @@ class System { bool upload_status_ = false; // true if we're in the middle of a OTA firmware upload bool ethernet_connected_ = false; + bool ntp_connected_ = false; + uint32_t ntp_last_check_ = 0; + // EMS-ESP settings // copies from WebSettings class in WebSettingsService.h and loaded with reload_settings() std::string hostname_ = FACTORY_WIFI_HOSTNAME;