From 85905a7045fad094fe8e3414da33e2dc69f5bb3e Mon Sep 17 00:00:00 2001 From: Slider0007 <115730895+Slider0007@users.noreply.github.com> Date: Sat, 3 Dec 2022 19:10:44 +0100 Subject: [PATCH 1/5] Improve MQTT connection handling (#1462) * modify mqtt init at startup + after disconnection * mqtt_init only when not initialized * Minor udapte * Apply suggestions from code review Co-authored-by: CaCO3 * Correct typo Co-authored-by: CaCO3 --- .../jomjol_flowcontroll/ClassFlowControll.cpp | 19 +++++--- .../jomjol_flowcontroll/ClassFlowControll.h | 1 + .../jomjol_flowcontroll/ClassFlowMQTT.cpp | 5 +- .../components/jomjol_mqtt/interface_mqtt.cpp | 48 +++++++++++-------- .../jomjol_tfliteclass/server_tflite.cpp | 2 + 5 files changed, 45 insertions(+), 30 deletions(-) diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp index 7af4c119..b078cada 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp @@ -140,6 +140,15 @@ string ClassFlowControll::GetMQTTMainTopic() return ""; } +bool ClassFlowControll::StartMQTTService() { + /* Start the MQTT service */ + for (int i = 0; i < FlowControll.size(); ++i) { + if (FlowControll[i]->name().compare("ClassFlowMQTT") == 0) { + return ((ClassFlowMQTT*) (FlowControll[i]))->Start(AutoIntervall); + } + } + return false; +} void ClassFlowControll::SetInitialParameter(void) @@ -311,7 +320,9 @@ bool ClassFlowControll::doFlow(string time) MQTTPublish(mqttServer_getMainTopic() + "/" + "status", flowStatus, false); string zw = "FlowControll.doFlow - " + FlowControll[i]->name(); - LogFile.WriteHeapInfo(zw); + #ifdef DEBUG_DETAIL_ON + LogFile.WriteHeapInfo(zw); + #endif if (!FlowControll[i]->doFlow(time)){ repeat++; @@ -551,12 +562,6 @@ bool ClassFlowControll::ReadParameter(FILE* pfile, string& aktparamgraph) } } } - - /* Start the MQTT service */ - for (int i = 0; i < FlowControll.size(); ++i) - if (FlowControll[i]->name().compare("ClassFlowMQTT") == 0) - return ((ClassFlowMQTT*) (FlowControll[i]))->Start(AutoIntervall); - return true; } diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.h b/code/components/jomjol_flowcontroll/ClassFlowControll.h index 5fd3b08a..026e30b1 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.h +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.h @@ -71,6 +71,7 @@ public: t_CNNType GetTypeDigital(); t_CNNType GetTypeAnalog(); + bool StartMQTTService(); int CleanTempFolder(); diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp index 39470c65..d350b18e 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp @@ -203,9 +203,8 @@ bool ClassFlowMQTT::Start(float AutoIntervall) { keepAlive, SetRetainFlag, (void *)&GotConnected); if (!MQTT_Init()) { - if (!MQTT_Init()) { // Retry - return false; - } + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Init at startup failed! Retry with next publish call"); + return false; } return true; diff --git a/code/components/jomjol_mqtt/interface_mqtt.cpp b/code/components/jomjol_mqtt/interface_mqtt.cpp index 8b411f74..d742b1d3 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.cpp +++ b/code/components/jomjol_mqtt/interface_mqtt.cpp @@ -17,10 +17,11 @@ std::map>* subscribeFu int failedOnRound = -1; - + esp_mqtt_event_id_t esp_mmqtt_ID = MQTT_EVENT_ANY; // ESP_EVENT_ANY_ID +bool mqtt_initialized = false; bool mqtt_connected = false; esp_mqtt_client_handle_t client = NULL; std::string uri, client_id, lwt_topic, lwt_connected, lwt_disconnected, user, password, maintopic; @@ -36,29 +37,27 @@ bool MQTTPublish(std::string _key, std::string _content, int retained_flag) { return true; // Fail quietly } + #ifdef DEBUG_DETAIL_ON LogFile.WriteHeapInfo("MQTT Publish"); #endif - if (!mqtt_connected) { - LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Not connected, trying to re-connect..."); + if (!mqtt_initialized) { if (!MQTT_Init()) { - if (!MQTT_Init()) { // Retry - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to init, skipping all MQTT publishings in this round!"); - failedOnRound = getCountFlowRounds(); - return false; - } + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Init failed, skipping all MQTT publishings in this round!"); + failedOnRound = getCountFlowRounds(); + return false; } - } + } msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag); if (msg_id < 0) { LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Failed to publish topic '" + _key + "', re-trying..."); - + esp_mqtt_client_reconnect(client); + msg_id = esp_mqtt_client_publish(client, _key.c_str(), _content.c_str(), 0, 1, retained_flag); if (msg_id < 0) { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to publish topic '" + _key + "', skipping all MQTT publishings in this round!"); - mqtt_connected = false; // Force re-init on next call failedOnRound = getCountFlowRounds(); return false; } @@ -91,9 +90,7 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) break; case MQTT_EVENT_DISCONNECTED: ESP_LOGD(TAG, "MQTT_EVENT_DISCONNECTED"); - LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Disconnected! Going to re-connect..."); - mqtt_connected = false; // Force re-init on next call - esp_mqtt_client_reconnect(client); + mqtt_connected = false; break; case MQTT_EVENT_SUBSCRIBED: ESP_LOGD(TAG, "MQTT_EVENT_SUBSCRIBED, msg_id=%d", event->msg_id); @@ -122,7 +119,8 @@ static esp_err_t mqtt_event_handler_cb(esp_mqtt_event_handle_t event) break; case MQTT_EVENT_ERROR: ESP_LOGD(TAG, "MQTT_EVENT_ERROR"); - mqtt_connected = false; // Force re-init on next call + mqtt_initialized = false; // Force re-init on next publish call + mqtt_connected = false; break; default: ESP_LOGD(TAG, "Other event id:%d", event->event_id); @@ -179,7 +177,9 @@ bool MQTT_Init() { .lwt_msg = lw.c_str(), .lwt_retain = 1, .lwt_msg_len = (int)(lw.length()), - .keepalive = keepalive + .keepalive = keepalive, + .disable_auto_reconnect = false, // Reconnection routine active + .reconnect_timeout_ms = 10000 // Try to reconnect to broker every 10s }; if (user.length() && password.length()){ @@ -190,6 +190,7 @@ bool MQTT_Init() { #ifdef DEBUG_DETAIL_ON LogFile.WriteHeapInfo("MQTT Client Init"); #endif + client = esp_mqtt_client_init(&mqtt_cfg); if (client) { @@ -197,6 +198,7 @@ bool MQTT_Init() { if (ret != ESP_OK) { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Could not register event (ret=" + std::to_string(ret) + ")!"); + mqtt_initialized = false; return false; } @@ -211,25 +213,31 @@ bool MQTT_Init() { if (ret != ESP_OK) { LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Could not start client (ret=" + std::to_string(ret) + ")!"); + mqtt_initialized = false; return false; } } } else { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Could not init client!"); + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Init failed, no handle created!"); + mqtt_initialized = false; return false; } - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Init successful"); + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Client started, waiting for established connection..."); + mqtt_initialized = true; return true; } void MQTTdestroy_client() { - if (client != NULL) { + if (client) { esp_mqtt_client_stop(client); esp_mqtt_client_destroy(client); + client = NULL; + mqtt_initialized = false; + mqtt_connected = false; } } @@ -283,7 +291,7 @@ void MQTTregisterSubscribeFunction(std::string topic, std::function Date: Sat, 3 Dec 2022 22:28:22 +0100 Subject: [PATCH 2/5] compare only the first 7 characters of the hashes (#1472) Co-authored-by: CaCO3 --- code/main/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/main/main.cpp b/code/main/main.cpp index 852429f9..8c8a650e 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -223,7 +223,7 @@ extern "C" void app_main(void) LogFile.WriteToFile(ESP_LOG_INFO, TAG, "================== Main Started ================="); LogFile.WriteToFile(ESP_LOG_INFO, TAG, "================================================="); - if (getHTMLcommit() != std::string(GIT_REV)) { + if (getHTMLcommit().substr(0, 7) != std::string(GIT_REV).substr(0, 7)) { // Compare the first 7 characters of both hashes LogFile.WriteToFile(ESP_LOG_WARN, TAG, std::string("Web UI version (") + getHTMLcommit() + ") does not match firmware version (" + std::string(GIT_REV) + ") !"); } From a122b37c812f7b2d27bd4ac31e1cee182b56bb0b Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Sun, 4 Dec 2022 15:12:20 +0100 Subject: [PATCH 3/5] Quick Fix for MQTT Init Problem --- .../jomjol_flowcontroll/ClassFlowControll.cpp | 2 +- .../jomjol_flowcontroll/ClassFlowMQTT.cpp | 9 +++++++++ code/components/jomjol_mqtt/interface_mqtt.cpp | 17 +++++++++++++++++ code/components/jomjol_mqtt/interface_mqtt.h | 2 ++ code/dependencies.lock | 3 ++- 5 files changed, 31 insertions(+), 2 deletions(-) diff --git a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp index b078cada..4e963a09 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowControll.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowControll.cpp @@ -146,7 +146,7 @@ bool ClassFlowControll::StartMQTTService() { if (FlowControll[i]->name().compare("ClassFlowMQTT") == 0) { return ((ClassFlowMQTT*) (FlowControll[i]))->Start(AutoIntervall); } - } + } return false; } diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp index d350b18e..1c3c08b5 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp @@ -189,6 +189,15 @@ string ClassFlowMQTT::GetMQTTMainTopic() bool ClassFlowMQTT::Start(float AutoIntervall) { +// printf("URI: %s, MAINTOPIC: %s", uri.c_str(), maintopic.c_str()); + + if ((uri.length() == 0) || (maintopic.length() == 0)) + { + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "MQTT not started because URI or Maintopic is not set. MQTT will be disabled."); + MQTTdisable(); + return false; + } + roundInterval = AutoIntervall; // Minutes keepAlive = roundInterval * 60 * 2.5; // Seconds, make sure it is greater thatn 2 rounds! diff --git a/code/components/jomjol_mqtt/interface_mqtt.cpp b/code/components/jomjol_mqtt/interface_mqtt.cpp index d742b1d3..cfa99348 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.cpp +++ b/code/components/jomjol_mqtt/interface_mqtt.cpp @@ -17,6 +17,8 @@ std::map>* subscribeFu int failedOnRound = -1; + +bool MQTT_Enabled = true; esp_mqtt_event_id_t esp_mmqtt_ID = MQTT_EVENT_ANY; // ESP_EVENT_ANY_ID @@ -29,6 +31,11 @@ int keepalive, SetRetainFlag; void (*callbackOnConnected)(std::string, int) = NULL; +void MQTTdisable() +{ + MQTT_Enabled = false; +} + bool MQTTPublish(std::string _key, std::string _content, int retained_flag) { int msg_id; std::string zw; @@ -163,6 +170,16 @@ void MQTT_Configure(std::string _mqttURI, std::string _clientid, std::string _us } bool MQTT_Init() { + + if (MQTT_Enabled == false) + return false; + + if ((client_id.length() == 0) || (lwt_topic.length() == 0)) + { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, std::string("Init with no Client_ID or Topic. Abort Init!")); + return false; + } + esp_err_t ret; LogFile.WriteToFile(ESP_LOG_INFO, TAG, std::string("Init")); diff --git a/code/components/jomjol_mqtt/interface_mqtt.h b/code/components/jomjol_mqtt/interface_mqtt.h index 63d513a8..514a93e2 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.h +++ b/code/components/jomjol_mqtt/interface_mqtt.h @@ -21,4 +21,6 @@ void MQTTregisterSubscribeFunction(std::string topic, std::function Date: Sun, 4 Dec 2022 15:43:44 +0100 Subject: [PATCH 4/5] remove redundant log text ("5 minutes delay" gets loged further down already. (#1480) Co-authored-by: CaCO3 --- code/components/jomjol_mqtt/interface_mqtt.cpp | 2 +- code/main/main.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/components/jomjol_mqtt/interface_mqtt.cpp b/code/components/jomjol_mqtt/interface_mqtt.cpp index cfa99348..0c4b0ab2 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.cpp +++ b/code/components/jomjol_mqtt/interface_mqtt.cpp @@ -10,7 +10,7 @@ //#define DEBUG_DETAIL_ON -static const char *TAG = "MQTT INTERFACE"; +static const char *TAG = "MQTT IF"; std::map>* connectFunktionMap = NULL; std::map>* subscribeFunktionMap = NULL; diff --git a/code/main/main.cpp b/code/main/main.cpp index 8c8a650e..e97236e9 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -213,7 +213,7 @@ extern "C" void app_main(void) vTaskDelay( xDelay ); if (!setup_time()) { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "NTP Initialization failed. Will restart in 5 minutes!"); + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "NTP Initialization failed!"); initSucessful = false; } @@ -248,14 +248,14 @@ extern "C" void app_main(void) vTaskDelay( xDelay ); if (camStatus != ESP_OK) { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to initialize camera module. Will restart in 5 minutes!"); + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Failed to initialize camera module!"); LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Check that your camera module is working and connected properly!"); initSucessful = false; } } else { // Test Camera camera_fb_t * fb = esp_camera_fb_get(); if (!fb) { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Camera Framebuffer cannot be initialzed. Will restart in 5 minutes!"); + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Camera Framebuffer cannot be initialized!"); initSucessful = false; } else { From 735086415068f7569f8ddca043ee840462d94f09 Mon Sep 17 00:00:00 2001 From: jomjol <30766535+jomjol@users.noreply.github.com> Date: Sun, 4 Dec 2022 15:47:38 +0100 Subject: [PATCH 5/5] QuickFix MQTT Reboot --- Changelog.md | 49 ++++++------------------------------------------- 1 file changed, 6 insertions(+), 43 deletions(-) diff --git a/Changelog.md b/Changelog.md index 81056010..28b74c04 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,49 +2,6 @@ ## [Unreleased] -### Added - -- n.a. - -### Changed - -- n.a. - -### Fixed - -- Re-updated build environment to v5.2.0 (from accidental downgrad to v4.4.0) - -### Removed - -- n.a. - - - -## [13.0.2] - 2022-12-02 - -### Added - -- n.a. - -### Changed - -- Update Tool "Logfile downloader and combiner" to handle the new csv file format. -- Added MQTT topic `status` containing Digitalization Status. -- Added timezone to MQTT topic `timestamp`. -- Disable heap logs by default -- Cleanup loglevel info (moved some entries to debug level) -- Updated logging informations - -### Fixed - -- Corrected Version comparison between firmware and Web UI. - -### Removed - -- n.a. - -## [13.0.1] - 2022-11-28 - **Home Assistant MQTT Discovery Support** ### Update Procedure @@ -103,6 +60,9 @@ If anything breaks you can try to enforce manual update as following: - [#1176](https://github.com/jomjol/AI-on-the-edge-device/discussions/1176) accept minor negative values (-0.2) if extended resolution is enabled - [#1143](https://github.com/jomjol/AI-on-the-edge-device/issues/1143) added config parameter `AnalogDigitalTransitionStart`. It can setup very early and very late digit transition starts. - New version of `dig-class100` (v1.4.0): added images of heliowatt powermeter +- NEW v13.0.2: Update Tool "Logfile downloader and combiner" to handle the new csv file format. +- NEW v13.0.2: MQTT: Added MQTT topic `status` (Digitalization Status), Timezone to MQTT topic `timestamp`.# +- NEW v13.0.2: Logging: Disable heap logs by default, cleanup ### Fixed @@ -114,6 +74,9 @@ If anything breaks you can try to enforce manual update as following: - Failed NTP time sync during startup gets now retried every round if needed - Whitespaces and `=` in MQTT and InfluxDB passwords - Various minor fixes and improvements +- NEW v13.0.2: Corrected Version comparison between firmware and Web UI. +- NEW v13.0.3: Re-updated build environment to v5.2.0 (from accidental downgrad to v4.4.0) +- **NEW v13.0.4**: Fix for reboot in case of MQTT not used ### Removed