From a6f3bc3f712851f1c45943f597394d164fe90dde Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 23 Aug 2022 19:49:19 +0200 Subject: [PATCH 1/4] Added version to system json --- src/mqtt/HomeAssistantMqttHandler.cpp | 3 ++- src/mqtt/JsonMqttHandler.cpp | 4 +++- web/jsonsys.json | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/mqtt/HomeAssistantMqttHandler.cpp b/src/mqtt/HomeAssistantMqttHandler.cpp index 85ad96d1..f8678796 100644 --- a/src/mqtt/HomeAssistantMqttHandler.cpp +++ b/src/mqtt/HomeAssistantMqttHandler.cpp @@ -203,7 +203,8 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw) { (uint32_t) (millis64()/1000), hw->getVcc(), hw->getWifiRssi(), - hw->getTemperature() + hw->getTemperature(), + VERSION ); mqtt->publish(topic + "/state", json); } diff --git a/src/mqtt/JsonMqttHandler.cpp b/src/mqtt/JsonMqttHandler.cpp index 82847182..132d8e32 100644 --- a/src/mqtt/JsonMqttHandler.cpp +++ b/src/mqtt/JsonMqttHandler.cpp @@ -1,4 +1,5 @@ #include "JsonMqttHandler.h" +#include "version.h" #include "hexutils.h" #include "Uptime.h" #include "web/root/json1_json.h" @@ -280,7 +281,8 @@ bool JsonMqttHandler::publishSystem(HwTools* hw) { (uint32_t) (millis64()/1000), hw->getVcc(), hw->getWifiRssi(), - hw->getTemperature() + hw->getTemperature(), + VERSION ); init = mqtt->publish(topic, json); return init; diff --git a/web/jsonsys.json b/web/jsonsys.json index 9c1bdccb..55d0b443 100644 --- a/web/jsonsys.json +++ b/web/jsonsys.json @@ -4,5 +4,6 @@ "up" : %d, "vcc" : %.3f, "rssi": %d, - "temp": %.2f + "temp": %.2f, + "version": "%s" } From a3c7a09211ba98909e5d727576a2d2f01ee5c8d5 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 23 Aug 2022 20:21:19 +0200 Subject: [PATCH 2/4] Adding peaks to data.json and MQTT RAW --- src/EnergyAccounting.cpp | 31 +++++++++++++++++++++++++++++++ src/EnergyAccounting.h | 1 + src/mqtt/RawMqttHandler.cpp | 3 +++ src/web/AmsWebServer.cpp | 11 +++++++++-- web/data.json | 1 + 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/EnergyAccounting.cpp b/src/EnergyAccounting.cpp index 4b54af21..60deaa43 100644 --- a/src/EnergyAccounting.cpp +++ b/src/EnergyAccounting.cpp @@ -260,6 +260,37 @@ float EnergyAccounting::getMonthMax() { return maxHour > 0 ? maxHour / count / 100.0 : 0.0; } +float EnergyAccounting::getPeak(uint8_t num) { + if(num < 1 || num > 5) return 0.0; + + uint8_t count = 0; + bool included[5] = { false, false, false, false, false }; + + while(count < config->hours) { + uint8_t maxIdx = 0; + uint16_t maxVal = 0; + for(uint8_t i = 0; i < 5; i++) { + if(included[i]) continue; + if(data.peaks[i].value > maxVal) { + maxVal = data.peaks[i].value; + maxIdx = i; + } + } + included[maxIdx] = true; + count++; + } + + uint8_t pos = 0; + for(uint8_t i = 0; i < 5; i++) { + if(!included[i]) continue; + pos++; + if(pos == num) { + return data.peaks[i].value / 100.0; + } + } + return 0.0; +} + bool EnergyAccounting::load() { if(!LittleFS.begin()) { if(debugger->isActive(RemoteDebug::ERROR)) { diff --git a/src/EnergyAccounting.h b/src/EnergyAccounting.h index 30a894ed..c0c76e32 100644 --- a/src/EnergyAccounting.h +++ b/src/EnergyAccounting.h @@ -57,6 +57,7 @@ public: float getMonthMax(); uint8_t getCurrentThreshold(); + float getPeak(uint8_t); EnergyAccountingData getData(); void setData(EnergyAccountingData&); diff --git a/src/mqtt/RawMqttHandler.cpp b/src/mqtt/RawMqttHandler.cpp index dffdb8a6..48f48a3f 100644 --- a/src/mqtt/RawMqttHandler.cpp +++ b/src/mqtt/RawMqttHandler.cpp @@ -74,6 +74,9 @@ bool RawMqttHandler::publish(AmsData* data, AmsData* meterState, EnergyAccountin } mqtt->publish(topic + "/realtime/import/hour", String(ea->getUseThisHour(), 3)); mqtt->publish(topic + "/realtime/import/day", String(ea->getUseToday(), 2)); + for(uint8_t i = 1; i <= ea->getConfig()->hours; i++) { + mqtt->publish(topic + "/realtime/import/peak/" + String(i, 10), String(ea->getPeak(i), 10), true, 0); + } mqtt->publish(topic + "/realtime/import/threshold", String(ea->getCurrentThreshold(), 10), true, 0); mqtt->publish(topic + "/realtime/import/monthmax", String(ea->getMonthMax(), 3), true, 0); mqtt->publish(topic + "/realtime/export/hour", String(ea->getProducedThisHour(), 3)); diff --git a/src/web/AmsWebServer.cpp b/src/web/AmsWebServer.cpp index 68f65684..c9e1e4a6 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -591,9 +591,9 @@ void AmsWebServer::configThresholdsHtml() { String html = String((const __FlashStringHelper*) THRESHOLDS_HTML); for(int i = 0; i < 9; i++) { - html.replace("{t" + String(i) + "}", String(config->thresholds[i])); + html.replace("{t" + String(i) + "}", String(config->thresholds[i], 10)); } - html.replace("{h}", String(config->hours)); + html.replace("{h}", String(config->hours, 10)); server.setContentLength(html.length() + HEAD_HTML_LEN + FOOT_HTML_LEN); server.send_P(200, MIME_HTML, HEAD_HTML); @@ -708,6 +708,12 @@ void AmsWebServer::dataJson() { if(eapi != NULL && strlen(eapi->getToken()) > 0) price = eapi->getValueForHour(0); + String peaks = ""; + for(uint8_t i = 1; i <= ea->getConfig()->hours; i++) { + if(!peaks.isEmpty()) peaks += ","; + peaks += String(ea->getPeak(i)); + } + snprintf_P(buf, BufferSize, DATA_JSON, maxPwr == 0 ? meterState->isThreePhase() ? 20000 : 10000 : maxPwr, meterConfig->productionCapacity, @@ -744,6 +750,7 @@ void AmsWebServer::dataJson() { meterState->getMeterType(), meterConfig->distributionSystem, ea->getMonthMax(), + peaks.c_str(), ea->getCurrentThreshold(), ea->getUseThisHour(), ea->getCostThisHour(), diff --git a/web/data.json b/web/data.json index 0265bb0f..0581d6ac 100644 --- a/web/data.json +++ b/web/data.json @@ -35,6 +35,7 @@ "ds" : %d, "ea" : { "x" : %.1f, + "p" : [ %s ], "t" : %d, "h" : { "u" : %.2f, From f18171fecc85b483199bb4bcdfc7573cb4091c6a Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 23 Aug 2022 20:39:47 +0200 Subject: [PATCH 3/4] Fixed MQTT byte mode --- src/AmsToMqttBridge.ino | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index 77261984..a10be9ac 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -835,6 +835,7 @@ bool readHanPort() { len += hanSerial->readBytes(hanBuffer+len, BUF_SIZE_HAN-len); if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) { mqtt->publish(topic.c_str(), toHex(hanBuffer+pos, len)); + mqtt->loop(); } while(hanSerial->available()) hanSerial->read(); // Make sure it is all empty, in case we overflowed buffer above len = 0; @@ -851,6 +852,7 @@ bool readHanPort() { // If MQTT bytestream payload is selected (mqttHandler == NULL), send the payload to MQTT if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) { mqtt->publish(topic.c_str(), toHex(hanBuffer+pos, ctx.length)); + mqtt->loop(); } debugV("Using application data:"); @@ -1175,6 +1177,7 @@ int16_t unwrapData(uint8_t *buf, DataParserContext &context) { // If MQTT bytestream payload is selected (mqttHandler == NULL), send the payload to MQTT if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) { mqtt->publish(topic.c_str(), toHex(buf, curLen)); + mqtt->loop(); } break; case DATA_TAG_MBUS: @@ -1182,6 +1185,7 @@ int16_t unwrapData(uint8_t *buf, DataParserContext &context) { // If MQTT bytestream payload is selected (mqttHandler == NULL), send the payload to MQTT if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) { mqtt->publish(topic.c_str(), toHex(buf, curLen)); + mqtt->loop(); } break; case DATA_TAG_GBT: @@ -1200,6 +1204,7 @@ int16_t unwrapData(uint8_t *buf, DataParserContext &context) { debugV("DSMR frame:"); if(mqttEnabled && mqtt != NULL && mqttHandler == NULL) { mqtt->publish(topic.c_str(), (char*) buf); + mqtt->loop(); } break; } From e232b875fad5240edc61e33561a2ac8be6eab341 Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Tue, 23 Aug 2022 21:07:06 +0200 Subject: [PATCH 4/4] Fixed Aidon timestamp --- src/IEC6205675.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/IEC6205675.cpp b/src/IEC6205675.cpp index 15cb81d5..8ebe54f8 100644 --- a/src/IEC6205675.cpp +++ b/src/IEC6205675.cpp @@ -266,7 +266,9 @@ IEC6205675::IEC6205675(const char* d, uint8_t useMeterType, MeterConfig* meterCo if(meterTs != NULL) { AmsOctetTimestamp* amst = (AmsOctetTimestamp*) meterTs; time_t ts = decodeCosemDateTime(amst->dt); - if(meterType == AmsTypeKamstrup || meterType == AmsTypeAidon) { + if(meterType == AmsTypeAidon) { + meterTimestamp = ts - 3600; + } else if(meterType == AmsTypeKamstrup) { meterTimestamp = tz.toUTC(ts); } else { meterTimestamp = ts;