From ee376827fd7683f6df29648b9687a03c9d0885ad Mon Sep 17 00:00:00 2001 From: MalteSchm Date: Thu, 6 Apr 2023 09:40:46 +0200 Subject: [PATCH] merging functionality from PL refactor --- include/PowerLimiter.h | 7 +++--- src/PowerLimiter.cpp | 51 +++++++++++++++++++++--------------------- 2 files changed, 30 insertions(+), 28 deletions(-) diff --git a/include/PowerLimiter.h b/include/PowerLimiter.h index 7ef47178..c3503f15 100644 --- a/include/PowerLimiter.h +++ b/include/PowerLimiter.h @@ -8,8 +8,8 @@ #include typedef enum { - STATE_PL_SHUTDOWN = 0, - STATE_ACTIVE + SHUTDOWN = 0, + ACTIVE } plStates; typedef enum { @@ -32,8 +32,9 @@ private: uint32_t _lastLoop = 0; int32_t _lastRequestedPowerLimit = 0; uint32_t _lastLimitSetTime = 0; - plStates _plState = STATE_ACTIVE; + plStates _plState = ACTIVE; bool _disabled = false; + bool _batteryDischargeEnabled = false; float _powerMeter1Power; float _powerMeter2Power; diff --git a/src/PowerLimiter.cpp b/src/PowerLimiter.cpp index 9240ff53..b1db679f 100644 --- a/src/PowerLimiter.cpp +++ b/src/PowerLimiter.cpp @@ -33,9 +33,7 @@ void PowerLimiterClass::loop() _lastLoop = millis(); - // Debug state transistions - - + // Debug state transistions, TODO: Remove MessageOutput.printf("****************** PL STATE: %i\r\n", _plState); std::shared_ptr inverter = Hoymiles.getInverterByPos(config.PowerLimiter_InverterId); @@ -45,26 +43,26 @@ void PowerLimiterClass::loop() // Make sure inverter is turned off if PL is disabled by user // Make sure inverter is turned off when lower battery threshold is reached - // In this case we willbe in some state and want to reach STATE_PL_SHUTDOWN - if ((!config.PowerLimiter_Enabled && _plState != STATE_PL_SHUTDOWN) + // In this case we are in some state and want to reach STATE_PL_SHUTDOWN + if (((!config.PowerLimiter_Enabled || _disabled) && _plState != SHUTDOWN) || isStopThresholdReached(inverter)) { if (inverter->isProducing()) { MessageOutput.printf("PL initiated inverter shutdown.\r\n"); inverter->sendPowerControlRequest(Hoymiles.getRadio(), false); } else { - _plState = STATE_PL_SHUTDOWN; + _plState = SHUTDOWN; } return; } - // PL is disabled + // If power limiter is disabled if (!config.PowerLimiter_Enabled) { return; } float dcVoltage = inverter->Statistics()->getChannelFieldValue(TYPE_DC, (ChannelNum_t) config.PowerLimiter_InverterChannelId, FLD_UDC); - float acPower = inverter->Statistics()->getChannelFieldValue(TYPE_AC, (ChannelNum_t) config.PowerLimiter_InverterChannelId, FLD_PAC); - float correctedDcVoltage = dcVoltage + (acPower * config.PowerLimiter_VoltageLoadCorrectionFactor); + //float acPower = inverter->Statistics()->getChannelFieldValue(TYPE_AC, (ChannelNum_t) config.PowerLimiter_InverterChannelId, FLD_PAC); + //float correctedDcVoltage = dcVoltage + (acPower * config.PowerLimiter_VoltageLoadCorrectionFactor); // If the last inverter update is too old, don't do anything. // If the last inverter update was before the last limit updated, don't do anything. @@ -81,24 +79,27 @@ void PowerLimiterClass::loop() dcVoltage, config.PowerLimiter_VoltageStartThreshold, config.PowerLimiter_VoltageStopThreshold, inverter->isProducing()); } - // Check if we need to move state away from STATE_PL_SHUTDOWN - if (_plState == STATE_PL_SHUTDOWN) { - - // Allow discharge when start threshold reached - // This is also the trigger for drain strategy: EMPTY_WHEN_FULL - if (isStartThresholdReached(inverter)) { - _plState = STATE_ACTIVE; - } - - // Allow discharge when drain strategy is EMPTY_AT_NIGHT - if (config.PowerLimiter_BatteryDrainStategy == EMPTY_AT_NIGHT) { - _plState = STATE_ACTIVE; - } - - return; + // If we're in shutdown move to active operation + if (_plState == SHUTDOWN) { + _plState = ACTIVE; } - int32_t newPowerLimit = calcPowerLimit(inverter, canUseDirectSolarPower()); + if (isStopThresholdReached(inverter)) { + // Disable battery discharge when empty + _batteryDischargeEnabled = false; + } else if (!canUseDirectSolarPower() || + config.PowerLimiter_BatteryDrainStategy == EMPTY_AT_NIGHT) { + // Enable battery discharge + _batteryDischargeEnabled = true; + } + + // This checks if the battery discharge start conditions are met for the EMPTY_WHEN_FULL case + if (isStartThresholdReached(inverter) && config.PowerLimiter_BatteryDrainStategy == EMPTY_WHEN_FULL) { + _batteryDischargeEnabled = true; + } + + int32_t newPowerLimit = calcPowerLimit(inverter, !_batteryDischargeEnabled); + // Debug, TODO: Remove MessageOutput.printf("****************************** Powerlimit: %i\r\n", newPowerLimit); setNewPowerLimit(inverter, newPowerLimit); }