Browse Source

Merge pull request #6 from DanielR92/zero-export

add fixes for NotEnabledOrNotSelected
Manual merge
Bugfixes
pull/1551/head
tictrick 6 months ago
committed by GitHub
parent
commit
65cbf5cd7d
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      src/config/settings.h
  2. 254
      src/plugins/zeroExport/powermeter.h
  3. 119
      src/plugins/zeroExport/zeroExport.h
  4. 1
      src/publisher/pubMqtt.h

2
src/config/settings.h

@ -352,8 +352,6 @@ typedef struct {
bool debug; bool debug;
zeroExportGroup_t groups[ZEROEXPORT_MAX_GROUPS]; zeroExportGroup_t groups[ZEROEXPORT_MAX_GROUPS];
// uint8_t query_device; // 0 - Tibber, 1 - Shelly, 2 - other (rs232?) // uint8_t query_device; // 0 - Tibber, 1 - Shelly, 2 - other (rs232?)
// char monitor_url[ZEXPORT_ADDR_LEN]; // char monitor_url[ZEXPORT_ADDR_LEN];
// char json_path[ZEXPORT_ADDR_LEN]; // char json_path[ZEXPORT_ADDR_LEN];

254
src/plugins/zeroExport/powermeter.h

@ -21,6 +21,13 @@ typedef struct {
float *Arg; float *Arg;
} OBISHandler; } OBISHandler;
typedef struct {
float P;
float P1;
float P2;
float P3;
} PowerMeterBuffer_t;
class powermeter { class powermeter {
public: public:
powermeter() { powermeter() {
@ -29,44 +36,67 @@ class powermeter {
~powermeter() { ~powermeter() {
} }
bool setup(zeroExport_t *cfg /*Hier muss noch geklärt werden was gebraucht wird*/) { bool setup(zeroExport_t *cfg, JsonObject *log /*Hier muss noch geklärt werden was gebraucht wird*/) {
mCfg = cfg; mCfg = cfg;
mLog = log;
return true; return true;
} }
void loop(void) { /** loop
} * abfrage der gruppen um die aktuellen Werte (Zähler) zu ermitteln.
/** groupGetPowermeter
* Holt die Daten vom Powermeter
* @param group
* @returns true/false
*/ */
bool getData(JsonObject logObj, uint8_t group) { void loop(void)
bool result = false; {
PowerMeterBuffer_t power;
if(millis() - previousMillis <= 3000) return; // skip when it is to fast
for (u_short group = 0; group < ZEROEXPORT_MAX_GROUPS; group++)
{
switch (mCfg->groups[group].pm_type) { switch (mCfg->groups[group].pm_type) {
case 1: case zeroExportPowermeterType_t::Shelly:
result = getPowermeterWattsShelly(logObj, group); getPowermeterWattsShelly(*mLog, group);
break; break;
case 2: case zeroExportPowermeterType_t::Tasmota:
result = getPowermeterWattsTasmota(logObj, group); getPowermeterWattsTasmota(*mLog, group);
break; break;
case 3: case zeroExportPowermeterType_t::Mqtt:
result = getPowermeterWattsMqtt(logObj, group); getPowermeterWattsMqtt(*mLog, group);
break; break;
case 4: case zeroExportPowermeterType_t::Hichi:
result = getPowermeterWattsHichi(logObj, group); getPowermeterWattsHichi(*mLog, group);
break; break;
case 5: case zeroExportPowermeterType_t::Tibber:
result = getPowermeterWattsTibber(logObj, group); power = getPowermeterWattsTibber(*mLog, group);
break; break;
} }
if (!result) {
logObj["err"] = "type: " + String(mCfg->groups[group].pm_type); bufferWrite(power, group);
}
previousMillis = millis();
} }
return result; /** groupGetPowermeter
* Holt die Daten vom Powermeter
* @param group
* @returns true/false
*/
PowerMeterBuffer_t getDataAVG(uint8_t group) {
PowerMeterBuffer_t avg;
avg.P = avg.P1 = avg.P2 = avg.P2 = avg.P3 = 0;
for (int i = 0; i < 5; i++)
{
avg.P += powermeterbuffer[group][i].P;
avg.P1 += powermeterbuffer[group][i].P1;
avg.P2 += powermeterbuffer[group][i].P2;
avg.P3 += powermeterbuffer[group][i].P3;
}
avg.P = avg.P / 5;
avg.P1 = avg.P1 / 5;
avg.P2 = avg.P2 / 5;
avg.P3 = avg.P3 / 5;
return avg;
} }
private: private:
@ -76,16 +106,11 @@ class powermeter {
* @param group * @param group
* @returns true/false * @returns true/false
*/ */
bool getPowermeterWattsShelly(JsonObject logObj, uint8_t group) { PowerMeterBuffer_t getPowermeterWattsShelly(JsonObject logObj, uint8_t group) {
bool result = false; PowerMeterBuffer_t result;
logObj["mod"] = "getPowermeterWattsShelly"; logObj["mod"] = "getPowermeterWattsShelly";
mCfg->groups[group].pmPower = 0;
mCfg->groups[group].pmPowerL1 = 0;
mCfg->groups[group].pmPowerL2 = 0;
mCfg->groups[group].pmPowerL3 = 0;
HTTPClient http; HTTPClient http;
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
http.setUserAgent("Ahoy-Agent"); http.setUserAgent("Ahoy-Agent");
@ -107,57 +132,48 @@ class powermeter {
DeserializationError error = deserializeJson(doc, http.getString()); DeserializationError error = deserializeJson(doc, http.getString());
if (error) { if (error) {
logObj["err"] = "deserializeJson: " + String(error.c_str()); logObj["err"] = "deserializeJson: " + String(error.c_str());
return false; return result;
} else { } else {
if (doc.containsKey(F("total_power"))) { if (doc.containsKey(F("total_power"))) {
// Shelly 3EM // Shelly 3EM
mCfg->groups[group].pmPower = doc["total_power"]; result.P = doc["total_power"];
result = true;
} else if (doc.containsKey(F("em:0"))) { } else if (doc.containsKey(F("em:0"))) {
// Shelly pro 3EM // Shelly pro 3EM
mCfg->groups[group].pmPower = doc["em:0"]["total_act_power"]; result.P = doc["em:0"]["total_act_power"];
result = true;
} else { } else {
// Keine Daten // Keine Daten
mCfg->groups[group].pmPower = 0; result.P = 0;
} }
if (doc.containsKey(F("emeters"))) { if (doc.containsKey(F("emeters"))) {
// Shelly 3EM // Shelly 3EM
mCfg->groups[group].pmPowerL1 = doc["emeters"][0]["power"]; result.P1 = doc["emeters"][0]["power"];
result = true;
} else if (doc.containsKey(F("em:0"))) { } else if (doc.containsKey(F("em:0"))) {
// Shelly pro 3EM // Shelly pro 3EM
mCfg->groups[group].pmPowerL1 = doc["em:0"]["a_act_power"]; result.P1 = doc["em:0"]["a_act_power"];
result = true;
} else if (doc.containsKey(F("switch:0"))) { } else if (doc.containsKey(F("switch:0"))) {
// Shelly plus1pm plus2pm // Shelly plus1pm plus2pm
mCfg->groups[group].pmPowerL1 = doc["switch:0"]["apower"]; result.P1 = doc["switch:0"]["apower"];
mCfg->groups[group].pmPower += mCfg->groups[group].pmPowerL1; result.P += result.P1;
result = true;
} else if (doc.containsKey(F("apower"))) { } else if (doc.containsKey(F("apower"))) {
// Shelly Alternative // Shelly Alternative
mCfg->groups[group].pmPowerL1 = doc["apower"]; result.P1 = doc["apower"];
mCfg->groups[group].pmPower += mCfg->groups[group].pmPowerL1; result.P += result.P1;
result = true;
} else { } else {
// Keine Daten // Keine Daten
mCfg->groups[group].pmPowerL1 = 0; result.P1 = 0;
} }
if (doc.containsKey(F("emeters"))) { if (doc.containsKey(F("emeters"))) {
// Shelly 3EM // Shelly 3EM
mCfg->groups[group].pmPowerL2 = doc["emeters"][1]["power"]; result.P2 = doc["emeters"][1]["power"];
result = true;
} else if (doc.containsKey(F("em:0"))) { } else if (doc.containsKey(F("em:0"))) {
// Shelly pro 3EM // Shelly pro 3EM
mCfg->groups[group].pmPowerL2 = doc["em:0"]["b_act_power"]; result.P2 = doc["em:0"]["b_act_power"];
result = true;
} else if (doc.containsKey(F("switch:1"))) { } else if (doc.containsKey(F("switch:1"))) {
// Shelly plus1pm plus2pm // Shelly plus1pm plus2pm
mCfg->groups[group].pmPowerL2 = doc["switch.1"]["apower"]; result.P2 = doc["switch.1"]["apower"];
mCfg->groups[group].pmPower += mCfg->groups[group].pmPowerL2; result.P += result.P2;
result = true;
//} else if (doc.containsKey(F("apower"))) { //} else if (doc.containsKey(F("apower"))) {
// Shelly Alternative // Shelly Alternative
// mCfg->groups[group].pmPowerL2 = doc["apower"]; // mCfg->groups[group].pmPowerL2 = doc["apower"];
@ -165,22 +181,19 @@ class powermeter {
// ret = true; // ret = true;
} else { } else {
// Keine Daten // Keine Daten
mCfg->groups[group].pmPowerL2 = 0; result.P2 = 0;
} }
if (doc.containsKey(F("emeters"))) { if (doc.containsKey(F("emeters"))) {
// Shelly 3EM // Shelly 3EM
mCfg->groups[group].pmPowerL3 = doc["emeters"][2]["power"]; result.P3 = doc["emeters"][2]["power"];
result = true;
} else if (doc.containsKey(F("em:0"))) { } else if (doc.containsKey(F("em:0"))) {
// Shelly pro 3EM // Shelly pro 3EM
mCfg->groups[group].pmPowerL3 = doc["em:0"]["c_act_power"]; result.P3 = doc["em:0"]["c_act_power"];
result = true;
} else if (doc.containsKey(F("switch:2"))) { } else if (doc.containsKey(F("switch:2"))) {
// Shelly plus1pm plus2pm // Shelly plus1pm plus2pm
mCfg->groups[group].pmPowerL3 = doc["switch:2"]["apower"]; result.P3 = doc["switch:2"]["apower"];
mCfg->groups[group].pmPower += mCfg->groups[group].pmPowerL3; result.P += result.P3;
result = true;
//} else if (doc.containsKey(F("apower"))) { //} else if (doc.containsKey(F("apower"))) {
// Shelly Alternative // Shelly Alternative
// mCfg->groups[group].pmPowerL3 = doc["apower"]; // mCfg->groups[group].pmPowerL3 = doc["apower"];
@ -188,17 +201,11 @@ class powermeter {
// result = true; // result = true;
} else { } else {
// Keine Daten // Keine Daten
mCfg->groups[group].pmPowerL3 = 0; result.P3 = 0;
} }
} }
} }
http.end(); http.end();
logObj["P"] = mCfg->groups[group].pmPower;
logObj["P1"] = mCfg->groups[group].pmPowerL1;
logObj["P2"] = mCfg->groups[group].pmPowerL2;
logObj["P3"] = mCfg->groups[group].pmPowerL3;
return result; return result;
} }
@ -250,17 +257,10 @@ class powermeter {
* } * }
* } * }
*/ */
bool getPowermeterWattsTasmota(JsonObject logObj, uint8_t group) { PowerMeterBuffer_t getPowermeterWattsTasmota(JsonObject logObj, uint8_t group) {
bool result = false; PowerMeterBuffer_t result;
logObj["mod"] = "getPowermeterWattsTasmota"; logObj["mod"] = "getPowermeterWattsTasmota";
mCfg->groups[group].pmPower = 0;
mCfg->groups[group].pmPowerL1 = 0;
mCfg->groups[group].pmPowerL2 = 0;
mCfg->groups[group].pmPowerL3 = 0;
result = true;
/* /*
// TODO: nicht komplett // TODO: nicht komplett
@ -329,28 +329,16 @@ class powermeter {
* @param group * @param group
* @returns true/false * @returns true/false
*/ */
bool getPowermeterWattsMqtt(JsonObject logObj, uint8_t group) { PowerMeterBuffer_t getPowermeterWattsMqtt(JsonObject logObj, uint8_t group) {
bool result = false; PowerMeterBuffer_t result;
logObj["mod"] = "getPowermeterWattsMqtt"; logObj["mod"] = "getPowermeterWattsMqtt";
mCfg->groups[group].pmPower = 0;
mCfg->groups[group].pmPowerL1 = 0;
mCfg->groups[group].pmPowerL2 = 0;
mCfg->groups[group].pmPowerL3 = 0;
// Hier neuer Code - Anfang // Hier neuer Code - Anfang
// TODO: Noch nicht komplett // TODO: Noch nicht komplett
result = true;
// Hier neuer Code - Ende // Hier neuer Code - Ende
logObj["P"] = mCfg->groups[group].pmPower;
logObj["P1"] = mCfg->groups[group].pmPowerL1;
logObj["P2"] = mCfg->groups[group].pmPowerL2;
logObj["P3"] = mCfg->groups[group].pmPowerL3;
return result; return result;
} }
@ -360,28 +348,16 @@ class powermeter {
* @param group * @param group
* @returns true/false * @returns true/false
*/ */
bool getPowermeterWattsHichi(JsonObject logObj, uint8_t group) { PowerMeterBuffer_t getPowermeterWattsHichi(JsonObject logObj, uint8_t group) {
bool result = false; PowerMeterBuffer_t result;
logObj["mod"] = "getPowermeterWattsHichi"; logObj["mod"] = "getPowermeterWattsHichi";
mCfg->groups[group].pmPower = 0;
mCfg->groups[group].pmPowerL1 = 0;
mCfg->groups[group].pmPowerL2 = 0;
mCfg->groups[group].pmPowerL3 = 0;
// Hier neuer Code - Anfang // Hier neuer Code - Anfang
// TODO: Noch nicht komplett // TODO: Noch nicht komplett
result = true;
// Hier neuer Code - Ende // Hier neuer Code - Ende
logObj["P"] = mCfg->groups[group].pmPower;
logObj["P1"] = mCfg->groups[group].pmPowerL1;
logObj["P2"] = mCfg->groups[group].pmPowerL2;
logObj["P3"] = mCfg->groups[group].pmPowerL3;
return result; return result;
} }
@ -416,7 +392,6 @@ class powermeter {
07 01 00 02 08 01 ff #objName: OBIS-Kennzahl für Wirkenergie Einspeisung Tarif1 07 01 00 02 08 01 ff #objName: OBIS-Kennzahl für Wirkenergie Einspeisung Tarif1
07 01 00 02 08 02 ff #objName: OBIS-Kennzahl für Wirkenergie Einspeisung Tarif2 07 01 00 02 08 02 ff #objName: OBIS-Kennzahl für Wirkenergie Einspeisung Tarif2
*/ */
const std::list<OBISHandler> smlHandlerList{ const std::list<OBISHandler> smlHandlerList{
{{0x01, 0x00, 0x10, 0x07, 0x00, 0xff}, &smlOBISW, &_powerMeterTotal}, // total - OBIS-Kennzahl für momentane Gesamtwirkleistung {{0x01, 0x00, 0x10, 0x07, 0x00, 0xff}, &smlOBISW, &_powerMeterTotal}, // total - OBIS-Kennzahl für momentane Gesamtwirkleistung
@ -427,13 +402,10 @@ class powermeter {
{{0x01, 0x00, 0x01, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterImport}, {{0x01, 0x00, 0x01, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterImport},
{{0x01, 0x00, 0x02, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterExport}}; {{0x01, 0x00, 0x02, 0x08, 0x00, 0xff}, &smlOBISWh, &_powerMeterExport}};
bool getPowermeterWattsTibber(JsonObject logObj, uint8_t group) { PowerMeterBuffer_t getPowermeterWattsTibber(JsonObject logObj, uint8_t group) {
bool result = false; PowerMeterBuffer_t result;
mCfg->groups[group].pmPower = 0; logObj["mod"] = "getPowermeterWattsTibber";
mCfg->groups[group].pmPowerL1 = 0;
mCfg->groups[group].pmPowerL2 = 0;
mCfg->groups[group].pmPowerL3 = 0;
HTTPClient http; HTTPClient http;
http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); http.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS);
@ -449,33 +421,25 @@ class powermeter {
http.begin(url); http.begin(url);
http.addHeader("Authorization", "Basic " + auth); http.addHeader("Authorization", "Basic " + auth);
if (http.GET() == HTTP_CODE_OK && http.getSize() != 0) { if (http.GET() == HTTP_CODE_OK && http.getSize() > 0) {
String myString = http.getString(); String myString = http.getString();
char floatBuffer[20];
double readVal = 0; double readVal = 0;
unsigned char c; unsigned char c;
for (int i = 0; i < http.getSize(); ++i) { for (int i = 0; i < http.getSize(); ++i) {
c = myString[i]; c = myString[i];
sml_states_t smlCurrentState = smlState(c); sml_states_t smlCurrentState = smlState(c);
switch (smlCurrentState) { switch (smlCurrentState) {
case SML_FINAL: case SML_FINAL:
mCfg->groups[group].pmPower = _powerMeterTotal; result.P = _powerMeterTotal;
result.P1 = _powerMeter1Power;
mCfg->groups[group].pmPowerL1 = _powerMeter1Power; result.P2 = _powerMeter2Power;
mCfg->groups[group].pmPowerL2 = _powerMeter2Power; result.P3 = _powerMeter3Power;
mCfg->groups[group].pmPowerL3 = _powerMeter3Power;
if(! (_powerMeter1Power && _powerMeter2Power && _powerMeter3Power)) if(! (_powerMeter1Power && _powerMeter2Power && _powerMeter3Power)) {
{ result.P1 = result.P2 = result.P3 = _powerMeterTotal / 3;
mCfg->groups[group].pmPowerL1 = _powerMeterTotal / 3;
mCfg->groups[group].pmPowerL2 = _powerMeterTotal / 3;
mCfg->groups[group].pmPowerL3 = _powerMeterTotal / 3;
} }
result = true;
break; break;
case SML_LISTEND: case SML_LISTEND:
// check handlers on last received list // check handlers on last received list
@ -486,31 +450,29 @@ class powermeter {
} }
} }
break; break;
default:
logObj["SML_DEFAULT"] = String(smlCurrentState);
break;
}
} }
} }
else
{
logObj["result"] = String(result);
logObj["http_size"] = String(http.getSize());
} }
http.end(); http.end();
logObj["P"] = mCfg->groups[group].pmPower;
logObj["P1"] = mCfg->groups[group].pmPowerL1;
logObj["P2"] = mCfg->groups[group].pmPowerL2;
logObj["P3"] = mCfg->groups[group].pmPowerL3;
return result; return result;
} }
private: void bufferWrite(PowerMeterBuffer_t raw, short group)
{
powermeterbuffer[group][powerbufferpos[group]] = raw;
powerbufferpos[group]++;
if(powerbufferpos[group] >= 5) powerbufferpos[group] = 0;
}
zeroExport_t *mCfg; zeroExport_t *mCfg;
JsonObject *mLog;
unsigned long previousMillis = 0;
PowerMeterBuffer_t powermeterbuffer[ZEROEXPORT_MAX_GROUPS][5] = { 0 };
short powerbufferpos[ZEROEXPORT_MAX_GROUPS] = { 0 };
}; };
// TODO: Vorlagen für Powermeter-Analyse // TODO: Vorlagen für Powermeter-Analyse

119
src/plugins/zeroExport/zeroExport.h

@ -46,7 +46,7 @@ class ZeroExport {
mApi = api; mApi = api;
mMqtt = mqtt; mMqtt = mqtt;
mIsInitialized = mPowermeter.setup(mCfg); mIsInitialized = mPowermeter.setup(mCfg, &mLog);
} }
/** loop /** loop
@ -408,26 +408,51 @@ class ZeroExport {
* Subscribe section * Subscribe section
*/ */
void onMqttMessage(JsonObject obj) { void onMqttMessage(JsonObject obj) {
if ((!mIsInitialized) || (!mCfg->enabled)) return; if (!mIsInitialized) return;
return; String topic = String(obj["topic"]);
// MQTT":{"val":0,"path":"zero","cmd":"set","id":0} if(!topic.indexOf("/zero/set/")) return;
if (strcmp(obj["cmd"], "set") != 0 && strcmp(obj["path"], "zero") != 0) {
mLog["t"] = "onMqttMessage";
if (obj["path"] == "zero" && obj["cmd"] == "set")
{
// "topic":"inverter/zero/set/groups/0/enabled"
// @TODO: state machine init
if (topic.indexOf("groups") != -1) {
String i = topic.substring(topic.length() - 10, topic.length() - 8);
uint id = i.toInt();
mCfg->groups[id].enabled = (bool)obj["val"];
}
else
{
mCfg->enabled = (bool)obj["val"]; mCfg->enabled = (bool)obj["val"];
mLog["zero_enable"] = mCfg->enabled;
}
return;
} }
mLog["MQTT"] = obj; mLog["Msg"] = obj;
sendLog(); sendLog();
clearLog(); clearLog();
} }
private: private:
/** NotEnabledOrNotSelected
* Inverter not enabled -> ignore || Inverter not selected -> ignore
*/
bool NotEnabledOrNotSelected(uint8_t group, uint8_t inv) {
return ((!mCfg->groups[group].inverters[inv].enabled) || (mCfg->groups[group].inverters[inv].id < 0));
}
/** groupInit /** groupInit
* Initialize the group and search the InverterPointer * Initialize the group and search the InverterPointer
* @param group * @param group
* @returns true/false * @returns true/false
* @todo getInverterById statt getInverterByPos, dann würde die Variable *iv und die Schleife nicht gebraucht. * @todo getInverterById statt getInverterByPos, dann würde die Variable *iv und die Schleife nicht gebraucht.
*/ */
bool groupInit(uint8_t group, unsigned long *tsp, bool *doLog) { bool groupInit(uint8_t group, unsigned long *tsp, bool *doLog) {
uint8_t result = false; uint8_t result = false;
@ -444,17 +469,15 @@ class ZeroExport {
// Search/Set ivPointer // Search/Set ivPointer
JsonArray logArr = mLog.createNestedArray("ix"); JsonArray logArr = mLog.createNestedArray("ix");
for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) {
JsonObject logObj = logArr.createNestedObject(); JsonObject logObj = logArr.createNestedObject();
logObj["i"] = inv; logObj["i"] = inv;
mIv[group][inv] = nullptr; mIv[group][inv] = nullptr;
// Inverter not enabled -> ignore // Inverter not enabled or not selected -> ignore
if (!mCfg->groups[group].inverters[inv].enabled) continue; if (NotEnabledOrNotSelected(group, inv)) continue;
// Inverter not selected -> ignore
if (mCfg->groups[group].inverters[inv].id < 0) continue;
// Load Config // Load Config
Inverter<> *iv; Inverter<> *iv;
@ -526,11 +549,8 @@ class ZeroExport {
JsonObject logObj = logArr.createNestedObject(); JsonObject logObj = logArr.createNestedObject();
logObj["i"] = inv; logObj["i"] = inv;
// Inverter not enabled -> ignore // Inverter not enabled or not selected -> ignore
if (!mCfg->groups[group].inverters[inv].enabled) continue; if (NotEnabledOrNotSelected(group, inv)) continue;
// Inverter not selected -> ignore
if (mCfg->groups[group].inverters[inv].id < 0) continue;
// Inverter is not available -> wait // Inverter is not available -> wait
if (!mIv[group][inv]->isAvailable()) { if (!mIv[group][inv]->isAvailable()) {
@ -569,11 +589,8 @@ class ZeroExport {
JsonObject logObj = logArr.createNestedObject(); JsonObject logObj = logArr.createNestedObject();
logObj["i"] = inv; logObj["i"] = inv;
// Inverter not enabled -> ignore // Inverter not enabled or not selected -> ignore
if (!mCfg->groups[group].inverters[inv].enabled) continue; if (NotEnabledOrNotSelected(group, inv)) continue;
// Inverter not selected -> ignore
if (mCfg->groups[group].inverters[inv].id < 0) continue;
if (!mIv[group][inv]->isAvailable()) continue; if (!mIv[group][inv]->isAvailable()) continue;
@ -668,11 +685,8 @@ class ZeroExport {
for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) {
// zeroExportGroupInverter_t *cfgGroupInv = &mCfg->groups[group].inverters[inv]; // zeroExportGroupInverter_t *cfgGroupInv = &mCfg->groups[group].inverters[inv];
// Inverter not enabled -> ignore // Inverter not enabled or not selected -> ignore
if (!mCfg->groups[group].inverters[inv].enabled) continue; if (NotEnabledOrNotSelected(group, inv)) continue;
// Inverter not selected -> ignore
if (mCfg->groups[group].inverters[inv].id < 0) continue;
// Abbruch weil Inverter nicht verfügbar // Abbruch weil Inverter nicht verfügbar
if (!mIv[group][inv]->isAvailable()) { if (!mIv[group][inv]->isAvailable()) {
@ -698,11 +712,8 @@ class ZeroExport {
for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) {
// zeroExportGroupInverter_t *cfgGroupInv = &mCfg->groups[group].inverters[inv]; // zeroExportGroupInverter_t *cfgGroupInv = &mCfg->groups[group].inverters[inv];
// Inverter not enabled -> ignore // Inverter not enabled or not selected -> ignore
if (!mCfg->groups[group].inverters[inv].enabled) continue; if (NotEnabledOrNotSelected(group, inv)) continue;
// Inverter not selected -> ignore
if (mCfg->groups[group].inverters[inv].id < 0) continue;
// Abbruch weil Inverter nicht verfügbar // Abbruch weil Inverter nicht verfügbar
if (!mIv[group][inv]->isAvailable()) { if (!mIv[group][inv]->isAvailable()) {
@ -738,13 +749,15 @@ class ZeroExport {
*/ */
bool groupGetPowermeter(uint8_t group, unsigned long *tsp, bool *doLog) { bool groupGetPowermeter(uint8_t group, unsigned long *tsp, bool *doLog) {
if (mCfg->debug) mLog["t"] = "groupGetPowermeter"; if (mCfg->debug) mLog["t"] = "groupGetPowermeter";
mCfg->groups[group].lastRun = *tsp; mCfg->groups[group].lastRun = *tsp;
*doLog = true; *doLog = true;
bool result = false; mCfg->groups[group].pmPower = mPowermeter.getDataAVG(group).P;
result = mPowermeter.getData(mLog, group); mCfg->groups[group].pmPowerL1 = mPowermeter.getDataAVG(group).P1;
mCfg->groups[group].pmPowerL2 = mPowermeter.getDataAVG(group).P2;
mCfg->groups[group].pmPowerL3 = mPowermeter.getDataAVG(group).P3;
if ( if (
(mCfg->groups[group].pmPower == 0) && (mCfg->groups[group].pmPower == 0) &&
(mCfg->groups[group].pmPowerL1 == 0) && (mCfg->groups[group].pmPowerL1 == 0) &&
@ -753,6 +766,11 @@ class ZeroExport {
return false; return false;
} }
mLog["P"] = mCfg->groups[group].pmPower;
mLog["P1"] = mCfg->groups[group].pmPowerL1;
mLog["P2"] = mCfg->groups[group].pmPowerL2;
mLog["P3"] = mCfg->groups[group].pmPowerL3;
return true; return true;
} }
@ -1062,14 +1080,9 @@ class ZeroExport {
JsonObject logObj = logArr.createNestedObject(); JsonObject logObj = logArr.createNestedObject();
logObj["i"] = inv; logObj["i"] = inv;
// Inverter not enabled -> ignore // Inverter not enabled or not selected -> ignore
if (!mCfg->groups[group].inverters[inv].enabled) { if (NotEnabledOrNotSelected(group, inv)) continue;
continue;
}
// Inverter not selected -> ignore
if (mCfg->groups[group].inverters[inv].id < 0) {
continue;
}
*doLog = true; *doLog = true;
// Reset // Reset
if ((mCfg->groups[group].inverters[inv].doReboot) && (mCfg->groups[group].inverters[inv].waitRebootAck == 0)) { if ((mCfg->groups[group].inverters[inv].doReboot) && (mCfg->groups[group].inverters[inv].waitRebootAck == 0)) {
@ -1136,11 +1149,8 @@ class ZeroExport {
JsonObject logObj = logArr.createNestedObject(); JsonObject logObj = logArr.createNestedObject();
logObj["i"] = inv; logObj["i"] = inv;
// Inverter not enabled -> ignore // Inverter not enabled or not selected -> ignore
if (!mCfg->groups[group].inverters[inv].enabled) continue; if (NotEnabledOrNotSelected(group, inv)) continue;
// Inverter not selected -> ignore
if (mCfg->groups[group].inverters[inv].id < 0) continue;
if (mCfg->debug) *doLog = true; if (mCfg->debug) *doLog = true;
@ -1234,11 +1244,8 @@ class ZeroExport {
JsonObject logObj = logArr.createNestedObject(); JsonObject logObj = logArr.createNestedObject();
logObj["i"] = inv; logObj["i"] = inv;
// Inverter not enabled -> ignore // Inverter not enabled or not selected -> ignore
if (!mCfg->groups[group].inverters[inv].enabled) continue; if (NotEnabledOrNotSelected(group, inv)) continue;
// Inverter not selected -> ignore
if (mCfg->groups[group].inverters[inv].id < 0) continue;
// if isOff -> Limit Pmin // if isOff -> Limit Pmin
if (!mIv[group][inv]->isProducing()) { if (!mIv[group][inv]->isProducing()) {
@ -1322,15 +1329,23 @@ class ZeroExport {
JsonObject obj = doc.to<JsonObject>(); JsonObject obj = doc.to<JsonObject>();
*doLog = true; *doLog = true;
String gr;
// Init // Init
if (!mIsSubscribed) { if (!mIsSubscribed) {
mIsSubscribed = true; mIsSubscribed = true;
mMqtt->publish("zero/set/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false); mMqtt->publish("zero/set/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false);
mMqtt->subscribe("zero/set/enabled", QOS_2); mMqtt->subscribe("zero/set/enabled", QOS_2);
gr = "zero/set/groups/" + String(group) + "/enabled";
mMqtt->publish(gr.c_str(), ((mCfg->groups[group].enabled) ? dict[STR_TRUE] : dict[STR_FALSE]) , false);
mMqtt->subscribe(gr.c_str(), QOS_2);
} }
mMqtt->publish("zero/state/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false); mMqtt->publish("zero/state/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE]), false);
gr = "zero/state/groups/" + String(group) + "/enabled";
mMqtt->publish(gr.c_str(), ((mCfg->groups[group].enabled) ? dict[STR_TRUE] : dict[STR_FALSE]) , false);
// if (mCfg->groups[group].publishPower) { // if (mCfg->groups[group].publishPower) {
// mCfg->groups[group].publishPower = false; // mCfg->groups[group].publishPower = false;

1
src/publisher/pubMqtt.h

@ -311,6 +311,7 @@ class PubMqtt {
DynamicJsonDocument json(128); DynamicJsonDocument json(128);
JsonObject root = json.to<JsonObject>(); JsonObject root = json.to<JsonObject>();
root["topic"] = String(topic);
bool limitAbs = false; bool limitAbs = false;
if(len > 0) { if(len > 0) {

Loading…
Cancel
Save