diff --git a/src/AmsToMqttBridge.ino b/src/AmsToMqttBridge.ino index a5726a84..06ef83b4 100644 --- a/src/AmsToMqttBridge.ino +++ b/src/AmsToMqttBridge.ino @@ -836,6 +836,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; @@ -852,6 +853,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:"); @@ -1177,6 +1179,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: @@ -1184,6 +1187,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: @@ -1202,6 +1206,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; } 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/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; 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/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 c583e2ff..2825ec5d 100644 --- a/src/web/AmsWebServer.cpp +++ b/src/web/AmsWebServer.cpp @@ -594,9 +594,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); @@ -711,6 +711,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, @@ -747,6 +753,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, 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" }