Adapted HA integration for 15min pricing

This commit is contained in:
Gunnar Skjold
2025-10-02 12:24:33 +02:00
parent 04d73b2db0
commit add6c6ad9f
3 changed files with 179 additions and 112 deletions

View File

@@ -55,9 +55,9 @@ private:
String updateTopic; String updateTopic;
String sensorNamePrefix; String sensorNamePrefix;
bool l1Init, l2Init, l2eInit, l3Init, l3eInit, l4Init, l4eInit, rtInit, rteInit, pInit, sInit, rInit, fInit, preInit; bool l1Init, l2Init, l2eInit, l3Init, l3eInit, l4Init, l4eInit, rtInit, rteInit, pInit, sInit, rInit, fInit;
bool tInit[32] = {false}; bool tInit[32] = {false};
bool prInit[38] = {false}; uint8_t priceImportInit = 0, priceExportInit = 0;
uint32_t lastThresholdPublish = 0; uint32_t lastThresholdPublish = 0;
HwTools* hw; HwTools* hw;

View File

@@ -17,113 +17,112 @@ struct HomeAssistantSensor {
const char* uom; const char* uom;
const char* devcl; const char* devcl;
const char* stacl; const char* stacl;
const char* uid;
}; };
const uint8_t List1SensorCount PROGMEM = 2; const uint8_t List1SensorCount PROGMEM = 2;
const HomeAssistantSensor List1Sensors[List1SensorCount] PROGMEM = { const HomeAssistantSensor List1Sensors[List1SensorCount] PROGMEM = {
{"Active import", "/power", "P", 30, "W", "power", "measurement"}, {"Active import", "/power", "P", 30, "W", "power", "measurement", ""},
{"Data timestamp", "/power", "t", 30, "", "timestamp", ""} {"Data timestamp", "/power", "t", 30, "", "timestamp", "", ""}
}; };
const uint8_t List2SensorCount PROGMEM = 8; const uint8_t List2SensorCount PROGMEM = 8;
const HomeAssistantSensor List2Sensors[List2SensorCount] PROGMEM = { const HomeAssistantSensor List2Sensors[List2SensorCount] PROGMEM = {
{"Reactive import", "/power", "Q", 30, "var", "reactive_power", "measurement"}, {"Reactive import", "/power", "Q", 30, "var", "reactive_power", "measurement", ""},
{"Reactive export", "/power", "QO", 30, "var", "reactive_power", "measurement"}, {"Reactive export", "/power", "QO", 30, "var", "reactive_power", "measurement", ""},
{"L1 current", "/power", "I1", 30, "A", "current", "measurement"}, {"L1 current", "/power", "I1", 30, "A", "current", "measurement", ""},
{"L2 current", "/power", "I2", 30, "A", "current", "measurement"}, {"L2 current", "/power", "I2", 30, "A", "current", "measurement", ""},
{"L3 current", "/power", "I3", 30, "A", "current", "measurement"}, {"L3 current", "/power", "I3", 30, "A", "current", "measurement", ""},
{"L1 voltage", "/power", "U1", 30, "V", "voltage", "measurement"}, {"L1 voltage", "/power", "U1", 30, "V", "voltage", "measurement", ""},
{"L2 voltage", "/power", "U2", 30, "V", "voltage", "measurement"}, {"L2 voltage", "/power", "U2", 30, "V", "voltage", "measurement", ""},
{"L3 voltage", "/power", "U3", 30, "V", "voltage", "measurement"} {"L3 voltage", "/power", "U3", 30, "V", "voltage", "measurement", ""}
}; };
const uint8_t List2ExportSensorCount PROGMEM = 1; const uint8_t List2ExportSensorCount PROGMEM = 1;
const HomeAssistantSensor List2ExportSensors[List2ExportSensorCount] PROGMEM = { const HomeAssistantSensor List2ExportSensors[List2ExportSensorCount] PROGMEM = {
{"Active export", "/power", "PO", 30, "W", "power", "measurement"} {"Active export", "/power", "PO", 30, "W", "power", "measurement", ""}
}; };
const uint8_t List3SensorCount PROGMEM = 4; const uint8_t List3SensorCount PROGMEM = 4;
const HomeAssistantSensor List3Sensors[List3SensorCount] PROGMEM = { const HomeAssistantSensor List3Sensors[List3SensorCount] PROGMEM = {
{"Accumulated active import", "/energy", "tPI", 4000, "kWh", "energy", "total_increasing"}, {"Accumulated active import", "/energy", "tPI", 4000, "kWh", "energy", "total_increasing", ""},
{"Accumulated reactive import","/energy", "tQI", 4000, "kvarh","", "total_increasing"}, {"Accumulated reactive import","/energy", "tQI", 4000, "kvarh","", "total_increasing", ""},
{"Accumulated reactive export","/energy", "tQO", 4000, "kvarh","", "total_increasing"}, {"Accumulated reactive export","/energy", "tQO", 4000, "kvarh","", "total_increasing", ""},
{"Meter timestamp", "/energy", "rtc", 4000, "", "timestamp", ""} {"Meter timestamp", "/energy", "rtc", 4000, "", "timestamp", "", ""}
}; };
const uint8_t List3ExportSensorCount PROGMEM = 1; const uint8_t List3ExportSensorCount PROGMEM = 1;
const HomeAssistantSensor List3ExportSensors[List3ExportSensorCount] PROGMEM = { const HomeAssistantSensor List3ExportSensors[List3ExportSensorCount] PROGMEM = {
{"Accumulated active export", "/energy", "tPO", 4000, "kWh", "energy", "total_increasing"} {"Accumulated active export", "/energy", "tPO", 4000, "kWh", "energy", "total_increasing", ""}
}; };
const uint8_t List4SensorCount PROGMEM = 10; const uint8_t List4SensorCount PROGMEM = 10;
const HomeAssistantSensor List4Sensors[List4SensorCount] PROGMEM = { const HomeAssistantSensor List4Sensors[List4SensorCount] PROGMEM = {
{"Power factor", "/power", "PF", 30, "%", "power_factor", "measurement"}, {"Power factor", "/power", "PF", 30, "%", "power_factor", "measurement", ""},
{"L1 power factor", "/power", "PF1", 30, "%", "power_factor", "measurement"}, {"L1 power factor", "/power", "PF1", 30, "%", "power_factor", "measurement", ""},
{"L2 power factor", "/power", "PF2", 30, "%", "power_factor", "measurement"}, {"L2 power factor", "/power", "PF2", 30, "%", "power_factor", "measurement", ""},
{"L3 power factor", "/power", "PF3", 30, "%", "power_factor", "measurement"}, {"L3 power factor", "/power", "PF3", 30, "%", "power_factor", "measurement", ""},
{"L1 active import", "/power", "P1", 30, "W", "power", "measurement"}, {"L1 active import", "/power", "P1", 30, "W", "power", "measurement", ""},
{"L2 active import", "/power", "P2", 30, "W", "power", "measurement"}, {"L2 active import", "/power", "P2", 30, "W", "power", "measurement", ""},
{"L3 active import", "/power", "P3", 30, "W", "power", "measurement"}, {"L3 active import", "/power", "P3", 30, "W", "power", "measurement", ""},
{"L1 accumulated active import","/power", "tPI1", 30, "kWh", "energy", "total_increasing"}, {"L1 accumulated active import","/power", "tPI1", 30, "kWh", "energy", "total_increasing", ""},
{"L2 accumulated active import","/power", "tPI2", 30, "kWh", "energy", "total_increasing"}, {"L2 accumulated active import","/power", "tPI2", 30, "kWh", "energy", "total_increasing", ""},
{"L3 accumulated active import","/power", "tPI3", 30, "kWh", "energy", "total_increasing"} {"L3 accumulated active import","/power", "tPI3", 30, "kWh", "energy", "total_increasing", ""}
}; };
const uint8_t List4ExportSensorCount PROGMEM = 6; const uint8_t List4ExportSensorCount PROGMEM = 6;
const HomeAssistantSensor List4ExportSensors[List4ExportSensorCount] PROGMEM = { const HomeAssistantSensor List4ExportSensors[List4ExportSensorCount] PROGMEM = {
{"L1 active export", "/power", "PO1", 30, "W", "power", "measurement"}, {"L1 active export", "/power", "PO1", 30, "W", "power", "measurement", ""},
{"L2 active export", "/power", "PO2", 30, "W", "power", "measurement"}, {"L2 active export", "/power", "PO2", 30, "W", "power", "measurement", ""},
{"L3 active export", "/power", "PO3", 30, "W", "power", "measurement"}, {"L3 active export", "/power", "PO3", 30, "W", "power", "measurement", ""},
{"L1 accumulated active export","/power", "tPO1", 30, "kWh", "energy", "total_increasing"}, {"L1 accumulated active export","/power", "tPO1", 30, "kWh", "energy", "total_increasing", ""},
{"L2 accumulated active export","/power", "tPO2", 30, "kWh", "energy", "total_increasing"}, {"L2 accumulated active export","/power", "tPO2", 30, "kWh", "energy", "total_increasing", ""},
{"L3 accumulated active export","/power", "tPO3", 30, "kWh", "energy", "total_increasing"} {"L3 accumulated active export","/power", "tPO3", 30, "kWh", "energy", "total_increasing", ""}
}; };
const uint8_t RealtimeSensorCount PROGMEM = 8; const uint8_t RealtimeSensorCount PROGMEM = 8;
const HomeAssistantSensor RealtimeSensors[RealtimeSensorCount] PROGMEM = { const HomeAssistantSensor RealtimeSensors[RealtimeSensorCount] PROGMEM = {
{"Month max", "/realtime","max", 120, "kWh", "energy", ""}, {"Month max", "/realtime","max", 120, "kWh", "energy", "", ""},
{"Tariff threshold", "/realtime","threshold", 120, "kWh", "energy", ""}, {"Tariff threshold", "/realtime","threshold", 120, "kWh", "energy", "", ""},
{"Current hour used", "/realtime","hour.use", 120, "kWh", "energy", "total_increasing"}, {"Current hour used", "/realtime","hour.use", 120, "kWh", "energy", "total_increasing", ""},
{"Current hour cost", "/realtime","hour.cost", 120, "", "monetary", ""}, {"Current hour cost", "/realtime","hour.cost", 120, "", "monetary", "", ""},
{"Current day used", "/realtime","day.use", 120, "kWh", "energy", "total_increasing"}, {"Current day used", "/realtime","day.use", 120, "kWh", "energy", "total_increasing", ""},
{"Current day cost", "/realtime","day.cost", 120, "", "monetary", ""}, {"Current day cost", "/realtime","day.cost", 120, "", "monetary", "", ""},
{"Current month used", "/realtime","month.use", 120, "kWh", "energy", "total_increasing"}, {"Current month used", "/realtime","month.use", 120, "kWh", "energy", "total_increasing", ""},
{"Current month cost", "/realtime","month.cost", 120, "", "monetary", ""} {"Current month cost", "/realtime","month.cost", 120, "", "monetary", "", ""}
}; };
const uint8_t RealtimeExportSensorCount PROGMEM = 6; const uint8_t RealtimeExportSensorCount PROGMEM = 6;
const HomeAssistantSensor RealtimeExportSensors[RealtimeExportSensorCount] PROGMEM = { const HomeAssistantSensor RealtimeExportSensors[RealtimeExportSensorCount] PROGMEM = {
{"Current hour produced", "/realtime","hour.produced", 120, "kWh", "energy", "total_increasing"}, {"Current hour produced", "/realtime","hour.produced", 120, "kWh", "energy", "total_increasing", ""},
{"Current hour income", "/realtime","hour.income", 120, "", "monetary", ""}, {"Current hour income", "/realtime","hour.income", 120, "", "monetary", "", ""},
{"Current day produced", "/realtime","day.produced", 120, "kWh", "energy", "total_increasing"}, {"Current day produced", "/realtime","day.produced", 120, "kWh", "energy", "total_increasing", ""},
{"Current day income", "/realtime","day.income", 120, "", "monetary", ""}, {"Current day income", "/realtime","day.income", 120, "", "monetary", "", ""},
{"Current month produced", "/realtime","month.produced", 120, "kWh", "energy", "total_increasing"}, {"Current month produced", "/realtime","month.produced", 120, "kWh", "energy", "total_increasing", ""},
{"Current month income", "/realtime","month.income", 120, "", "monetary", ""} {"Current month income", "/realtime","month.income", 120, "", "monetary", "", ""}
}; };
const HomeAssistantSensor RealtimePeakSensor PROGMEM = {"Current month peak %d", "/realtime", "peaks[%d]", 4000, "kWh", "energy", ""}; 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 HomeAssistantSensor RealtimeThresholdSensor PROGMEM = {"Tariff threshold %d", "/realtime", "thresholds[%d]", 4000, "kWh", "energy", "", ""};
const uint8_t PriceSensorCount PROGMEM = 5; const uint8_t PriceSensorCount PROGMEM = 5;
const HomeAssistantSensor PriceSensors[PriceSensorCount] PROGMEM = { const HomeAssistantSensor PriceSensors[PriceSensorCount] PROGMEM = {
{"Minimum price ahead", "/prices", "prices.min", 4000, "", "monetary", ""}, {"Minimum price ahead", "/prices", "prices.min", 4000, "", "monetary", "", ""},
{"Maximum price ahead", "/prices", "prices.max", 4000, "", "monetary", ""}, {"Maximum price ahead", "/prices", "prices.max", 4000, "", "monetary", "", ""},
{"Cheapest 1hr period ahead", "/prices", "prices.cheapest1hr", 4000, "", "timestamp", ""}, {"Cheapest 1hr period ahead", "/prices", "prices.cheapest1hr", 4000, "", "timestamp", "", ""},
{"Cheapest 3hr period ahead", "/prices", "prices.cheapest3hr", 4000, "", "timestamp", ""}, {"Cheapest 3hr period ahead", "/prices", "prices.cheapest3hr", 4000, "", "timestamp", "", ""},
{"Cheapest 6hr period ahead", "/prices", "prices.cheapest6hr", 4000, "", "timestamp", ""} {"Cheapest 6hr period ahead", "/prices", "prices.cheapest6hr", 4000, "", "timestamp", "", ""}
}; };
const HomeAssistantSensor PriceSensor PROGMEM = {"Price in %02d %s", "/prices", "prices['%d']", 4000, "", "monetary", ""};
const uint8_t SystemSensorCount PROGMEM = 3; const uint8_t SystemSensorCount PROGMEM = 3;
const HomeAssistantSensor SystemSensors[SystemSensorCount] PROGMEM = { const HomeAssistantSensor SystemSensors[SystemSensorCount] PROGMEM = {
{"Status", "/state", "rssi", 180, "dBm", "signal_strength", "measurement"}, {"Status", "/state", "rssi", 180, "dBm", "signal_strength", "measurement", ""},
{"Supply volt", "/state", "vcc", 180, "V", "voltage", "measurement"}, {"Supply volt", "/state", "vcc", 180, "V", "voltage", "measurement", ""},
{"Uptime", "/state", "up", 180, "s", "duration", "measurement"} {"Uptime", "/state", "up", 180, "s", "duration", "measurement", ""}
}; };
const HomeAssistantSensor TemperatureSensor PROGMEM = {"Temperature sensor %s", "/temperatures", "temperatures['%s']", 900, "°C", "temperature", "measurement"}; const HomeAssistantSensor TemperatureSensor PROGMEM = {"Temperature sensor %s", "/temperatures", "temperatures['%s']", 900, "°C", "temperature", "measurement", ""};
#endif #endif

