Various fixes for HA

This commit is contained in:
Gunnar Skjold
2023-03-26 15:12:24 +02:00
parent be522b40f9
commit 0178dc4184
13 changed files with 423 additions and 131 deletions

View File

@@ -17,7 +17,7 @@ public:
};
virtual ~AmsMqttHandler() {};
virtual bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea);
virtual bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea, EntsoeApi* eapi);
virtual bool publishTemperatures(AmsConfiguration*, HwTools*);
virtual bool publishPrices(EntsoeApi* eapi);
virtual bool publishSystem(HwTools*, EntsoeApi*, EnergyAccounting*);

View File

@@ -9,7 +9,7 @@ public:
DomoticzMqttHandler(MQTTClient* mqtt, char* buf, DomoticzConfig config) : AmsMqttHandler(mqtt, buf) {
this->config = config;
};
bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea);
bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea, EntsoeApi* eapi);
bool publishTemperatures(AmsConfiguration*, HwTools*);
bool publishPrices(EntsoeApi*);
bool publishSystem(HwTools* hw, EntsoeApi* eapi, EnergyAccounting* ea);

View File

@@ -1,7 +1,7 @@
#include "DomoticzMqttHandler.h"
#include "json/domoticz_json.h"
bool DomoticzMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea) {
bool DomoticzMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea, EntsoeApi* eapi) {
bool ret = false;
if (config.elidx > 0) {
if(data->getActiveImportCounter() > 1.0) {

View File

@@ -2,6 +2,7 @@
#define _HOMEASSISTANTMQTTHANDLER_H
#include "AmsMqttHandler.h"
#include "HomeAssistantStatic.h"
class HomeAssistantMqttHandler : public AmsMqttHandler {
public:
@@ -9,12 +10,28 @@ public:
this->clientId = clientId;
this->topic = String(topic);
this->hw = hw;
l1Init = l2Init = l2eInit = l3Init = l3eInit = l4Init = l4eInit = rtInit = rteInit = pInit = sInit = false;
};
bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea);
bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea, EntsoeApi* eapi);
bool publishTemperatures(AmsConfiguration*, HwTools*);
bool publishPrices(EntsoeApi*);
bool publishSystem(HwTools* hw, EntsoeApi* eapi, EnergyAccounting* ea);
void publishSensor(const HomeAssistantSensor& sensor);
void publishList1Sensors();
void publishList1ExportSensors();
void publishList2Sensors();
void publishList2ExportSensors();
void publishList3Sensors();
void publishList3ExportSensors();
void publishList4Sensors();
void publishList4ExportSensors();
void publishRealtimeSensors(EnergyAccounting* ea, EntsoeApi* eapi);
void publishRealtimeExportSensors(EnergyAccounting* ea, EntsoeApi* eapi);
void publishTemperatureSensor(uint8_t index, String id);
void publishPriceSensors(EntsoeApi* eapi);
void publishSystemSensors();
private:
String haTopic = "homeassistant/sensor/";
@@ -26,7 +43,9 @@ private:
#endif
String haManuf = "AmsToMqttBridge";
bool autodiscoverInit = false;
bool l1Init, l2Init, l2eInit, l3Init, l3eInit, l4Init, l4eInit, rtInit, rteInit, pInit, sInit;
bool tInit[32] = {false};
bool prInit[38] = {false};
String clientId;
String topic;

View File

@@ -3,7 +3,7 @@
#include "Arduino.h"
struct HomeAssistantSensor {
typedef struct HomeAssistantSensor {
const char* name;
const char* topic;
const char* path;
@@ -13,69 +13,100 @@ struct HomeAssistantSensor {
};
const uint8_t HA_SENSOR_COUNT PROGMEM = 60;
HomeAssistantSensor HA_SENSORS[HA_SENSOR_COUNT] PROGMEM = {
{"Status", "/state", "rssi", "dBm", "signal_strength", "\"measurement\""},
{"Supply volt", "/state", "vcc", "V", "voltage", "\"measurement\""},
{"Temperature", "/state", "temp", "°C", "temperature", "\"measurement\""},
{"Active import", "/power", "P", "W", "power", "\"measurement\""},
{"L1 active import", "/power", "P1", "W", "power", "\"measurement\""},
{"L2 active import", "/power", "P2", "W", "power", "\"measurement\""},
{"L3 active import", "/power", "P3", "W", "power", "\"measurement\""},
const uint8_t List1SensorCount PROGMEM = 1;
const HomeAssistantSensor List1Sensors[List1SensorCount] PROGMEM = {
{"Active import", "/power", "P", "W", "power", "\"measurement\""}
};
const uint8_t List2SensorCount PROGMEM = 8;
const HomeAssistantSensor List2Sensors[List2SensorCount] PROGMEM = {
{"Reactive import", "/power", "Q", "var", "reactive_power", "\"measurement\""},
{"Active export", "/power", "PO", "W", "power", "\"measurement\""},
{"L1 active export", "/power", "PO1", "W", "power", "\"measurement\""},
{"L2 active export", "/power", "PO2", "W", "power", "\"measurement\""},
{"L3 active export", "/power", "PO3", "W", "power", "\"measurement\""},
{"Reactive export", "/power", "QO", "var", "reactive_power", "\"measurement\""},
{"L1 current", "/power", "I1", "A", "current", "\"measurement\""},
{"L2 current", "/power", "I2", "A", "current", "\"measurement\""},
{"L3 current", "/power", "I3", "A", "current", "\"measurement\""},
{"L1 voltage", "/power", "U1", "V", "voltage", "\"measurement\""},
{"L2 voltage", "/power", "U2", "V", "voltage", "\"measurement\""},
{"L3 voltage", "/power", "U3", "V", "voltage", "\"measurement\""},
{"L3 voltage", "/power", "U3", "V", "voltage", "\"measurement\""}
};
const uint8_t List2ExportSensorCount PROGMEM = 1;
const HomeAssistantSensor List2ExportSensors[List2ExportSensorCount] PROGMEM = {
{"Active export", "/power", "PO", "W", "power", "\"measurement\""}
};
const uint8_t List3SensorCount PROGMEM = 3;
const HomeAssistantSensor List3Sensors[List3SensorCount] PROGMEM = {
{"Accumulated active import", "/energy", "tPI", "kWh", "energy", "\"total_increasing\""},
{"Accumulated active export", "/energy", "tPO", "kWh", "energy", "\"total_increasing\""},
{"Accumulated reactive import","/energy", "tQI", "kvarh","energy", "\"total_increasing\""},
{"Accumulated reactive export","/energy", "tQO", "kvarh","energy", "\"total_increasing\""},
{"Accumulated reactive import","/energy", "tQI", "", "energy", "\"total_increasing\""},
{"Accumulated reactive export","/energy", "tQO", "", "energy", "\"total_increasing\""}
};
const uint8_t List3ExportSensorCount PROGMEM = 1;
const HomeAssistantSensor List3ExportSensors[List3ExportSensorCount] PROGMEM = {
{"Accumulated active export", "/energy", "tPO", "kWh", "energy", "\"total_increasing\""}
};
const uint8_t List4SensorCount PROGMEM = 7;
const HomeAssistantSensor List4Sensors[List4SensorCount] PROGMEM = {
{"Power factor", "/power", "PF", "%", "power_factor", "\"measurement\""},
{"L1 power factor", "/power", "PF1", "%", "power_factor", "\"measurement\""},
{"L2 power factor", "/power", "PF2", "%", "power_factor", "\"measurement\""},
{"L3 power factor", "/power", "PF3", "%", "power_factor", "\"measurement\""},
{"Price current hour", "/prices", "prices['0']", "", "monetary", ""},
{"Price next hour", "/prices", "prices['1']", "", "monetary", ""},
{"Price in two hour", "/prices", "prices['2']", "", "monetary", ""},
{"Price in three hour", "/prices", "prices['3']", "", "monetary", ""},
{"Price in four hour", "/prices", "prices['4']", "", "monetary", ""},
{"Price in five hour", "/prices", "prices['5']", "", "monetary", ""},
{"Price in six hour", "/prices", "prices['6']", "", "monetary", ""},
{"Price in seven hour", "/prices", "prices['7']", "", "monetary", ""},
{"Price in eight hour", "/prices", "prices['8']", "", "monetary", ""},
{"Price in nine hour", "/prices", "prices['9']", "", "monetary", ""},
{"Price in ten hour", "/prices", "prices['10']", "", "monetary", ""},
{"Price in eleven hour", "/prices", "prices['11']", "", "monetary", ""},
{"L1 active import", "/power", "P1", "W", "power", "\"measurement\""},
{"L2 active import", "/power", "P2", "W", "power", "\"measurement\""},
{"L3 active import", "/power", "P3", "W", "power", "\"measurement\""}
};
const uint8_t List4ExportSensorCount PROGMEM = 3;
const HomeAssistantSensor List4ExportSensors[List4ExportSensorCount] PROGMEM = {
{"L1 active export", "/power", "PO1", "W", "power", "\"measurement\""},
{"L2 active export", "/power", "PO2", "W", "power", "\"measurement\""},
{"L3 active export", "/power", "PO3", "W", "power", "\"measurement\""}
};
const uint8_t RealtimeSensorCount PROGMEM = 8;
const HomeAssistantSensor RealtimeSensors[RealtimeSensorCount] PROGMEM = {
{"Month max", "/realtime","max", "kWh", "energy", ""},
{"Tariff threshold", "/realtime","threshold", "kWh", "energy", ""},
{"Current hour used", "/realtime","hour.use", "kWh", "energy", ""},
{"Current hour cost", "/realtime","hour.cost", "", "monetary", ""},
{"Current day used", "/realtime","day.use", "kWh", "energy", ""},
{"Current day cost", "/realtime","day.cost", "", "monetary", ""},
{"Current month used", "/realtime","month.use", "kWh", "energy", ""},
{"Current month cost", "/realtime","month.cost", "", "monetary", ""}
};
const uint8_t RealtimeExportSensorCount PROGMEM = 6;
const HomeAssistantSensor RealtimeExportSensors[RealtimeExportSensorCount] PROGMEM = {
{"Current hour produced", "/realtime","hour.produced", "kWh", "energy", ""},
{"Current hour income", "/realtime","hour.income", "", "monetary", ""},
{"Current day produced", "/realtime","day.produced", "kWh", "energy", ""},
{"Current day income", "/realtime","day.income", "", "monetary", ""},
{"Current month produced", "/realtime","month.produced", "kWh", "energy", ""},
{"Current month income", "/realtime","month.income", "", "monetary", ""}
};
const HomeAssistantSensor RealtimePeakSensor PROGMEM = {"Current month peak %d", "/realtime", "peaks[%d]", "kWh", "energy", ""};
const uint8_t PriceSensorCount PROGMEM = 5;
const HomeAssistantSensor PriceSensors[PriceSensorCount] PROGMEM = {
{"Minimum price ahead", "/prices", "prices.min", "", "monetary", ""},
{"Maximum price ahead", "/prices", "prices.max", "", "monetary", ""},
{"Cheapest 1hr period ahead", "/prices", "prices.cheapest1hr","", "timestamp", ""},
{"Cheapest 3hr period ahead", "/prices", "prices.cheapest3hr","", "timestamp", ""},
{"Cheapest 6hr period ahead", "/prices", "prices.cheapest6hr","", "timestamp", ""},
{"Month max", "/realtime","max", "kWh", "energy", "\"total_increasing\""},
{"Tariff threshold", "/realtime","threshold", "kWh", "energy", "\"total_increasing\""},
{"Current hour used", "/realtime","hour.use", "kWh", "energy", "\"total_increasing\""},
{"Current hour cost", "/realtime","hour.cost", "", "monetary", "\"total_increasing\""},
{"Current hour produced", "/realtime","hour.produced", "kWh", "energy", "\"total_increasing\""},
{"Current day used", "/realtime","day.use", "kWh", "energy", "\"total_increasing\""},
{"Current day cost", "/realtime","day.cost", "", "monetary", "\"total_increasing\""},
{"Current day produced", "/realtime","day.produced", "kWh", "energy", "\"total_increasing\""},
{"Current month used", "/realtime","month.use", "kWh", "energy", "\"total_increasing\""},
{"Current month cost", "/realtime","month.cost", "", "monetary", "\"total_increasing\""},
{"Current month produced", "/realtime","month.produced", "kWh", "energy", "\"total_increasing\""},
{"Current month peak 1", "/realtime","peaks[0]", "kWh", "energy", ""},
{"Current month peak 2", "/realtime","peaks[1]", "kWh", "energy", ""},
{"Current month peak 3", "/realtime","peaks[2]", "kWh", "energy", ""},
{"Current month peak 4", "/realtime","peaks[3]", "kWh", "energy", ""},
{"Current month peak 5", "/realtime","peaks[4]", "kWh", "energy", ""},
{"Cheapest 6hr period ahead", "/prices", "prices.cheapest6hr","", "timestamp", ""}
};
const HomeAssistantSensor PriceSensor PROGMEM = {"Price in %02d %s", "/prices", "prices['%d']", "", "monetary", ""};
const uint8_t SystemSensorCount PROGMEM = 2;
const HomeAssistantSensor SystemSensors[SystemSensorCount] PROGMEM = {
{"Status", "/state", "rssi", "dBm", "signal_strength", "\"measurement\""},
{"Supply volt", "/state", "vcc", "V", "voltage", "\"measurement\""}
};
const HomeAssistantSensor TemperatureSensor PROGMEM = {"Temperature sensor %s", "/temperatures", "temperatures['%s']", "°C", "temperature", "\"measurement\""};
#endif

View File

@@ -5,16 +5,19 @@
"hour" : {
"use" : %.2f,
"cost" : %.2f,
"produced" : %.2f
"produced" : %.2f,
"income" : %.2f
},
"day" : {
"use" : %.2f,
"cost" : %.2f,
"produced" : %.2f
"produced" : %.2f,
"income" : %.2f
},
"month" : {
"use" : %.2f,
"cost" : %.2f,
"produced" : %.2f
"produced" : %.2f,
"income" : %.2f
}
}

View File

@@ -1,5 +1,4 @@
#include "HomeAssistantMqttHandler.h"
#include "HomeAssistantStatic.h"
#include "hexutils.h"
#include "Uptime.h"
#include "version.h"
@@ -12,11 +11,13 @@
#include "json/hadiscover_json.h"
#include "json/realtime_json.h"
bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea) {
bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea, EntsoeApi* eapi) {
if(topic.isEmpty() || !mqtt->connected())
return false;
if(data->getListType() >= 3) { // publish energy counts
publishList3Sensors();
if(data->getActiveExportCounter() > 0.0) publishList3ExportSensors();
snprintf_P(json, BufferSize, HA2_JSON,
data->getActiveImportCounter(),
data->getActiveExportCounter(),
@@ -30,11 +31,14 @@ bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, En
String meterModel = data->getMeterModel();
meterModel.replace("\\", "\\\\");
if(data->getListType() == 1) { // publish power counts
publishList1Sensors();
snprintf_P(json, BufferSize, HA1_JSON,
data->getActiveImportPower()
);
mqtt->publish(topic + "/power", json);
} else if(data->getListType() <= 3) { // publish power counts and volts/amps
publishList2Sensors();
if(data->getActiveExportPower() > 0) publishList2ExportSensors();
snprintf_P(json, BufferSize, HA3_JSON,
data->getListId().c_str(),
data->getMeterId().c_str(),
@@ -52,6 +56,8 @@ bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, En
);
mqtt->publish(topic + "/power", json);
} else if(data->getListType() == 4) { // publish power counts and volts/amps/phase power and PF
publishList4Sensors();
if(data->getL1ActiveExportPower() > 0 || data->getL2ActiveExportPower() > 0 || data->getL3ActiveExportPower() > 0) publishList4ExportSensors();
snprintf_P(json, BufferSize, HA4_JSON,
data->getListId().c_str(),
data->getMeterId().c_str(),
@@ -81,6 +87,8 @@ bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, En
}
if(ea->isInitialized()) {
publishRealtimeSensors(ea, eapi);
if(ea->getProducedThisHour() > 0.0 || ea->getProducedToday() > 0.0 || ea->getProducedThisMonth() > 0.0) publishRealtimeExportSensors(ea, eapi);
String peaks = "";
uint8_t peakCount = ea->getConfig()->hours;
if(peakCount > 5) peakCount = 5;
@@ -95,12 +103,15 @@ bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, En
ea->getUseThisHour(),
ea->getCostThisHour(),
ea->getProducedThisHour(),
ea->getIncomeThisHour(),
ea->getUseToday(),
ea->getCostToday(),
ea->getProducedToday(),
ea->getIncomeToday(),
ea->getUseThisMonth(),
ea->getCostThisMonth(),
ea->getProducedThisMonth()
ea->getProducedThisMonth(),
ea->getIncomeThisMonth()
);
mqtt->publish(topic + "/realtime", json);
}
@@ -110,7 +121,7 @@ bool HomeAssistantMqttHandler::publish(AmsData* data, AmsData* previousState, En
bool HomeAssistantMqttHandler::publishTemperatures(AmsConfiguration* config, HwTools* hw) {
int count = hw->getTempSensorCount();
if(count == 0) return false;
if(count < 2) return false;
int size = 32 + (count * 26);
@@ -121,11 +132,13 @@ bool HomeAssistantMqttHandler::publishTemperatures(AmsConfiguration* config, HwT
TempSensorData* data = hw->getTempSensorData(i);
if(data != NULL) {
char* pos = buf+strlen(buf);
String id = toHex(data->address, 8);
snprintf(pos, 26, "\"%s\":%.2f,",
toHex(data->address, 8).c_str(),
id.c_str(),
data->lastRead
);
data->changed = false;
publishTemperatureSensor(i+1, id);
delay(1);
}
}
@@ -140,14 +153,16 @@ bool HomeAssistantMqttHandler::publishPrices(EntsoeApi* eapi) {
if(eapi->getValueForHour(0) == ENTSOE_NO_VALUE)
return false;
publishPriceSensors(eapi);
time_t now = time(nullptr);
float min1hr = 0.0, min3hr = 0.0, min6hr = 0.0;
int8_t min1hrIdx = -1, min3hrIdx = -1, min6hrIdx = -1;
float min = INT16_MAX, max = INT16_MIN;
float values[24];
for(int i = 0;i < 24; i++) values[i] = ENTSOE_NO_VALUE;
for(uint8_t i = 0; i < 24; i++) {
float values[38];
for(int i = 0;i < 38; i++) values[i] = ENTSOE_NO_VALUE;
for(uint8_t i = 0; i < 38; i++) {
float val = eapi->getValueForHour(now, i);
values[i] = val;
@@ -234,6 +249,32 @@ bool HomeAssistantMqttHandler::publishPrices(EntsoeApi* eapi) {
values[9],
values[10],
values[11],
values[12],
values[13],
values[14],
values[15],
values[16],
values[17],
values[18],
values[19],
values[20],
values[21],
values[22],
values[23],
values[24],
values[25],
values[26],
values[27],
values[28],
values[29],
values[30],
values[31],
values[32],
values[33],
values[34],
values[35],
values[36],
values[37],
min == INT16_MAX ? 0.0 : min,
max == INT16_MIN ? 0.0 : max,
ts1hr,
@@ -247,6 +288,9 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw, EntsoeApi* eapi, Energ
if(topic.isEmpty() || !mqtt->connected())
return false;
publishSystemSensors();
if(hw->getTemperature() > -50) publishTemperatureSensor(0, "");
snprintf_P(json, BufferSize, JSONSYS_JSON,
WiFi.macAddress().c_str(),
clientId.c_str(),
@@ -256,64 +300,207 @@ bool HomeAssistantMqttHandler::publishSystem(HwTools* hw, EntsoeApi* eapi, Energ
hw->getTemperature(),
VERSION
);
mqtt->publish(topic + "/state", json);
if(!autodiscoverInit) {
#if defined(ESP8266)
String haUID = WiFi.hostname();
#elif defined(ESP32)
String haUID = WiFi.getHostname();
#endif
String haUrl = "http://" + haUID + ".local/";
// Could this be necessary? haUID.replace("-", "_");
uint8_t peakCount = ea->getConfig()->hours;
if(peakCount > 5) peakCount = 5;
uint8_t peaks = 0;
for(int i=0;i<HA_SENSOR_COUNT;i++) {
HomeAssistantSensor sensor = HA_SENSORS[i];
String uid = String(sensor.path);
uid.replace(".", "");
uid.replace("[", "");
uid.replace("]", "");
uid.replace("'", "");
String uom = String(sensor.uom);
if(strncmp(sensor.devcl, "monetary", 8) == 0) {
if(eapi == NULL) continue;
if(strncmp(sensor.path, "prices", 5) == 0) {
uom = String(eapi->getCurrency()) + "/kWh";
} else {
uom = String(eapi->getCurrency());
}
}
if(strncmp(sensor.path, "peaks[", 6) == 0) {
if(peaks >= peakCount) continue;
peaks++;
}
if(strncmp(sensor.path, "temp", 4) == 0) {
if(hw->getTemperature() < 0) continue;
}
snprintf_P(json, BufferSize, HADISCOVER_JSON,
sensor.name,
topic.c_str(), sensor.topic,
haUID.c_str(), uid.c_str(),
haUID.c_str(), uid.c_str(),
uom.c_str(),
sensor.path,
sensor.devcl,
haUID.c_str(),
haName.c_str(),
haModel.c_str(),
VERSION,
haManuf.c_str(),
haUrl.c_str(),
strlen_P(sensor.stacl) > 0 ? ", \"stat_cla\" :" : "",
strlen_P(sensor.stacl) > 0 ? (char *) FPSTR(sensor.stacl) : ""
);
mqtt->publish(haTopic + haUID + "_" + uid.c_str() + "/config", json, true, 0);
}
autodiscoverInit = true;
}
return true;
return mqtt->publish(topic + "/state", json);
}
void HomeAssistantMqttHandler::publishSensor(const HomeAssistantSensor& sensor) {
#if defined(ESP8266)
String haUID = WiFi.hostname();
#elif defined(ESP32)
String haUID = WiFi.getHostname();
#endif
String haUrl = "http://" + haUID + ".local/";
String uid = String(sensor.path);
uid.replace(".", "");
uid.replace("[", "");
uid.replace("]", "");
uid.replace("'", "");
String uom = String(sensor.uom);
snprintf_P(json, BufferSize, HADISCOVER_JSON,
sensor.name,
topic.c_str(), sensor.topic,
haUID.c_str(), uid.c_str(),
haUID.c_str(), uid.c_str(),
uom.c_str(),
sensor.path,
sensor.devcl,
haUID.c_str(),
haName.c_str(),
haModel.c_str(),
VERSION,
haManuf.c_str(),
haUrl.c_str(),
strlen_P(sensor.stacl) > 0 ? ", \"stat_cla\" :" : "",
strlen_P(sensor.stacl) > 0 ? (char *) FPSTR(sensor.stacl) : ""
);
mqtt->publish(haTopic + haUID + "_" + uid.c_str() + "/config", json, true, 0);
}
void HomeAssistantMqttHandler::publishList1Sensors() {
if(l1Init) return;
for(uint8_t i = 0; i < List1SensorCount; i++) {
publishSensor(List1Sensors[i]);
}
l1Init = true;
}
void HomeAssistantMqttHandler::publishList2Sensors() {
if(l2Init) return;
for(uint8_t i = 0; i < List2SensorCount; i++) {
publishSensor(List2Sensors[i]);
}
l2Init = true;
}
void HomeAssistantMqttHandler::publishList2ExportSensors() {
if(l2eInit) return;
for(uint8_t i = 0; i < List2ExportSensorCount; i++) {
publishSensor(List2ExportSensors[i]);
}
l2eInit = true;
}
void HomeAssistantMqttHandler::publishList3Sensors() {
if(l3Init) return;
for(uint8_t i = 0; i < List3SensorCount; i++) {
publishSensor(List3Sensors[i]);
}
l3Init = true;
}
void HomeAssistantMqttHandler::publishList3ExportSensors() {
if(l3eInit) return;
for(uint8_t i = 0; i < List3ExportSensorCount; i++) {
publishSensor(List3ExportSensors[i]);
}
l3eInit = true;
}
void HomeAssistantMqttHandler::publishList4Sensors() {
if(l4Init) return;
for(uint8_t i = 0; i < List4SensorCount; i++) {
publishSensor(List4Sensors[i]);
}
l4Init = true;
}
void HomeAssistantMqttHandler::publishList4ExportSensors() {
if(l4eInit) return;
for(uint8_t i = 0; i < List4ExportSensorCount; i++) {
publishSensor(List4ExportSensors[i]);
}
l4eInit = true;
}
void HomeAssistantMqttHandler::publishRealtimeSensors(EnergyAccounting* ea, EntsoeApi* eapi) {
if(rtInit) return;
for(uint8_t i = 0; i < RealtimeSensorCount; i++) {
HomeAssistantSensor sensor = RealtimeSensors[i];
if(strncmp(sensor.devcl, "monetary", 8) == 0) {
if(eapi == NULL) continue;
sensor.uom = eapi->getCurrency();
}
publishSensor(sensor);
}
uint8_t peakCount = ea->getConfig()->hours;
if(peakCount > 5) peakCount = 5;
for(uint8_t i = 0; i < peakCount; i++) {
char name[strlen(RealtimePeakSensor.name)];
snprintf(name, strlen(RealtimePeakSensor.name), RealtimePeakSensor.name, i+1);
char path[strlen(RealtimePeakSensor.path)];
snprintf(path, strlen(RealtimePeakSensor.path), RealtimePeakSensor.path, i+1);
HomeAssistantSensor sensor = {
name,
RealtimePeakSensor.topic,
path,
RealtimePeakSensor.uom,
RealtimePeakSensor.devcl,
RealtimePeakSensor.stacl
};
publishSensor(sensor);
}
rtInit = true;
}
void HomeAssistantMqttHandler::publishRealtimeExportSensors(EnergyAccounting* ea, EntsoeApi* eapi) {
if(rteInit) return;
for(uint8_t i = 0; i < RealtimeExportSensorCount; i++) {
HomeAssistantSensor sensor = RealtimeExportSensors[i];
if(strncmp(sensor.devcl, "monetary", 8) == 0) {
if(eapi == NULL) continue;
sensor.uom = eapi->getCurrency();
}
publishSensor(sensor);
}
rteInit = true;
}
void HomeAssistantMqttHandler::publishTemperatureSensor(uint8_t index, String id) {
if(index > 32) return;
if(tInit[index]) return;
char name[strlen(TemperatureSensor.name)+id.length()];
snprintf(name, strlen(TemperatureSensor.name)+id.length(), TemperatureSensor.name, id.c_str());
char path[strlen(TemperatureSensor.path)+id.length()];
if(index == 0) {
memcpy_P(path, PSTR("temp\0"), 5);
} else {
snprintf(path, strlen(TemperatureSensor.path)+id.length(), TemperatureSensor.path, id.c_str());
}
HomeAssistantSensor sensor = {
name,
index == 0 ? SystemSensors[0].topic : TemperatureSensor.topic,
path,
TemperatureSensor.uom,
TemperatureSensor.devcl,
TemperatureSensor.stacl
};
publishSensor(sensor);
tInit[index] = true;
}
void HomeAssistantMqttHandler::publishPriceSensors(EntsoeApi* eapi) {
if(eapi == NULL) return;
String uom = String(eapi->getCurrency()) + "/kWh";
if(!pInit) {
for(uint8_t i = 0; i < PriceSensorCount; i++) {
HomeAssistantSensor sensor = PriceSensors[i];
if(strncmp(sensor.devcl, "monetary", 8) == 0) {
sensor.uom = uom.c_str();
}
publishSensor(sensor);
}
pInit = true;
}
for(uint8_t i = 0; i < 38; i++) {
if(prInit[i]) continue;
float val = eapi->getValueForHour(i);
if(val == ENTSOE_NO_VALUE) continue;
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 = {
i == 0 ? "Price current hour" : name,
PriceSensor.topic,
path,
uom.c_str(),
PriceSensor.devcl,
PriceSensor.stacl
};
publishSensor(sensor);
prInit[i] = true;
}
}
void HomeAssistantMqttHandler::publishSystemSensors() {
if(sInit) return;
for(uint8_t i = 0; i < SystemSensorCount; i++) {
publishSensor(SystemSensors[i]);
}
sInit = true;
}

View File

@@ -10,7 +10,7 @@ public:
this->topic = String(topic);
this->hw = hw;
};
bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea);
bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea, EntsoeApi* eapi);
bool publishTemperatures(AmsConfiguration*, HwTools*);
bool publishPrices(EntsoeApi*);
bool publishSystem(HwTools* hw, EntsoeApi* eapi, EnergyAccounting* ea);

View File

@@ -13,6 +13,32 @@
"9" : %.4f,
"10" : %.4f,
"11" : %.4f,
"12" : %.4f,
"13" : %.4f,
"14" : %.4f,
"15" : %.4f,
"16" : %.4f,
"17" : %.4f,
"18" : %.4f,
"19" : %.4f,
"20" : %.4f,
"21" : %.4f,
"22" : %.4f,
"23" : %.4f,
"24" : %.4f,
"25" : %.4f,
"26" : %.4f,
"27" : %.4f,
"28" : %.4f,
"29" : %.4f,
"30" : %.4f,
"31" : %.4f,
"32" : %.4f,
"33" : %.4f,
"34" : %.4f,
"35" : %.4f,
"36" : %.4f,
"37" : %.4f,
"min" : %.4f,
"max" : %.4f,
"cheapest1hr" : "%s",

View File

@@ -9,7 +9,7 @@
#include "json/jsonsys_json.h"
#include "json/jsonprices_json.h"
bool JsonMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea) {
bool JsonMqttHandler::publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea, EntsoeApi* eapi) {
if(topic.isEmpty() || !mqtt->connected())
return false;
@@ -183,9 +183,9 @@ bool JsonMqttHandler::publishPrices(EntsoeApi* eapi) {
float min1hr = 0.0, min3hr = 0.0, min6hr = 0.0;
int8_t min1hrIdx = -1, min3hrIdx = -1, min6hrIdx = -1;
float min = INT16_MAX, max = INT16_MIN;
float values[24];
for(int i = 0;i < 24; i++) values[i] = ENTSOE_NO_VALUE;
for(uint8_t i = 0; i < 24; i++) {
float values[38];
for(int i = 0;i < 38; i++) values[i] = ENTSOE_NO_VALUE;
for(uint8_t i = 0; i < 38; i++) {
float val = eapi->getValueForHour(now, i);
values[i] = val;
@@ -272,6 +272,32 @@ bool JsonMqttHandler::publishPrices(EntsoeApi* eapi) {
values[9],
values[10],
values[11],
values[12],
values[13],
values[14],
values[15],
values[16],
values[17],
values[18],
values[19],
values[20],
values[21],
values[22],
values[23],
values[24],
values[25],
values[26],
values[27],
values[28],
values[29],
values[30],
values[31],
values[32],
values[33],
values[34],
values[35],
values[36],
values[37],
min == INT16_MAX ? 0.0 : min,
max == INT16_MIN ? 0.0 : max,
ts1hr,

View File

@@ -9,7 +9,7 @@ public:
this->topic = String(topic);
this->full = full;
};
bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea);
bool publish(AmsData* data, AmsData* previousState, EnergyAccounting* ea, EntsoeApi* eapi);
bool publishTemperatures(AmsConfiguration*, HwTools*);
bool publishPrices(EntsoeApi*);
bool publishSystem(HwTools* hw, EntsoeApi* eapi, EnergyAccounting* ea);

View File

@@ -2,7 +2,7 @@
#include "hexutils.h"
#include "Uptime.h"
bool RawMqttHandler::publish(AmsData* data, AmsData* meterState, EnergyAccounting* ea) {
bool RawMqttHandler::publish(AmsData* data, AmsData* meterState, EnergyAccounting* ea, EntsoeApi* eapi) {
if(topic.isEmpty() || !mqtt->connected())
return false;