Reverted some MQTT changes

This commit is contained in:
Gunnar Skjold
2025-10-01 11:21:47 +02:00
parent 7f96c80b81
commit 04d73b2db0
7 changed files with 67 additions and 131 deletions

View File

@@ -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;

View File

@@ -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 = {

View File

@@ -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")) {

View File

@@ -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,

View File

@@ -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

View File

@@ -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();
}

View File

@@ -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();
}
}