Skip to content

Commit

Permalink
DPL: refactor code determining battery charge cycle state
Browse files Browse the repository at this point in the history
  • Loading branch information
schlimmchen committed Mar 9, 2024
1 parent c6f8180 commit be15050
Showing 1 changed file with 31 additions and 36 deletions.
67 changes: 31 additions & 36 deletions src/PowerLimiter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,38 +224,35 @@ void PowerLimiterClass::loop()
}
}

// Battery charging cycle conditions
// First we always disable discharge if the battery is empty
if (isStopThresholdReached()) {
// Disable battery discharge when empty
_batteryDischargeEnabled = false;
} else {
// UI: Solar Passthrough Enabled -> false
// Battery discharge can be enabled when start threshold is reached
if (!config.PowerLimiter.SolarPassThroughEnabled && isStartThresholdReached()) {
_batteryDischargeEnabled = true;
}

// UI: Solar Passthrough Enabled -> true && EMPTY_AT_NIGHT
if (config.PowerLimiter.SolarPassThroughEnabled && config.PowerLimiter.BatteryDrainStategy == EMPTY_AT_NIGHT) {
if(isStartThresholdReached()) {
// In this case we should only discharge the battery as long it is above startThreshold
_batteryDischargeEnabled = true;
auto getBatteryPower = [this,&config]() -> bool {
if (isStopThresholdReached()) { return false; }

if (isStartThresholdReached()) { return true; }

// with solar passthrough, and the respective drain strategy, we
// may start discharging the battery when it is nighttime. we also
// stop the discharge cycle if it becomes daytime again.
// TODO(schlimmchen): should be supported by sunrise and sunset, such
// that a thunderstorm or other events that drastically lower the solar
// power do not cause the start of a discharge cycle during the day.
if (config.PowerLimiter.SolarPassThroughEnabled &&
config.PowerLimiter.BatteryDrainStategy == EMPTY_AT_NIGHT) {
return !canUseDirectSolarPower();
}
else {
// In this case we should only discharge the battery when there is no sunshine
_batteryDischargeEnabled = !canUseDirectSolarPower();
}
}

// UI: Solar Passthrough Enabled -> true && EMPTY_WHEN_FULL
// Battery discharge can be enabled when start threshold is reached
if (config.PowerLimiter.SolarPassThroughEnabled && isStartThresholdReached() && config.PowerLimiter.BatteryDrainStategy == EMPTY_WHEN_FULL) {
_batteryDischargeEnabled = true;
}
}
// we are between start and stop threshold and keep the state that was
// last triggered, either charging or discharging.
return _batteryDischargeEnabled;
};

_batteryDischargeEnabled = getBatteryPower();

auto logging = [this,&config]() -> void {
MessageOutput.printf("[DPL::loop] PowerMeter: %d W, target consumption: %d W, solar power: %d W\r\n",
static_cast<int32_t>(round(PowerMeter.getPowerTotal())),
config.PowerLimiter.TargetPowerConsumption,
getSolarChargePower());

if (_verboseLogging) {
MessageOutput.printf("[DPL::loop] battery interface %s, SoC: %d %%, StartTH: %d %%, StopTH: %d %%, SoC age: %d s, ignore: %s\r\n",
(config.Battery.Enabled?"enabled":"disabled"),
Battery.getStats()->getSoC(),
Expand All @@ -275,15 +272,13 @@ void PowerLimiterClass::loop()
(isStopThresholdReached()?"yes":"no"),
(_inverter->isProducing()?"is":"is NOT"));

MessageOutput.printf("[DPL::loop] SolarPT %s, Drain Strategy: %i, canUseDirectSolarPower: %s\r\n",
MessageOutput.printf("[DPL::loop] battery discharging %s, SolarPT %s, Drain Strategy: %i\r\n",
(_batteryDischargeEnabled?"allowed":"prevented"),
(config.PowerLimiter.SolarPassThroughEnabled?"enabled":"disabled"),
config.PowerLimiter.BatteryDrainStategy, (canUseDirectSolarPower()?"yes":"no"));
config.PowerLimiter.BatteryDrainStategy);
};

MessageOutput.printf("[DPL::loop] battery discharging %s, PowerMeter: %d W, target consumption: %d W\r\n",
(_batteryDischargeEnabled?"allowed":"prevented"),
static_cast<int32_t>(round(PowerMeter.getPowerTotal())),
config.PowerLimiter.TargetPowerConsumption);
}
if (_verboseLogging) { logging(); }

// Calculate and set Power Limit (NOTE: might reset _inverter to nullptr!)
int32_t newPowerLimit = calcPowerLimit(_inverter, canUseDirectSolarPower(), _batteryDischargeEnabled);
Expand Down

0 comments on commit be15050

Please sign in to comment.