refactoring calcPowerLimit and setPowerLimit
This commit is contained in:
parent
98faffc3ca
commit
9521deea25
@ -169,6 +169,30 @@ int32_t PowerLimiterClass::calcPowerLimit(std::shared_ptr<InverterAbstract> inve
|
|||||||
|
|
||||||
int32_t newPowerLimit = round(PowerMeter.getPowerTotal());
|
int32_t newPowerLimit = round(PowerMeter.getPowerTotal());
|
||||||
|
|
||||||
|
// Safety check, return on too old power meter values
|
||||||
|
if ((millis() - PowerMeter.getLastPowerMeterUpdate()) > (30 * 1000)) {
|
||||||
|
// If the power meter values are older than 30 seconds,
|
||||||
|
// set the limit to config.PowerLimiter_LowerPowerLimit for safety reasons.
|
||||||
|
MessageOutput.println("[PowerLimiterClass::loop] Power Meter values too old. Using lower limit");
|
||||||
|
return config.PowerLimiter_LowerPowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if grid power consumption is within the limits of the target consumption + hysteresis
|
||||||
|
if (newPowerLimit >= (config.PowerLimiter_TargetPowerConsumption - config.PowerLimiter_TargetPowerConsumptionHysteresis) &&
|
||||||
|
newPowerLimit <= (config.PowerLimiter_TargetPowerConsumption + config.PowerLimiter_TargetPowerConsumptionHysteresis)) {
|
||||||
|
// The values have not changed much. We just use the old setting
|
||||||
|
MessageOutput.println("[PowerLimiterClass::loop] reusing old limit");
|
||||||
|
return _lastRequestedPowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (config.PowerLimiter_IsInverterBehindPowerMeter) {
|
||||||
|
// If the inverter the behind the power meter (part of measurement),
|
||||||
|
// the produced power of this inverter has also to be taken into account.
|
||||||
|
// We don't use FLD_PAC from the statistics, because that
|
||||||
|
// data might be too old and unrelieable.
|
||||||
|
newPowerLimit += _lastRequestedPowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
float efficency = inverter->Statistics()->getChannelFieldValue(TYPE_AC, (ChannelNum_t) config.PowerLimiter_InverterChannelId, FLD_EFF);
|
float efficency = inverter->Statistics()->getChannelFieldValue(TYPE_AC, (ChannelNum_t) config.PowerLimiter_InverterChannelId, FLD_EFF);
|
||||||
int32_t victronChargePower = this->getDirectSolarPower();
|
int32_t victronChargePower = this->getDirectSolarPower();
|
||||||
int32_t adjustedVictronChargePower = victronChargePower * (efficency > 0.0 ? (efficency / 100.0) : 1.0); // if inverter is off, use 1.0
|
int32_t adjustedVictronChargePower = victronChargePower * (efficency > 0.0 ? (efficency / 100.0) : 1.0); // if inverter is off, use 1.0
|
||||||
@ -176,53 +200,50 @@ int32_t PowerLimiterClass::calcPowerLimit(std::shared_ptr<InverterAbstract> inve
|
|||||||
MessageOutput.printf("[PowerLimiterClass::loop] victronChargePower: %d, efficiency: %.2f, consumeSolarPowerOnly: %s, powerConsumption: %d \r\n",
|
MessageOutput.printf("[PowerLimiterClass::loop] victronChargePower: %d, efficiency: %.2f, consumeSolarPowerOnly: %s, powerConsumption: %d \r\n",
|
||||||
victronChargePower, efficency, consumeSolarPowerOnly ? "true" : "false", newPowerLimit);
|
victronChargePower, efficency, consumeSolarPowerOnly ? "true" : "false", newPowerLimit);
|
||||||
|
|
||||||
// Safety check: Are the power meter values not too old?
|
// We're not trying to hit 0 exactly but take an offset into account
|
||||||
if (millis() - PowerMeter.getLastPowerMeterUpdate() < (30 * 1000)) {
|
// This means we never fully compensate the used power with the inverter
|
||||||
if (config.PowerLimiter_IsInverterBehindPowerMeter) {
|
newPowerLimit -= config.PowerLimiter_TargetPowerConsumption;
|
||||||
// If the inverter the behind the power meter (part of measurement),
|
|
||||||
// the produced power of this inverter has also to be taken into account.
|
|
||||||
// We don't use FLD_PAC from the statistics, because that
|
|
||||||
// data might be too old and unrelieable.
|
|
||||||
newPowerLimit += _lastRequestedPowerLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
newPowerLimit -= config.PowerLimiter_TargetPowerConsumption;
|
int32_t upperPowerLimit = config.PowerLimiter_UpperPowerLimit;
|
||||||
|
if (consumeSolarPowerOnly && (upperPowerLimit > adjustedVictronChargePower)) {
|
||||||
int32_t upperPowerLimit = config.PowerLimiter_UpperPowerLimit;
|
// Battery voltage too low, use Victron solar power (corrected by efficency factor) only
|
||||||
if (consumeSolarPowerOnly && (upperPowerLimit > adjustedVictronChargePower)) {
|
upperPowerLimit = adjustedVictronChargePower;
|
||||||
// Battery voltage too low, use Victron solar power (corrected by efficency factor) only
|
|
||||||
upperPowerLimit = adjustedVictronChargePower;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (newPowerLimit > upperPowerLimit)
|
|
||||||
newPowerLimit = upperPowerLimit;
|
|
||||||
} else {
|
|
||||||
// If the power meter values are older than 30 seconds,
|
|
||||||
// set the limit to config.PowerLimiter_LowerPowerLimit for safety reasons.
|
|
||||||
newPowerLimit = config.PowerLimiter_LowerPowerLimit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newPowerLimit > upperPowerLimit)
|
||||||
|
newPowerLimit = upperPowerLimit;
|
||||||
|
|
||||||
MessageOutput.printf("[PowerLimiterClass::loop] newPowerLimit: %d\r\n", newPowerLimit);
|
MessageOutput.printf("[PowerLimiterClass::loop] newPowerLimit: %d\r\n", newPowerLimit);
|
||||||
return newPowerLimit;
|
return newPowerLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PowerLimiterClass::setNewPowerLimit(std::shared_ptr<InverterAbstract> inverter, int32_t newPowerLimit)
|
void PowerLimiterClass::setNewPowerLimit(std::shared_ptr<InverterAbstract> inverter, int32_t newPowerLimit)
|
||||||
{
|
{
|
||||||
if(_lastRequestedPowerLimit != newPowerLimit) {
|
CONFIG_T& config = Configuration.get();
|
||||||
CONFIG_T& config = Configuration.get();
|
|
||||||
|
|
||||||
// if limit too low turn inverter offf
|
// Start the inverter in case it's inactive and if the requested power is high enough
|
||||||
if (newPowerLimit < config.PowerLimiter_LowerPowerLimit) {
|
if (!inverter->isProducing() && newPowerLimit > config.PowerLimiter_LowerPowerLimit) {
|
||||||
if (inverter->isProducing()) {
|
MessageOutput.println("[PowerLimiterClass::loop] Starting up inverter...");
|
||||||
MessageOutput.println("[PowerLimiterClass::loop] Stopping inverter...");
|
inverter->sendPowerControlRequest(Hoymiles.getRadio(), true);
|
||||||
inverter->sendPowerControlRequest(Hoymiles.getRadio(), false);
|
_lastCommandSent = millis();
|
||||||
_lastCommandSent = millis();
|
}
|
||||||
}
|
|
||||||
newPowerLimit = config.PowerLimiter_LowerPowerLimit;
|
// Stop the inverter if limit is below threshold.
|
||||||
} else if (!inverter->isProducing()) {
|
// We'll also set the power limit to the lower value in this case
|
||||||
MessageOutput.println("[PowerLimiterClass::loop] Starting up inverter...");
|
if (newPowerLimit < config.PowerLimiter_LowerPowerLimit) {
|
||||||
inverter->sendPowerControlRequest(Hoymiles.getRadio(), true);
|
if (inverter->isProducing()) {
|
||||||
|
MessageOutput.println("[PowerLimiterClass::loop] Stopping inverter...");
|
||||||
|
inverter->sendPowerControlRequest(Hoymiles.getRadio(), false);
|
||||||
_lastCommandSent = millis();
|
_lastCommandSent = millis();
|
||||||
}
|
}
|
||||||
|
newPowerLimit = config.PowerLimiter_LowerPowerLimit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set the actual limit. We'll only do this is if the limit is in the right range
|
||||||
|
// and differs from the last requested value
|
||||||
|
if( _lastRequestedPowerLimit != newPowerLimit &&
|
||||||
|
/* newPowerLimit > config.PowerLimiter_LowerPowerLimit && --> This will always be true given the check above, kept for code readability */
|
||||||
|
newPowerLimit < config.PowerLimiter_UpperPowerLimit ) {
|
||||||
MessageOutput.printf("[PowerLimiterClass::loop] Limit Non-Persistent: %d W\r\n", newPowerLimit);
|
MessageOutput.printf("[PowerLimiterClass::loop] Limit Non-Persistent: %d W\r\n", newPowerLimit);
|
||||||
inverter->sendActivePowerControlRequest(Hoymiles.getRadio(), newPowerLimit, PowerLimitControlType::AbsolutNonPersistent);
|
inverter->sendActivePowerControlRequest(Hoymiles.getRadio(), newPowerLimit, PowerLimitControlType::AbsolutNonPersistent);
|
||||||
_lastRequestedPowerLimit = newPowerLimit;
|
_lastRequestedPowerLimit = newPowerLimit;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user