From 5e65e807b77404c8a9a12fb0e5410a264f0c7ddd Mon Sep 17 00:00:00 2001 From: Florian Date: Wed, 4 Sep 2024 10:31:51 -0500 Subject: [PATCH] [SYS] Externalize utils functions (#2046) To declutter main.ino code Co-authored-by: Florian <1technophile@users.noreply.github.com> --- .gitignore | 1 + lib/TheengsUtils/TheengsUtils.cpp | 177 ++++++++++++++++++++++++++ lib/TheengsUtils/TheengsUtils.h | 49 +++++++ main/ZactuatorFASTLED.ino | 8 +- main/ZactuatorONOFF.ino | 6 +- main/ZactuatorPWM.ino | 4 +- main/ZactuatorSomfy.ino | 2 +- main/ZboardM5.ino | 2 +- main/ZcommonRF.ino | 2 +- main/ZdisplaySSD1306.ino | 2 +- main/Zgateway2G.ino | 4 +- main/ZgatewayBT.ino | 4 +- main/ZgatewayIR.ino | 2 +- main/ZgatewayLORA.ino | 10 +- main/ZgatewayPilight.ino | 4 +- main/ZgatewayRF.ino | 4 +- main/ZgatewayRF2.ino | 4 +- main/ZgatewayRFM69.ino | 4 +- main/ZgatewaySERIAL.ino | 2 +- main/ZgatewaySRFB.ino | 18 +-- main/ZsensorRN8209.ino | 6 +- main/ZwebUI.ino | 6 +- main/main.ino | 205 +++--------------------------- 23 files changed, 295 insertions(+), 231 deletions(-) create mode 100644 lib/TheengsUtils/TheengsUtils.cpp create mode 100644 lib/TheengsUtils/TheengsUtils.h diff --git a/.gitignore b/.gitignore index d460f6a..1da706d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ node_modules main/certs/private* lib/* !lib/esp32-bt-lib +!lib/TheengsUtils CMakeLists.txt dependencies.lock sdkconfig.* diff --git a/lib/TheengsUtils/TheengsUtils.cpp b/lib/TheengsUtils/TheengsUtils.cpp new file mode 100644 index 0000000..272d420 --- /dev/null +++ b/lib/TheengsUtils/TheengsUtils.cpp @@ -0,0 +1,177 @@ +/* + Theengs - IoT Interoperability + + Copyright: (c)Florian ROBERT + + This file is part of Theengs products. + + Theengs is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Theengs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include "TheengsUtils.h" + +String TheengsUtils::toString(uint64_t input) { + String result = ""; + uint8_t base = 10; + + do { + char c = input % base; + input /= base; + + if (c < 10) + c += '0'; + else + c += 'A' - 10; + result = c + result; + } while (input); + return result; +} + +/* +* @brief Convert the spaces of the certificate into new lines +*/ +std::string TheengsUtils::processCert(const char* cert) { + std::string certStr(cert); + size_t pos = 0; + while ((pos = certStr.find(' ', pos)) != std::string::npos) { + if (pos < 4 || (pos >= 27 && pos <= certStr.length() - 25) || pos >= certStr.length() - 4) { + certStr.replace(pos, 1, "\n"); + } + pos++; + } + return certStr; +} + +std::string TheengsUtils::generateHash(const std::string& input) { + // Implementation depends on your hash function + // This is a placeholder + return "hash_placeholder"; +} + +bool TheengsUtils::cmpToMainTopic(const char* topicOri, const char* toAdd) { + // Implementation depends on mqtt_topic and gateway_name + // You might need to pass these as parameters or make them class members + return false; +} + +unsigned long TheengsUtils::uptime() { + static unsigned long lastUptime = 0; + static unsigned long uptimeAdd = 0; + unsigned long uptime = millis() / 1000 + uptimeAdd; + if (uptime < lastUptime) { + uptime += 4294967; + uptimeAdd += 4294967; + } + lastUptime = uptime; + return uptime; +} + +void TheengsUtils::syncNTP() { + configTime(0, 0, "pool.ntp.org"); + time_t now = time(nullptr); + while (now < 8 * 3600 * 2) { + delay(500); + now = time(nullptr); + } +} + +int TheengsUtils::unixtimestamp() { + return time(nullptr); +} + +String TheengsUtils::UTCtimestamp() { + time_t now; + time(&now); + char buffer[sizeof "yyyy-MM-ddThh:mm:ssZ"]; + strftime(buffer, sizeof buffer, "%FT%TZ", gmtime(&now)); + return buffer; +} + +void TheengsUtils::revert_hex_data(const char* in, char* out, int l) { + //reverting array 2 by 2 to get the data in good order + int i = l - 2, j = 0; + while (i != -2) { + if (i % 2 == 0) + out[j] = in[i + 1]; + else + out[j] = in[i - 1]; + j++; + i--; + } + out[l - 1] = '\0'; +} + +/** + * Retrieve an unsigned long value from a char array extract representing hexadecimal data, reversed or not, + * This value can represent a negative value if canBeNegative is set to true + */ +long TheengsUtils::value_from_hex_data(const char* service_data, int offset, int data_length, bool reverse, bool canBeNegative) { + char data[data_length + 1]; + memcpy(data, &service_data[offset], data_length); + data[data_length] = '\0'; + long value; + if (reverse) { + // reverse data order + char rev_data[data_length + 1]; + revert_hex_data(data, rev_data, data_length + 1); + value = strtol(rev_data, NULL, 16); + } else { + value = strtol(data, NULL, 16); + } + if (value > 65000 && data_length <= 4 && canBeNegative) + value = value - 65535; + return value; +} + +/* + rounds a number to 2 decimal places + example: round(3.14159) -> 3.14 +*/ +double TheengsUtils::round2(float value) { + return (int)(value * 100 + 0.5) / 100.0; +} + +/* +From a byte array to an hexa char array ("A220EE...", double the size) + */ +bool TheengsUtils::_rawToHex(byte* in, char* out, int rawSize) { + for (unsigned char p = 0; p < rawSize; p++) { + sprintf_P(&out[p * 2], PSTR("%02X\r"), in[p]); + } + return true; +} + +/* +From an hexa char array ("A220EE...") to a byte array (half the size) + */ +bool TheengsUtils::_hexToRaw(const char* in, byte* out, int rawSize) { + if (strlen(in) != rawSize * 2) + return false; + char tmp[3] = {0}; + for (unsigned char p = 0; p < rawSize; p++) { + memcpy(tmp, &in[p * 2], 2); + out[p] = strtol(tmp, NULL, 16); + } + return true; +} + +char* TheengsUtils::ip2CharArray(IPAddress ip) { + static char ipChar[16]; + sprintf(ipChar, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); + return ipChar; +} + +bool TheengsUtils::to_bool(String const& s) { + return s != "0" && s != "false" && s != "False" && s != "FALSE"; +} \ No newline at end of file diff --git a/lib/TheengsUtils/TheengsUtils.h b/lib/TheengsUtils/TheengsUtils.h new file mode 100644 index 0000000..e4f857e --- /dev/null +++ b/lib/TheengsUtils/TheengsUtils.h @@ -0,0 +1,49 @@ +/* + Theengs - IoT Interoperability + + Copyright: (c)Florian ROBERT + + This file is part of Theengs products. + + Theengs is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Theengs is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef THEENGS_UTIL_H +#define THEENGS_UTIL_H + +#include +#include +#include +#include + +class TheengsUtils { +public: + static String toString(uint64_t input); + static std::string processCert(const char* cert); + static std::string generateHash(const std::string& input); + static bool cmpToMainTopic(const char* topicOri, const char* toAdd); + static unsigned long uptime(); + static void syncNTP(); + static int unixtimestamp(); + static String UTCtimestamp(); + static void revert_hex_data(const char* in, char* out, int l); + static long value_from_hex_data(const char* service_data, int offset, int data_length, bool reverse, bool canBeNegative = true); + static double round2(float value); + static bool _rawToHex(byte* in, char* out, int rawSize); + static bool _hexToRaw(const char* in, byte* out, int rawSize); + static char* ip2CharArray(IPAddress ip); + static bool to_bool(String const& s); +}; + +#endif \ No newline at end of file diff --git a/main/ZactuatorFASTLED.ino b/main/ZactuatorFASTLED.ino index e7bfa50..abb38a8 100644 --- a/main/ZactuatorFASTLED.ino +++ b/main/ZactuatorFASTLED.ino @@ -103,7 +103,7 @@ void MQTTtoFASTLED(char* topicOri, JsonObject& jsonData) { //trc(topicOri); //number = (long)strtol(&datacallback[1], NULL, 16); - if (cmpToMainTopic(topicOri, subjectMQTTtoFASTLEDsetled)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoFASTLEDsetled)) { Log.trace(F("MQTTtoFASTLED JSON analysis" CR)); int ledNr = jsonData["led"]; Log.notice(F("Led numero: %d" CR), ledNr); @@ -126,19 +126,19 @@ void MQTTtoFASTLED(char* topicOri, char* datacallback) { Log.trace(F("MQTTtoFASTLED: " CR)); currentLEDState = GENERAL; long number = 0; - if (cmpToMainTopic(topicOri, subjectMQTTtoFASTLED)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoFASTLED)) { number = (long)strtol(&datacallback[1], NULL, 16); Log.notice(F("Number: %l" CR), number); for (int i = 0; i < FASTLED_NUM_LEDS; i++) { leds[i] = number; } FastLED.show(); - } else if (cmpToMainTopic(topicOri, subjectMQTTtoFASTLEDsetbrightness)) { + } else if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoFASTLEDsetbrightness)) { number = (long)strtol(&datacallback[1], NULL, 16); Log.notice(F("Number: %l" CR), number); FastLED.setBrightness(number); FastLED.show(); - } else if (cmpToMainTopic(topicOri, subjectMQTTtoFASTLEDsetanimation)) { + } else if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoFASTLEDsetanimation)) { String payload = datacallback; Log.notice(F("Datacallback: %s" CR), datacallback); if (strstr(datacallback, "fire") != NULL) { diff --git a/main/ZactuatorONOFF.ino b/main/ZactuatorONOFF.ino index 7696de6..54a945a 100644 --- a/main/ZactuatorONOFF.ino +++ b/main/ZactuatorONOFF.ino @@ -133,7 +133,7 @@ void setupONOFF() { # if jsonReceiving void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) { - if (cmpToMainTopic(topicOri, subjectMQTTtoONOFF)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoONOFF)) { Log.trace(F("MQTTtoONOFF json data analysis" CR)); int boolSWITCHTYPE = ONOFFdata["cmd"] | 99; int gpio = ONOFFdata["gpio"] | ACTUATOR_ONOFF_GPIO; @@ -179,7 +179,7 @@ void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) { } } } - if (cmpToMainTopic(topicOri, subjectMQTTtoONOFFset)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoONOFFset)) { Log.trace(F("MQTTtoONOFF json set" CR)); /* * Configuration modifications priorities: @@ -204,7 +204,7 @@ void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) { # if simpleReceiving void MQTTtoONOFF(char* topicOri, char* datacallback) { - if ((cmpToMainTopic(topicOri, subjectMQTTtoONOFF))) { + if ((TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoONOFF))) { Log.trace(F("MQTTtoONOFF" CR)); char* endptr = NULL; long gpio = strtol(datacallback, &endptr, 10); diff --git a/main/ZactuatorPWM.ino b/main/ZactuatorPWM.ino index c5757a0..18975fa 100644 --- a/main/ZactuatorPWM.ino +++ b/main/ZactuatorPWM.ino @@ -197,7 +197,7 @@ boolean PWMtoMQTT() { # if jsonReceiving void MQTTtoPWM(char* topicOri, JsonObject& jsonData) { - if (cmpToMainTopic(topicOri, subjectMQTTtoPWMset)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoPWMset)) { Log.trace(F("MQTTtoPWM JSON analysis" CR)); // Parse the target value for each channel int modifiedChannelBits = 0; @@ -230,7 +230,7 @@ void MQTTtoPWM(char* topicOri, JsonObject& jsonData) { } } fadeIsComplete = false; // The values will start to change during PWMLoop - } else if (cmpToMainTopic(topicOri, subjectMQTTtoPWMcalibrate)) { + } else if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoPWMcalibrate)) { // Read the optional calibration data for each channel for (int i = 0; i < kNumChannels; ++i) { char key[64]; diff --git a/main/ZactuatorSomfy.ino b/main/ZactuatorSomfy.ino index ecae060..fa224cd 100644 --- a/main/ZactuatorSomfy.ino +++ b/main/ZactuatorSomfy.ino @@ -50,7 +50,7 @@ void setupSomfy() { # if jsonReceiving void MQTTtoSomfy(char* topicOri, JsonObject& jsonData) { - if (cmpToMainTopic(topicOri, subjectMQTTtoSomfy)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoSomfy)) { Log.trace(F("MQTTtoSomfy json data analysis" CR)); float txFrequency = jsonData["frequency"] | RFConfig.frequency; # ifdef ZradioCC1101 // set Receive off and Transmitt on diff --git a/main/ZboardM5.ino b/main/ZboardM5.ino index 276f717..d42fa69 100644 --- a/main/ZboardM5.ino +++ b/main/ZboardM5.ino @@ -117,7 +117,7 @@ void loopM5() { } void MQTTtoM5(char* topicOri, JsonObject& M5data) { // json object decoding - if (cmpToMainTopic(topicOri, subjectMQTTtoM5set)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoM5set)) { Log.trace(F("MQTTtoM5 json set" CR)); // Log display set between M5 lcd (true) and serial monitor (false) if (M5data.containsKey("log-lcd")) { diff --git a/main/ZcommonRF.ino b/main/ZcommonRF.ino index 3bbdd2b..ca439bf 100644 --- a/main/ZcommonRF.ino +++ b/main/ZcommonRF.ino @@ -301,7 +301,7 @@ void RFConfig_load() { } void MQTTtoRFset(char* topicOri, JsonObject& RFdata) { - if (cmpToMainTopic(topicOri, subjectMQTTtoRFset)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoRFset)) { Log.trace(F("MQTTtoRF json set" CR)); /* diff --git a/main/ZdisplaySSD1306.ino b/main/ZdisplaySSD1306.ino index db0d3a4..a3f8cac 100644 --- a/main/ZdisplaySSD1306.ino +++ b/main/ZdisplaySSD1306.ino @@ -154,7 +154,7 @@ Handler for mqtt commands sent to the module */ void MQTTtoSSD1306(char* topicOri, JsonObject& SSD1306data) { // json object decoding bool success = false; - if (cmpToMainTopic(topicOri, subjectMQTTtoSSD1306set)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoSSD1306set)) { Log.trace(F("MQTTtoSSD1306 json set" CR)); // properties if (SSD1306data.containsKey("onstate")) { diff --git a/main/Zgateway2G.ino b/main/Zgateway2G.ino index 3c8b44b..0f027a5 100644 --- a/main/Zgateway2G.ino +++ b/main/Zgateway2G.ino @@ -100,7 +100,7 @@ void MQTTto2G(char* topicOri, char* datacallback) { String data = datacallback; String topic = topicOri; - if (cmpToMainTopic(topicOri, subjectMQTTto2G)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTto2G)) { Log.trace(F("MQTTto2G data analysis" CR)); // 2G DATA ANALYSIS String phone_number = ""; @@ -128,7 +128,7 @@ void MQTTto2G(char* topicOri, char* datacallback) { # if jsonReceiving void MQTTto2G(char* topicOri, JsonObject& SMSdata) { - if (cmpToMainTopic(topicOri, subjectMQTTto2G)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTto2G)) { const char* sms = SMSdata["message"]; const char* phone = SMSdata["phone"]; Log.trace(F("MQTTto2G json data analysis" CR)); diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index 6604140..085ea94 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -1474,7 +1474,7 @@ void MQTTtoBTAction(JsonObject& BTdata) { } void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding - if (cmpToMainTopic(topicOri, subjectMQTTtoBTset)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoBTset)) { Log.trace(F("MQTTtoBT json set" CR)); // Black list & white list set @@ -1512,7 +1512,7 @@ void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding // Load config from json if available BTConfig_fromJson(BTdata); - } else if (cmpToMainTopic(topicOri, subjectMQTTtoBT)) { + } else if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoBT)) { KnownBTActions(BTdata); MQTTtoBTAction(BTdata); } diff --git a/main/ZgatewayIR.ino b/main/ZgatewayIR.ino index 7ec4878..e47d1f7 100644 --- a/main/ZgatewayIR.ino +++ b/main/ZgatewayIR.ino @@ -163,7 +163,7 @@ bool sendIdentifiedProtocol(const char* protocol_name, uint64_t data, const char # if jsonReceiving void MQTTtoIR(char* topicOri, JsonObject& IRdata) { - if (cmpToMainTopic(topicOri, subjectMQTTtoIR)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoIR)) { Log.trace(F("MQTTtoIR json" CR)); uint64_t data = IRdata["value"]; const char* raw = IRdata["raw"]; diff --git a/main/ZgatewayLORA.ino b/main/ZgatewayLORA.ino index 4e7c7fd..116ee3f 100644 --- a/main/ZgatewayLORA.ino +++ b/main/ZgatewayLORA.ino @@ -435,7 +435,7 @@ void LORAtoMQTT() { } // We have non-ascii data: create hex string of the data char hex[packetSize * 2 + 1]; - _rawToHex(packet, hex, packetSize); + TheengsUtils::_rawToHex(packet, hex, packetSize); // Terminate with a null character hex[packetSize * 2] = 0; @@ -484,7 +484,7 @@ void LORAtoMQTT() { # if jsonReceiving void MQTTtoLORA(char* topicOri, JsonObject& LORAdata) { // json object decoding - if (cmpToMainTopic(topicOri, subjectMQTTtoLORA)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoLORA)) { Log.trace(F("MQTTtoLORA json" CR)); const char* message = LORAdata["message"]; const char* hex = LORAdata["hex"]; @@ -497,7 +497,7 @@ void MQTTtoLORA(char* topicOri, JsonObject& LORAdata) { // json object decoding } else if (hex) { // We have hex data: create convert to binary byte raw[strlen(hex) / 2]; - _hexToRaw(hex, raw, sizeof(raw)); + TheengsUtils::_hexToRaw(hex, raw, sizeof(raw)); LoRa.write((uint8_t*)raw, sizeof(raw)); } else { // ascii payload @@ -512,7 +512,7 @@ void MQTTtoLORA(char* topicOri, JsonObject& LORAdata) { // json object decoding Log.error(F("MQTTtoLORA Fail json" CR)); } } - if (cmpToMainTopic(topicOri, subjectMQTTtoLORAset)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoLORAset)) { Log.trace(F("MQTTtoLORA json set" CR)); /* * Configuration modifications priorities: @@ -536,7 +536,7 @@ void MQTTtoLORA(char* topicOri, JsonObject& LORAdata) { // json object decoding # endif # if simpleReceiving void MQTTtoLORA(char* topicOri, char* LORAarray) { // json object decoding - if (cmpToMainTopic(topicOri, subjectMQTTtoLORA)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoLORA)) { LoRa.beginPacket(); LoRa.print(LORAarray); LoRa.endPacket(); diff --git a/main/ZgatewayPilight.ino b/main/ZgatewayPilight.ino index 70d7e23..1d0bb84 100644 --- a/main/ZgatewayPilight.ino +++ b/main/ZgatewayPilight.ino @@ -154,7 +154,7 @@ void PilighttoMQTT() { } void MQTTtoPilight(char* topicOri, JsonObject& Pilightdata) { - if (cmpToMainTopic(topicOri, subjectMQTTtoPilightProtocol)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoPilightProtocol)) { bool success = false; if (Pilightdata.containsKey("reset")) { rf.limitProtocols(rf.availableProtocols()); @@ -194,7 +194,7 @@ void MQTTtoPilight(char* topicOri, JsonObject& Pilightdata) { pub(subjectGTWPilighttoMQTT, "{\"Status\": \"Error\"}"); // Fail feedback Log.error(F("MQTTtoPilightProtocol Fail json" CR)); } - } else if (cmpToMainTopic(topicOri, subjectMQTTtoPilight)) { + } else if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoPilight)) { const char* message = Pilightdata["message"]; Log.notice(F("MQTTtoPilight message: %s" CR), message); const char* protocol = Pilightdata["protocol"]; diff --git a/main/ZgatewayRF.ino b/main/ZgatewayRF.ino index baa4606..30e6e51 100644 --- a/main/ZgatewayRF.ino +++ b/main/ZgatewayRF.ino @@ -193,7 +193,7 @@ void MQTTtoRF(char* topicOri, char* datacallback) { valueBITS = (topic.substring(pos3, pos3 + 2)).toInt(); } - if ((cmpToMainTopic(topicOri, subjectMQTTtoRF)) && (valuePRT == 0) && (valuePLSL == 0) && (valueBITS == 0)) { + if ((TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoRF)) && (valuePRT == 0) && (valuePLSL == 0) && (valueBITS == 0)) { Log.trace(F("MQTTtoRF dflt" CR)); mySwitch.setProtocol(1, 350); mySwitch.send(data, 24); @@ -225,7 +225,7 @@ void MQTTtoRF(char* topicOri, char* datacallback) { # if jsonReceiving void MQTTtoRF(char* topicOri, JsonObject& RFdata) { // json object decoding - if (cmpToMainTopic(topicOri, subjectMQTTtoRF)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoRF)) { Log.trace(F("MQTTtoRF json" CR)); uint64_t data = RFdata["value"]; if (data != 0) { diff --git a/main/ZgatewayRF2.ino b/main/ZgatewayRF2.ino index d523948..9097948 100644 --- a/main/ZgatewayRF2.ino +++ b/main/ZgatewayRF2.ino @@ -141,7 +141,7 @@ void MQTTtoRF2(char* topicOri, char* datacallback) { //We look into the subject to see if a special RF protocol is defined String topic = topicOri; bool boolSWITCHTYPE; - boolSWITCHTYPE = to_bool(datacallback); + boolSWITCHTYPE = TheengsUtils::to_bool(datacallback); bool isDimCommand = false; long valueCODE = 0; @@ -243,7 +243,7 @@ void MQTTtoRF2(char* topicOri, char* datacallback) { # if jsonReceiving void MQTTtoRF2(char* topicOri, JsonObject& RF2data) { // json object decoding - if (cmpToMainTopic(topicOri, subjectMQTTtoRF2)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoRF2)) { Log.trace(F("MQTTtoRF2 json" CR)); int boolSWITCHTYPE = RF2data["switchType"] | 99; bool success = false; diff --git a/main/ZgatewayRFM69.ino b/main/ZgatewayRFM69.ino index b5bafa0..fb6dad9 100644 --- a/main/ZgatewayRFM69.ino +++ b/main/ZgatewayRFM69.ino @@ -172,7 +172,7 @@ bool RFM69toMQTT(void) { # if simpleReceiving void MQTTtoRFM69(char* topicOri, char* datacallback) { - if (cmpToMainTopic(topicOri, subjectMQTTtoRFM69)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoRFM69)) { Log.trace(F("MQTTtoRFM69 data analysis" CR)); char data[RF69_MAX_DATA_LEN + 1]; memcpy(data, (void*)datacallback, RF69_MAX_DATA_LEN); @@ -201,7 +201,7 @@ void MQTTtoRFM69(char* topicOri, char* datacallback) { # endif # if jsonReceiving void MQTTtoRFM69(char* topicOri, JsonObject& RFM69data) { - if (cmpToMainTopic(topicOri, subjectMQTTtoRFM69)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoRFM69)) { const char* data = RFM69data["data"]; Log.trace(F("MQTTtoRFM69 json data analysis" CR)); if (data) { diff --git a/main/ZgatewaySERIAL.ino b/main/ZgatewaySERIAL.ino index ed5320b..f2c08f4 100644 --- a/main/ZgatewaySERIAL.ino +++ b/main/ZgatewaySERIAL.ino @@ -243,7 +243,7 @@ void sendMQTTfromNestedJson(JsonVariant obj, char* topic, int level, int maxLeve # endif void XtoSERIAL(const char* topicOri, JsonObject& SERIALdata) { - if (cmpToMainTopic(topicOri, subjectXtoSERIAL) || SYSConfig.serial) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectXtoSERIAL) || SYSConfig.serial) { Log.trace(F(" MQTTtoSERIAL" CR)); const char* prefix = SERIALdata["prefix"] | SERIALPre; const char* postfix = SERIALdata["postfix"] | SERIALPost; diff --git a/main/ZgatewaySRFB.ino b/main/ZgatewaySRFB.ino index e86ccad..df0640d 100644 --- a/main/ZgatewaySRFB.ino +++ b/main/ZgatewaySRFB.ino @@ -54,7 +54,7 @@ void _rfbSend(byte* message) { void _rfbSend(byte* message, int times) { char buffer[RF_MESSAGE_SIZE]; - _rawToHex(message, buffer, RF_MESSAGE_SIZE); + TheengsUtils::_rawToHex(message, buffer, RF_MESSAGE_SIZE); Log.notice(F("[RFBRIDGE] Sending MESSAGE" CR)); for (int i = 0; i < times; i++) { @@ -99,23 +99,23 @@ void _rfbDecode() { char buffer[RF_MESSAGE_SIZE * 2 + 1] = {0}; if (action == RF_CODE_RFIN) { - _rawToHex(&_uartbuf[1], buffer, RF_MESSAGE_SIZE); + TheengsUtils::_rawToHex(&_uartbuf[1], buffer, RF_MESSAGE_SIZE); Log.trace(F("Creating SRFB buffer" CR)); StaticJsonDocument SRFBdataBuffer; JsonObject SRFBdata = SRFBdataBuffer.to(); SRFBdata["raw"] = String(buffer).substring(0, 18); - int val_Tsyn = (int)(int)value_from_hex_data(buffer, 0, 4, false, false); + int val_Tsyn = (int)(int)TheengsUtils::value_from_hex_data(buffer, 0, 4, false, false); SRFBdata["delay"] = (int)val_Tsyn; - int val_Tlow = (int)value_from_hex_data(buffer, 4, 4, false, false); + int val_Tlow = (int)TheengsUtils::value_from_hex_data(buffer, 4, 4, false, false); SRFBdata["val_Tlow"] = (int)val_Tlow; - int val_Thigh = (int)value_from_hex_data(buffer, 8, 4, false, false); + int val_Thigh = (int)TheengsUtils::value_from_hex_data(buffer, 8, 4, false, false); SRFBdata["val_Thigh"] = (int)val_Thigh; - unsigned long MQTTvalue = (unsigned long)value_from_hex_data(buffer, 12, 8, false, false); + unsigned long MQTTvalue = (unsigned long)TheengsUtils::value_from_hex_data(buffer, 12, 8, false, false); SRFBdata["value"] = (unsigned long)MQTTvalue; if (!isAduplicateSignal(MQTTvalue) && MQTTvalue != 0) { // conditions to avoid duplications of RF -->MQTT @@ -233,7 +233,7 @@ void MQTTtoSRFB(char* topicOri, char* datacallback) { valueRPT = 1; byte message_b[RF_MESSAGE_SIZE]; - _hexToRaw(datacallback, message_b, RF_MESSAGE_SIZE); + TheengsUtils::_hexToRaw(datacallback, message_b, RF_MESSAGE_SIZE); _rfbSend(message_b, valueRPT); // Acknowledgement to the GTWRF topic pub(subjectGTWSRFBtoMQTT, datacallback); // we acknowledge the sending by publishing the value to an acknowledgement topic, for the moment even if it is a signal repetition we acknowledge also @@ -245,12 +245,12 @@ void MQTTtoSRFB(char* topicOri, JsonObject& SRFBdata) { // RF DATA ANALYSIS const char* raw = SRFBdata["raw"]; int valueRPT = SRFBdata["repeat"] | 1; - if (cmpToMainTopic(topicOri, subjectMQTTtoSRFB)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoSRFB)) { Log.trace(F("MQTTtoSRFB json" CR)); if (raw) { // send raw in priority when defined in the json Log.trace(F("MQTTtoSRFB raw ok" CR)); byte message_b[RF_MESSAGE_SIZE]; - _hexToRaw(raw, message_b, RF_MESSAGE_SIZE); + TheengsUtils::_hexToRaw(raw, message_b, RF_MESSAGE_SIZE); _rfbSend(message_b, valueRPT); } else { unsigned long data = SRFBdata["value"]; diff --git a/main/ZsensorRN8209.ino b/main/ZsensorRN8209.ino index 3addc2b..cd0c68a 100644 --- a/main/ZsensorRN8209.ino +++ b/main/ZsensorRN8209.ino @@ -75,13 +75,13 @@ void rn8209_loop(void* mode) { JsonObject RN8209data = RN8209dataBuffer.to(); if (retc == 0) { previousCurrent = current; - RN8209data["current"] = round2(current); + RN8209data["current"] = TheengsUtils::round2(current); } uint32_t temp_power = 0; retp = rn8209c_read_power(phase_A, &temp_power); if (retv == 0) { previousVoltage = voltage; - RN8209data["volt"] = round2(voltage); + RN8209data["volt"] = TheengsUtils::round2(voltage); } if (ret == 1) { power = temp_power; @@ -90,7 +90,7 @@ void rn8209_loop(void* mode) { } if (retp == 0) { power = power / 10000.0; - RN8209data["power"] = round2(power); + RN8209data["power"] = TheengsUtils::round2(power); } PublishingTimerRN8209 = now; if (RN8209data) { diff --git a/main/ZwebUI.ino b/main/ZwebUI.ino index 41c0df1..5ddb635 100644 --- a/main/ZwebUI.ino +++ b/main/ZwebUI.ino @@ -1288,9 +1288,9 @@ void handleCL() { requestToken = esp_random(); # ifdef ESP32_ETHERNET - snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_cloud_body, jsonChar, gateway_name, " cloud checked", " Not", (String(CLOUDGATEWAY) + "token/start").c_str(), (char*)ETH.macAddress().c_str(), ("http://" + String(ip2CharArray(ETH.localIP())) + "/").c_str(), gateway_name, uptime(), requestToken); + snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_cloud_body, jsonChar, gateway_name, " cloud checked", " Not", (String(CLOUDGATEWAY) + "token/start").c_str(), (char*)ETH.macAddress().c_str(), ("http://" + String(TheengsUtils::ip2CharArray(ETH.localIP())) + "/").c_str(), gateway_name, uptime(), requestToken); # else - snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_cloud_body, jsonChar, gateway_name, cloudEnabled, deviceToken, (String(CLOUDGATEWAY) + "token/start").c_str(), (char*)WiFi.macAddress().c_str(), ("http://" + String(ip2CharArray(WiFi.localIP())) + "/").c_str(), gateway_name, uptime(), requestToken); + snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, config_cloud_body, jsonChar, gateway_name, cloudEnabled, deviceToken, (String(CLOUDGATEWAY) + "token/start").c_str(), (char*)WiFi.macAddress().c_str(), ("http://" + String(TheengsUtils::ip2CharArray(WiFi.localIP())) + "/").c_str(), gateway_name, uptime(), requestToken); # endif response += String(buffer); snprintf(buffer, WEB_TEMPLATE_BUFFER_MAX_SIZE, footer, OMG_VERSION); @@ -1686,7 +1686,7 @@ void WebUILoop() { void MQTTtoWebUI(char* topicOri, JsonObject& WebUIdata) { // json object decoding bool success = false; - if (cmpToMainTopic(topicOri, subjectMQTTtoWebUIset)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoWebUIset)) { WEBUI_TRACE_LOG(F("MQTTtoWebUI json set" CR)); // properties if (WebUIdata.containsKey("displayMetric")) { diff --git a/main/main.ino b/main/main.ino index fa4c3a6..246b397 100644 --- a/main/main.ino +++ b/main/main.ino @@ -85,6 +85,8 @@ bool ready_to_sleep = false; #include +#include "TheengsUtils.h" + struct JsonBundle { StaticJsonDocument doc; }; @@ -372,85 +374,6 @@ void Config_update(JsonObject& data, const char* key, T& var) { } } -void revert_hex_data(const char* in, char* out, int l) { - //reverting array 2 by 2 to get the data in good order - int i = l - 2, j = 0; - while (i != -2) { - if (i % 2 == 0) - out[j] = in[i + 1]; - else - out[j] = in[i - 1]; - j++; - i--; - } - out[l - 1] = '\0'; -} - -/** - * Retrieve an unsigned long value from a char array extract representing hexadecimal data, reversed or not, - * This value can represent a negative value if canBeNegative is set to true - */ -long value_from_hex_data(const char* service_data, int offset, int data_length, bool reverse, bool canBeNegative = true) { - char data[data_length + 1]; - memcpy(data, &service_data[offset], data_length); - data[data_length] = '\0'; - long value; - if (reverse) { - // reverse data order - char rev_data[data_length + 1]; - revert_hex_data(data, rev_data, data_length + 1); - value = strtol(rev_data, NULL, 16); - } else { - value = strtol(data, NULL, 16); - } - if (value > 65000 && data_length <= 4 && canBeNegative) - value = value - 65535; - Log.trace(F("value %D" CR), value); - return value; -} - -/* - rounds a number to 2 decimal places - example: round(3.14159) -> 3.14 -*/ -double round2(double value) { - return (int)(value * 100 + 0.5) / 100.0; -} - -/* -From an hexa char array ("A220EE...") to a byte array (half the size) - */ -bool _hexToRaw(const char* in, byte* out, int rawSize) { - if (strlen(in) != rawSize * 2) - return false; - char tmp[3] = {0}; - for (unsigned char p = 0; p < rawSize; p++) { - memcpy(tmp, &in[p * 2], 2); - out[p] = strtol(tmp, NULL, 16); - } - return true; -} - -/* -From a byte array to an hexa char array ("A220EE...", double the size) - */ -bool _rawToHex(byte* in, char* out, int rawSize) { - for (unsigned char p = 0; p < rawSize; p++) { - sprintf_P(&out[p * 2], PSTR("%02X" CR), in[p]); - } - return true; -} - -char* ip2CharArray(IPAddress ip) { //from Nick Lee https://stackoverflow.com/questions/28119653/arduino-display-ethernet-localip - static char a[16]; - sprintf(a, "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); - return a; -} - -bool to_bool(String const& s) { // thanks Chris Jester-Young from stackoverflow - return s != "0"; -} - /* * Dispatch json messages towards the communication layer * @@ -458,10 +381,10 @@ bool to_bool(String const& s) { // thanks Chris Jester-Young from stackoverflow void jsonDispatch(JsonObject& data) { if (data.containsKey("origin")) { #if message_UTCtimestamp == true - data["UTCtime"] = UTCtimestamp(); + data["UTCtime"] = TheengsUtils::UTCtimestamp(); #endif #if message_unixtimestamp == true - data["unixtime"] = unixtimestamp(); + data["unixtime"] = TheengsUtils::unixtimestamp(); #endif pubWebUI((char*)data["origin"].as(), data); if (SYSConfig.mqtt && !SYSConfig.offline) { @@ -649,7 +572,7 @@ void pub(const char* topicori, JsonObject& data) { # else uint64_t value = data["value"]; if (value != 0) { - topic = topic + "/" + toString(value); + topic = topic + "/" + TheengsUtils::toString(value); } # endif #endif @@ -826,37 +749,6 @@ void pubMQTT(String topic, unsigned long payload) { pubMQTT(topic.c_str(), val); } -/* -* @brief Convert the spaces of the certificate into new lines -*/ -std::string processCert(const char* cert) { - std::string certStr(cert); - size_t pos = 0; - while ((pos = certStr.find(' ', pos)) != std::string::npos) { - if (pos < 4 || (pos >= 27 && pos <= certStr.length() - 25) || pos >= certStr.length() - 4) { - certStr.replace(pos, 1, "\n"); - } - pos++; - } - return certStr; -} - -bool cmpToMainTopic(const char* topicOri, const char* toAdd) { - // Is string "" equal to ""? - // Compare first part with first chunk - if (strncmp(topicOri, mqtt_topic, strlen(mqtt_topic)) != 0) - return false; - // Move pointer of sizeof chunk - topicOri += strlen(mqtt_topic); - // And so on... - if (strncmp(topicOri, gateway_name, strlen(gateway_name)) != 0) - return false; - topicOri += strlen(gateway_name); - if (strncmp(topicOri, toAdd, strlen(toAdd)) != 0) - return false; - return true; -} - void delayWithOTA(long waitMillis) { long waitStep = 100; for (long waitedMillis = 0; waitedMillis < waitMillis; waitedMillis += waitStep) { @@ -2298,17 +2190,17 @@ void setupwifi(bool reset_settings) { cnt_parameters_array[cnt_index].isConnectionSecure = *custom_mqtt_secure.getValue(); cnt_parameters_array[cnt_index].isCertValidate = *custom_validate_cert.getValue(); if (strlen(custom_mqtt_cert.getValue()) > MIN_CERT_LENGTH) { - cnt_parameters_array[cnt_index].server_cert = processCert(custom_mqtt_cert.getValue()); + cnt_parameters_array[cnt_index].server_cert = TheengsUtils::processCert(custom_mqtt_cert.getValue()); } if (strlen(custom_ota_server_cert.getValue()) > MIN_CERT_LENGTH) { - cnt_parameters_array[cnt_index].ota_server_cert = processCert(custom_ota_server_cert.getValue()); + cnt_parameters_array[cnt_index].ota_server_cert = TheengsUtils::processCert(custom_ota_server_cert.getValue()); } # if MQTT_SECURE_SIGNED_CLIENT if (strlen(custom_client_cert.getValue()) > MIN_CERT_LENGTH) { - cnt_parameters_array[cnt_index].client_cert = processCert(custom_client_cert.getValue()); + cnt_parameters_array[cnt_index].client_cert = TheengsUtils::processCert(custom_client_cert.getValue()); } if (strlen(custom_client_key.getValue()) > MIN_CERT_LENGTH) { - cnt_parameters_array[cnt_index].client_key = processCert(custom_client_key.getValue()); + cnt_parameters_array[cnt_index].client_key = TheengsUtils::processCert(custom_client_key.getValue()); } # endif # endif @@ -2503,7 +2395,7 @@ void loop() { } if (now > (timer_sys_checks + (TimeBetweenCheckingSYS * 1000)) || !timer_sys_checks) { #if message_UTCtimestamp || message_unixtimestamp - syncNTP(); + TheengsUtils::syncNTP(); #endif if (!timer_sys_checks) { // Update check at start up only #if defined(ESP32) && defined(MQTT_HTTPS_FW_UPDATE) @@ -2697,34 +2589,6 @@ float intTemperatureRead() { } #endif -void syncNTP() { - configTime(0, 0, NTP_SERVER); - time_t now = time(nullptr); - uint8_t count = 0; - Log.trace(F("Waiting for NTP time sync" CR)); - while ((now < 8 * 3600 * 2) && count++ < 60) { - delay(500); - now = time(nullptr); - } - - if (count >= 60) { - Log.error(F("Unable to update - invalid time" CR)); - return; - } -} - -int unixtimestamp() { - return time(nullptr); -} - -String UTCtimestamp() { - time_t now; - time(&now); - char buffer[sizeof "yyyy-MM-ddThh:mm:ssZ"]; - strftime(buffer, sizeof buffer, "%FT%TZ", gmtime(&now)); - return buffer; -} - /* Erase flash and restart the ESP */ @@ -2783,7 +2647,7 @@ String stateMeasures() { minFreeMem = ESP.getMinFreeHeap(); SYSdata["minmem"] = minFreeMem; # ifndef NO_INT_TEMP_READING - SYSdata["tempc"] = round2(intTemperatureRead()); + SYSdata["tempc"] = TheengsUtils::round2(intTemperatureRead()); # endif SYSdata["freestck"] = uxTaskGetStackHighWaterMark(NULL); SYSdata["powermode"] = SYSConfig.powerMode; @@ -2793,7 +2657,7 @@ String stateMeasures() { if (ethConnected) { #ifdef ESP32_ETHERNET SYSdata["mac"] = (char*)ETH.macAddress().c_str(); - SYSdata["ip"] = ip2CharArray(ETH.localIP()); + SYSdata["ip"] = TheengsUtils::ip2CharArray(ETH.localIP()); ETH.fullDuplex() ? SYSdata["fd"] = (bool)"true" : SYSdata["fd"] = (bool)"false"; SYSdata["linkspeed"] = (int)ETH.linkSpeed(); #endif @@ -2801,7 +2665,7 @@ String stateMeasures() { SYSdata["rssi"] = (long)WiFi.RSSI(); SYSdata["SSID"] = (char*)WiFi.SSID().c_str(); SYSdata["BSSID"] = (char*)WiFi.BSSIDstr().c_str(); - SYSdata["ip"] = ip2CharArray(WiFi.localIP()); + SYSdata["ip"] = TheengsUtils::ip2CharArray(WiFi.localIP()); SYSdata["mac"] = (char*)WiFi.macAddress().c_str(); } #ifdef ZboardM5STACK @@ -3152,7 +3016,7 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) { jsondata["origin"] = subjectRLStoMQTT; enqueueJsonObject(jsondata); - std::string ota_cert = processCert(HttpsFwUpdateData["ota_server_cert"] | ""); + std::string ota_cert = TheengsUtils::processCert(HttpsFwUpdateData["ota_server_cert"] | ""); Log.notice(F("OTA cert: %s" CR), ota_cert.c_str()); if (ota_cert.length() < MIN_CERT_LENGTH && !strstr(url, "http:")) { # if !MQTT_BROKER_MODE @@ -3189,7 +3053,7 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) { } else # endif { - syncNTP(); + TheengsUtils::syncNTP(); } # ifdef ESP32 @@ -3284,7 +3148,7 @@ void readCntParameters(int index) { #endif void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding - if (cmpToMainTopic(topicOri, subjectMQTTtoSYSset)) { + if (TheengsUtils::cmpToMainTopic(topicOri, subjectMQTTtoSYSset)) { bool restartESP = false; Log.trace(F("MQTTtoSYS json" CR)); if (SYSdata.containsKey("cmd")) { @@ -3303,7 +3167,7 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding #ifdef RGB_INDICATORS if (SYSdata.containsKey("rgbb") && SYSdata["rgbb"].is()) { if (SYSdata["rgbb"] >= 0 && SYSdata["rgbb"] <= 255) { - SYSConfig.rgbbrightness = round2(SYSdata["rgbb"]); + SYSConfig.rgbbrightness = TheengsUtils::round2(SYSdata["rgbb"]); leds.setBrightness(SYSConfig.rgbbrightness); leds.show(); # ifdef ZactuatorONOFF @@ -3441,22 +3305,22 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding // Copy the certs to the memory if (SYSdata.containsKey("mqtt_server_cert") && SYSdata["mqtt_server_cert"].is()) { - cnt_parameters_array[cnt_index].server_cert = processCert(SYSdata["mqtt_server_cert"].as()); + cnt_parameters_array[cnt_index].server_cert = TheengsUtils::processCert(SYSdata["mqtt_server_cert"].as()); Log.trace(F("Assigning server cert %s" CR), generateHash(cnt_parameters_array[cnt_index].server_cert).c_str()); cnt_parameters_array[cnt_index].validConnection = false; } if (SYSdata.containsKey("mqtt_client_cert") && SYSdata["mqtt_client_cert"].is()) { - cnt_parameters_array[cnt_index].client_cert = processCert(SYSdata["mqtt_client_cert"].as()); + cnt_parameters_array[cnt_index].client_cert = TheengsUtils::processCert(SYSdata["mqtt_client_cert"].as()); Log.trace(F("Assigning client cert %s" CR), generateHash(cnt_parameters_array[cnt_index].client_cert).c_str()); cnt_parameters_array[cnt_index].validConnection = false; } if (SYSdata.containsKey("mqtt_client_key") && SYSdata["mqtt_client_key"].is()) { - cnt_parameters_array[cnt_index].client_key = processCert(SYSdata["mqtt_client_key"].as()); + cnt_parameters_array[cnt_index].client_key = TheengsUtils::processCert(SYSdata["mqtt_client_key"].as()); Log.trace(F("Assigning client key %s" CR), generateHash(cnt_parameters_array[cnt_index].client_key).c_str()); cnt_parameters_array[cnt_index].validConnection = false; } if (SYSdata.containsKey("ota_server_cert") && SYSdata["ota_server_cert"].is()) { - cnt_parameters_array[cnt_index].ota_server_cert = processCert(SYSdata["ota_server_cert"].as()); + cnt_parameters_array[cnt_index].ota_server_cert = TheengsUtils::processCert(SYSdata["ota_server_cert"].as()); Log.trace(F("Assigning OTA server cert %s" CR), generateHash(cnt_parameters_array[cnt_index].ota_server_cert).c_str()); } @@ -3534,30 +3398,3 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding } } } - -#if valueAsATopic && !defined(ZgatewayPilight) -String toString(uint64_t input) { - String result = ""; - uint8_t base = 10; - - do { - char c = input % base; - input /= base; - - if (c < 10) - c += '0'; - else - c += 'A' - 10; - result = c + result; - } while (input); - return result; -} - -#else - -String toString(uint32_t input) { - String result = String(input); - - return result; -} -#endif