|
@ -63,7 +63,7 @@ class ZeroExport { |
|
|
unsigned long Tsp = millis(); |
|
|
unsigned long Tsp = millis(); |
|
|
|
|
|
|
|
|
mPowermeter.loop(&Tsp, &DoLog); |
|
|
mPowermeter.loop(&Tsp, &DoLog); |
|
|
if (DoLog) sendLog(); |
|
|
// if (DoLog) sendLog();
|
|
|
clearLog(); |
|
|
clearLog(); |
|
|
DoLog = false; |
|
|
DoLog = false; |
|
|
|
|
|
|
|
@ -247,7 +247,7 @@ class ZeroExport { |
|
|
// Select all Inverter to reboot
|
|
|
// Select all Inverter to reboot
|
|
|
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { |
|
|
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { |
|
|
for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { |
|
|
for (uint8_t inv = 0; inv < ZEROEXPORT_GROUP_MAX_INVERTERS; inv++) { |
|
|
mCfg->groups[group].inverters[inv].doReboot = true; |
|
|
// mCfg->groups[group].inverters[inv].doReboot = 1;
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -261,28 +261,37 @@ class ZeroExport { |
|
|
if ((!mIsInitialized) || (!mCfg->enabled)) return; |
|
|
if ((!mIsInitialized) || (!mCfg->enabled)) return; |
|
|
|
|
|
|
|
|
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { |
|
|
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { |
|
|
|
|
|
bool DoLog = false; |
|
|
|
|
|
unsigned long bTsp = millis(); |
|
|
|
|
|
|
|
|
|
|
|
mLog["g"] = group; |
|
|
|
|
|
mLog["t"] = "resetWaitLimitAck"; |
|
|
|
|
|
|
|
|
|
|
|
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++) { |
|
|
if (iv->id == (uint8_t)mCfg->groups[group].inverters[inv].id) { |
|
|
if (iv->id == (uint8_t)mCfg->groups[group].inverters[inv].id) { |
|
|
unsigned long bTsp = millis(); |
|
|
JsonObject logObj = logArr.createNestedObject(); |
|
|
|
|
|
|
|
|
mLog["t"] = "resetWaitLimitAck"; |
|
|
logObj["i"] = inv; |
|
|
mLog["g"] = group; |
|
|
logObj["id"] = iv->id; |
|
|
mLog["i"] = inv; |
|
|
|
|
|
mLog["id"] = iv->id; |
|
|
|
|
|
mCfg->groups[group].inverters[inv].waitLimitAck = 0; |
|
|
mCfg->groups[group].inverters[inv].waitLimitAck = 0; |
|
|
mLog["w"] = 0; |
|
|
logObj["wL"] = mCfg->groups[group].inverters[inv].waitLimitAck; |
|
|
|
|
|
|
|
|
if (mCfg->debug) { |
|
|
DoLog = true; |
|
|
unsigned long eTsp = millis(); |
|
|
|
|
|
mLog["B"] = bTsp; |
|
|
|
|
|
mLog["E"] = eTsp; |
|
|
|
|
|
mLog["D"] = eTsp - bTsp; |
|
|
|
|
|
} |
|
|
|
|
|
sendLog(); |
|
|
|
|
|
clearLog(); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (mCfg->debug) { |
|
|
|
|
|
unsigned long eTsp = millis(); |
|
|
|
|
|
mLog["B"] = bTsp; |
|
|
|
|
|
mLog["E"] = eTsp; |
|
|
|
|
|
mLog["D"] = eTsp - bTsp; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(DoLog) sendLog(); |
|
|
|
|
|
clearLog(); |
|
|
|
|
|
DoLog = false; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -295,28 +304,37 @@ class ZeroExport { |
|
|
if ((!mIsInitialized) || (!mCfg->enabled)) return; |
|
|
if ((!mIsInitialized) || (!mCfg->enabled)) return; |
|
|
|
|
|
|
|
|
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { |
|
|
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { |
|
|
|
|
|
bool DoLog = false; |
|
|
|
|
|
unsigned long bTsp = millis(); |
|
|
|
|
|
|
|
|
|
|
|
mLog["g"] = group; |
|
|
|
|
|
mLog["t"] = "resetWaitPowerAck"; |
|
|
|
|
|
|
|
|
|
|
|
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++) { |
|
|
if (iv->id == mCfg->groups[group].inverters[inv].id) { |
|
|
if (iv->id == mCfg->groups[group].inverters[inv].id) { |
|
|
unsigned long bTsp = millis(); |
|
|
JsonObject logObj = logArr.createNestedObject(); |
|
|
|
|
|
|
|
|
mLog["t"] = "resetWaitPowerAck"; |
|
|
logObj["i"] = inv; |
|
|
mLog["g"] = group; |
|
|
logObj["id"] = iv->id; |
|
|
mLog["i"] = inv; |
|
|
|
|
|
mLog["id"] = iv->id; |
|
|
|
|
|
mCfg->groups[group].inverters[inv].waitPowerAck = 30; |
|
|
mCfg->groups[group].inverters[inv].waitPowerAck = 30; |
|
|
mLog["w"] = 30; |
|
|
logObj["wP"] = mCfg->groups[group].inverters[inv].waitPowerAck; |
|
|
|
|
|
|
|
|
if (mCfg->debug) { |
|
|
DoLog = true; |
|
|
unsigned long eTsp = millis(); |
|
|
|
|
|
mLog["B"] = bTsp; |
|
|
|
|
|
mLog["E"] = eTsp; |
|
|
|
|
|
mLog["D"] = eTsp - bTsp; |
|
|
|
|
|
} |
|
|
|
|
|
sendLog(); |
|
|
|
|
|
clearLog(); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (mCfg->debug) { |
|
|
|
|
|
unsigned long eTsp = millis(); |
|
|
|
|
|
mLog["B"] = bTsp; |
|
|
|
|
|
mLog["E"] = eTsp; |
|
|
|
|
|
mLog["D"] = eTsp - bTsp; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(DoLog) sendLog(); |
|
|
|
|
|
clearLog(); |
|
|
|
|
|
DoLog = false; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -329,28 +347,37 @@ class ZeroExport { |
|
|
if ((!mIsInitialized) || (!mCfg->enabled)) return; |
|
|
if ((!mIsInitialized) || (!mCfg->enabled)) return; |
|
|
|
|
|
|
|
|
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { |
|
|
for (uint8_t group = 0; group < ZEROEXPORT_MAX_GROUPS; group++) { |
|
|
|
|
|
bool DoLog = false; |
|
|
|
|
|
unsigned long bTsp = millis(); |
|
|
|
|
|
|
|
|
|
|
|
mLog["g"] = group; |
|
|
|
|
|
mLog["t"] = "resetWaitRebootAck"; |
|
|
|
|
|
|
|
|
|
|
|
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++) { |
|
|
if (iv->id == mCfg->groups[group].inverters[inv].id) { |
|
|
if (iv->id == mCfg->groups[group].inverters[inv].id) { |
|
|
unsigned long bTsp = millis(); |
|
|
JsonObject logObj = logArr.createNestedObject(); |
|
|
|
|
|
|
|
|
mLog["t"] = "resetWaitRebootAck"; |
|
|
logObj["i"] = inv; |
|
|
mLog["g"] = group; |
|
|
logObj["id"] = iv->id; |
|
|
mLog["i"] = inv; |
|
|
|
|
|
mLog["id"] = iv->id; |
|
|
|
|
|
mCfg->groups[group].inverters[inv].waitRebootAck = 30; |
|
|
mCfg->groups[group].inverters[inv].waitRebootAck = 30; |
|
|
mLog["w"] = 30; |
|
|
logObj["wR"] = mCfg->groups[group].inverters[inv].waitRebootAck; |
|
|
|
|
|
|
|
|
if (mCfg->debug) { |
|
|
DoLog = true; |
|
|
unsigned long eTsp = millis(); |
|
|
|
|
|
mLog["B"] = bTsp; |
|
|
|
|
|
mLog["E"] = eTsp; |
|
|
|
|
|
mLog["D"] = eTsp - bTsp; |
|
|
|
|
|
} |
|
|
|
|
|
sendLog(); |
|
|
|
|
|
clearLog(); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (mCfg->debug) { |
|
|
|
|
|
unsigned long eTsp = millis(); |
|
|
|
|
|
mLog["B"] = bTsp; |
|
|
|
|
|
mLog["E"] = eTsp; |
|
|
|
|
|
mLog["D"] = eTsp - bTsp; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(DoLog) sendLog(); |
|
|
|
|
|
clearLog(); |
|
|
|
|
|
DoLog = false; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1004,8 +1031,8 @@ class ZeroExport { |
|
|
mLog["y3"] = y3; |
|
|
mLog["y3"] = y3; |
|
|
|
|
|
|
|
|
bool grpTarget[7] = {false, false, false, false, false, false, false}; |
|
|
bool grpTarget[7] = {false, false, false, false, false, false, false}; |
|
|
uint8_t ivId_Pmin[7] = {0, 0, 0, 0, 0, 0, 0}; |
|
|
int8_t ivId_Pmin[7] = {-1, -1, -1, -1, -1, -1, -1}; |
|
|
uint8_t ivId_Pmax[7] = {0, 0, 0, 0, 0, 0, 0}; |
|
|
int8_t ivId_Pmax[7] = {-1, -1, -1, -1, -1, -1, -1}; |
|
|
uint16_t ivPmin[7] = {65535, 65535, 65535, 65535, 65535, 65535, 65535}; |
|
|
uint16_t ivPmin[7] = {65535, 65535, 65535, 65535, 65535, 65535, 65535}; |
|
|
uint16_t ivPmax[7] = {0, 0, 0, 0, 0, 0, 0}; |
|
|
uint16_t ivPmax[7] = {0, 0, 0, 0, 0, 0, 0}; |
|
|
|
|
|
|
|
@ -1141,46 +1168,47 @@ class ZeroExport { |
|
|
// Inverter not available -> ignore
|
|
|
// Inverter not available -> ignore
|
|
|
if (!mIv[group][inv]->isAvailable()) { |
|
|
if (!mIv[group][inv]->isAvailable()) { |
|
|
logObj["a"] = false; |
|
|
logObj["a"] = false; |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
logObj["dR"] = cfgGroupInv->doReboot; |
|
|
|
|
|
logObj["wR"] = cfgGroupInv->waitRebootAck; |
|
|
|
|
|
|
|
|
|
|
|
// Wait
|
|
|
|
|
|
if (cfgGroupInv->waitRebootAck > 0) { |
|
|
result = false; |
|
|
result = false; |
|
|
|
|
|
if (!mCfg->debug) *doLog = true; |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Reset
|
|
|
// Reset
|
|
|
if ((cfgGroupInv->doReboot == 2) && (cfgGroupInv->waitRebootAck == 0)) { |
|
|
if ((cfgGroupInv->doReboot == 2) && (cfgGroupInv->waitRebootAck == 0)) { |
|
|
/// result = false;
|
|
|
cfgGroupInv->doReboot = -1; |
|
|
cfgGroupInv->doReboot = 0; |
|
|
if (!mCfg->debug) { |
|
|
logObj["act"] = "done"; |
|
|
logObj["act"] = "done"; |
|
|
|
|
|
*doLog = true; |
|
|
|
|
|
} |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Calculate
|
|
|
// Calculate
|
|
|
if (cfgGroupInv->doReboot == 1) { |
|
|
if (cfgGroupInv->doReboot == 1) { |
|
|
cfgGroupInv->doReboot = 2; |
|
|
cfgGroupInv->doReboot = 2; |
|
|
} |
|
|
cfgGroupInv->waitRebootAck = 120; |
|
|
|
|
|
|
|
|
// Wait
|
|
|
|
|
|
if (cfgGroupInv->waitRebootAck > 0) { |
|
|
|
|
|
logObj["w"] = cfgGroupInv->waitRebootAck; |
|
|
|
|
|
result = false; |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Inverter nothing to do -> ignore
|
|
|
// Inverter nothing to do -> ignore
|
|
|
if (cfgGroupInv->doReboot == 0) { |
|
|
if (cfgGroupInv->doReboot == -1) { |
|
|
logObj["act"] = "nothing to do"; |
|
|
if (!mCfg->debug) { |
|
|
|
|
|
logObj["act"] = "nothing to do"; |
|
|
|
|
|
*doLog = true; |
|
|
|
|
|
} |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
result = false; |
|
|
result = false; |
|
|
|
|
|
|
|
|
*doLog = true; |
|
|
*doLog = true; |
|
|
|
|
|
|
|
|
if (!mCfg->debug) logObj["act"] = cfgGroupInv->doReboot; |
|
|
|
|
|
|
|
|
|
|
|
// wait for Ack
|
|
|
|
|
|
cfgGroupInv->waitRebootAck = 120; |
|
|
|
|
|
logObj["wR"] = cfgGroupInv->waitRebootAck; |
|
|
|
|
|
|
|
|
|
|
|
// send Command
|
|
|
// send Command
|
|
|
DynamicJsonDocument doc(512); |
|
|
DynamicJsonDocument doc(512); |
|
|
JsonObject obj = doc.to<JsonObject>(); |
|
|
JsonObject obj = doc.to<JsonObject>(); |
|
@ -1188,7 +1216,7 @@ class ZeroExport { |
|
|
obj["path"] = "ctrl"; |
|
|
obj["path"] = "ctrl"; |
|
|
obj["cmd"] = "restart"; |
|
|
obj["cmd"] = "restart"; |
|
|
mApi->ctrlRequest(obj); |
|
|
mApi->ctrlRequest(obj); |
|
|
logObj["d"] = obj; |
|
|
if (!mCfg->debug) logObj["d"] = obj; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return result; |
|
|
return result; |
|
@ -1222,15 +1250,26 @@ class ZeroExport { |
|
|
// Inverter not available -> ignore
|
|
|
// Inverter not available -> ignore
|
|
|
if (!mIv[group][inv]->isAvailable()) { |
|
|
if (!mIv[group][inv]->isAvailable()) { |
|
|
logObj["a"] = false; |
|
|
logObj["a"] = false; |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
logObj["dP"] = cfgGroupInv->doPower; |
|
|
|
|
|
logObj["wP"] = cfgGroupInv->waitPowerAck; |
|
|
|
|
|
|
|
|
|
|
|
// Wait
|
|
|
|
|
|
if (cfgGroupInv->waitPowerAck > 0) { |
|
|
result = false; |
|
|
result = false; |
|
|
|
|
|
if (!mCfg->debug) *doLog = true; |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Reset
|
|
|
// Reset
|
|
|
if ((cfgGroupInv->doPower != -1) && (cfgGroupInv->waitPowerAck == 0)) { |
|
|
if ((cfgGroupInv->doPower != -1) && (cfgGroupInv->waitPowerAck == 0)) { |
|
|
/// result = false;
|
|
|
|
|
|
cfgGroupInv->doPower = -1; |
|
|
cfgGroupInv->doPower = -1; |
|
|
logObj["act"] = "done"; |
|
|
if (!mCfg->debug) { |
|
|
|
|
|
logObj["act"] = "done"; |
|
|
|
|
|
*doLog = true; |
|
|
|
|
|
} |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1243,7 +1282,8 @@ class ZeroExport { |
|
|
(cfgGroupInv->limitNew > cfgGroupInv->powerMin) && |
|
|
(cfgGroupInv->limitNew > cfgGroupInv->powerMin) && |
|
|
(mIv[group][inv]->isProducing() == false)) { |
|
|
(mIv[group][inv]->isProducing() == false)) { |
|
|
// On
|
|
|
// On
|
|
|
cfgGroupInv->doPower = true; |
|
|
cfgGroupInv->doPower = 1; |
|
|
|
|
|
cfgGroupInv->waitPowerAck = 120; |
|
|
logObj["act"] = "on"; |
|
|
logObj["act"] = "on"; |
|
|
} |
|
|
} |
|
|
if ( |
|
|
if ( |
|
@ -1252,33 +1292,23 @@ class ZeroExport { |
|
|
(cfgGroupInv->limitNew < (cfgGroupInv->powerMin - 50))) && |
|
|
(cfgGroupInv->limitNew < (cfgGroupInv->powerMin - 50))) && |
|
|
(mIv[group][inv]->isProducing() == true)) { |
|
|
(mIv[group][inv]->isProducing() == true)) { |
|
|
// Off
|
|
|
// Off
|
|
|
cfgGroupInv->doPower = false; |
|
|
cfgGroupInv->doPower = 0; |
|
|
|
|
|
cfgGroupInv->waitPowerAck = 120; |
|
|
logObj["act"] = "off"; |
|
|
logObj["act"] = "off"; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Wait
|
|
|
// Inverter nothing to do -> ignore
|
|
|
if (cfgGroupInv->waitPowerAck > 0) { |
|
|
|
|
|
logObj["w"] = cfgGroupInv->waitPowerAck; |
|
|
|
|
|
result = false; |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Nothing todo
|
|
|
|
|
|
if (cfgGroupInv->doPower == -1) { |
|
|
if (cfgGroupInv->doPower == -1) { |
|
|
logObj["act"] = "nothing to do"; |
|
|
if (!mCfg->debug) { |
|
|
|
|
|
logObj["act"] = "nothing to do"; |
|
|
|
|
|
*doLog = true; |
|
|
|
|
|
} |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
result = false; |
|
|
result = false; |
|
|
|
|
|
|
|
|
*doLog = true; |
|
|
*doLog = true; |
|
|
|
|
|
|
|
|
if (!mCfg->debug) logObj["act"] = cfgGroupInv->doPower; |
|
|
|
|
|
|
|
|
|
|
|
// wait for Ack
|
|
|
|
|
|
cfgGroupInv->waitPowerAck = 120; |
|
|
|
|
|
logObj["wP"] = cfgGroupInv->waitPowerAck; |
|
|
|
|
|
|
|
|
|
|
|
// send Command
|
|
|
// send Command
|
|
|
DynamicJsonDocument doc(512); |
|
|
DynamicJsonDocument doc(512); |
|
|
JsonObject obj = doc.to<JsonObject>(); |
|
|
JsonObject obj = doc.to<JsonObject>(); |
|
@ -1287,7 +1317,7 @@ class ZeroExport { |
|
|
obj["path"] = "ctrl"; |
|
|
obj["path"] = "ctrl"; |
|
|
obj["cmd"] = "power"; |
|
|
obj["cmd"] = "power"; |
|
|
mApi->ctrlRequest(obj); |
|
|
mApi->ctrlRequest(obj); |
|
|
logObj["d"] = obj; |
|
|
if (!mCfg->debug) logObj["d"] = obj; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return result; |
|
|
return result; |
|
@ -1321,15 +1351,27 @@ class ZeroExport { |
|
|
// Inverter not available -> ignore
|
|
|
// Inverter not available -> ignore
|
|
|
if (!mIv[group][inv]->isAvailable()) { |
|
|
if (!mIv[group][inv]->isAvailable()) { |
|
|
logObj["a"] = false; |
|
|
logObj["a"] = false; |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
logObj["dL"] = cfgGroupInv->doLimit; |
|
|
|
|
|
logObj["wL"] = cfgGroupInv->waitLimitAck; |
|
|
|
|
|
logObj["L"] = cfgGroupInv->limit; |
|
|
|
|
|
|
|
|
|
|
|
// Wait
|
|
|
|
|
|
if (cfgGroupInv->waitLimitAck > 0) { |
|
|
result = false; |
|
|
result = false; |
|
|
|
|
|
if (!mCfg->debug) *doLog = true; |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Reset
|
|
|
// Reset
|
|
|
if ((cfgGroupInv->doLimit) && (cfgGroupInv->waitLimitAck == 0)) { |
|
|
if ((cfgGroupInv->doLimit != -1) && (cfgGroupInv->waitLimitAck == 0)) { |
|
|
/// result = false;
|
|
|
cfgGroupInv->doLimit = -1; |
|
|
cfgGroupInv->doLimit = false; |
|
|
if (!mCfg->debug) { |
|
|
logObj["act"] = "done"; |
|
|
logObj["act"] = "done"; |
|
|
|
|
|
*doLog = true; |
|
|
|
|
|
} |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -1340,75 +1382,76 @@ class ZeroExport { |
|
|
cfgGroupInv->limitNew = cfgGroupInv->powerMin; |
|
|
cfgGroupInv->limitNew = cfgGroupInv->powerMin; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Restriction LimitNew >= Pmin
|
|
|
// Restriction LimitNew < Pmin
|
|
|
if (cfgGroupInv->limitNew < cfgGroupInv->powerMin) { |
|
|
if (cfgGroupInv->limitNew < cfgGroupInv->powerMin) { |
|
|
cfgGroupInv->limitNew = cfgGroupInv->powerMin; |
|
|
cfgGroupInv->limitNew = cfgGroupInv->powerMin; |
|
|
} |
|
|
} |
|
|
// Restriction LimitNew >= 2%
|
|
|
|
|
|
uint16_t power2proz = mIv[group][inv]->getMaxPower() / 100 * 2; |
|
|
// Restriction LimitNew < 2%
|
|
|
|
|
|
uint16_t power2proz = (mIv[group][inv]->getMaxPower() *2) / 100; |
|
|
if (cfgGroupInv->limitNew < power2proz) { |
|
|
if (cfgGroupInv->limitNew < power2proz) { |
|
|
cfgGroupInv->limitNew = power2proz; |
|
|
cfgGroupInv->limitNew = power2proz; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Restriction LimitNew <= Pmax
|
|
|
// Restriction LimitNew > Pmax
|
|
|
if (cfgGroupInv->limitNew > cfgGroupInv->powerMax) { |
|
|
if (cfgGroupInv->limitNew > cfgGroupInv->powerMax) { |
|
|
cfgGroupInv->limitNew = cfgGroupInv->powerMax; |
|
|
cfgGroupInv->limitNew = cfgGroupInv->powerMax; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// Reject limit if difference < 5 W
|
|
|
// Restriction LimitNew > 100%
|
|
|
/*
|
|
|
uint16_t power100proz = mIv[group][inv]->getMaxPower(); |
|
|
if ( |
|
|
if (cfgGroupInv->limitNew > power100proz) { |
|
|
(cfgGroupInv->limitNew > (cfgGroupInv->powerMin + ZEROEXPORT_GROUP_WR_LIMIT_MIN_DIFF)) && |
|
|
cfgGroupInv->limitNew = power100proz; |
|
|
(cfgGroupInv->limitNew > (cfgGroupInv->limit + ZEROEXPORT_GROUP_WR_LIMIT_MIN_DIFF)) && |
|
|
} |
|
|
(cfgGroupInv->limitNew < (cfgGroupInv->limit - ZEROEXPORT_GROUP_WR_LIMIT_MIN_DIFF))) { |
|
|
|
|
|
logObj["err"] = String("Diff < ") + String(ZEROEXPORT_GROUP_WR_LIMIT_MIN_DIFF) + String("W"); |
|
|
|
|
|
|
|
|
|
|
|
*doLog = true; |
|
|
// Restriction deltaLimitNew < 5 W
|
|
|
|
|
|
/*
|
|
|
|
|
|
if ( |
|
|
|
|
|
(cfgGroupInv->limitNew > (cfgGroupInv->powerMin + ZEROEXPORT_GROUP_WR_LIMIT_MIN_DIFF)) && |
|
|
|
|
|
(cfgGroupInv->limitNew > (cfgGroupInv->limit + ZEROEXPORT_GROUP_WR_LIMIT_MIN_DIFF)) && |
|
|
|
|
|
(cfgGroupInv->limitNew < (cfgGroupInv->limit - ZEROEXPORT_GROUP_WR_LIMIT_MIN_DIFF))) { |
|
|
|
|
|
logObj["err"] = String("Diff < ") + String(ZEROEXPORT_GROUP_WR_LIMIT_MIN_DIFF) + String("W"); |
|
|
|
|
|
|
|
|
return false; |
|
|
*doLog = true; |
|
|
} |
|
|
return false; |
|
|
*/ |
|
|
|
|
|
// Wait
|
|
|
|
|
|
if (cfgGroupInv->waitLimitAck > 0) { |
|
|
|
|
|
logObj["w"] = cfgGroupInv->waitLimitAck; |
|
|
|
|
|
result = false; |
|
|
|
|
|
continue; |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
// Nothing todo
|
|
|
logObj["zeLold"] = cfgGroupInv->limit; |
|
|
// if (cfgGroupInv->doLimit == false) {
|
|
|
|
|
|
// logObj["act"] = "nothing to do";
|
|
|
|
|
|
// continue;
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
if (cfgGroupInv->limit == cfgGroupInv->limitNew) { |
|
|
if (cfgGroupInv->limit != cfgGroupInv->limitNew) { |
|
|
/// logObj["act"] = "nothing to do";
|
|
|
cfgGroupInv->doLimit = 1; |
|
|
|
|
|
cfgGroupInv->waitLimitAck = 60; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
cfgGroupInv->limit = cfgGroupInv->limitNew; |
|
|
|
|
|
logObj["zeL"] = cfgGroupInv->limit; |
|
|
|
|
|
|
|
|
|
|
|
// Inverter nothing to do -> ignore
|
|
|
|
|
|
if (cfgGroupInv->doLimit == -1) { |
|
|
|
|
|
if (!mCfg->debug) { |
|
|
|
|
|
logObj["act"] = "nothing to do"; |
|
|
|
|
|
*doLog = true; |
|
|
|
|
|
} |
|
|
continue; |
|
|
continue; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
result = false; |
|
|
result = false; |
|
|
|
|
|
|
|
|
*doLog = true; |
|
|
*doLog = true; |
|
|
|
|
|
|
|
|
cfgGroupInv->doLimit = true; |
|
|
|
|
|
if (!mCfg->debug) logObj["act"] = cfgGroupInv->doLimit; |
|
|
|
|
|
|
|
|
|
|
|
cfgGroupInv->limit = cfgGroupInv->limitNew; |
|
|
|
|
|
logObj["zeL"] = (uint16_t)cfgGroupInv->limit; |
|
|
|
|
|
|
|
|
|
|
|
// wait for Ack
|
|
|
|
|
|
cfgGroupInv->waitLimitAck = 60; |
|
|
|
|
|
logObj["wL"] = cfgGroupInv->waitLimitAck; |
|
|
|
|
|
|
|
|
|
|
|
// send Command
|
|
|
// send Command
|
|
|
DynamicJsonDocument doc(512); |
|
|
DynamicJsonDocument doc(512); |
|
|
JsonObject obj = doc.to<JsonObject>(); |
|
|
JsonObject obj = doc.to<JsonObject>(); |
|
|
obj["val"] = (uint16_t)cfgGroupInv->limit; |
|
|
if (cfgGroupInv->limit > 0) { |
|
|
|
|
|
obj["val"] = cfgGroupInv->limit; |
|
|
|
|
|
} else { |
|
|
|
|
|
obj["val"] = 0; |
|
|
|
|
|
} |
|
|
obj["id"] = cfgGroupInv->id; |
|
|
obj["id"] = cfgGroupInv->id; |
|
|
obj["path"] = "ctrl"; |
|
|
obj["path"] = "ctrl"; |
|
|
obj["cmd"] = "limit_nonpersistent_absolute"; |
|
|
obj["cmd"] = "limit_nonpersistent_absolute"; |
|
|
mApi->ctrlRequest(obj); |
|
|
mApi->ctrlRequest(obj); |
|
|
logObj["d"] = obj; |
|
|
if (!mCfg->debug) logObj["d"] = obj; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
return result; |
|
|
return result; |
|
|