Continued implementation and changes after testing

This commit is contained in:
Gunnar Skjold
2026-03-26 14:16:27 +01:00
parent e91ef1a98c
commit ecd7017ac5
10 changed files with 637 additions and 531 deletions

View File

@@ -135,7 +135,7 @@ bool HomeAssistantMqttHandler::publishList1(AmsData* data, EnergyAccounting* ea)
char pt[24];
toJsonIsoTimestamp(data->getPackageTimestamp(), pt, sizeof(pt));
snprintf_P(json, BufferSize, HA1_JSON, data->getActiveImportPower(), pt);
snprintf_P(json, BUF_SIZE_COMMON, HA1_JSON, data->getActiveImportPower(), pt);
return mqtt.publish(pubTopic + "/power", json);
}
@@ -146,7 +146,7 @@ bool HomeAssistantMqttHandler::publishList2(AmsData* data, EnergyAccounting* ea)
char pt[24];
toJsonIsoTimestamp(data->getPackageTimestamp(), pt, sizeof(pt));
snprintf_P(json, BufferSize, HA3_JSON,
snprintf_P(json, BUF_SIZE_COMMON, HA3_JSON,
data->getListId().c_str(),
data->getMeterId().c_str(),
getMeterModel(data).c_str(),
@@ -176,7 +176,7 @@ bool HomeAssistantMqttHandler::publishList3(AmsData* data, EnergyAccounting* ea)
memset(pt, 0, 24);
toJsonIsoTimestamp(data->getPackageTimestamp(), pt, sizeof(pt));
snprintf_P(json, BufferSize, HA2_JSON,
snprintf_P(json, BUF_SIZE_COMMON, HA2_JSON,
data->getActiveImportCounter(),
data->getActiveExportCounter(),
data->getReactiveImportCounter(),
@@ -194,7 +194,7 @@ bool HomeAssistantMqttHandler::publishList4(AmsData* data, EnergyAccounting* ea)
char pt[24];
toJsonIsoTimestamp(data->getPackageTimestamp(), pt, sizeof(pt));
snprintf_P(json, BufferSize, HA4_JSON,
snprintf_P(json, BUF_SIZE_COMMON, HA4_JSON,
data->getListId().c_str(),
data->getMeterId().c_str(),
getMeterModel(data).c_str(),
@@ -246,7 +246,7 @@ bool HomeAssistantMqttHandler::publishRealtime(AmsData* data, EnergyAccounting*
if(!peaks.isEmpty()) peaks += ",";
peaks += String(ea->getPeak(i).value / 100.0, 2);
}
uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"max\":%.1f,\"peaks\":[%s],\"threshold\":%d,\"hour\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f},\"day\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f},\"month\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f}"),
uint16_t pos = snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"max\":%.1f,\"peaks\":[%s],\"threshold\":%d,\"hour\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f},\"day\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f},\"month\":{\"use\":%.2f,\"cost\":%.2f,\"produced\":%.2f,\"income\":%.2f}"),
ea->getMonthMax(),
peaks.c_str(),
ea->getCurrentThreshold(),
@@ -266,7 +266,7 @@ bool HomeAssistantMqttHandler::publishRealtime(AmsData* data, EnergyAccounting*
uint32_t ms = millis();
if(lastThresholdPublish == 0 || ms-lastThresholdPublish > 3600000) {
EnergyAccountingConfig* conf = ea->getConfig();
pos += snprintf_P(json+pos, BufferSize-pos, PSTR(",\"thresholds\": [%d,%d,%d,%d,%d,%d,%d,%d,%d]"),
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR(",\"thresholds\": [%d,%d,%d,%d,%d,%d,%d,%d,%d]"),
conf->thresholds[0],
conf->thresholds[1],
conf->thresholds[2],
@@ -283,7 +283,7 @@ bool HomeAssistantMqttHandler::publishRealtime(AmsData* data, EnergyAccounting*
time_t now = time(nullptr);
char pt[24];
toJsonIsoTimestamp(now, pt, sizeof(pt));
pos += snprintf_P(json+pos, BufferSize-pos, PSTR(",\"t\":%s"), pt);
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR(",\"t\":%s"), pt);
json[pos++] = '}';
json[pos] = '\0';
@@ -301,7 +301,7 @@ bool HomeAssistantMqttHandler::publishTemperatures(AmsConfiguration* config, HwT
TempSensorData* data = hw->getTempSensorData(i);
if(data != NULL) {
String id = toHex(data->address, 8);
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("\"%s\":%.2f,"),
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("\"%s\":%.2f,"),
id.c_str(),
data->lastRead
);
@@ -309,13 +309,13 @@ bool HomeAssistantMqttHandler::publishTemperatures(AmsConfiguration* config, HwT
publishTemperatureSensor(i+1, id);
}
}
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("}"));
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("}"));
time_t now = time(nullptr);
char pt[24];
toJsonIsoTimestamp(now, pt, sizeof(pt));
pos += snprintf_P(json+pos, BufferSize-pos, PSTR(",\"t\":%s"), pt);
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("}"));
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR(",\"t\":%s"), pt);
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("}"));
bool ret = mqtt.publish(pubTopic + "/temperatures", json);
loop();
@@ -416,33 +416,33 @@ bool HomeAssistantMqttHandler::publishPrices(PriceService* ps) {
toJsonIsoTimestamp(ts, ts6hr, sizeof(ts6hr));
}
uint16_t pos = snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"prices\":{\"import\":["), WiFi.macAddress().c_str());
uint16_t pos = snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"id\":\"%s\",\"prices\":{\"import\":["), WiFi.macAddress().c_str());
uint8_t currentPricePointIndex = ps->getCurrentPricePointIndex();
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,"));
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("null,"));
} else {
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val);
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("%.4f,"), val);
}
}
if(rteInit && ps->isExportPricesDifferentFromImport()) {
pos--;
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("],\"export\":["));
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-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,"));
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("null,"));
} else {
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("%.4f,"), val);
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR("%.4f,"), val);
}
}
}
pos--;
pos += snprintf_P(json+pos, BufferSize-pos, PSTR("],\"min\":%.4f,\"max\":%.4f,\"cheapest1hr\":%s,\"cheapest3hr\":%s,\"cheapest6hr\":%s}"),
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-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,
@@ -452,7 +452,7 @@ bool HomeAssistantMqttHandler::publishPrices(PriceService* ps) {
char pt[24];
toJsonIsoTimestamp(now, pt, sizeof(pt));
pos += snprintf_P(json+pos, BufferSize-pos, PSTR(",\"t\":%s"), pt);
pos += snprintf_P(json+pos, BUF_SIZE_COMMON-pos, PSTR(",\"t\":%s"), pt);
json[pos++] = '}';
json[pos] = '\0';
@@ -473,7 +473,7 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw, PriceService* ps, Ener
char pt[24];
toJsonIsoTimestamp(now, pt, sizeof(pt));
snprintf_P(json, BufferSize, PSTR("{\"id\":\"%s\",\"name\":\"%s\",\"up\":%d,\"vcc\":%.3f,\"rssi\":%d,\"temp\":%.2f,\"version\":\"%s\",\"t\":%s}"),
snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"id\":\"%s\",\"name\":\"%s\",\"up\":%d,\"vcc\":%.3f,\"rssi\":%d,\"temp\":%.2f,\"version\":\"%s\",\"t\":%s}"),
WiFi.macAddress().c_str(),
mqttConfig.clientId,
(uint32_t) (millis64()/1000),
@@ -499,7 +499,7 @@ void HomeAssistantMqttHandler::publishSensor(const HomeAssistantSensor sensor) {
uid.replace("]", "");
uid.replace("'", "");
}
snprintf_P(json, BufferSize, HADISCOVER_JSON,
snprintf_P(json, BUF_SIZE_COMMON, HADISCOVER_JSON,
sensorNamePrefix.c_str(),
sensor.name,
mqttConfig.publishTopic, sensor.topic,
@@ -805,7 +805,7 @@ bool HomeAssistantMqttHandler::publishRaw(uint8_t* raw, size_t length) {
if(strlen(mqttConfig.publishTopic) == 0 || !mqtt.connected())
return false;
if(length <= 0 || length > BufferSize) return false;
if(length <= 0 || length > BUF_SIZE_COMMON) return false;
if(!dInit) {
// Not sure how this sensor should be defined in HA, so skipping for now
@@ -815,7 +815,7 @@ bool HomeAssistantMqttHandler::publishRaw(uint8_t* raw, size_t length) {
String str = toHex(raw, length);
snprintf_P(json, BufferSize, PSTR("{\"data\":\"%s\"}"), str.c_str());
snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"data\":\"%s\"}"), str.c_str());
char topic[192];
snprintf_P(topic, 192, PSTR("%s/data"), mqttConfig.publishTopic);
bool ret = mqtt.publish(topic, json);
@@ -825,7 +825,7 @@ bool HomeAssistantMqttHandler::publishRaw(uint8_t* raw, size_t length) {
bool HomeAssistantMqttHandler::publishFirmware() {
if(!fInit) {
snprintf_P(json, BufferSize, PSTR("{\"name\":\"%sFirmware\",\"stat_t\":\"%s/firmware\",\"uniq_id\":\"%s_fwupgrade\",\"dev_cla\":\"firmware\",\"cmd_t\":\"%s\",\"pl_inst\":\"fwupgrade\"}"),
snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"name\":\"%sFirmware\",\"stat_t\":\"%s/firmware\",\"uniq_id\":\"%s_fwupgrade\",\"dev_cla\":\"firmware\",\"cmd_t\":\"%s\",\"pl_inst\":\"fwupgrade\"}"),
sensorNamePrefix.c_str(),
pubTopic.c_str(),
deviceUid.c_str(),
@@ -835,7 +835,7 @@ bool HomeAssistantMqttHandler::publishFirmware() {
loop();
return fInit;
}
snprintf_P(json, BufferSize, PSTR("{\"installed_version\":\"%s\",\"latest_version\":\"%s\",\"title\":\"amsreader firmware\",\"release_url\":\"https://github.com/UtilitechAS/amsreader-firmware/releases\",\"release_summary\":\"New version %s is available\",\"update_percentage\":%s}"),
snprintf_P(json, BUF_SIZE_COMMON, PSTR("{\"installed_version\":\"%s\",\"latest_version\":\"%s\",\"title\":\"amsreader firmware\",\"release_url\":\"https://github.com/UtilitechAS/amsreader-firmware/releases\",\"release_summary\":\"New version %s is available\",\"update_percentage\":%s}"),
FirmwareVersion::VersionString,
strlen(updater->getNextVersion()) == 0 ? FirmwareVersion::VersionString : updater->getNextVersion(),
strlen(updater->getNextVersion()) == 0 ? FirmwareVersion::VersionString : updater->getNextVersion(),