Added support for 15 minute price resolution (#1031)

* 15min prices WIP

* WIP more changes for 15min prices

* More work on 15min pricing

* Fixed some errors

* Some changes after testing

* Graphical changes for 15min pricing

* Adjustments on MQTT handlers after switching to 15min prices

* Reverted some MQTT changes

* Adapted HA integration for 15min pricing

* Adapted JSON payload for 15min

* Adjustments during testing

* Set default price interval

* Fixed refresh of price graph when data changes

* Bugfixes

* Fixed some issues with raw payload

* Adjustments for meter timestamp from Kamstrup

* Updated readme

* Added detailed breakdown of payloads coming from Norwegian meters

* Minor changes relating to price

* Fixed byte alignment on price config

* Changes to support RC upgraders
This commit is contained in:
Gunnar Skjold
2025-11-13 15:10:54 +01:00
committed by GitHub
parent ffd8d46f2e
commit c648546b61
44 changed files with 1073 additions and 637 deletions

View File

@@ -36,6 +36,7 @@ private:
bool full;
String topic;
uint32_t lastThresholdPublish = 0;
bool hasExport = false;
bool publishList1(AmsData* data, AmsData* meterState);
bool publishList2(AmsData* data, AmsData* meterState);

View File

@@ -41,6 +41,15 @@ bool RawMqttHandler::publish(AmsData* update, AmsData* previousState, EnergyAcco
publishList1(&data, previousState);
loop();
}
if(data.getListType() >= 2 && data.getActiveExportPower() > 0.0) {
hasExport = true;
}
if(data.getListType() >= 3 && data.getActiveExportCounter() > 0.0) {
hasExport = true;
}
if(ea->isInitialized()) {
publishRealtime(ea);
loop();
@@ -230,7 +239,7 @@ bool RawMqttHandler::publishTemperatures(AmsConfiguration* config, HwTools* hw)
bool RawMqttHandler::publishPrices(PriceService* ps) {
if(topic.isEmpty() || !mqtt.connected())
return false;
if(ps->getValueForHour(PRICE_DIRECTION_IMPORT, 0) == PRICE_NO_VALUE)
if(!ps->hasPrice())
return false;
time_t now = time(nullptr);
@@ -241,7 +250,7 @@ bool RawMqttHandler::publishPrices(PriceService* ps) {
float values[34];
for(int i = 0;i < 34; i++) values[i] = PRICE_NO_VALUE;
for(uint8_t i = 0; i < 34; i++) {
float val = ps->getValueForHour(PRICE_DIRECTION_IMPORT, now, i);
float val = ps->getPriceForRelativeHour(PRICE_DIRECTION_IMPORT, i);
values[i] = val;
if(i > 23) continue;
@@ -308,15 +317,33 @@ bool RawMqttHandler::publishPrices(PriceService* ps) {
sprintf(ts6hr, "%04d-%02d-%02dT%02d:00:00Z", tm.Year+1970, tm.Month, tm.Day, tm.Hour);
}
for(int i = 0; i < 34; i++) {
float val = values[i];
if(val == PRICE_NO_VALUE) {
mqtt.publish(topic + "/price/" + String(i), "", true, 0);
mqtt.publish(topic + "/price/resolution", String(ps->getResolutionInMinutes()), true, 0);
mqtt.loop();
uint8_t relativeIndex = 0;
uint8_t startIndex = ps->getCurrentPricePointIndex();
uint8_t numberOfPoints = ps->getNumberOfPointsAvailable();
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/" + String(relativeIndex), "", true, 0);
mqtt.loop();
} else {
mqtt.publish(topic + "/price/" + String(i), String(val, 4), true, 0);
mqtt.publish(topic + "/price/import/" + String(relativeIndex), 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/" + String(relativeIndex), "", true, 0);
mqtt.loop();
} else {
mqtt.publish(topic + "/price/export/" + String(relativeIndex), String(exportVal, 4), true, 0);
mqtt.loop();
}
}
relativeIndex++;
}
if(min != INT16_MAX) {
mqtt.publish(topic + "/price/min", String(min, 4), true, 0);
@@ -338,15 +365,6 @@ bool RawMqttHandler::publishPrices(PriceService* ps) {
mqtt.publish(topic + "/price/cheapest/6hr", String(ts6hr), true, 0);
mqtt.loop();
}
float exportPrice = ps->getEnergyPriceForHour(PRICE_DIRECTION_EXPORT, now, 0);
if(exportPrice == PRICE_NO_VALUE) {
mqtt.publish(topic + "/exportprice/0", "", true, 0);
mqtt.loop();
} else {
mqtt.publish(topic + "/exportprice/0", String(exportPrice, 4), true, 0);
mqtt.loop();
}
return true;
}