diff --git a/images/dashboard.png b/images/dashboard.png new file mode 100644 index 00000000..29eb7992 Binary files /dev/null and b/images/dashboard.png differ diff --git a/images/dayplot.png b/images/dayplot.png new file mode 100644 index 00000000..6e3098e2 Binary files /dev/null and b/images/dayplot.png differ diff --git a/images/future-energy-price.png b/images/future-energy-price.png new file mode 100644 index 00000000..119ed1d6 Binary files /dev/null and b/images/future-energy-price.png differ diff --git a/images/main-header.png b/images/main-header.png new file mode 100644 index 00000000..738442a3 Binary files /dev/null and b/images/main-header.png differ diff --git a/images/monthplot.png b/images/monthplot.png new file mode 100644 index 00000000..9d6a7f4f Binary files /dev/null and b/images/monthplot.png differ diff --git a/images/real-time-calculation.png b/images/real-time-calculation.png new file mode 100644 index 00000000..e5af9129 Binary files /dev/null and b/images/real-time-calculation.png differ diff --git a/images/sensor-displays.png b/images/sensor-displays.png new file mode 100644 index 00000000..e06bf053 Binary files /dev/null and b/images/sensor-displays.png differ diff --git a/images/status-bar.png b/images/status-bar.png new file mode 100644 index 00000000..37000f73 Binary files /dev/null and b/images/status-bar.png differ diff --git a/images/tempsensors.png b/images/tempsensors.png new file mode 100644 index 00000000..7484f170 Binary files /dev/null and b/images/tempsensors.png differ diff --git a/platformio.ini b/platformio.ini index 46ead7b2..3882f6ab 100755 --- a/platformio.ini +++ b/platformio.ini @@ -30,3 +30,4 @@ extra_scripts = scripts/makeweb.py build_flags = -D WEBSOCKET_DISABLED=1 +board_build.f_cpu = 160000000L diff --git a/src/AmsData.h b/src/AmsData.h index 05d506f3..0f8c87df 100644 --- a/src/AmsData.h +++ b/src/AmsData.h @@ -69,7 +69,7 @@ protected: String listId, meterId, meterModel; time_t meterTimestamp = 0; uint16_t activeImportPower = 0, reactiveImportPower = 0, activeExportPower = 0, reactiveExportPower = 0; - double l1voltage = 0, l2voltage = 0, l3voltage = 0, l1current = 0, l2current = 0, l3current = 0; + float l1voltage = 0, l2voltage = 0, l3voltage = 0, l1current = 0, l2current = 0, l3current = 0; float powerFactor = 0, l1PowerFactor = 0, l2PowerFactor = 0, l3PowerFactor = 0; float activeImportCounter = 0, reactiveImportCounter = 0, activeExportCounter = 0, reactiveExportCounter = 0; bool threePhase = false, twoPhase = false, counterEstimated = false; diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index c3f40306..3e911c7d 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -452,31 +452,35 @@ void loop() { } #if defined(ESP32) - if(eapi != NULL && ntpEnabled) { - if(eapi->loop() && mqtt != NULL && mqttHandler != NULL && mqtt->connected()) { - mqttHandler->publishPrices(eapi); - } - } - - if(config.isEntsoeChanged()) { - EntsoeConfig entsoe; - if(config.getEntsoeConfig(entsoe) && strlen(entsoe.token) > 0) { - if(eapi == NULL) { - eapi = new EntsoeApi(&Debug); - ws.setEntsoeApi(eapi); + try { + if(eapi != NULL && ntpEnabled) { + if(eapi->loop() && mqtt != NULL && mqttHandler != NULL && mqtt->connected()) { + mqttHandler->publishPrices(eapi); } - eapi->setup(entsoe); - } else if(eapi != NULL) { - delete eapi; - eapi = NULL; - ws.setEntsoeApi(NULL); } - config.ackEntsoeChange(); + + if(config.isEntsoeChanged()) { + EntsoeConfig entsoe; + if(config.getEntsoeConfig(entsoe) && strlen(entsoe.token) > 0) { + if(eapi == NULL) { + eapi = new EntsoeApi(&Debug); + ws.setEntsoeApi(eapi); + } + eapi->setup(entsoe); + } else if(eapi != NULL) { + delete eapi; + eapi = NULL; + ws.setEntsoeApi(NULL); + } + config.ackEntsoeChange(); + } + } catch(const std::exception& e) { + debugE("Exception in ENTSO-E loop (%s)", e.what()); } #endif ws.loop(); } - if(mqtt != NULL) { // Run loop regardless, to let MQTT do its work. + if(mqtt != NULL) { mqtt->loop(); delay(10); // Needed to preserve power. After adding this, the voltage is super smooth on a HAN powered device } @@ -702,11 +706,12 @@ void swapWifiMode() { } int len = 0; -uint8_t buf[BUF_SIZE]; +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); @@ -865,17 +870,19 @@ bool readHanPort() { hw.ledBlink(LED_INTERNAL, 1); if(mqttEnabled && mqttHandler != NULL && mqtt != NULL) { if(mqttHandler->publish(&data, &meterState, &ea)) { - if(data.getListType() >= 3 && eapi != NULL) { + mqtt->loop(); + delay(10); + if(data.getListType() == 3 && eapi != NULL) { mqttHandler->publishPrices(eapi); + mqtt->loop(); + delay(10); } if(data.getListType() >= 2) { mqttHandler->publishSystem(&hw); + mqtt->loop(); + delay(10); } } - if(mqtt != NULL) { - mqtt->loop(); - delay(10); - } } time_t now = time(nullptr); diff --git a/src/IEC6205675.cpp b/src/IEC6205675.cpp index 94438a4f..619dbf08 100644 --- a/src/IEC6205675.cpp +++ b/src/IEC6205675.cpp @@ -313,16 +313,13 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distribution if(l3PowerFactor != 0) l3PowerFactor /= 100; - int adiv = 1; int watt = abs((l1voltage * l1current) + (l2voltage * l2current) + (l3voltage * l3current)); - while(watt / (activeImportPower + activeExportPower + reactiveImportPower + reactiveExportPower) > 2) { - adiv *= 10; - watt /= 10; + if(watt / (activeImportPower + activeExportPower + reactiveImportPower + reactiveExportPower) > 2) { + l1current = l1current != 0 ? l1current / 10 : 0; + l2current = l2current != 0 ? l2current / 10 : 0; + l3current = l3current != 0 ? l3current / 10 : 0; } - l1current = l1current != 0 ? l1current / adiv : 0; - l2current = l2current != 0 ? l2current / adiv : 0; - l3current = l3current != 0 ? l3current / adiv : 0; } else if(meterType == AmsTypeSagemcom) { CosemData* meterTs = getCosemDataAt(1, ((char *) (d))); if(meterTs != NULL) { @@ -359,7 +356,7 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, uint8_t distribution if(l2current == 0.0 && l1current > 0.0 && l3current > 0.0) { l2current = (((activeImportPower - activeExportPower) * sqrt(3)) - (l1voltage * l1current) - (l3voltage * l3current)) / l2voltage; if(activeExportPower == 0.0) { - l2current = max((double) 0.0, l2current); + l2current = max((float) 0.0, l2current); } } } else if(twoPhase && l1current > 0.0 && l2current > 0.0 && l3current > 0.0) { @@ -401,6 +398,7 @@ CosemData* IEC6205675::getCosemDataAt(uint8_t index, const char* ptr) { pos += 2; } i++; + if(pos-ptr > 900) break; } while(item->base.type != HDLC_FLAG); return NULL; } @@ -444,6 +442,7 @@ CosemData* IEC6205675::findObis(uint8_t* obis, int matchlength, const char* ptr) default: pos += 2; } + if(pos-ptr > 900) break; } while(item->base.type != HDLC_FLAG); return NULL; } diff --git a/src/IEC6205675.h b/src/IEC6205675.h index fabd7211..089da58c 100644 --- a/src/IEC6205675.h +++ b/src/IEC6205675.h @@ -31,26 +31,12 @@ private: uint8_t AMS_OBIS_METER_ID_2[4] = { 0, 0, 5, 255 }; uint8_t AMS_OBIS_METER_TIMESTAMP[4] = { 1, 0, 0, 255 }; uint8_t AMS_OBIS_ACTIVE_IMPORT[4] = { 1, 7, 0, 255 }; - uint8_t AMS_OBIS_ACTIVE_IMPORT_L1[4] = { 21, 7, 0, 255 }; - uint8_t AMS_OBIS_ACTIVE_IMPORT_L2[4] = { 41, 7, 0, 255 }; - uint8_t AMS_OBIS_ACTIVE_IMPORT_L3[4] = { 61, 7, 0, 255 }; uint8_t AMS_OBIS_ACTIVE_EXPORT[4] = { 2, 7, 0, 255 }; - uint8_t AMS_OBIS_ACTIVE_EXPORT_L1[4] = { 22, 7, 0, 255 }; - uint8_t AMS_OBIS_ACTIVE_EXPORT_L2[4] = { 42, 7, 0, 255 }; - uint8_t AMS_OBIS_ACTIVE_EXPORT_L3[4] = { 62, 7, 0, 255 }; uint8_t AMS_OBIS_REACTIVE_IMPORT[4] = { 3, 7, 0, 255 }; - uint8_t AMS_OBIS_REACTIVE_IMPORT_L1[4] = { 23, 7, 0, 255 }; - uint8_t AMS_OBIS_REACTIVE_IMPORT_L2[4] = { 43, 7, 0, 255 }; - uint8_t AMS_OBIS_REACTIVE_IMPORT_L3[4] = { 63, 7, 0, 255 }; uint8_t AMS_OBIS_REACTIVE_EXPORT[4] = { 4, 7, 0, 255 }; - uint8_t AMS_OBIS_REACTIVE_EXPORT_L1[4] = { 24, 7, 0, 255 }; - uint8_t AMS_OBIS_REACTIVE_EXPORT_L2[4] = { 44, 7, 0, 255 }; - uint8_t AMS_OBIS_REACTIVE_EXPORT_L3[4] = { 64, 7, 0, 255 }; - uint8_t AMS_OBIS_CURRENT[4] = { 11, 7, 0, 255 }; uint8_t AMS_OBIS_CURRENT_L1[4] = { 31, 7, 0, 255 }; uint8_t AMS_OBIS_CURRENT_L2[4] = { 51, 7, 0, 255 }; uint8_t AMS_OBIS_CURRENT_L3[4] = { 71, 7, 0, 255 }; - uint8_t AMS_OBIS_VOLTAGE[4] = { 12, 7, 0, 255 }; uint8_t AMS_OBIS_VOLTAGE_L1[4] = { 32, 7, 0, 255 }; uint8_t AMS_OBIS_VOLTAGE_L2[4] = { 52, 7, 0, 255 }; uint8_t AMS_OBIS_VOLTAGE_L3[4] = { 72, 7, 0, 255 }; diff --git a/src/entsoe/EntsoeApi.cpp b/src/entsoe/EntsoeApi.cpp index 21321287..b8b7fe0c 100644 --- a/src/entsoe/EntsoeApi.cpp +++ b/src/entsoe/EntsoeApi.cpp @@ -9,6 +9,8 @@ #endif EntsoeApi::EntsoeApi(RemoteDebug* Debug) { + this->buf = (char*) malloc(BufferSize); + debugger = Debug; client.setInsecure(); @@ -120,8 +122,7 @@ bool EntsoeApi::loop() { breakTime(e1, d1); breakTime(e2, d2); - char url[256]; - snprintf(url, sizeof(url), "%s?securityToken=%s&documentType=A44&periodStart=%04d%02d%02d%02d%02d&periodEnd=%04d%02d%02d%02d%02d&in_Domain=%s&out_Domain=%s", + snprintf(buf, BufferSize, "%s?securityToken=%s&documentType=A44&periodStart=%04d%02d%02d%02d%02d&periodEnd=%04d%02d%02d%02d%02d&in_Domain=%s&out_Domain=%s", "https://transparency.entsoe.eu/api", getToken(), d1.Year+1970, d1.Month, d1.Day, 23, 00, d2.Year+1970, d2.Month, d2.Day, 23, 00, @@ -135,9 +136,9 @@ bool EntsoeApi::loop() { if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for today\n"); - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", url); + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", buf); EntsoeA44Parser* a44 = new EntsoeA44Parser(); - if(retrieve(url, a44) && a44->getPoint(0) != ENTSOE_NO_VALUE) { + if(retrieve(buf, a44) && a44->getPoint(0) != ENTSOE_NO_VALUE) { today = a44; return true; } else if(a44 != NULL) { @@ -160,8 +161,7 @@ bool EntsoeApi::loop() { breakTime(e1, d1); breakTime(e2, d2); - char url[256]; - snprintf(url, sizeof(url), "%s?securityToken=%s&documentType=A44&periodStart=%04d%02d%02d%02d%02d&periodEnd=%04d%02d%02d%02d%02d&in_Domain=%s&out_Domain=%s", + snprintf(buf, BufferSize, "%s?securityToken=%s&documentType=A44&periodStart=%04d%02d%02d%02d%02d&periodEnd=%04d%02d%02d%02d%02d&in_Domain=%s&out_Domain=%s", "https://transparency.entsoe.eu/api", getToken(), d1.Year+1970, d1.Month, d1.Day, 23, 00, d2.Year+1970, d2.Month, d2.Day, 23, 00, @@ -174,9 +174,9 @@ bool EntsoeApi::loop() { #endif if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Fetching prices for tomorrow\n"); - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", url); + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", buf); EntsoeA44Parser* a44 = new EntsoeA44Parser(); - if(retrieve(url, a44) && a44->getPoint(0) != ENTSOE_NO_VALUE) { + if(retrieve(buf, a44) && a44->getPoint(0) != ENTSOE_NO_VALUE) { tomorrow = a44; return true; } else if(a44 != NULL) { @@ -273,7 +273,6 @@ float EntsoeApi::getCurrencyMultiplier(const char* from, const char* to) { if(now > lastCurrencyFetch && (now - lastCurrencyFetch) < 900000) { lastCurrencyFetch = now; - char url[256]; DnbCurrParser p; #if defined(ESP32) @@ -282,17 +281,17 @@ float EntsoeApi::getCurrencyMultiplier(const char* from, const char* to) { ESP.wdtFeed(); #endif - snprintf(url, sizeof(url), "https://data.norges-bank.no/api/data/EXR/M.%s.NOK.SP?lastNObservations=1", from); + snprintf(buf, BufferSize, "https://data.norges-bank.no/api/data/EXR/M.%s.NOK.SP?lastNObservations=1", from); if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Retrieving %s to NOK conversion\n", from); - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", url); - if(retrieve(url, &p)) { + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", buf); + if(retrieve(buf, &p)) { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) got exchange rate %.4f\n", p.getValue()); currencyMultiplier = p.getValue(); if(strncmp(to, "NOK", 3) != 0) { - snprintf(url, sizeof(url), "https://data.norges-bank.no/api/data/EXR/M.%s.NOK.SP?lastNObservations=1", to); + snprintf(buf, BufferSize, "https://data.norges-bank.no/api/data/EXR/M.%s.NOK.SP?lastNObservations=1", to); if(debugger->isActive(RemoteDebug::INFO)) debugger->printf("(EntsoeApi) Retrieving %s to NOK conversion\n", to); - if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", url); - if(retrieve(url, &p)) { + if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) url: %s\n", buf); + if(retrieve(buf, &p)) { if(debugger->isActive(RemoteDebug::DEBUG)) debugger->printf("(EntsoeApi) got exchange rate %.4f\n", p.getValue()); currencyMultiplier /= p.getValue(); } else { diff --git a/src/entsoe/EntsoeApi.h b/src/entsoe/EntsoeApi.h index e36a43c3..e9161ded 100644 --- a/src/entsoe/EntsoeApi.h +++ b/src/entsoe/EntsoeApi.h @@ -45,6 +45,9 @@ private: Timezone* tz = NULL; + static const uint16_t BufferSize = 256; + char* buf; + float currencyMultiplier = ENTSOE_DEFAULT_MULTIPLIER; bool retrieve(const char* url, Stream* doc); diff --git a/src/mqtt/DomoticzMqttHandler.cpp b/src/mqtt/DomoticzMqttHandler.cpp index 96bffc18..11975d34 100644 --- a/src/mqtt/DomoticzMqttHandler.cpp +++ b/src/mqtt/DomoticzMqttHandler.cpp @@ -10,8 +10,7 @@ bool DomoticzMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyA if(energy > 0.0) { char val[16]; snprintf(val, 16, "%.1f;%.1f", (data->getActiveImportPower()/1.0), energy*1000.0); - char json[192]; - snprintf_P(json, sizeof(json), DOMOTICZ_JSON, + snprintf_P(json, BufferSize, DOMOTICZ_JSON, config.elidx, val ); @@ -25,8 +24,7 @@ bool DomoticzMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyA if (config.vl1idx > 0){ char val[16]; snprintf(val, 16, "%.2f", data->getL1Voltage()); - char json[192]; - snprintf_P(json, sizeof(json), DOMOTICZ_JSON, + snprintf_P(json, BufferSize, DOMOTICZ_JSON, config.vl1idx, val ); @@ -36,8 +34,7 @@ bool DomoticzMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyA if (config.vl2idx > 0){ char val[16]; snprintf(val, 16, "%.2f", data->getL2Voltage()); - char json[192]; - snprintf_P(json, sizeof(json), DOMOTICZ_JSON, + snprintf_P(json, BufferSize, DOMOTICZ_JSON, config.vl2idx, val ); @@ -47,8 +44,7 @@ bool DomoticzMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyA if (config.vl3idx > 0){ char val[16]; snprintf(val, 16, "%.2f", data->getL3Voltage()); - char json[192]; - snprintf_P(json, sizeof(json), DOMOTICZ_JSON, + snprintf_P(json, BufferSize, DOMOTICZ_JSON, config.vl3idx, val ); @@ -58,8 +54,7 @@ bool DomoticzMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyA if (config.cl1idx > 0){ char val[16]; snprintf(val, 16, "%.1f;%.1f;%.1f", data->getL1Current(), data->getL2Current(), data->getL3Current()); - char json[192]; - snprintf_P(json, sizeof(json), DOMOTICZ_JSON, + snprintf_P(json, BufferSize, DOMOTICZ_JSON, config.cl1idx, val ); diff --git a/src/mqtt/DomoticzMqttHandler.h b/src/mqtt/DomoticzMqttHandler.h index 118a4286..8c15a93c 100644 --- a/src/mqtt/DomoticzMqttHandler.h +++ b/src/mqtt/DomoticzMqttHandler.h @@ -8,14 +8,19 @@ class DomoticzMqttHandler : public AmsMqttHandler { public: DomoticzMqttHandler(MQTTClient* mqtt, DomoticzConfig config) : AmsMqttHandler(mqtt) { 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/JsonMqttHandler.cpp b/src/mqtt/JsonMqttHandler.cpp index 53ca6562..046c67fd 100644 --- a/src/mqtt/JsonMqttHandler.cpp +++ b/src/mqtt/JsonMqttHandler.cpp @@ -13,8 +13,7 @@ bool JsonMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccou return false; if(data->getListType() == 1) { - char json[192]; - snprintf_P(json, sizeof(json), JSON1_JSON, + snprintf_P(json, BufferSize, JSON1_JSON, WiFi.macAddress().c_str(), clientId.c_str(), (uint32_t) (millis64()/1000), @@ -28,8 +27,7 @@ bool JsonMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccou ); return mqtt->publish(topic, json); } else if(data->getListType() == 2) { - char json[384]; - snprintf_P(json, sizeof(json), JSON2_JSON, + snprintf_P(json, BufferSize, JSON2_JSON, WiFi.macAddress().c_str(), clientId.c_str(), (uint32_t) (millis64()/1000), @@ -55,8 +53,7 @@ bool JsonMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccou ); return mqtt->publish(topic, json); } else if(data->getListType() == 3) { - char json[512]; - snprintf_P(json, sizeof(json), JSON3_JSON, + snprintf_P(json, BufferSize, JSON3_JSON, WiFi.macAddress().c_str(), clientId.c_str(), (uint32_t) (millis64()/1000), @@ -87,8 +84,7 @@ bool JsonMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccou ); return mqtt->publish(topic, json); } else if(data->getListType() == 4) { - char json[768]; - snprintf_P(json, sizeof(json), JSON4_JSON, + snprintf_P(json, BufferSize, JSON4_JSON, WiFi.macAddress().c_str(), clientId.c_str(), (uint32_t) (millis64()/1000), @@ -235,8 +231,7 @@ bool JsonMqttHandler::publishPrices(EntsoeApi* eapi) { sprintf(ts6hr, "%04d-%02d-%02dT%02d:00:00Z", tm.Year+1970, tm.Month, tm.Day, tm.Hour); } - char json[384]; - snprintf_P(json, sizeof(json), JSONPRICES_JSON, + snprintf_P(json, BufferSize, JSONPRICES_JSON, WiFi.macAddress().c_str(), values[0], values[1], @@ -263,8 +258,7 @@ bool JsonMqttHandler::publishSystem(HwTools* hw) { if(init || topic.isEmpty() || !mqtt->connected()) return false; - char json[192]; - snprintf_P(json, sizeof(json), JSONSYS_JSON, + snprintf_P(json, BufferSize, JSONSYS_JSON, WiFi.macAddress().c_str(), clientId.c_str(), (uint32_t) (millis64()/1000), diff --git a/src/mqtt/JsonMqttHandler.h b/src/mqtt/JsonMqttHandler.h index 65236d1c..5c84ce8d 100644 --- a/src/mqtt/JsonMqttHandler.h +++ b/src/mqtt/JsonMqttHandler.h @@ -9,16 +9,20 @@ public: 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 4880066e..1cb8bf22 100644 --- a/src/mqtt/RawMqttHandler.h +++ b/src/mqtt/RawMqttHandler.h @@ -14,6 +14,8 @@ 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 52cbde31..949689be 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -55,6 +55,7 @@ AmsWebServer::AmsWebServer(RemoteDebug* Debug, HwTools* hw) { this->debugger = Debug; this->hw = hw; + this->json = (char*) malloc(JsonSize); } void AmsWebServer::setup(AmsConfiguration* config, GpioConfig* gpioConfig, MeterConfig* meterConfig, AmsData* meterState, AmsDataStorage* ds, EnergyAccounting* ea) { @@ -786,8 +787,7 @@ void AmsWebServer::dataJson() { if(eapi != NULL && strlen(eapi->getToken()) > 0) price = eapi->getValueForHour(0); - char json[512]; - snprintf_P(json, sizeof(json), DATA_JSON, + snprintf_P(json, JsonSize, DATA_JSON, maxPwr == 0 ? meterState->isThreePhase() ? 20000 : 10000 : maxPwr, meterConfig->productionCapacity, meterConfig->mainFuse == 0 ? 32 : meterConfig->mainFuse, @@ -850,8 +850,7 @@ void AmsWebServer::dayplotJson() { if(ds == NULL) { notFound(); } else { - char json[384]; - snprintf_P(json, sizeof(json), DAYPLOT_JSON, + snprintf_P(json, JsonSize, DAYPLOT_JSON, ds->getHour(0) / 1000.0, ds->getHour(1) / 1000.0, ds->getHour(2) / 1000.0, @@ -896,8 +895,7 @@ void AmsWebServer::monthplotJson() { if(ds == NULL) { notFound(); } else { - char json[512]; - snprintf_P(json, sizeof(json), MONTHPLOT_JSON, + snprintf_P(json, JsonSize, MONTHPLOT_JSON, ds->getDay(1) / 1000.0, ds->getDay(2) / 1000.0, ds->getDay(3) / 1000.0, @@ -951,8 +949,7 @@ void AmsWebServer::energyPriceJson() { prices[i] = eapi == NULL ? ENTSOE_NO_VALUE : eapi->getValueForHour(i); } - char json[768]; - snprintf_P(json, sizeof(json), ENERGYPRICE_JSON, + snprintf_P(json, JsonSize, ENERGYPRICE_JSON, eapi == NULL ? "" : eapi->getCurrency(), prices[0] == ENTSOE_NO_VALUE ? "null" : String(prices[0], 2).c_str(), prices[1] == ENTSOE_NO_VALUE ? "null" : String(prices[1], 2).c_str(), diff --git a/src/web/AmsWebServer.h b/src/web/AmsWebServer.h index 9d0cbd4d..6fa94bbc 100644 --- a/src/web/AmsWebServer.h +++ b/src/web/AmsWebServer.h @@ -58,6 +58,9 @@ private: File file; bool performRestart = false; + static const uint16_t JsonSize = 768; + char* json; + #if defined(ESP8266) ESP8266WebServer server; #elif defined(ESP32) // ARDUINO_ARCH_ESP32 diff --git a/web/head32.html b/web/head32.html index 16f4199a..76d0ee64 100644 --- a/web/head32.html +++ b/web/head32.html @@ -30,10 +30,10 @@ width: 50%; text-align: center; } - .ipo,.xpo { + .ipo,.epo { font-size: 1.7rem; } - .ipoa,.xpoa { + .ipoa,.epoa { font-size: 1.0rem; color: grey; } diff --git a/web/head8266.html b/web/head8266.html index 14f56b06..cd5f6ba9 100644 --- a/web/head8266.html +++ b/web/head8266.html @@ -30,10 +30,10 @@ width: 50%; text-align: center; } - .ipo,.xpo { + .ipo,.epo { font-size: 1.7rem; } - .ipoa,.xpoa { + .ipoa,.epoa { font-size: 1.0rem; color: grey; } diff --git a/webui2.png b/webui2.png index 71bdb478..b39ea7a6 100644 Binary files a/webui2.png and b/webui2.png differ