|
@ -546,16 +546,16 @@ class ZeroExport { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#if defined(ZEROEXPORT_POWERMETER_MQTT) |
|
|
// topic for powermeter?
|
|
|
// topic for powermeter?
|
|
|
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) |
|
|
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { |
|
|
{ |
|
|
if (mCfg->groups[group].pm_type == zeroExportPowermeterType_t::Mqtt) { |
|
|
if(mCfg->groups[group].pm_type == zeroExportPowermeterType_t::Mqtt) |
|
|
|
|
|
{ |
|
|
|
|
|
mLog["mqttDevice"] = "topicInverter"; |
|
|
mLog["mqttDevice"] = "topicInverter"; |
|
|
if (!topic.equals(mCfg->groups[group].pm_jsonPath)) return; |
|
|
if (!topic.equals(mCfg->groups[group].pm_jsonPath)) return; |
|
|
mCfg->groups[group].pm_P = (int32_t)obj["val"]; |
|
|
mCfg->groups[group].pm_P = (int32_t)obj["val"]; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
#endif /*defined(ZEROEXPORT_POWERMETER_MQTT)*/ |
|
|
|
|
|
|
|
|
if (mCfg->debug) mLog["Msg"] = obj; |
|
|
if (mCfg->debug) mLog["Msg"] = obj; |
|
|
sendLog(); |
|
|
sendLog(); |
|
@ -815,6 +815,7 @@ class ZeroExport { |
|
|
if (cfgGroup->inverters[inv].dcVoltage < cfgGroup->battVoltageOn) continue; |
|
|
if (cfgGroup->inverters[inv].dcVoltage < cfgGroup->battVoltageOn) continue; |
|
|
cfgGroup->battSwitch = true; |
|
|
cfgGroup->battSwitch = true; |
|
|
*doLog = true; |
|
|
*doLog = true; |
|
|
|
|
|
cfgGroup->isChangedBattery = true; |
|
|
} |
|
|
} |
|
|
} else { |
|
|
} else { |
|
|
// is on turn off
|
|
|
// is on turn off
|
|
@ -829,9 +830,20 @@ class ZeroExport { |
|
|
if (cfgGroup->inverters[inv].dcVoltage > cfgGroup->battVoltageOff) continue; |
|
|
if (cfgGroup->inverters[inv].dcVoltage > cfgGroup->battVoltageOff) continue; |
|
|
cfgGroup->battSwitch = false; |
|
|
cfgGroup->battSwitch = false; |
|
|
*doLog = true; |
|
|
*doLog = true; |
|
|
|
|
|
cfgGroup->isChangedBattery = true; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
// Battery
|
|
|
} else { |
|
|
|
|
|
mLog["en"] = false; |
|
|
|
|
|
|
|
|
|
|
|
cfgGroup->battSwitch = true; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
mLog["sw"] = cfgGroup->battSwitch; |
|
|
|
|
|
|
|
|
|
|
|
// MQTT - Battery
|
|
|
|
|
|
if (cfgGroup->isChangedBattery) { |
|
|
|
|
|
if (mMqtt->isConnected()) { |
|
|
String gr = "zero/state/groups/" + String(group) + "/battery"; |
|
|
String gr = "zero/state/groups/" + String(group) + "/battery"; |
|
|
mqttObj["enabled"] = cfgGroup->battEnabled; |
|
|
mqttObj["enabled"] = cfgGroup->battEnabled; |
|
|
mqttObj["voltageOn"] = cfgGroup->battVoltageOn; |
|
|
mqttObj["voltageOn"] = cfgGroup->battVoltageOn; |
|
@ -839,13 +851,9 @@ class ZeroExport { |
|
|
mqttObj["switch"] = cfgGroup->battSwitch; |
|
|
mqttObj["switch"] = cfgGroup->battSwitch; |
|
|
mqttPublish(gr.c_str(), mqttDoc.as<std::string>().c_str()); |
|
|
mqttPublish(gr.c_str(), mqttDoc.as<std::string>().c_str()); |
|
|
mqttDoc.clear(); |
|
|
mqttDoc.clear(); |
|
|
} else { |
|
|
cfgGroup->isChangedBattery = false; |
|
|
mLog["en"] = false; |
|
|
} |
|
|
|
|
|
|
|
|
cfgGroup->battSwitch = true; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
mLog["sw"] = cfgGroup->battSwitch; |
|
|
|
|
|
|
|
|
|
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
@ -881,13 +889,13 @@ class ZeroExport { |
|
|
mLog["P3"] = mCfg->groups[group].pm_P3; |
|
|
mLog["P3"] = mCfg->groups[group].pm_P3; |
|
|
|
|
|
|
|
|
// MQTT - Powermeter
|
|
|
// MQTT - Powermeter
|
|
|
if(mMqtt->isConnected()) |
|
|
if (mMqtt->isConnected()) { |
|
|
{ |
|
|
String gr = "zero/state/groups/" + String(group) + "/powermeter"; |
|
|
mqttObj["Sum"] = mCfg->groups[group].pm_P; |
|
|
mqttObj["Sum"] = mCfg->groups[group].pm_P; |
|
|
mqttObj["L1"] = mCfg->groups[group].pm_P1; |
|
|
mqttObj["L1"] = mCfg->groups[group].pm_P1; |
|
|
mqttObj["L2"] = mCfg->groups[group].pm_P2; |
|
|
mqttObj["L2"] = mCfg->groups[group].pm_P2; |
|
|
mqttObj["L3"] = mCfg->groups[group].pm_P3; |
|
|
mqttObj["L3"] = mCfg->groups[group].pm_P3; |
|
|
mMqtt->publish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), mqttDoc.as<std::string>().c_str(), false); |
|
|
mqttPublish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), mqttDoc.as<std::string>().c_str()); |
|
|
mqttDoc.clear(); |
|
|
mqttDoc.clear(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -898,7 +906,7 @@ class ZeroExport { |
|
|
// obj["L1"] = cfgGroup->pm_P1;
|
|
|
// obj["L1"] = cfgGroup->pm_P1;
|
|
|
// obj["L2"] = cfgGroup->pm_P2;
|
|
|
// obj["L2"] = cfgGroup->pm_P2;
|
|
|
// obj["L2"] = cfgGroup->pm_P3;
|
|
|
// obj["L2"] = cfgGroup->pm_P3;
|
|
|
// mMqtt->publish("zero/powermeter/W", doc.as<std::string>().c_str(), false);
|
|
|
// mqttPublish("zero/powermeter/W", doc.as<std::string>().c_str());
|
|
|
// doc.clear();
|
|
|
// doc.clear();
|
|
|
// }
|
|
|
// }
|
|
|
|
|
|
|
|
@ -1046,7 +1054,9 @@ class ZeroExport { |
|
|
return false; |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Advanced
|
|
|
// MATT - Advanced
|
|
|
|
|
|
if (cfgGroup->isChangedAdvanced) { |
|
|
|
|
|
if (mMqtt->isConnected()) { |
|
|
String gr = "zero/state/groups/" + String(group) + "/advanced"; |
|
|
String gr = "zero/state/groups/" + String(group) + "/advanced"; |
|
|
mqttObj["setPoint"] = cfgGroup->setPoint; |
|
|
mqttObj["setPoint"] = cfgGroup->setPoint; |
|
|
mqttObj["refresh"] = cfgGroup->refresh; |
|
|
mqttObj["refresh"] = cfgGroup->refresh; |
|
@ -1057,6 +1067,9 @@ class ZeroExport { |
|
|
mqttObj["Kd"] = cfgGroup->Kd; |
|
|
mqttObj["Kd"] = cfgGroup->Kd; |
|
|
mqttPublish(gr.c_str(), mqttDoc.as<std::string>().c_str()); |
|
|
mqttPublish(gr.c_str(), mqttDoc.as<std::string>().c_str()); |
|
|
mqttDoc.clear(); |
|
|
mqttDoc.clear(); |
|
|
|
|
|
cfgGroup->isChangedAdvanced = false; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
return true; |
|
|
return true; |
|
|
} |
|
|
} |
|
@ -1105,10 +1118,14 @@ class ZeroExport { |
|
|
|
|
|
|
|
|
if (cfgGroup->power > cfgGroup->powerMax) { |
|
|
if (cfgGroup->power > cfgGroup->powerMax) { |
|
|
int32_t diff = cfgGroup->power - cfgGroup->powerMax; |
|
|
int32_t diff = cfgGroup->power - cfgGroup->powerMax; |
|
|
y = y - diff; |
|
|
// y = y - diff;
|
|
|
y1 = y1 - (diff * y1 / y); |
|
|
// y1 = y1 - (diff * y1 / y);
|
|
|
y1 = y1 - (diff * y2 / y); |
|
|
// y2 = y2 - (diff * y2 / y);
|
|
|
y1 = y1 - (diff * y3 / y); |
|
|
// y3 = y3 - (diff * y3 / y);
|
|
|
|
|
|
y = -diff; |
|
|
|
|
|
y1 = -(diff * y1 / y); |
|
|
|
|
|
y2 = -(diff * y2 / y); |
|
|
|
|
|
y3 = -(diff * y3 / y); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// TDOD: nochmal durchdenken ... es muss für Sum und L1-3 sein
|
|
|
// TDOD: nochmal durchdenken ... es muss für Sum und L1-3 sein
|
|
@ -1559,54 +1576,61 @@ class ZeroExport { |
|
|
obj["cmd"] = "limit_nonpersistent_absolute"; |
|
|
obj["cmd"] = "limit_nonpersistent_absolute"; |
|
|
mApi->ctrlRequest(obj); |
|
|
mApi->ctrlRequest(obj); |
|
|
|
|
|
|
|
|
|
|
|
if (mCfg->debug) logObj["d"] = obj; |
|
|
|
|
|
|
|
|
// publish to mqtt when mqtt
|
|
|
// publish to mqtt when mqtt
|
|
|
if(mMqtt->isConnected()) |
|
|
if (mMqtt->isConnected()) { |
|
|
{ |
|
|
|
|
|
String gr = "zero/state/groups/" + String(group) + "/inverters/" + String(inv); |
|
|
String gr = "zero/state/groups/" + String(group) + "/inverters/" + String(inv); |
|
|
mqttObj["enabled"] = cfgGroupInv->enabled; |
|
|
mqttObj["enabled"] = cfgGroupInv->enabled; |
|
|
mqttObj["id"] = cfgGroupInv->id; |
|
|
// mqttObj["id"] = cfgGroupInv->id;
|
|
|
mqttObj["target"] = cfgGroupInv->target; |
|
|
// mqttObj["target"] = cfgGroupInv->target;
|
|
|
mqttObj["powerMin"] = cfgGroupInv->powerMin; |
|
|
mqttObj["powerMin"] = cfgGroupInv->powerMin; |
|
|
mqttObj["powerMax"] = cfgGroupInv->powerMax; |
|
|
mqttObj["powerMax"] = cfgGroupInv->powerMax; |
|
|
mMqtt->publish(gr.c_str(), mqttDoc.as<std::string>().c_str(), false); |
|
|
mqttObj["power"] = cfgGroupInv->power; |
|
|
|
|
|
mqttObj["limit"] = cfgGroupInv->limit; |
|
|
|
|
|
mqttPublish(gr.c_str(), mqttDoc.as<std::string>().c_str()); |
|
|
mqttDoc.clear(); |
|
|
mqttDoc.clear(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
if (mCfg->debug) logObj["d"] = obj; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return result; |
|
|
return result; |
|
|
} |
|
|
} |
|
|
/* mqttSubscribe
|
|
|
|
|
|
|
|
|
/** mqttSubscribe
|
|
|
* when a MQTT Msg is needed to subscribe, then a publish is leading |
|
|
* when a MQTT Msg is needed to subscribe, then a publish is leading |
|
|
|
|
|
* @param gr |
|
|
|
|
|
* @param payload |
|
|
|
|
|
* @returns void |
|
|
*/ |
|
|
*/ |
|
|
void mqttSubscribe(String gr, String payload) |
|
|
void mqttSubscribe(String gr, String payload) { |
|
|
{ |
|
|
|
|
|
mqttPublish(gr, payload); |
|
|
mqttPublish(gr, payload); |
|
|
mMqtt->subscribe(gr.c_str(), QOS_2); |
|
|
mMqtt->subscribe(gr.c_str(), QOS_2); |
|
|
} |
|
|
} |
|
|
/* PubInit
|
|
|
|
|
|
|
|
|
/** PubInit
|
|
|
* when a MQTT Msg is needed to Publish, but not to subscribe. |
|
|
* when a MQTT Msg is needed to Publish, but not to subscribe. |
|
|
|
|
|
* @param gr |
|
|
|
|
|
* @param payload |
|
|
|
|
|
* @param retain |
|
|
|
|
|
* @returns void |
|
|
*/ |
|
|
*/ |
|
|
void mqttPublish(String gr, String payload, bool retain = false) |
|
|
void mqttPublish(String gr, String payload, bool retain = false) { |
|
|
{ |
|
|
|
|
|
mMqtt->publish(gr.c_str(), payload.c_str(), retain); |
|
|
mMqtt->publish(gr.c_str(), payload.c_str(), retain); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/**
|
|
|
/** mqttInitTopic
|
|
|
* |
|
|
* Initialize, subscribe mqtt Topics |
|
|
|
|
|
* @param void |
|
|
|
|
|
* @returns void |
|
|
*/ |
|
|
*/ |
|
|
void mqttInitTopic() { |
|
|
void mqttInitTopic(void) { |
|
|
if (mIsSubscribed) return; |
|
|
if (mIsSubscribed) return; |
|
|
if (!mMqtt->isConnected()) return; |
|
|
if (!mMqtt->isConnected()) return; |
|
|
|
|
|
|
|
|
mIsSubscribed = true; |
|
|
mIsSubscribed = true; |
|
|
|
|
|
|
|
|
// Global (zeroExport)
|
|
|
// Global (zeroExport)
|
|
|
// TODO: Global wird fälschlicherweise hier je nach anzahl der aktivierten Gruppen bis zu 6x ausgeführt.
|
|
|
|
|
|
mqttSubscribe("zero/set/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE])); |
|
|
mqttSubscribe("zero/set/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE])); |
|
|
|
|
|
|
|
|
// TODO: Global wird fälschlicherweise hier je nach anzahl der aktivierten Gruppen bis zu 6x ausgeführt.
|
|
|
|
|
|
mqttSubscribe("zero/set/sleep", ((mCfg->sleep) ? dict[STR_TRUE] : dict[STR_FALSE])); |
|
|
mqttSubscribe("zero/set/sleep", ((mCfg->sleep) ? dict[STR_TRUE] : dict[STR_FALSE])); |
|
|
|
|
|
|
|
|
String gr; |
|
|
String gr; |
|
@ -1622,7 +1646,7 @@ class ZeroExport { |
|
|
|
|
|
|
|
|
// Powermeter
|
|
|
// Powermeter
|
|
|
|
|
|
|
|
|
// Inverters - Only Publish
|
|
|
// Inverters
|
|
|
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 = &cfgGroup->inverters[inv]; |
|
|
zeroExportGroupInverter_t *cfgGroupInv = &cfgGroup->inverters[inv]; |
|
|
|
|
|
|
|
@ -1638,46 +1662,32 @@ class ZeroExport { |
|
|
mqttSubscribe(gr + "/advanced/setPoint", String(cfgGroup->setPoint)); |
|
|
mqttSubscribe(gr + "/advanced/setPoint", String(cfgGroup->setPoint)); |
|
|
mqttSubscribe(gr + "/advanced/powerTolerance", String(cfgGroup->powerTolerance)); |
|
|
mqttSubscribe(gr + "/advanced/powerTolerance", String(cfgGroup->powerTolerance)); |
|
|
mqttSubscribe(gr + "/advanced/powerMax", String(cfgGroup->powerMax)); |
|
|
mqttSubscribe(gr + "/advanced/powerMax", String(cfgGroup->powerMax)); |
|
|
mqttSubscribe(gr + "/advanced/refresh", String(cfgGroup->refresh)); |
|
|
// mqttSubscribe(gr + "/advanced/refresh", String(cfgGroup->refresh));
|
|
|
mqttSubscribe(gr + "/advanced/Kp", String(cfgGroup->Kp)); |
|
|
// mqttSubscribe(gr + "/advanced/Kp", String(cfgGroup->Kp));
|
|
|
mqttSubscribe(gr + "/advanced/Ki", String(cfgGroup->Ki)); |
|
|
// mqttSubscribe(gr + "/advanced/Ki", String(cfgGroup->Ki));
|
|
|
mqttSubscribe(gr + "/advanced/Kd", String(cfgGroup->Kd)); |
|
|
// mqttSubscribe(gr + "/advanced/Kd", String(cfgGroup->Kd));
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/** groupPublish
|
|
|
/** groupPublish
|
|
|
* |
|
|
* |
|
|
*/ |
|
|
*/ |
|
|
|
|
|
/*
|
|
|
bool groupPublish(uint8_t group, unsigned long *tsp, bool *doLog) { |
|
|
bool groupPublish(uint8_t group, unsigned long *tsp, bool *doLog) { |
|
|
zeroExportGroup_t *cfgGroup = &mCfg->groups[group]; |
|
|
|
|
|
|
|
|
|
|
|
if (mCfg->debug) mLog["t"] = "groupPublish"; |
|
|
|
|
|
|
|
|
|
|
|
cfgGroup->lastRun = *tsp; |
|
|
|
|
|
|
|
|
|
|
|
if (mMqtt->isConnected()) { |
|
|
if (mMqtt->isConnected()) { |
|
|
// *doLog = true;
|
|
|
|
|
|
String gr; |
|
|
String gr; |
|
|
|
|
|
|
|
|
// Global (zeroExport)
|
|
|
|
|
|
mqttSubscribe("zero/set/enabled", ((mCfg->enabled) ? dict[STR_TRUE] : dict[STR_FALSE])); |
|
|
|
|
|
mqttSubscribe("zero/set/sleep", ((mCfg->sleep) ? dict[STR_TRUE] : dict[STR_FALSE])); |
|
|
|
|
|
|
|
|
|
|
|
// General
|
|
|
|
|
|
gr = "zero/state/groups/" + String(group) + "/enabled"; |
|
|
gr = "zero/state/groups/" + String(group) + "/enabled"; |
|
|
|
|
|
|
|
|
mqttPublish(gr.c_str(), ((cfgGroup->enabled) ? dict[STR_TRUE] : dict[STR_FALSE])); |
|
|
mqttPublish(gr.c_str(), ((cfgGroup->enabled) ? dict[STR_TRUE] : dict[STR_FALSE])); |
|
|
mqttPublish(gr.c_str(), ((cfgGroup->sleep) ? dict[STR_TRUE] : dict[STR_FALSE])); |
|
|
|
|
|
|
|
|
|
|
|
gr = "zero/state/groups/" + String(group) + "/sleep"; |
|
|
gr = "zero/state/groups/" + String(group) + "/sleep"; |
|
|
mMqtt->publish(gr.c_str(), ((cfgGroup->sleep) ? dict[STR_TRUE] : dict[STR_FALSE]), false); |
|
|
mqttPublish(gr.c_str(), ((cfgGroup->sleep) ? dict[STR_TRUE] : dict[STR_FALSE])); |
|
|
|
|
|
|
|
|
gr = "zero/state/groups/" + String(group) + "/name"; |
|
|
gr = "zero/state/groups/" + String(group) + "/name"; |
|
|
mMqtt->publish(gr.c_str(), cfgGroup->name, false); |
|
|
mqttPublish(gr.c_str(), cfgGroup->name); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
/** groupEmergency
|
|
|
/** groupEmergency
|
|
|
* Dieser State versucht zeroExport in einen sicheren Zustand zu bringen, wenn technische Ausfälle vorliegen. |
|
|
* Dieser State versucht zeroExport in einen sicheren Zustand zu bringen, wenn technische Ausfälle vorliegen. |
|
|