From 04d73b2db01f8f41f7bb97aa8512db70763a35dc Mon Sep 17 00:00:00 2001 From: Gunnar Skjold Date: Wed, 1 Oct 2025 11:21:47 +0200 Subject: [PATCH] Reverted some MQTT changes --- .../include/HomeAssistantMqttHandler.h | 3 +- .../include/HomeAssistantStatic.h | 6 +- .../src/HomeAssistantMqttHandler.cpp | 106 ++++++++---------- lib/JsonMqttHandler/src/JsonMqttHandler.cpp | 58 +--------- lib/PriceService/include/PriceService.h | 2 +- lib/PriceService/src/PriceService.cpp | 6 +- lib/RawMqttHandler/src/RawMqttHandler.cpp | 17 ++- 7 files changed, 67 insertions(+), 131 deletions(-) diff --git a/lib/HomeAssistantMqttHandler/include/HomeAssistantMqttHandler.h b/lib/HomeAssistantMqttHandler/include/HomeAssistantMqttHandler.h index 692faa76..f191394c 100644 --- a/lib/HomeAssistantMqttHandler/include/HomeAssistantMqttHandler.h +++ b/lib/HomeAssistantMqttHandler/include/HomeAssistantMqttHandler.h @@ -55,8 +55,9 @@ private: String updateTopic; String sensorNamePrefix; - bool l1Init, l2Init, l2eInit, l3Init, l3eInit, l4Init, l4eInit, rtInit, rteInit, pInit, sInit, rInit, fInit, prInit, preInit; + bool l1Init, l2Init, l2eInit, l3Init, l3eInit, l4Init, l4eInit, rtInit, rteInit, pInit, sInit, rInit, fInit, preInit; bool tInit[32] = {false}; + bool prInit[38] = {false}; uint32_t lastThresholdPublish = 0; HwTools* hw; diff --git a/lib/HomeAssistantMqttHandler/include/HomeAssistantStatic.h b/lib/HomeAssistantMqttHandler/include/HomeAssistantStatic.h index 17bc05be..14da564f 100644 --- a/lib/HomeAssistantMqttHandler/include/HomeAssistantStatic.h +++ b/lib/HomeAssistantMqttHandler/include/HomeAssistantStatic.h @@ -105,16 +105,16 @@ const HomeAssistantSensor RealtimeExportSensors[RealtimeExportSensorCount] PROGM const HomeAssistantSensor RealtimePeakSensor PROGMEM = {"Current month peak %d", "/realtime", "peaks[%d]", 4000, "kWh", "energy", ""}; const HomeAssistantSensor RealtimeThresholdSensor PROGMEM = {"Tariff threshold %d", "/realtime", "thresholds[%d]", 4000, "kWh", "energy", ""}; -const uint8_t PriceSensorCount PROGMEM = 6; +const uint8_t PriceSensorCount PROGMEM = 5; const HomeAssistantSensor PriceSensors[PriceSensorCount] PROGMEM = { - {"Import price", "/prices", "prices.import.current", 4000, "", "monetary", ""}, {"Minimum price ahead", "/prices", "prices.min", 4000, "", "monetary", ""}, {"Maximum price ahead", "/prices", "prices.max", 4000, "", "monetary", ""}, {"Cheapest 1hr period ahead", "/prices", "prices.cheapest1hr", 4000, "", "timestamp", ""}, {"Cheapest 3hr period ahead", "/prices", "prices.cheapest3hr", 4000, "", "timestamp", ""}, {"Cheapest 6hr period ahead", "/prices", "prices.cheapest6hr", 4000, "", "timestamp", ""} }; -const HomeAssistantSensor ExportPriceSensor PROGMEM = {"Export price", "/prices", "prices.export.current", 4000, "", "monetary", ""}; + +const HomeAssistantSensor PriceSensor PROGMEM = {"Price in %02d %s", "/prices", "prices['%d']", 4000, "", "monetary", ""}; const uint8_t SystemSensorCount PROGMEM = 3; const HomeAssistantSensor SystemSensors[SystemSensorCount] PROGMEM = { diff --git a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp index 9f13d527..b8c23be9 100644 --- a/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp +++ b/lib/HomeAssistantMqttHandler/src/HomeAssistantMqttHandler.cpp @@ -442,34 +442,16 @@ bool HomeAssistantMqttHandler::publishPrices(PriceService* ps) { sprintf_P(ts6hr, PSTR("%04d-%02d-%02dT%02d:00:00Z"), tm.Year+1970, tm.Month, tm.Day, tm.Hour); } - uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"prices\":{\"import\":{\"current\":%.4f,\"all\":["), - WiFi.macAddress().c_str(), - ps->getCurrentPrice(PRICE_DIRECTION_IMPORT) - ); - uint8_t numberOfPoints = ps->getNumberOfPointsAvailable(); - for(int i = 0; i < numberOfPoints; i++) { - float val = ps->getPricePoint(PRICE_DIRECTION_IMPORT, i); - if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("null,")); - } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val); - } - } - if(rteInit && ps->isExportPricesDifferentFromImport()) { - pos--; - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("]},\"export\":{\"current\":%.4f,\"all\":["), ps->getCurrentPrice(PRICE_DIRECTION_EXPORT)); - for(int i = 0; i < numberOfPoints; i++) { - float val = ps->getPricePoint(PRICE_DIRECTION_EXPORT, i); - if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("null,")); + uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"prices\":{"), WiFi.macAddress().c_str()); + for(uint8_t i = 0;i < 38; i++) { + if(values[i] == PRICE_NO_VALUE) { + pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%d\":null,"), i); } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val); - } + pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%d\":%.4f,"), i, values[i]); } } - pos--; - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("]},\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":\"%s\",\"cheapest3hr\":\"%s\",\"cheapest6hr\":\"%s\"}}"), + pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":\"%s\",\"cheapest3hr\":\"%s\",\"cheapest6hr\":\"%s\"}"), min == INT16_MAX ? 0.0 : min, max == INT16_MIN ? 0.0 : max, ts1hr, @@ -477,6 +459,13 @@ bool HomeAssistantMqttHandler::publishPrices(PriceService* ps) { ts6hr ); + float val = ps->getPriceForRelativeHour(PRICE_DIRECTION_EXPORT, 0); + if(val == PRICE_NO_VALUE) { + pos += snprintf_P(json+pos, BufferSize-pos, PSTR(",\"exportprices\":{\"0\":null}")); + } else { + pos += snprintf_P(json+pos, BufferSize-pos, PSTR(",\"exportprices\":{\"0\":%.4f}"), val); + } + char pt[24]; memset(pt, 0, 24); if(now > 0) { @@ -701,51 +690,47 @@ void HomeAssistantMqttHandler::publishPriceSensors(PriceService* ps) { } pInit = true; } - if(!prInit && ps->hasPrice()) { - for(uint8_t i = 0; i < ps->getNumberOfPointsAvailable(); i++) { - char name[32]; - snprintf_P(name, 32, PSTR("Import price point %02d"), i); - char path[32]; - snprintf_P(path, 32, PSTR("prices.import.all[%d]"), i); - HomeAssistantSensor sensor = { - name, - "/prices", - path, - ps->getResolutionInMinutes() * 60 + 30, - uom.c_str(), - "monetary", - "" - }; - publishSensor(sensor); - } - prInit = true; - } + for(uint8_t i = 0; i < 38; i++) { + if(prInit[i]) continue; + float val = ps->getPriceForRelativeHour(PRICE_DIRECTION_IMPORT, i); + if(val == PRICE_NO_VALUE) continue; - if(rteInit && !preInit && ps->isExportPricesDifferentFromImport()) { - HomeAssistantSensor sensor = ExportPriceSensor; - sensor.uom = uom.c_str(); - publishSensor(sensor); - - for(uint8_t i = 0; i < ps->getNumberOfPointsAvailable(); i++) { - char name[32]; - snprintf_P(name, 32, PSTR("Export price point %02d"), i); - char path[32]; - snprintf_P(path, 32, PSTR("prices.export.all[%d]"), i); + char name[strlen(PriceSensor.name)+2]; + snprintf(name, strlen(PriceSensor.name)+2, PriceSensor.name, i, i == 1 ? "hour" : "hours"); + char path[strlen(PriceSensor.path)+1]; + snprintf(path, strlen(PriceSensor.path)+1, PriceSensor.path, i); HomeAssistantSensor sensor = { - name, - "/prices", + i == 0 ? "Price current hour" : name, + PriceSensor.topic, path, - ps->getResolutionInMinutes() * 60 + 30, + PriceSensor.ttl, uom.c_str(), - "monetary", - "" + PriceSensor.devcl, + i == 0 ? "total" : PriceSensor.stacl + }; + publishSensor(sensor); + prInit[i] = true; + } + + float exportPrice = ps->getPriceForRelativeHour(PRICE_DIRECTION_EXPORT, 0); + if(exportPrice != PRICE_NO_VALUE) { + char path[20]; + snprintf(path, 20, "exportprices['%d']", 0); + HomeAssistantSensor sensor = { + "Export price current hour", + PriceSensor.topic, + path, + PriceSensor.ttl, + uom.c_str(), + PriceSensor.devcl, + "total" }; publishSensor(sensor); - } preInit = true; } } + void HomeAssistantMqttHandler::publishSystemSensors() { if(sInit) return; for(uint8_t i = 0; i < SystemSensorCount; i++) { @@ -812,8 +797,9 @@ void HomeAssistantMqttHandler::onMessage(String &topic, String &payload) { if (debugger->isActive(RemoteDebug::INFO)) #endif debugger->printf_P(PSTR("Received online status from HA, resetting sensor status\n")); - l1Init = l2Init = l2eInit = l3Init = l3eInit = l4Init = l4eInit = rtInit = rteInit = pInit = sInit = rInit = prInit = preInit = false; + l1Init = l2Init = l2eInit = l3Init = l3eInit = l4Init = l4eInit = rtInit = rteInit = pInit = sInit = rInit = preInit = false; for(uint8_t i = 0; i < 32; i++) tInit[i] = false; + for(uint8_t i = 0; i < 38; i++) prInit[i] = false; } } else if(topic.equals(subTopic)) { if(payload.equals("fwupgrade")) { diff --git a/lib/JsonMqttHandler/src/JsonMqttHandler.cpp b/lib/JsonMqttHandler/src/JsonMqttHandler.cpp index 2e7430c2..41733db6 100644 --- a/lib/JsonMqttHandler/src/JsonMqttHandler.cpp +++ b/lib/JsonMqttHandler/src/JsonMqttHandler.cpp @@ -365,66 +365,20 @@ bool JsonMqttHandler::publishPrices(PriceService* ps) { char pf[4]; uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\","), WiFi.macAddress().c_str()); - uint8_t numberOfPoints = ps->getNumberOfPointsAvailable(); if(mqttConfig.payloadFormat != 6) { memset(pf, 0, 4); - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"prices\":{\"import\":{\"current\":%.4f,\"all\":["), ps->getCurrentPrice(PRICE_DIRECTION_IMPORT)); - for(int i = 0; i < numberOfPoints; i++) { - float val = ps->getPricePoint(PRICE_DIRECTION_IMPORT, i); - if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("null,")); - } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val); - } - } - if(hasExport && ps->isExportPricesDifferentFromImport()) { - pos--; - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("]},\"export\":{\"current\":%.4f,\"all\":["), ps->getCurrentPrice(PRICE_DIRECTION_EXPORT)); - for(int i = 0; i < numberOfPoints; i++) { - float val = ps->getPricePoint(PRICE_DIRECTION_EXPORT, i); - if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("null,")); - } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val); - } - } - } - pos--; - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("]},")); + pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"prices\":{")); } else { strcpy_P(pf, PSTR("pr_")); - float val = ps->getCurrentPrice(PRICE_DIRECTION_IMPORT); - if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%sc\":null,"), pf); - } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%sc\":%.4f,"), pf, val); - } - for(uint8_t i = 0;i < numberOfPoints; i++) { - val = ps->getPricePoint(PRICE_DIRECTION_IMPORT, i); - if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%s%02d\":null,"), pf, i); - } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%s%02d\":%.4f,"), pf, i, val); } - } - if(hasExport && ps->isExportPricesDifferentFromImport()) { - float val = ps->getCurrentPrice(PRICE_DIRECTION_EXPORT); - if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%sec\":null,"), pf); + + for(uint8_t i = 0;i < 38; i++) { + if(values[i] == PRICE_NO_VALUE) { + pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%s%d\":null,"), pf, i); } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%sec\":%.4f,"), pf, val); - } - for(uint8_t i = 0;i < numberOfPoints; i++) { - val = ps->getPricePoint(PRICE_DIRECTION_EXPORT, i); - if(val == PRICE_NO_VALUE) { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%se%02d\":null,"), pf, i); - } else { - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%se%02d\":%.4f,"), pf, i, val); + pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%s%d\":%.4f,"), pf, i, values[i]); } } - } - } - pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%smin\":%.4f,\"%smax\":%.4f,\"%scheapest1hr\":\"%s\",\"%scheapest3hr\":\"%s\",\"%scheapest6hr\":\"%s\"}"), pf, diff --git a/lib/PriceService/include/PriceService.h b/lib/PriceService/include/PriceService.h index f75c2953..e508ac30 100644 --- a/lib/PriceService/include/PriceService.h +++ b/lib/PriceService/include/PriceService.h @@ -80,6 +80,7 @@ public: uint8_t getResolutionInMinutes(); uint8_t getNumberOfPointsAvailable(); + uint8_t getCurrentPricePointIndex(); bool isExportPricesDifferentFromImport(); @@ -140,6 +141,5 @@ private: bool timeIsInPeriod(tmElements_t tm, PriceConfig pc); float getFixedPrice(uint8_t direction, int8_t hour); float getEnergyPricePoint(uint8_t direction, uint8_t point); - uint8_t getCurrentPricePointIndex(); }; #endif diff --git a/lib/PriceService/src/PriceService.cpp b/lib/PriceService/src/PriceService.cpp index be630b0e..15ce6f6c 100644 --- a/lib/PriceService/src/PriceService.cpp +++ b/lib/PriceService/src/PriceService.cpp @@ -113,7 +113,7 @@ uint8_t PriceService::getResolutionInMinutes() { } uint8_t PriceService::getNumberOfPointsAvailable() { - if(today == NULL) return 0; + if(today == NULL) return getResolutionInMinutes() == 15 ? 96 : 24; if(tomorrow != NULL) return today->getNumberOfPoints() + tomorrow->getNumberOfPoints(); return today->getNumberOfPoints(); } @@ -768,10 +768,8 @@ bool PriceService::timeIsInPeriod(tmElements_t tm, PriceConfig pc) { } uint8_t PriceService::getCurrentPricePointIndex() { - if(today == NULL) return 0; - time_t ts = time(nullptr); tmElements_t tm; breakTime(tz->toLocal(ts), tm); - return ((tm.Hour * 60) + tm.Minute) / today->getResolutionInMinutes(); + return ((tm.Hour * 60) + tm.Minute) / getResolutionInMinutes(); } \ No newline at end of file diff --git a/lib/RawMqttHandler/src/RawMqttHandler.cpp b/lib/RawMqttHandler/src/RawMqttHandler.cpp index 306156bc..23a568fb 100644 --- a/lib/RawMqttHandler/src/RawMqttHandler.cpp +++ b/lib/RawMqttHandler/src/RawMqttHandler.cpp @@ -317,31 +317,28 @@ bool RawMqttHandler::publishPrices(PriceService* ps) { sprintf(ts6hr, "%04d-%02d-%02dT%02d:00:00Z", tm.Year+1970, tm.Month, tm.Day, tm.Hour); } - mqtt.publish(topic + "/price/import/current", String(ps->getCurrentPrice(PRICE_DIRECTION_IMPORT), 4), true, 0); + mqtt.publish(topic + "/price/resolution", String(ps->getResolutionInMinutes()), true, 0); mqtt.loop(); - if(hasExport && ps->isExportPricesDifferentFromImport()) { - mqtt.publish(topic + "/price/export/current", String(ps->getCurrentPrice(PRICE_DIRECTION_EXPORT), 4), true, 0); - mqtt.loop(); - } + uint8_t startIndex = ps->getCurrentPricePointIndex(); uint8_t numberOfPoints = ps->getNumberOfPointsAvailable(); - for(int i = 0; i < numberOfPoints; i++) { + for(int i = startIndex; i < numberOfPoints; i++) { float importVal = ps->getPricePoint(PRICE_DIRECTION_IMPORT, i); if(importVal == PRICE_NO_VALUE) { - mqtt.publish(topic + "/price/import/all/" + String(i), "", true, 0); + mqtt.publish(topic + "/price/import/" + String(i), "", true, 0); mqtt.loop(); } else { - mqtt.publish(topic + "/price/import/all/" + String(i), String(importVal, 4), true, 0); + mqtt.publish(topic + "/price/import/" + String(i), String(importVal, 4), true, 0); mqtt.loop(); } if(hasExport && ps->isExportPricesDifferentFromImport()) { float exportVal = ps->getPricePoint(PRICE_DIRECTION_EXPORT, i); if(exportVal == PRICE_NO_VALUE) { - mqtt.publish(topic + "/price/export/all/" + String(i), "", true, 0); + mqtt.publish(topic + "/price/export/" + String(i), "", true, 0); mqtt.loop(); } else { - mqtt.publish(topic + "/price/export/all/" + String(i), String(exportVal, 4), true, 0); + mqtt.publish(topic + "/price/export/" + String(i), String(exportVal, 4), true, 0); mqtt.loop(); } }