From cbbb52d32ac40a9c5672673fc95c4420ee899f7f Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 22 Feb 2022 21:05:34 +0100 Subject: [PATCH] Some cleanup and buffer sharing --- src/AmsDataStorage.cpp | 30 ++++++++++++++--------------- src/AmsToMqttBridge.ino | 19 +++++++++--------- src/EnergyAccounting.cpp | 6 +++--- src/mqtt/AmsMqttHandler.h | 5 ++++- src/mqtt/DomoticzMqttHandler.h | 6 +----- src/mqtt/HomeAssistantMqttHandler.h | 7 +------ src/mqtt/JsonMqttHandler.cpp | 11 ++++------- src/mqtt/JsonMqttHandler.h | 6 +----- src/mqtt/RawMqttHandler.h | 4 +--- src/web/AmsWebServer.cpp | 22 +++++++++------------ src/web/AmsWebServer.h | 2 +- 11 files changed, 49 insertions(+), 69 deletions(-) diff --git a/src/AmsDataStorage.cpp b/src/AmsDataStorage.cpp index 4aaddc98..1b0ffa9a 100644 --- a/src/AmsDataStorage.cpp +++ b/src/AmsDataStorage.cpp @@ -21,7 +21,7 @@ bool AmsDataStorage::update(AmsData* data) { } time_t now = time(nullptr); - if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Time is: %d\n", now); + if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Time is: %lld\n", (int64_t) now); if(tz == NULL) { if(debugger->isActive(RemoteDebug::VERBOSE)) debugger->printf("(AmsDataStorage) Timezone is missing\n"); return false; @@ -30,18 +30,18 @@ bool AmsDataStorage::update(AmsData* data) { if(data->getMeterTimestamp() > BUILD_EPOCH) { now = data->getMeterTimestamp(); if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Using meter timestamp, which is: %d\n", now); + debugger->printf("(AmsDataStorage) Using meter timestamp, which is: %lld\n", (int64_t) now); } } else if(data->getPackageTimestamp() > BUILD_EPOCH) { now = data->getPackageTimestamp(); if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Using package timestamp, which is: %d\n", now); + debugger->printf("(AmsDataStorage) Using package timestamp, which is: %lld\n", (int64_t) now); } } } if(now < BUILD_EPOCH) { if(debugger->isActive(RemoteDebug::VERBOSE)) { - debugger->printf("(AmsDataStorage) Invalid time: %d\n", now); + debugger->printf("(AmsDataStorage) Invalid time: %lld\n", (int64_t) now); } return false; } @@ -63,7 +63,7 @@ bool AmsDataStorage::update(AmsData* data) { return true; } else { if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Last day update: %d\n", day.lastMeterReadTime); + debugger->printf("(AmsDataStorage) Last day update: %lld\n", (int64_t) day.lastMeterReadTime); } tmElements_t last; breakTime(day.lastMeterReadTime, last); @@ -85,7 +85,7 @@ bool AmsDataStorage::update(AmsData* data) { month.lastMeterReadTime = now; } else { if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Last month update: %d\n", month.lastMeterReadTime); + debugger->printf("(AmsDataStorage) Last month update: %lld\n", (int64_t) month.lastMeterReadTime); } tmElements_t last; breakTime(tz->toLocal(month.lastMeterReadTime), last); @@ -147,7 +147,7 @@ bool AmsDataStorage::update(AmsData* data) { setHour(last.Hour, val); if(debugger->isActive(RemoteDebug::INFO)) { - debugger->printf("(AmsDataStorage) Estimated usage for hour %u: %.1f (%lu)\n", last.Hour, val, cur); + debugger->printf("(AmsDataStorage) Estimated usage for hour %u: %.1f (%lld)\n", last.Hour, val, (int64_t) cur); } day.activeImport += ipm * minutes; @@ -200,7 +200,7 @@ bool AmsDataStorage::update(AmsData* data) { breakTime(tz->toLocal(month.lastMeterReadTime), last); month.lastMeterReadTime = month.lastMeterReadTime - (last.Hour * 3600) - (last.Minute * 60) - last.Second; if(debugger->isActive(RemoteDebug::DEBUG)) { - debugger->printf("(AmsDataStorage) Last month read after resetting to midnight: %lu\n", month.lastMeterReadTime); + debugger->printf("(AmsDataStorage) Last month read after resetting to midnight: %lld\n", (int64_t) month.lastMeterReadTime); } time_t stopAt = now - (ltz.Hour * 3600) - (ltz.Minute * 60) - ltz.Second; @@ -213,7 +213,7 @@ bool AmsDataStorage::update(AmsData* data) { setDay(last.Day, val); if(debugger->isActive(RemoteDebug::INFO)) { - debugger->printf("(AmsDataStorage) Estimated usage for day %u: %.1f (%lu)\n", last.Day, val, cur); + debugger->printf("(AmsDataStorage) Estimated usage for day %u: %.1f (%lld)\n", last.Day, val, (int64_t) cur); } month.activeImport += iph * hours; @@ -289,7 +289,7 @@ bool AmsDataStorage::save() { File file = LittleFS.open(FILE_DAYPLOT, "w"); char buf[sizeof(day)]; memcpy(buf, &day, sizeof(day)); - for(int i = 0; i < sizeof(day); i++) { + for(unsigned long i = 0; i < sizeof(day); i++) { file.write(buf[i]); } file.close(); @@ -298,7 +298,7 @@ bool AmsDataStorage::save() { File file = LittleFS.open(FILE_MONTHPLOT, "w"); char buf[sizeof(month)]; memcpy(buf, &month, sizeof(month)); - for(int i = 0; i < sizeof(month); i++) { + for(unsigned long i = 0; i < sizeof(month); i++) { file.write(buf[i]); } file.close(); @@ -342,11 +342,11 @@ bool AmsDataStorage::isDayHappy() { tmElements_t tm, last; if(now < day.lastMeterReadTime) { - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(AmsDataStorage) Day %lu < %lu\n", now, day.lastMeterReadTime); + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(AmsDataStorage) Day %lld < %lld\n", (int64_t) now, (int64_t) day.lastMeterReadTime); return false; } if(now-day.lastMeterReadTime > 3600) { - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(AmsDataStorage) Day %lu - %lu > 3600\n", now, day.lastMeterReadTime); + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(AmsDataStorage) Day %lld - %lld > 3600\n", (int64_t) now, (int64_t) day.lastMeterReadTime); return false; } breakTime(tz->toLocal(now), tm); @@ -370,11 +370,11 @@ bool AmsDataStorage::isMonthHappy() { tmElements_t tm, last; if(now < month.lastMeterReadTime) { - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(AmsDataStorage) Month %lu < %lu\n", now, month.lastMeterReadTime); + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(AmsDataStorage) Month %lld < %lld\n", (int64_t) now, (int64_t) month.lastMeterReadTime); return false; } if(now-month.lastMeterReadTime > 86400) { - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(AmsDataStorage) Month %lu - %lu > 3600\n", now, month.lastMeterReadTime); + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(AmsDataStorage) Month %lld - %lld > 3600\n", (int64_t) now, (int64_t) month.lastMeterReadTime); return false; } breakTime(tz->toLocal(now), tm); diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index f217daad..7393b61e 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -54,6 +54,8 @@ ADC_MODE(ADC_VCC); #include "IEC6205621.h" #include "IEC6205675.h" +uint8_t buf[BUF_SIZE]; + HwTools hw; DNSServer* dnsServer = NULL; @@ -66,7 +68,7 @@ EntsoeApi* eapi = NULL; Timezone* tz; -AmsWebServer ws(&Debug, &hw); +AmsWebServer ws(buf, &Debug, &hw); MQTTClient *mqtt = NULL; WiFiClient *mqttClient = new WiFiClient(); @@ -738,12 +740,10 @@ void swapWifiMode() { } int len = 0; -uint8_t* buf = NULL; MbusAssembler* ma = NULL; int currentMeterType = -1; bool readHanPort() { if(!hanSerial->available()) return false; - if(buf == NULL) buf = (uint8_t*) malloc(BUF_SIZE); if(currentMeterType == -1) { hanSerial->readBytes(buf, BUF_SIZE); @@ -1151,19 +1151,19 @@ void MQTT_connect() { switch(mqttConfig.payloadFormat) { case 0: - mqttHandler = new JsonMqttHandler(mqtt, mqttConfig.clientId, mqttConfig.publishTopic, &hw); + mqttHandler = new JsonMqttHandler(mqtt, (char*) buf, mqttConfig.clientId, mqttConfig.publishTopic, &hw); break; case 1: case 2: - mqttHandler = new RawMqttHandler(mqtt, mqttConfig.publishTopic, mqttConfig.payloadFormat == 2); + mqttHandler = new RawMqttHandler(mqtt, (char*) buf, mqttConfig.publishTopic, mqttConfig.payloadFormat == 2); break; case 3: DomoticzConfig domo; config.getDomoticzConfig(domo); - mqttHandler = new DomoticzMqttHandler(mqtt, domo); + mqttHandler = new DomoticzMqttHandler(mqtt, (char*) buf, domo); break; case 4: - mqttHandler = new HomeAssistantMqttHandler(mqtt, mqttConfig.clientId, mqttConfig.publishTopic, &hw); + mqttHandler = new HomeAssistantMqttHandler(mqtt, (char*) buf, mqttConfig.clientId, mqttConfig.publishTopic, &hw); break; } @@ -1245,9 +1245,8 @@ void MQTT_connect() { debugE("Failed to connect to MQTT: %d", mqtt->lastError()); #if defined(ESP8266) if(mqttSecureClient) { - char buf[64]; - mqttSecureClient->getLastSSLError(buf,64); - Debug.println(buf); + mqttSecureClient->getLastSSLError((char*) buf, BUF_SIZE); + Debug.println((char*) buf); } #endif } diff --git a/src/EnergyAccounting.cpp b/src/EnergyAccounting.cpp index 28231213..90664509 100644 --- a/src/EnergyAccounting.cpp +++ b/src/EnergyAccounting.cpp @@ -38,7 +38,7 @@ bool EnergyAccounting::update(AmsData* amsData) { if(!init) { currentHour = local.Hour; currentDay = local.Day; - if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EnergyAccounting) Initializing data at %lu\n", now); + if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EnergyAccounting) Initializing data at %lld\n", (int64_t) now); if(!load()) { if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EnergyAccounting) Unable to load existing data"); data = { 1, local.Month, 0, 0, 0, 0 }; @@ -48,7 +48,7 @@ bool EnergyAccounting::update(AmsData* amsData) { } if(!initPrice && eapi != NULL && eapi->getValueForHour(0) != ENTSOE_NO_VALUE) { - if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EnergyAccounting) Initializing prices at %lu\n", now); + if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EnergyAccounting) Initializing prices at %lld\n", (int64_t) now); calcDayCost(); } @@ -246,7 +246,7 @@ bool EnergyAccounting::save() { File file = LittleFS.open(FILE_ENERGYACCOUNTING, "w"); char buf[sizeof(data)]; memcpy(buf, &data, sizeof(data)); - for(int i = 0; i < sizeof(data); i++) { + for(unsigned long i = 0; i < sizeof(data); i++) { file.write(buf[i]); } file.close(); diff --git a/src/mqtt/AmsMqttHandler.h b/src/mqtt/AmsMqttHandler.h index 10272f7a..e5364e4e 100644 --- a/src/mqtt/AmsMqttHandler.h +++ b/src/mqtt/AmsMqttHandler.h @@ -11,8 +11,9 @@ class AmsMqttHandler { public: - AmsMqttHandler(MQTTClient* mqtt) { + AmsMqttHandler(MQTTClient* mqtt, char* buf) { this->mqtt = mqtt; + this->json = buf; }; virtual bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea); @@ -22,6 +23,8 @@ public: protected: MQTTClient* mqtt; + char* json; + uint16_t BufferSize = 1024; }; #endif diff --git a/src/mqtt/DomoticzMqttHandler.h b/src/mqtt/DomoticzMqttHandler.h index 8c15a93c..145bffe5 100644 --- a/src/mqtt/DomoticzMqttHandler.h +++ b/src/mqtt/DomoticzMqttHandler.h @@ -6,21 +6,17 @@ class DomoticzMqttHandler : public AmsMqttHandler { public: - DomoticzMqttHandler(MQTTClient* mqtt, DomoticzConfig config) : AmsMqttHandler(mqtt) { + DomoticzMqttHandler(MQTTClient* mqtt, char* buf, DomoticzConfig config) : AmsMqttHandler(mqtt, buf) { this->config = config; - this->json = (char*) malloc(BufferSize); }; bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea); bool publishTemperatures(AmsConfiguration*, HwTools*); bool publishPrices(EntsoeApi*); bool publishSystem(HwTools*); - static const uint16_t BufferSize = 192; - private: DomoticzConfig config; int energy = 0.0; - char* json; }; #endif diff --git a/src/mqtt/HomeAssistantMqttHandler.h b/src/mqtt/HomeAssistantMqttHandler.h index 2f1765ad..bbb1dd4f 100644 --- a/src/mqtt/HomeAssistantMqttHandler.h +++ b/src/mqtt/HomeAssistantMqttHandler.h @@ -5,19 +5,16 @@ class HomeAssistantMqttHandler : public AmsMqttHandler { public: - HomeAssistantMqttHandler(MQTTClient* mqtt, const char* clientId, const char* topic, HwTools* hw) : AmsMqttHandler(mqtt) { + HomeAssistantMqttHandler(MQTTClient* mqtt, char* buf, const char* clientId, const char* topic, HwTools* hw) : AmsMqttHandler(mqtt, buf) { this->clientId = clientId; this->topic = String(topic); this->hw = hw; - this->json = (char*) malloc(BufferSize); }; bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea); bool publishTemperatures(AmsConfiguration*, HwTools*); bool publishPrices(EntsoeApi*); bool publishSystem(HwTools*); - static const uint16_t BufferSize = 768; - private: static const uint8_t sensors = 17; String topics[sensors] = {"/state", "/state", "/state", "/power", "/power", "/power", "/power", "/power", "/power", "/power", "/power", "/power", "/power", "/energy", "/energy", "/energy", "/energy"}; @@ -44,7 +41,5 @@ private: String topic; HwTools* hw; uint8_t sequence = 0, listType = 0; - char* json; - }; #endif diff --git a/src/mqtt/JsonMqttHandler.cpp b/src/mqtt/JsonMqttHandler.cpp index 046c67fd..b1c67c0f 100644 --- a/src/mqtt/JsonMqttHandler.cpp +++ b/src/mqtt/JsonMqttHandler.cpp @@ -127,15 +127,12 @@ bool JsonMqttHandler::publishTemperatures(AmsConfiguration* config, HwTools* hw) if(count < 2) return false; - int size = 32 + (count * 26); - - char buf[size]; - snprintf(buf, 24, "{\"temperatures\":{"); + snprintf(json, 24, "{\"temperatures\":{"); for(int i = 0; i < count; i++) { TempSensorData* data = hw->getTempSensorData(i); if(data != NULL) { - char* pos = buf+strlen(buf); + char* pos = json+strlen(json); snprintf(pos, 26, "\"%s\":%.2f,", toHex(data->address, 8).c_str(), data->lastRead @@ -144,9 +141,9 @@ bool JsonMqttHandler::publishTemperatures(AmsConfiguration* config, HwTools* hw) delay(1); } } - char* pos = buf+strlen(buf); + char* pos = json+strlen(json); snprintf(count == 0 ? pos : pos-1, 8, "}}"); - return mqtt->publish(topic, buf); + return mqtt->publish(topic, json); } bool JsonMqttHandler::publishPrices(EntsoeApi* eapi) { diff --git a/src/mqtt/JsonMqttHandler.h b/src/mqtt/JsonMqttHandler.h index 5c84ce8d..b799bbbe 100644 --- a/src/mqtt/JsonMqttHandler.h +++ b/src/mqtt/JsonMqttHandler.h @@ -5,24 +5,20 @@ class JsonMqttHandler : public AmsMqttHandler { public: - JsonMqttHandler(MQTTClient* mqtt, const char* clientId, const char* topic, HwTools* hw) : AmsMqttHandler(mqtt) { + JsonMqttHandler(MQTTClient* mqtt, char* buf, const char* clientId, const char* topic, HwTools* hw) : AmsMqttHandler(mqtt, buf) { this->clientId = clientId; this->topic = String(topic); this->hw = hw; - this->json = (char*) malloc(BufferSize); }; bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea); bool publishTemperatures(AmsConfiguration*, HwTools*); bool publishPrices(EntsoeApi*); bool publishSystem(HwTools*); - static const uint16_t BufferSize = 768; - private: String clientId; String topic; HwTools* hw; bool init = false; - char* json; }; #endif diff --git a/src/mqtt/RawMqttHandler.h b/src/mqtt/RawMqttHandler.h index 1cb8bf22..091103cb 100644 --- a/src/mqtt/RawMqttHandler.h +++ b/src/mqtt/RawMqttHandler.h @@ -5,7 +5,7 @@ class RawMqttHandler : public AmsMqttHandler { public: - RawMqttHandler(MQTTClient* mqtt, const char* topic, bool full) : AmsMqttHandler(mqtt) { + RawMqttHandler(MQTTClient* mqtt, char* buf, const char* topic, bool full) : AmsMqttHandler(mqtt, buf) { this->topic = String(topic); this->full = full; }; @@ -14,8 +14,6 @@ public: bool publishPrices(EntsoeApi*); bool publishSystem(HwTools*); - static const uint16_t BufferSize = 128; - private: String topic; bool full; diff --git a/src/web/AmsWebServer.cpp b/src/web/AmsWebServer.cpp index 156eb4f3..13a9f86d 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -52,10 +52,10 @@ #include "base64.h" -AmsWebServer::AmsWebServer(RemoteDebug* Debug, HwTools* hw) { +AmsWebServer::AmsWebServer(uint8_t* buf, RemoteDebug* Debug, HwTools* hw) { this->debugger = Debug; this->hw = hw; - this->json = (char*) malloc(JsonSize); + this->json = (char*) buf; } void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, MeterConfig* meterConfig, AmsData* meterState, AmsDataStorage* ds, EnergyAccounting* ea) { @@ -66,12 +66,11 @@ void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, Meter this->ds = ds; this->ea = ea; - char jsuri[32]; - snprintf(jsuri, 32, "/application-%s.js", VERSION); + snprintf(json, 32, "/application-%s.js", VERSION); server.on("/", HTTP_GET, std::bind(&AmsWebServer::indexHtml, this)); server.on("/", HTTP_POST, std::bind(&AmsWebServer::handleSetup, this)); - server.on(jsuri, HTTP_GET, std::bind(&AmsWebServer::applicationJs, this)); + server.on(json, HTTP_GET, std::bind(&AmsWebServer::applicationJs, this)); server.on("/temperature", HTTP_GET, std::bind(&AmsWebServer::temperature, this)); server.on("/temperature", HTTP_POST, std::bind(&AmsWebServer::temperaturePost, this)); server.on("/temperature.json", HTTP_GET, std::bind(&AmsWebServer::temperatureJson, this)); @@ -240,17 +239,14 @@ void AmsWebServer::temperatureJson() { return; int count = hw->getTempSensorCount(); - int size = 16 + (count * 72); - - char buf[size]; - snprintf(buf, 16, "{\"c\":%d,\"s\":[", count); + snprintf(json, 16, "{\"c\":%d,\"s\":[", count); for(int i = 0; i < count; i++) { TempSensorData* data = hw->getTempSensorData(i); if(data == NULL) continue; TempSensorConfig* conf = config->getTempSensorConfig(data->address); - char* pos = buf+strlen(buf); + char* pos = json+strlen(json); snprintf_P(pos, 72, TEMPSENSOR_JSON, i, toHex(data->address, 8).c_str(), @@ -260,15 +256,15 @@ void AmsWebServer::temperatureJson() { ); delay(10); } - char* pos = buf+strlen(buf); + char* pos = json+strlen(json); snprintf(count == 0 ? pos : pos-1, 8, "]}"); server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); server.sendHeader("Pragma", "no-cache"); server.sendHeader("Expires", "-1"); - server.setContentLength(strlen(buf)); - server.send(200, "application/json", buf); + server.setContentLength(strlen(json)); + server.send(200, "application/json", json); } void AmsWebServer::price() { diff --git a/src/web/AmsWebServer.h b/src/web/AmsWebServer.h index a51b3d22..0a6430f3 100644 --- a/src/web/AmsWebServer.h +++ b/src/web/AmsWebServer.h @@ -31,7 +31,7 @@ class AmsWebServer { public: - AmsWebServer(RemoteDebug* Debug, HwTools* hw); + AmsWebServer(uint8_t* buf, RemoteDebug* Debug, HwTools* hw); void setup(AmsConfiguration*, GpioConfig*, MeterConfig*, AmsData*, AmsDataStorage*, EnergyAccounting*); void loop(); void setMqtt(MQTTClient* mqtt);