Skip to content

Commit

Permalink
DPL: multiple inverters: add proper support for solar-powered inverte…
Browse files Browse the repository at this point in the history
…rs (#1343)
  • Loading branch information
AndreasBoehm authored and schlimmchen committed Nov 17, 2024
1 parent cf4a59c commit cbffafa
Showing 1 changed file with 55 additions and 4 deletions.
59 changes: 55 additions & 4 deletions src/PowerLimiterSolarInverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,59 @@ uint16_t PowerLimiterSolarInverter::getMaxIncreaseWatts() const
{
if (!isEligible()) { return 0; }

// TODO(schlimmchen): left for the author of the scaling method: @AndreasBoehm
return std::min(getConfiguredMaxPowerWatts() - getCurrentOutputAcWatts(), 100);
// the maximum increase possible for this inverter
int16_t maxTotalIncrease = getConfiguredMaxPowerWatts() - getCurrentOutputAcWatts();

if (!isProducing()) {
// the inverter is not producing, we don't know how much we can increase
// the power, so we return the maximum possible increase
return maxTotalIncrease;
}

auto pStats = _spInverter->Statistics();
std::vector<MpptNum_t> dcMppts = _spInverter->getMppts();
size_t dcTotalMppts = dcMppts.size();

float inverterEfficiencyFactor = pStats->getChannelFieldValue(TYPE_INV, CH0, FLD_EFF) / 100;

// 98% of the expected power is good enough
auto expectedAcPowerPerMppt = (getCurrentLimitWatts() / dcTotalMppts) * 0.98;

size_t dcNonShadedMppts = 0;
auto nonShadedMpptACPowerSum = 0.0;

for (auto& m : dcMppts) {
float mpptPowerAC = 0.0;
std::vector<ChannelNum_t> mpptChnls = _spInverter->getChannelsDCByMppt(m);

for (auto& c : mpptChnls) {
mpptPowerAC += pStats->getChannelFieldValue(TYPE_DC, c, FLD_PDC) * inverterEfficiencyFactor;
}

if (mpptPowerAC >= expectedAcPowerPerMppt) {
nonShadedMpptACPowerSum += mpptPowerAC;
dcNonShadedMppts++;
}
}

if (dcNonShadedMppts == 0) {
// all mppts are shaded, we can't increase the power
return 0;
}

if (dcNonShadedMppts == dcTotalMppts) {
// no MPPT is shaded, we assume that we can increase the power by the maximum
return maxTotalIncrease;
}

int16_t maxPowerPerMppt = getConfiguredMaxPowerWatts() / dcTotalMppts;

int16_t currentPowerPerNonShadedMppt = nonShadedMpptACPowerSum / dcNonShadedMppts;

int16_t maxIncreasePerNonShadedMppt = maxPowerPerMppt - currentPowerPerNonShadedMppt;

// maximum increase based on the non-shaded mppts
return maxIncreasePerNonShadedMppt * dcNonShadedMppts;
}

uint16_t PowerLimiterSolarInverter::applyReduction(uint16_t reduction, bool)
Expand Down Expand Up @@ -100,7 +151,7 @@ uint16_t PowerLimiterSolarInverter::scaleLimit(uint16_t expectedOutputWatts)
auto expectedAcPowerPerMppt = (getCurrentLimitWatts() / dcTotalMppts) * 0.98;

if (_verboseLogging) {
MessageOutput.printf("%s expected AC power per mppt %f W\r\n",
MessageOutput.printf("%s expected AC power per MPPT %.0f W\r\n",
_logPrefix, expectedAcPowerPerMppt);
}

Expand All @@ -121,7 +172,7 @@ uint16_t PowerLimiterSolarInverter::scaleLimit(uint16_t expectedOutputWatts)
}

if (_verboseLogging) {
MessageOutput.printf("%s mppt-%c AC power %f W\r\n",
MessageOutput.printf("%s MPPT-%c AC power %.0f W\r\n",
_logPrefix, m + 'a', mpptPowerAC);
}
}
Expand Down

0 comments on commit cbffafa

Please sign in to comment.