From a1a77ae5d9751119e1b1880468eaed99d60cfd22 Mon Sep 17 00:00:00 2001 From: CaCO3 Date: Mon, 27 Feb 2023 18:26:46 +0100 Subject: [PATCH] Improve MQTT (#2091) * moved functions * use hostname as default MQTT maintopic if parameter is not set * use hostname as default MQTT client ID * Only send Homassistant Discovery and Static Topics on the first connect. Retry in next round if any topic failed * . * add missing return code usage * send maintopic/connection on every round like the system topics --------- Co-authored-by: CaCO3 --- .../jomjol_flowcontroll/ClassFlowMQTT.cpp | 32 ++-- code/components/jomjol_helper/Helper.cpp | 31 ++++ code/components/jomjol_helper/Helper.h | 4 + .../components/jomjol_mqtt/interface_mqtt.cpp | 3 +- code/components/jomjol_mqtt/server_mqtt.cpp | 155 ++++++++++++------ code/components/jomjol_mqtt/server_mqtt.h | 2 +- code/main/main.cpp | 132 ++++++--------- 7 files changed, 209 insertions(+), 150 deletions(-) diff --git a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp index e85e3152f..003cfaa6f 100644 --- a/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp +++ b/code/components/jomjol_flowcontroll/ClassFlowMQTT.cpp @@ -37,7 +37,7 @@ void ClassFlowMQTT::SetInitialParameter(void) topicUptime = ""; topicFreeMem = ""; - clientname = "AIOTED-" + getMac(); + clientname = wlan_config.hostname; OldValue = ""; flowpostprocessing = NULL; @@ -166,7 +166,6 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph) if (((toUpper(splitted[0]) == "TOPIC") || (toUpper(splitted[0]) == "MAINTOPIC")) && (splitted.size() > 1)) { maintopic = splitted[1]; - mqttServer_setMainTopic(maintopic); } } @@ -175,6 +174,8 @@ bool ClassFlowMQTT::ReadParameter(FILE* pfile, string& aktparamgraph) * How ever we need the interval parameter from the ClassFlowControll, but that only gets started later. * To work around this, we delay the start and trigger it from ClassFlowControll::ReadParameter() */ + mqttServer_setMainTopic(maintopic); + return true; } @@ -210,6 +211,7 @@ bool ClassFlowMQTT::Start(float AutoInterval) bool ClassFlowMQTT::doFlow(string zwtime) { + bool success; std::string result; std::string resulterror = ""; std::string resultraw = ""; @@ -221,7 +223,7 @@ bool ClassFlowMQTT::doFlow(string zwtime) string zw = ""; string namenumber = ""; - publishSystemData(); + success = publishSystemData(); if (flowpostprocessing && getMQTTisConnected()) { @@ -247,13 +249,13 @@ bool ClassFlowMQTT::doFlow(string zwtime) if (result.length() > 0) - MQTTPublish(namenumber + "value", result, SetRetainFlag); + success |= MQTTPublish(namenumber + "value", result, SetRetainFlag); if (resulterror.length() > 0) - MQTTPublish(namenumber + "error", resulterror, SetRetainFlag); + success |= MQTTPublish(namenumber + "error", resulterror, SetRetainFlag); if (resultrate.length() > 0) { - MQTTPublish(namenumber + "rate", resultrate, SetRetainFlag); + success |= MQTTPublish(namenumber + "rate", resultrate, SetRetainFlag); std::string resultRatePerTimeUnit; if (getTimeUnit() == "h") { // Need conversion to be per hour @@ -262,22 +264,22 @@ bool ClassFlowMQTT::doFlow(string zwtime) else { // Keep per minute resultRatePerTimeUnit = resultrate; } - MQTTPublish(namenumber + "rate_per_time_unit", resultRatePerTimeUnit, SetRetainFlag); + success |= MQTTPublish(namenumber + "rate_per_time_unit", resultRatePerTimeUnit, SetRetainFlag); } if (resultchangabs.length() > 0) { - MQTTPublish(namenumber + "changeabsolut", resultchangabs, SetRetainFlag); // Legacy API - MQTTPublish(namenumber + "rate_per_digitalization_round", resultchangabs, SetRetainFlag); + success |= MQTTPublish(namenumber + "changeabsolut", resultchangabs, SetRetainFlag); // Legacy API + success |= MQTTPublish(namenumber + "rate_per_digitalization_round", resultchangabs, SetRetainFlag); } if (resultraw.length() > 0) - MQTTPublish(namenumber + "raw", resultraw, SetRetainFlag); + success |= MQTTPublish(namenumber + "raw", resultraw, SetRetainFlag); if (resulttimestamp.length() > 0) - MQTTPublish(namenumber + "timestamp", resulttimestamp, SetRetainFlag); + success |= MQTTPublish(namenumber + "timestamp", resulttimestamp, SetRetainFlag); std::string json = flowpostprocessing->getJsonFromNumber(i, "\n"); - MQTTPublish(namenumber + "json", json, SetRetainFlag); + success |= MQTTPublish(namenumber + "json", json, SetRetainFlag); } } @@ -295,10 +297,14 @@ bool ClassFlowMQTT::doFlow(string zwtime) // result = result + "\t" + zw; // } // } - // MQTTPublish(topic, result, SetRetainFlag); + // success |= MQTTPublish(topic, result, SetRetainFlag); // } OldValue = result; + + if (!success) { + LogFile.WriteToFile(ESP_LOG_WARN, TAG, "One or more MQTT topics failed to be published!"); + } return true; } diff --git a/code/components/jomjol_helper/Helper.cpp b/code/components/jomjol_helper/Helper.cpp index 77dade32a..3417eb58b 100644 --- a/code/components/jomjol_helper/Helper.cpp +++ b/code/components/jomjol_helper/Helper.cpp @@ -963,3 +963,34 @@ std::string UrlDecode(const std::string& value) return result; } + + +bool replaceString(std::string& s, std::string const& toReplace, std::string const& replaceWith) { + return replaceString(s, toReplace, replaceWith, true); +} + + +bool replaceString(std::string& s, std::string const& toReplace, std::string const& replaceWith, bool logIt) { + std::size_t pos = s.find(toReplace); + + if (pos == std::string::npos) { // Not found + return false; + } + + std::string old = s; + s.replace(pos, toReplace.length(), replaceWith); + if (logIt) { + LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line '" + old + "' to '" + s + "'"); + } + return true; +} + + +bool isInString(std::string& s, std::string const& toFind) { + std::size_t pos = s.find(toFind); + + if (pos == std::string::npos) { // Not found + return false; + } + return true; +} diff --git a/code/components/jomjol_helper/Helper.h b/code/components/jomjol_helper/Helper.h index edb161fbe..f70e615f2 100644 --- a/code/components/jomjol_helper/Helper.h +++ b/code/components/jomjol_helper/Helper.h @@ -95,4 +95,8 @@ const char* get404(void); std::string UrlDecode(const std::string& value); +bool replaceString(std::string& s, std::string const& toReplace, std::string const& replaceWith); +bool replaceString(std::string& s, std::string const& toReplace, std::string const& replaceWith, bool logIt); +bool isInString(std::string& s, std::string const& toFind); + #endif //HELPER_H diff --git a/code/components/jomjol_mqtt/interface_mqtt.cpp b/code/components/jomjol_mqtt/interface_mqtt.cpp index fc1f328a4..0d3771bc7 100644 --- a/code/components/jomjol_mqtt/interface_mqtt.cpp +++ b/code/components/jomjol_mqtt/interface_mqtt.cpp @@ -326,8 +326,7 @@ bool mqtt_handler_flow_start(std::string _topic, char* _data, int _data_len) { void MQTTconnected(){ if (mqtt_connected) { LogFile.WriteToFile(ESP_LOG_INFO, TAG, "Connected to broker"); - MQTTPublish(lwt_topic, lwt_connected, true); // Publish "connected" to maintopic/connection - + if (connectFunktionMap != NULL) { for(std::map>::iterator it = connectFunktionMap->begin(); it != connectFunktionMap->end(); ++it) { it->second(); diff --git a/code/components/jomjol_mqtt/server_mqtt.cpp b/code/components/jomjol_mqtt/server_mqtt.cpp index 7a34a68c3..74cdccd49 100644 --- a/code/components/jomjol_mqtt/server_mqtt.cpp +++ b/code/components/jomjol_mqtt/server_mqtt.cpp @@ -47,7 +47,7 @@ void mqttServer_setMeterType(std::string _meterType, std::string _valueUnit, std rateUnit = _rateUnit; } -void sendHomeAssistantDiscoveryTopic(std::string group, std::string field, +bool sendHomeAssistantDiscoveryTopic(std::string group, std::string field, std::string name, std::string icon, std::string unit, std::string deviceClass, std::string stateClass, std::string entityCategory) { std::string version = std::string(libfive_git_version()); @@ -131,26 +131,29 @@ void sendHomeAssistantDiscoveryTopic(std::string group, std::string field, "}" + "}"; - MQTTPublish(topicFull, payload, true); + return MQTTPublish(topicFull, payload, true); } -void MQTThomeassistantDiscovery() { - if (!getMQTTisConnected()) - return; +bool MQTThomeassistantDiscovery() { + bool allSendsSuccessed = false; - LogFile.WriteToFile(ESP_LOG_INFO, TAG, "MQTT - Sending Homeassistant Discovery Topics (Meter Type: " + meterType + ", Value Unit: " + valueUnit + " , Rate Unit: " + rateUnit + ")..."); + if (!getMQTTisConnected()) { + LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Unable to send Homeassistant Discovery Topics, we are not connected to the MQTT broker!"); + return false; + } - // Group | Field | User Friendly Name | Icon | Unit | Device Class | State Class | Entity Category - sendHomeAssistantDiscoveryTopic("", "uptime", "Uptime", "clock-time-eight-outline", "s", "", "", "diagnostic"); - sendHomeAssistantDiscoveryTopic("", "MAC", "MAC Address", "network-outline", "", "", "", "diagnostic"); - sendHomeAssistantDiscoveryTopic("", "hostname", "Hostname", "network-outline", "", "", "", "diagnostic"); - sendHomeAssistantDiscoveryTopic("", "freeMem", "Free Memory", "memory", "B", "", "measurement", "diagnostic"); - sendHomeAssistantDiscoveryTopic("", "wifiRSSI", "Wi-Fi RSSI", "wifi", "dBm", "signal_strength", "", "diagnostic"); - sendHomeAssistantDiscoveryTopic("", "CPUtemp", "CPU Temperature", "thermometer", "°C", "temperature", "measurement", "diagnostic"); - sendHomeAssistantDiscoveryTopic("", "interval", "Interval", "clock-time-eight-outline", "min", "" , "measurement", "diagnostic"); - sendHomeAssistantDiscoveryTopic("", "IP", "IP", "network-outline", "", "", "", "diagnostic"); - sendHomeAssistantDiscoveryTopic("", "status", "Status", "list-status", "", "", "", "diagnostic"); + LogFile.WriteToFile(ESP_LOG_INFO, TAG, "MQTT - Sending Homeassistant Discovery Topics (Meter Type: " + meterType + ", Value Unit: " + valueUnit + " , Rate Unit: " + rateUnit + ")..."); + // Group | Field | User Friendly Name | Icon | Unit | Device Class | State Class | Entity Category + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "uptime", "Uptime", "clock-time-eight-outline", "s", "", "", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "MAC", "MAC Address", "network-outline", "", "", "", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "hostname", "Hostname", "network-outline", "", "", "", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "freeMem", "Free Memory", "memory", "B", "", "measurement", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "wifiRSSI", "Wi-Fi RSSI", "wifi", "dBm", "signal_strength", "", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "CPUtemp", "CPU Temperature", "thermometer", "°C", "temperature", "measurement", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "interval", "Interval", "clock-time-eight-outline", "min", "" , "measurement", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "IP", "IP", "network-outline", "", "", "", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic("", "status", "Status", "list-status", "", "", "", "diagnostic"); for (int i = 0; i < (*NUMBERS).size(); ++i) { @@ -159,76 +162,126 @@ void MQTThomeassistantDiscovery() { group = ""; } - // Group | Field | User Friendly Name | Icon | Unit | Device Class | State Class | Entity Category - sendHomeAssistantDiscoveryTopic(group, "value", "Value", "gauge", valueUnit, meterType, "total_increasing", ""); - sendHomeAssistantDiscoveryTopic(group, "raw", "Raw Value", "raw", valueUnit, "", "total_increasing", "diagnostic"); - sendHomeAssistantDiscoveryTopic(group, "error", "Error", "alert-circle-outline", "", "", "", "diagnostic"); + // Group | Field | User Friendly Name | Icon | Unit | Device Class | State Class | Entity Category + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "value", "Value", "gauge", valueUnit, meterType, "total_increasing", ""); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "raw", "Raw Value", "raw", valueUnit, "", "total_increasing", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "error", "Error", "alert-circle-outline", "", "", "", "diagnostic"); /* Not announcing "rate" as it is better to use rate_per_time_unit resp. rate_per_digitalization_round */ - // sendHomeAssistantDiscoveryTopic(group, "rate", "Rate (Unit/Minute)", "swap-vertical", "", "", "", ""); // Legacy, always Unit per Minute - sendHomeAssistantDiscoveryTopic(group, "rate_per_time_unit", "Rate (" + rateUnit + ")", "swap-vertical", rateUnit, "", "", ""); - sendHomeAssistantDiscoveryTopic(group, "rate_per_digitalization_round", "Change since last digitalization round", "arrow-expand-vertical", valueUnit, "", "measurement", ""); // correctly the Unit is Uint/Interval! - sendHomeAssistantDiscoveryTopic(group, "timestamp", "Timestamp", "clock-time-eight-outline", "", "timestamp", "", "diagnostic"); - sendHomeAssistantDiscoveryTopic(group, "json", "JSON", "code-json", "", "", "", "diagnostic"); - sendHomeAssistantDiscoveryTopic(group, "problem", "Problem", "alert-outline", "", "problem", "", ""); // Special binary sensor which is based on error topic + // allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "rate", "Rate (Unit/Minute)", "swap-vertical", "", "", "", ""); // Legacy, always Unit per Minute + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "rate_per_time_unit", "Rate (" + rateUnit + ")", "swap-vertical", rateUnit, "", "", ""); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "rate_per_digitalization_round", "Change since last digitalization round", "arrow-expand-vertical", valueUnit, "", "measurement", ""); // correctly the Unit is Uint/Interval! + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "timestamp", "Timestamp", "clock-time-eight-outline", "", "timestamp", "", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "json", "JSON", "code-json", "", "", "", "diagnostic"); + allSendsSuccessed |= sendHomeAssistantDiscoveryTopic(group, "problem", "Problem", "alert-outline", "", "problem", "", ""); // Special binary sensor which is based on error topic } + + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Successfully published all Homeassistant Discovery MQTT topics"); + return allSendsSuccessed; } -void publishSystemData() { - if (!getMQTTisConnected()) - return; +bool publishSystemData() { + bool allSendsSuccessed = false; + + if (!getMQTTisConnected()) { + LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Unable to send System Topics, we are not connected to the MQTT broker!"); + return false; + } char tmp_char[50]; LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Publishing system MQTT topics..."); + allSendsSuccessed |= MQTTPublish(maintopic + "/" + std::string(LWT_TOPIC), LWT_CONNECTED, retainFlag); // Publish "connected" to maintopic/connection + sprintf(tmp_char, "%ld", (long)getUpTime()); - MQTTPublish(maintopic + "/" + "uptime", std::string(tmp_char), retainFlag); + allSendsSuccessed |= MQTTPublish(maintopic + "/" + "uptime", std::string(tmp_char), retainFlag); sprintf(tmp_char, "%lu", (long) getESPHeapSize()); - MQTTPublish(maintopic + "/" + "freeMem", std::string(tmp_char), retainFlag); + allSendsSuccessed |= MQTTPublish(maintopic + "/" + "freeMem", std::string(tmp_char), retainFlag); sprintf(tmp_char, "%d", get_WIFI_RSSI()); - MQTTPublish(maintopic + "/" + "wifiRSSI", std::string(tmp_char), retainFlag); + allSendsSuccessed |= MQTTPublish(maintopic + "/" + "wifiRSSI", std::string(tmp_char), retainFlag); sprintf(tmp_char, "%d", (int)temperatureRead()); - MQTTPublish(maintopic + "/" + "CPUtemp", std::string(tmp_char), retainFlag); + allSendsSuccessed |= MQTTPublish(maintopic + "/" + "CPUtemp", std::string(tmp_char), retainFlag); + + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Successfully published all System MQTT topics"); + return allSendsSuccessed; } -void publishStaticData() { - if (!getMQTTisConnected()) - return; +bool publishStaticData() { + bool allSendsSuccessed = false; + + if (!getMQTTisConnected()) { + LogFile.WriteToFile(ESP_LOG_WARN, TAG, "Unable to send Static Topics, we are not connected to the MQTT broker!"); + return false; + } LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Publishing static MQTT topics..."); - MQTTPublish(maintopic + "/" + "MAC", getMac(), retainFlag); - MQTTPublish(maintopic + "/" + "IP", *getIPAddress(), retainFlag); - MQTTPublish(maintopic + "/" + "hostname", wlan_config.hostname, retainFlag); + allSendsSuccessed |= MQTTPublish(maintopic + "/" + "MAC", getMac(), retainFlag); + allSendsSuccessed |= MQTTPublish(maintopic + "/" + "IP", *getIPAddress(), retainFlag); + allSendsSuccessed |= MQTTPublish(maintopic + "/" + "hostname", wlan_config.hostname, retainFlag); std::stringstream stream; stream << std::fixed << std::setprecision(1) << roundInterval; // minutes - MQTTPublish(maintopic + "/" + "interval", stream.str(), retainFlag); + allSendsSuccessed |= MQTTPublish(maintopic + "/" + "interval", stream.str(), retainFlag); + + LogFile.WriteToFile(ESP_LOG_DEBUG, TAG, "Successfully published all Static MQTT topics"); + return allSendsSuccessed; } esp_err_t sendDiscovery_and_static_Topics(httpd_req_t *req) { + bool success = false; + if (HomeassistantDiscovery) { - MQTThomeassistantDiscovery(); + success = MQTThomeassistantDiscovery(); } - publishStaticData(); - - const char* resp_str = (const char*) req->user_ctx; - httpd_resp_send(req, resp_str, strlen(resp_str)); + success |= publishStaticData(); - return ESP_OK; + if (success) { + char msg[] = "MQTT Homeassistant Discovery and Static Topics sent!"; + httpd_resp_send(req, msg, strlen(msg)); + return ESP_OK; + } + else { + LogFile.WriteToFile(ESP_LOG_WARN, TAG, "One or more MQTT topics failed to be published!"); + char msg[] = "Failed to send MQTT topics!"; + httpd_resp_send(req, msg, strlen(msg)); + return ESP_FAIL; + } } void GotConnected(std::string maintopic, bool retainFlag) { - if (HomeassistantDiscovery) { - MQTThomeassistantDiscovery(); + static bool initialStaticOrHomeassistantDiscoveryTopicsGotSent = false; + bool success = false; + + /* Only send Homeassistant Discovery and Static topics on the first time connecting */ + if (!initialStaticOrHomeassistantDiscoveryTopicsGotSent) { + if (HomeassistantDiscovery) { + success = MQTThomeassistantDiscovery(); + } + + success |= publishStaticData(); + + if (success) { + /* Sending of all Homeassistant Discovery and Static Topics was successfull. + * Will no no longer send it on a re-connect! + * (But it is still possible to trigger sending through the REST API). */ + initialStaticOrHomeassistantDiscoveryTopicsGotSent = true; + } + else { + LogFile.WriteToFile(ESP_LOG_WARN, TAG, "One or more static or Homeassistant Discovery MQTT topics failed to be published! Will try again on the next round."); + } } - publishStaticData(); - publishSystemData(); + /* The System Data changes at runtime, therefore we always send it after a re-connect */ + success |= publishSystemData(); + + if (!success) { + LogFile.WriteToFile(ESP_LOG_WARN, TAG, "One or more MQTT topics failed to be published!"); + } } void register_server_mqtt_uri(httpd_handle_t server) { @@ -237,7 +290,7 @@ void register_server_mqtt_uri(httpd_handle_t server) { uri.uri = "/mqtt_publish_discovery"; uri.handler = sendDiscovery_and_static_Topics; - uri.user_ctx = (void*) "MQTT Discovery and Static Topics sent"; + uri.user_ctx = (void*) ""; httpd_register_uri_handler(server, &uri); } diff --git a/code/components/jomjol_mqtt/server_mqtt.h b/code/components/jomjol_mqtt/server_mqtt.h index 3cd266c37..55019b070 100644 --- a/code/components/jomjol_mqtt/server_mqtt.h +++ b/code/components/jomjol_mqtt/server_mqtt.h @@ -16,7 +16,7 @@ std::string mqttServer_getMainTopic(); void register_server_mqtt_uri(httpd_handle_t server); -void publishSystemData(); +bool publishSystemData(); std::string getTimeUnit(void); void GotConnected(std::string maintopic, bool SetRetainFlag); diff --git a/code/main/main.cpp b/code/main/main.cpp index 622b2ad83..686b7f37f 100644 --- a/code/main/main.cpp +++ b/code/main/main.cpp @@ -86,10 +86,6 @@ extern std::string getHTMLversion(void); extern std::string getHTMLcommit(void); std::vector splitString(const std::string& str); -bool replace(std::string& s, std::string const& toReplace, std::string const& replaceWith); -bool replace(std::string& s, std::string const& toReplace, std::string const& replaceWith, bool logIt); -//bool replace_all(std::string& s, std::string const& toReplace, std::string const& replaceWith); -bool isInString(std::string& s, std::string const& toFind); void migrateConfiguration(void); static const char *TAG = "MAIN"; @@ -495,7 +491,7 @@ void migrateConfiguration(void) { if (configLines[i].find("[") != std::string::npos) { // Start of new section section = configLines[i]; - replace(section, ";", "", false); // Remove possible semicolon (just for the string comparison) + replaceString(section, ";", "", false); // Remove possible semicolon (just for the string comparison) //ESP_LOGI(TAG, "New section: %s", section.c_str()); } @@ -510,79 +506,79 @@ void migrateConfiguration(void) { * - Only one whitespace before/after the equal sign */ if (section == "[MakeImage]") { - migrated = migrated | replace(configLines[i], "[MakeImage]", "[TakeImage]"); // Rename the section itself + migrated = migrated | replaceString(configLines[i], "[MakeImage]", "[TakeImage]"); // Rename the section itself } if (section == "[MakeImage]" || section == "[TakeImage]") { - migrated = migrated | replace(configLines[i], "LogImageLocation", "RawImagesLocation"); - migrated = migrated | replace(configLines[i], "LogfileRetentionInDays", "RawImagesRetention"); + migrated = migrated | replaceString(configLines[i], "LogImageLocation", "RawImagesLocation"); + migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "RawImagesRetention"); - migrated = migrated | replace(configLines[i], ";Demo = true", ";Demo = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";Demo", "Demo"); // Enable it + migrated = migrated | replaceString(configLines[i], ";Demo = true", ";Demo = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";Demo", "Demo"); // Enable it - migrated = migrated | replace(configLines[i], ";FixedExposure = true", ";FixedExposure = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";FixedExposure", "FixedExposure"); // Enable it + migrated = migrated | replaceString(configLines[i], ";FixedExposure = true", ";FixedExposure = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";FixedExposure", "FixedExposure"); // Enable it } if (section == "[Alignment]") { - migrated = migrated | replace(configLines[i], ";InitialMirror = true", ";InitialMirror = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";InitialMirror", "InitialMirror"); // Enable it + migrated = migrated | replaceString(configLines[i], ";InitialMirror = true", ";InitialMirror = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";InitialMirror", "InitialMirror"); // Enable it - migrated = migrated | replace(configLines[i], ";FlipImageSize = true", ";FlipImageSize = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";FlipImageSize", "FlipImageSize"); // Enable it + migrated = migrated | replaceString(configLines[i], ";FlipImageSize = true", ";FlipImageSize = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";FlipImageSize", "FlipImageSize"); // Enable it } if (section == "[Digits]") { - migrated = migrated | replace(configLines[i], "LogImageLocation", "ROIImagesLocation"); - migrated = migrated | replace(configLines[i], "LogfileRetentionInDays", "ROIImagesRetention"); + migrated = migrated | replaceString(configLines[i], "LogImageLocation", "ROIImagesLocation"); + migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "ROIImagesRetention"); } if (section == "[Analog]") { - migrated = migrated | replace(configLines[i], "LogImageLocation", "ROIImagesLocation"); - migrated = migrated | replace(configLines[i], "LogfileRetentionInDays", "ROIImagesRetention"); - migrated = migrated | replace(configLines[i], "ExtendedResolution", ";UNUSED_PARAMETER"); // This parameter is no longer used + migrated = migrated | replaceString(configLines[i], "LogImageLocation", "ROIImagesLocation"); + migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "ROIImagesRetention"); + migrated = migrated | replaceString(configLines[i], "ExtendedResolution", ";UNUSED_PARAMETER"); // This parameter is no longer used } if (section == "[PostProcessing]") { - migrated = migrated | replace(configLines[i], ";PreValueUse = true", ";PreValueUse = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";PreValueUse", "PreValueUse"); // Enable it + migrated = migrated | replaceString(configLines[i], ";PreValueUse = true", ";PreValueUse = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";PreValueUse", "PreValueUse"); // Enable it /* AllowNegativeRates has a as prefix! */ if (isInString(configLines[i], "AllowNegativeRates") && isInString(configLines[i], ";")) { // It is the parameter "AllowNegativeRates" and it is commented out - migrated = migrated | replace(configLines[i], "true", "false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";", ""); // Enable it + migrated = migrated | replaceString(configLines[i], "true", "false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it } /* IgnoreLeadingNaN has a as prefix! */ if (isInString(configLines[i], "IgnoreLeadingNaN") && isInString(configLines[i], ";")) { // It is the parameter "IgnoreLeadingNaN" and it is commented out - migrated = migrated | replace(configLines[i], "true", "false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";", ""); // Enable it + migrated = migrated | replaceString(configLines[i], "true", "false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it } /* ExtendedResolution has a as prefix! */ if (isInString(configLines[i], "ExtendedResolution") && isInString(configLines[i], ";")) { // It is the parameter "ExtendedResolution" and it is commented out - migrated = migrated | replace(configLines[i], "true", "false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";", ""); // Enable it + migrated = migrated | replaceString(configLines[i], "true", "false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";", ""); // Enable it } - migrated = migrated | replace(configLines[i], ";ErrorMessage = true", ";ErrorMessage = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";ErrorMessage", "ErrorMessage"); // Enable it + migrated = migrated | replaceString(configLines[i], ";ErrorMessage = true", ";ErrorMessage = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";ErrorMessage", "ErrorMessage"); // Enable it - migrated = migrated | replace(configLines[i], ";CheckDigitIncreaseConsistency = true", ";CheckDigitIncreaseConsistency = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";CheckDigitIncreaseConsistency", "CheckDigitIncreaseConsistency"); // Enable it + migrated = migrated | replaceString(configLines[i], ";CheckDigitIncreaseConsistency = true", ";CheckDigitIncreaseConsistency = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";CheckDigitIncreaseConsistency", "CheckDigitIncreaseConsistency"); // Enable it } if (section == "[MQTT]") { - migrated = migrated | replace(configLines[i], "SetRetainFlag", "RetainMessages"); // First rename it, enable it with its default value - migrated = migrated | replace(configLines[i], ";RetainMessages = true", ";RetainMessages = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";RetainMessages", "RetainMessages"); // Enable it + migrated = migrated | replaceString(configLines[i], "SetRetainFlag", "RetainMessages"); // First rename it, enable it with its default value + migrated = migrated | replaceString(configLines[i], ";RetainMessages = true", ";RetainMessages = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";RetainMessages", "RetainMessages"); // Enable it - migrated = migrated | replace(configLines[i], ";HomeassistantDiscovery = true", ";HomeassistantDiscovery = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";HomeassistantDiscovery", "HomeassistantDiscovery"); // Enable it + migrated = migrated | replaceString(configLines[i], ";HomeassistantDiscovery = true", ";HomeassistantDiscovery = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";HomeassistantDiscovery", "HomeassistantDiscovery"); // Enable it if (configLines[i].rfind("Topic", 0) != std::string::npos) // only if string starts with "Topic" (Was the naming in very old version) { - migrated = migrated | replace(configLines[i], "Topic", "MainTopic"); + migrated = migrated | replaceString(configLines[i], "Topic", "MainTopic"); } } @@ -595,34 +591,34 @@ void migrateConfiguration(void) { } if (section == "[DataLogging]") { - migrated = migrated | replace(configLines[i], "DataLogRetentionInDays", "DataFilesRetention"); + migrated = migrated | replaceString(configLines[i], "DataLogRetentionInDays", "DataFilesRetention"); /* DataLogActive is true by default! */ - migrated = migrated | replace(configLines[i], ";DataLogActive = false", ";DataLogActive = true"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";DataLogActive", "DataLogActive"); // Enable it + migrated = migrated | replaceString(configLines[i], ";DataLogActive = false", ";DataLogActive = true"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";DataLogActive", "DataLogActive"); // Enable it } if (section == "[AutoTimer]") { - migrated = migrated | replace(configLines[i], "Intervall", "Interval"); - migrated = migrated | replace(configLines[i], ";AutoStart = true", ";AutoStart = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";AutoStart", "AutoStart"); // Enable it + migrated = migrated | replaceString(configLines[i], "Intervall", "Interval"); + migrated = migrated | replaceString(configLines[i], ";AutoStart = true", ";AutoStart = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";AutoStart", "AutoStart"); // Enable it } if (section == "[Debug]") { - migrated = migrated | replace(configLines[i], "Logfile ", "LogLevel "); // Whitespace needed so it does not match `LogfileRetentionInDays` + migrated = migrated | replaceString(configLines[i], "Logfile ", "LogLevel "); // Whitespace needed so it does not match `LogfileRetentionInDays` /* LogLevel (resp. LogFile) was originally a boolean, but we switched it to an int * For both cases (true/false), we set it to level 2 (WARNING) */ - migrated = migrated | replace(configLines[i], "LogLevel = true", "LogLevel = 2"); - migrated = migrated | replace(configLines[i], "LogLevel = false", "LogLevel = 2"); - migrated = migrated | replace(configLines[i], "LogfileRetentionInDays", "LogfilesRetention"); + migrated = migrated | replaceString(configLines[i], "LogLevel = true", "LogLevel = 2"); + migrated = migrated | replaceString(configLines[i], "LogLevel = false", "LogLevel = 2"); + migrated = migrated | replaceString(configLines[i], "LogfileRetentionInDays", "LogfilesRetention"); } if (section == "[System]") { - migrated = migrated | replace(configLines[i], "RSSIThreashold", "RSSIThreshold"); - migrated = migrated | replace(configLines[i], "AutoAdjustSummertime", ";UNUSED_PARAMETER"); // This parameter is no longer used + migrated = migrated | replaceString(configLines[i], "RSSIThreashold", "RSSIThreshold"); + migrated = migrated | replaceString(configLines[i], "AutoAdjustSummertime", ";UNUSED_PARAMETER"); // This parameter is no longer used - migrated = migrated | replace(configLines[i], ";SetupMode = true", ";SetupMode = false"); // Set it to its default value - migrated = migrated | replace(configLines[i], ";SetupMode", "SetupMode"); // Enable it + migrated = migrated | replaceString(configLines[i], ";SetupMode = true", ";SetupMode = false"); // Set it to its default value + migrated = migrated | replaceString(configLines[i], ";SetupMode", "SetupMode"); // Enable it } } @@ -683,33 +679,3 @@ std::vector splitString(const std::string& str) { return found; }*/ - - -bool replace(std::string& s, std::string const& toReplace, std::string const& replaceWith) { - return replace(s, toReplace, replaceWith, true); -} - -bool replace(std::string& s, std::string const& toReplace, std::string const& replaceWith, bool logIt) { - std::size_t pos = s.find(toReplace); - - if (pos == std::string::npos) { // Not found - return false; - } - - std::string old = s; - s.replace(pos, toReplace.length(), replaceWith); - if (logIt) { - LogFile.WriteToFile(ESP_LOG_ERROR, TAG, "Migrated Configfile line '" + old + "' to '" + s + "'"); - } - return true; -} - - -bool isInString(std::string& s, std::string const& toFind) { - std::size_t pos = s.find(toFind); - - if (pos == std::string::npos) { // Not found - return false; - } - return true; -}