|
|
@ -286,7 +286,7 @@ class ZeroExport { |
|
|
|
unsigned long bTsp = millis(); |
|
|
|
|
|
|
|
mLog["g"] = group; |
|
|
|
mLog["s"] = (100 + (uint8_t)zeroExportState::SETLIMIT); |
|
|
|
mLog["s"] = (uint8_t)zeroExportState::SETLIMIT; |
|
|
|
if (mCfg->debug) mLog["t"] = "eventAckSetLimit"; |
|
|
|
|
|
|
|
JsonArray logArr = mLog.createNestedArray("ix"); |
|
|
@ -296,7 +296,7 @@ class ZeroExport { |
|
|
|
JsonObject logObj = logArr.createNestedObject(); |
|
|
|
|
|
|
|
logObj["i"] = inv; |
|
|
|
logObj["id"] = iv->id; |
|
|
|
if (mCfg->debug) logObj["id"] = iv->id; |
|
|
|
mCfg->groups[group].inverters[inv].waitAckSetLimit = 0; |
|
|
|
logObj["wL"] = mCfg->groups[group].inverters[inv].waitAckSetLimit; |
|
|
|
|
|
|
@ -330,7 +330,7 @@ class ZeroExport { |
|
|
|
unsigned long bTsp = millis(); |
|
|
|
|
|
|
|
mLog["g"] = group; |
|
|
|
mLog["s"] = (100 + (uint8_t)zeroExportState::SETPOWER); |
|
|
|
mLog["s"] = (uint8_t)zeroExportState::SETPOWER; |
|
|
|
if (mCfg->debug) mLog["t"] = "eventAckSetPower"; |
|
|
|
|
|
|
|
JsonArray logArr = mLog.createNestedArray("ix"); |
|
|
@ -374,7 +374,7 @@ class ZeroExport { |
|
|
|
unsigned long bTsp = millis(); |
|
|
|
|
|
|
|
mLog["g"] = group; |
|
|
|
mLog["s"] = (100 + (uint8_t)zeroExportState::SETREBOOT); |
|
|
|
mLog["s"] = (uint8_t)zeroExportState::SETREBOOT; |
|
|
|
if (mCfg->debug) mLog["t"] = "eventAckSetReboot"; |
|
|
|
|
|
|
|
JsonArray logArr = mLog.createNestedArray("ix"); |
|
|
@ -435,7 +435,7 @@ class ZeroExport { |
|
|
|
// Calculate
|
|
|
|
int32_t ivLp = iv->actPowerLimit; |
|
|
|
int32_t ivPm = iv->getMaxPower(); |
|
|
|
; |
|
|
|
|
|
|
|
int32_t ivL = (ivPm * ivLp) / 100; |
|
|
|
int32_t zeL = mCfg->groups[group].inverters[inv].limit; |
|
|
|
|
|
|
@ -701,6 +701,7 @@ class ZeroExport { |
|
|
|
*/ |
|
|
|
bool groupGetInverterData(uint8_t group, unsigned long *tsp, bool *doLog) { |
|
|
|
zeroExportGroup_t *cfgGroup = &mCfg->groups[group]; |
|
|
|
bool result = true; |
|
|
|
|
|
|
|
cfgGroup->lastRun = *tsp; |
|
|
|
|
|
|
@ -709,9 +710,6 @@ class ZeroExport { |
|
|
|
*doLog = true; |
|
|
|
} |
|
|
|
|
|
|
|
// Init data
|
|
|
|
cfgGroup->power = 0; |
|
|
|
|
|
|
|
// Get Data
|
|
|
|
JsonArray logArr = mLog.createNestedArray("ix"); |
|
|
|
int32_t power = 0; |
|
|
@ -725,7 +723,10 @@ class ZeroExport { |
|
|
|
// Inverter not enabled or not selected -> ignore
|
|
|
|
if (NotEnabledOrNotSelected(group, inv)) continue; |
|
|
|
|
|
|
|
if (!mIv[group][inv]->isAvailable()) continue; |
|
|
|
if (!mIv[group][inv]->isAvailable()) { |
|
|
|
result = false; |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
record_t<> *rec; |
|
|
|
rec = mIv[group][inv]->getRecordStruct(RealTimeRunData_Debug); |
|
|
@ -736,14 +737,22 @@ class ZeroExport { |
|
|
|
power += cfgGroupInv->power; |
|
|
|
|
|
|
|
// Get dcVoltage
|
|
|
|
cfgGroupInv->dcVoltage = mIv[group][inv]->getChannelFieldValue(CH1, FLD_UDC, rec); |
|
|
|
float U = mIv[group][inv]->getChannelFieldValue(CH1, FLD_UDC, rec); |
|
|
|
if (U == 0) { |
|
|
|
result = false; |
|
|
|
continue; |
|
|
|
} |
|
|
|
cfgGroupInv->dcVoltage = U; |
|
|
|
logObj["U"] = cfgGroupInv->dcVoltage; |
|
|
|
} |
|
|
|
|
|
|
|
cfgGroup->power = power; |
|
|
|
mLog["P"] = cfgGroup->power; |
|
|
|
|
|
|
|
return true; |
|
|
|
if ((cfgGroup->battEnabled) && (cfgGroup->power > 0)) |
|
|
|
cfgGroup->battSwitch = true; |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/** groupBatteryprotection
|
|
|
@ -791,24 +800,37 @@ class ZeroExport { |
|
|
|
return false; |
|
|
|
} |
|
|
|
|
|
|
|
bool switchOn = true; |
|
|
|
bool switchOff = false; |
|
|
|
for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { |
|
|
|
// Inverter not enabled or not selected -> ignore
|
|
|
|
if (NotEnabledOrNotSelected(group, inv)) continue; |
|
|
|
// Check
|
|
|
|
JsonArray logArr = mLog.createNestedArray("ix"); |
|
|
|
|
|
|
|
if (cfgGroup->inverters[inv].dcVoltage < cfgGroup->battVoltageOn) switchOn = false; |
|
|
|
if (cfgGroup->inverters[inv].dcVoltage < cfgGroup->battVoltageOff) switchOff = true; |
|
|
|
} |
|
|
|
if (!cfgGroup->battSwitch) { |
|
|
|
// is off turn on
|
|
|
|
for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { |
|
|
|
// Inverter not enabled or not selected -> ignore
|
|
|
|
if (NotEnabledOrNotSelected(group, inv)) continue; |
|
|
|
|
|
|
|
if (switchOff == true) { |
|
|
|
cfgGroup->battSwitch = false; |
|
|
|
*doLog = true; |
|
|
|
} else { |
|
|
|
if (switchOn == true) { |
|
|
|
JsonObject logObj = logArr.createNestedObject(); |
|
|
|
logObj["i"] = inv; |
|
|
|
logObj["U"] = cfgGroup->inverters[inv].dcVoltage; |
|
|
|
|
|
|
|
if (cfgGroup->inverters[inv].dcVoltage < cfgGroup->battVoltageOn) continue; |
|
|
|
cfgGroup->battSwitch = true; |
|
|
|
*doLog = true; |
|
|
|
} |
|
|
|
} else { |
|
|
|
// is on turn off
|
|
|
|
for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { |
|
|
|
// Inverter not enabled or not selected -> ignore
|
|
|
|
if (NotEnabledOrNotSelected(group, inv)) continue; |
|
|
|
|
|
|
|
JsonObject logObj = logArr.createNestedObject(); |
|
|
|
logObj["i"] = inv; |
|
|
|
logObj["U"] = cfgGroup->inverters[inv].dcVoltage; |
|
|
|
|
|
|
|
if (cfgGroup->inverters[inv].dcVoltage > cfgGroup->battVoltageOff) continue; |
|
|
|
cfgGroup->battSwitch = false; |
|
|
|
*doLog = true; |
|
|
|
} |
|
|
|
} |
|
|
|
// Battery
|
|
|
|
String gr = "zero/state/groups/" + String(group) + "/battery"; |
|
|
@ -866,12 +888,10 @@ class ZeroExport { |
|
|
|
mqttObj["L1"] = mCfg->groups[group].pm_P1; |
|
|
|
mqttObj["L2"] = mCfg->groups[group].pm_P2; |
|
|
|
mqttObj["L3"] = mCfg->groups[group].pm_P3; |
|
|
|
mMqtt->publish("zero/state/powermeter/P", mqttDoc.as<std::string>().c_str(), false); |
|
|
|
mMqtt->publish(String("zero/state/groups/" + String(group) + "/powermeter/P").c_str(), mqttDoc.as<std::string>().c_str(), false); |
|
|
|
mqttDoc.clear(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (cfgGroup->pm_Publish_W) {
|
|
|
|
// cfgGroup->pm_Publish_W = false;
|
|
|
|
// obj["todo"] = "true";
|
|
|
@ -1120,9 +1140,9 @@ class ZeroExport { |
|
|
|
// Inverter not enabled or not selected -> ignore
|
|
|
|
if (NotEnabledOrNotSelected(group, inv)) continue; |
|
|
|
|
|
|
|
/// record_t<> *rec;
|
|
|
|
/// rec = mIv[group][inv]->getRecordStruct(RealTimeRunData_Debug);
|
|
|
|
/// cfgGroupInv->power = mIv[group][inv]->getChannelFieldValue(CH0, FLD_PAC, rec);
|
|
|
|
/// record_t<> *rec;
|
|
|
|
/// rec = mIv[group][inv]->getRecordStruct(RealTimeRunData_Debug);
|
|
|
|
/// cfgGroupInv->power = mIv[group][inv]->getChannelFieldValue(CH0, FLD_PAC, rec);
|
|
|
|
|
|
|
|
if ((cfgGroupInv->power < ivPmin[cfgGroupInv->target]) && (cfgGroupInv->limit < cfgGroupInv->powerMax) && (cfgGroupInv->limit < mIv[group][inv]->getMaxPower())) { |
|
|
|
grpTarget[cfgGroupInv->target] = true; |
|
|
@ -1251,6 +1271,7 @@ class ZeroExport { |
|
|
|
if (mCfg->debug) { |
|
|
|
logObj["dR"] = cfgGroupInv->doReboot; |
|
|
|
logObj["wR"] = cfgGroupInv->waitAckSetReboot; |
|
|
|
*doLog = true; |
|
|
|
} |
|
|
|
|
|
|
|
// Wait
|
|
|
@ -1437,9 +1458,9 @@ class ZeroExport { |
|
|
|
continue; |
|
|
|
} |
|
|
|
|
|
|
|
logObj["wL"] = cfgGroupInv->waitAckSetLimit; |
|
|
|
if (mCfg->debug) { |
|
|
|
logObj["dL"] = cfgGroupInv->doLimit; |
|
|
|
logObj["wL"] = cfgGroupInv->waitAckSetLimit; |
|
|
|
logObj["L"] = cfgGroupInv->limit; |
|
|
|
} |
|
|
|
|
|
|
@ -1686,18 +1707,6 @@ class ZeroExport { |
|
|
|
* Sendet den LogSpeicher über Webserial und/oder MQTT |
|
|
|
*/ |
|
|
|
void sendLog(void) { |
|
|
|
|
|
|
|
//if (mLog["s"] == 1) return;
|
|
|
|
//if (mLog["s"] == 2) return;
|
|
|
|
//if (mLog["s"] == 3) return;
|
|
|
|
if (mLog["s"] == 4) return; |
|
|
|
//if (mLog["s"] == 5) return;
|
|
|
|
//if (mLog["s"] == 6) return;
|
|
|
|
//if (mLog["s"] == 7) return;
|
|
|
|
//if (mLog["s"] == 8) return;
|
|
|
|
//if (mLog["s"] == 9) return;
|
|
|
|
//if (mLog["s"] == 10) return;
|
|
|
|
|
|
|
|
// Log over Webserial
|
|
|
|
if (mCfg->log_over_webserial) { |
|
|
|
DPRINTLN(DBG_INFO, String("ze: ") + mDocLog.as<String>()); |
|
|
|