View File

@@ -442,31 +442,41 @@ bool HomeAssistantMqttHandler::publishPrices(PriceService* ps) {
sprintf_P(ts6hr, PSTR("%04d-%02d-%02dT%02d:00:00Z"), tm.Year+1970, tm.Month, tm.Day, tm.Hour); 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\":{"), WiFi.macAddress().c_str()); uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"prices\":{\"import\":["), WiFi.macAddress().c_str());
for(uint8_t i = 0;i < 38; i++) {
if(values[i] == PRICE_NO_VALUE) { uint8_t currentPricePointIndex = ps->getCurrentPricePointIndex();
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%d\":null,"), i); uint8_t numberOfPoints = ps->getNumberOfPointsAvailable();
for(int i = currentPricePointIndex; 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\":["));
for(int i = currentPricePointIndex; 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 { } else {
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%d\":%.4f,"), i, values[i]); pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val);
}
} }
} }
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":\"%s\",\"cheapest3hr\":\"%s\",\"cheapest6hr\":\"%s\"}"), pos--;
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("],\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":\"%s\",\"cheapest3hr\":\"%s\",\"cheapest6hr\":\"%s\"}"),
min == INT16_MAX ? 0.0 : min, min == INT16_MAX ? 0.0 : min,
max == INT16_MIN ? 0.0 : max, max == INT16_MIN ? 0.0 : max,
ts1hr, ts1hr,
ts3hr, ts3hr,
ts6hr ts6hr
); );
float val = ps->getPriceForRelativeHour(PRICE_DIRECTION_EXPORT, 0); char pt[24];
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); memset(pt, 0, 24);
if(now > 0) { if(now > 0) {
tmElements_t tm; tmElements_t tm;
@@ -515,11 +525,16 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw, PriceService* ps, Ener
} }
void HomeAssistantMqttHandler::publishSensor(const HomeAssistantSensor sensor) { void HomeAssistantMqttHandler::publishSensor(const HomeAssistantSensor sensor) {
String uid = String(sensor.path); String uid;
uid.replace(".", ""); if(strlen(sensor.uid) > 0) {
uid.replace("[", ""); uid = String(sensor.uid);
uid.replace("]", ""); } else {
uid.replace("'", ""); uid = String(sensor.path);
uid.replace(".", "");
uid.replace("[", "");
uid.replace("]", "");
uid.replace("'", "");
}
snprintf_P(json, BufferSize, HADISCOVER_JSON, snprintf_P(json, BufferSize, HADISCOVER_JSON,
sensorNamePrefix.c_str(), sensorNamePrefix.c_str(),
sensor.name, sensor.name,
@@ -542,7 +557,7 @@ void HomeAssistantMqttHandler::publishSensor(const HomeAssistantSensor sensor) {
strlen_P(sensor.stacl) > 0 ? (char *) FPSTR(sensor.stacl) : "", strlen_P(sensor.stacl) > 0 ? (char *) FPSTR(sensor.stacl) : "",
strlen_P(sensor.stacl) > 0 ? "\"" : "" strlen_P(sensor.stacl) > 0 ? "\"" : ""
); );
mqtt.publish(sensorTopic + "/" + deviceUid + "_" + uid.c_str() + "/config", json, true, 0); mqtt.publish(sensorTopic + "/" + deviceUid + "_" + uid + "/config", json, true, 0);
loop(); loop();
} }
@@ -631,7 +646,8 @@ void HomeAssistantMqttHandler::publishRealtimeSensors(EnergyAccounting* ea, Pric
RealtimePeakSensor.ttl, RealtimePeakSensor.ttl,
RealtimePeakSensor.uom, RealtimePeakSensor.uom,
RealtimePeakSensor.devcl, RealtimePeakSensor.devcl,
RealtimePeakSensor.stacl RealtimePeakSensor.stacl,
RealtimePeakSensor.uid
}; };
publishSensor(sensor); publishSensor(sensor);
} }
@@ -670,7 +686,8 @@ void HomeAssistantMqttHandler::publishTemperatureSensor(uint8_t index, String id
TemperatureSensor.ttl, TemperatureSensor.ttl,
TemperatureSensor.uom, TemperatureSensor.uom,
TemperatureSensor.devcl, TemperatureSensor.devcl,
TemperatureSensor.stacl TemperatureSensor.stacl,
TemperatureSensor.uid
}; };
publishSensor(sensor); publishSensor(sensor);
tInit[index] = true; tInit[index] = true;
@@ -690,43 +707,92 @@ void HomeAssistantMqttHandler::publishPriceSensors(PriceService* ps) {
} }
pInit = true; pInit = 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;
char name[strlen(PriceSensor.name)+2]; uint8_t currentPricePointIndex = ps->getCurrentPricePointIndex();
snprintf(name, strlen(PriceSensor.name)+2, PriceSensor.name, i, i == 1 ? "hour" : "hours"); uint8_t numberOfPoints = ps->getNumberOfPointsAvailable();
char path[strlen(PriceSensor.path)+1];
snprintf(path, strlen(PriceSensor.path)+1, PriceSensor.path, i); if(priceImportInit < numberOfPoints-currentPricePointIndex) {
uint8_t importPriceSensorNo = 0;
for(int pricePointIndex = currentPricePointIndex; pricePointIndex < numberOfPoints; pricePointIndex++) {
float val = ps->getPricePoint(PRICE_DIRECTION_IMPORT, pricePointIndex);
if(val == PRICE_NO_VALUE) break;
if(importPriceSensorNo < priceImportInit) {
importPriceSensorNo++;
continue;
}
uint8_t resolution = ps->getResolutionInMinutes();
char path[64];
memset(path, 0, 64);
snprintf_P(path, 64, PSTR("prices.import[%d]"), importPriceSensorNo);
char uid[32];
memset(uid, 0, 32);
snprintf_P(uid, 32, PSTR("prices%d"), importPriceSensorNo);
char name[64];
if(resolution == 60)
snprintf_P(name, 64, PSTR("Import price in %02d hour%s"), importPriceSensorNo, importPriceSensorNo == 1 ? "" : "s");
else
snprintf_P(name, 64, PSTR("Import price in %03d minutes"), importPriceSensorNo * resolution);
HomeAssistantSensor sensor = { HomeAssistantSensor sensor = {
i == 0 ? "Price current hour" : name, importPriceSensorNo == 0 ? "Current import price" : name,
PriceSensor.topic, "/prices",
path, path,
PriceSensor.ttl, resolution * 60 + 300,
uom.c_str(), uom.c_str(),
PriceSensor.devcl, "monetary",
i == 0 ? "total" : PriceSensor.stacl importPriceSensorNo == 0 ? "total" : "",
uid
}; };
publishSensor(sensor); publishSensor(sensor);
prInit[i] = true;
priceImportInit = importPriceSensorNo++;
}
} }
float exportPrice = ps->getPriceForRelativeHour(PRICE_DIRECTION_EXPORT, 0); if(priceExportInit < numberOfPoints-currentPricePointIndex) {
if(exportPrice != PRICE_NO_VALUE) { uint8_t exportPriceSensorNo = 0;
char path[20]; for(int pricePointIndex = currentPricePointIndex; pricePointIndex < numberOfPoints; pricePointIndex++) {
snprintf(path, 20, "exportprices['%d']", 0); float val = ps->getPricePoint(PRICE_DIRECTION_EXPORT, pricePointIndex);
if(val == PRICE_NO_VALUE) break;
if(exportPriceSensorNo < priceExportInit) {
exportPriceSensorNo++;
continue;
}
uint8_t resolution = ps->getResolutionInMinutes();
char path[64];
memset(path, 0, 64);
snprintf_P(path, 64, PSTR("prices.export[%d]"), exportPriceSensorNo);
char uid[32];
memset(uid, 0, 32);
snprintf_P(uid, 32, PSTR("exportprices%d"), exportPriceSensorNo);
char name[64];
if(resolution == 60)
snprintf_P(name, 64, PSTR("Export price in %02d hour%s"), exportPriceSensorNo, exportPriceSensorNo == 1 ? "" : "s");
else
snprintf_P(name, 64, PSTR("Export price in %03d minutes"), exportPriceSensorNo * resolution);
HomeAssistantSensor sensor = { HomeAssistantSensor sensor = {
"Export price current hour", exportPriceSensorNo == 0 ? "Current export price" : name,
PriceSensor.topic, "/prices",
path, path,
PriceSensor.ttl, resolution * 60 + 300,
uom.c_str(), uom.c_str(),
PriceSensor.devcl, "monetary",
"total" exportPriceSensorNo == 0 ? "total" : "",
uid
}; };
publishSensor(sensor); publishSensor(sensor);
preInit = true;
priceExportInit = exportPriceSensorNo++;
}
} }
} }
@@ -753,7 +819,8 @@ void HomeAssistantMqttHandler::publishThresholdSensors() {
RealtimeThresholdSensor.ttl, RealtimeThresholdSensor.ttl,
RealtimeThresholdSensor.uom, RealtimeThresholdSensor.uom,
RealtimeThresholdSensor.devcl, RealtimeThresholdSensor.devcl,
RealtimeThresholdSensor.stacl RealtimeThresholdSensor.stacl,
RealtimeThresholdSensor.uid
}; };
publishSensor(sensor); publishSensor(sensor);
} }
@@ -797,9 +864,10 @@ void HomeAssistantMqttHandler::onMessage(String &topic, String &payload) {
if (debugger->isActive(RemoteDebug::INFO)) if (debugger->isActive(RemoteDebug::INFO))
#endif #endif
debugger->printf_P(PSTR("Received online status from HA, resetting sensor status\n")); 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 = preInit = false; l1Init = l2Init = l2eInit = l3Init = l3eInit = l4Init = l4eInit = rtInit = rteInit = pInit = sInit = rInit = false;
for(uint8_t i = 0; i < 32; i++) tInit[i] = false; for(uint8_t i = 0; i < 32; i++) tInit[i] = false;
for(uint8_t i = 0; i < 38; i++) prInit[i] = false; priceImportInit = 0;
priceExportInit = 0;
} }
} else if(topic.equals(subTopic)) { } else if(topic.equals(subTopic)) {
if(payload.equals("fwupgrade")) { if(payload.equals("fwupgrade")) {