Skip to content

Commit

Permalink
determine solar inverter maxIncrease based on shaded mppts
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreasBoehm committed Oct 23, 2024
1 parent d69763c commit d828734
Showing 1 changed file with 55 additions and 2 deletions.
57 changes: 55 additions & 2 deletions src/PowerLimiterSolarInverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,61 @@ 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
// TODO(AndreasBoehm): should we increas by only 100W in this case? Or go for the max?
return 100; // TODO(AndreasBoehm) or maxTotalIncrease
}

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

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

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

// fall back to hoymiles peak efficiency as per datasheet if inverter
// is currently not producing (efficiency is zero in that case)
inverterEfficiencyFactor = (inverterEfficiencyFactor > 0) ? inverterEfficiencyFactor/100 : 0.967;

size_t dcNonShadedMppts = 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) {
dcNonShadedMppts++;
}
}

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

if (dcNonShadedMppts == dcTotalMppts) {
// no mppt is shaded, we can increase the power by the maximum
// TODO(AndreasBoehm): If none of the mppts are shaded we assume that we can increase the power by the maximum. is this correct?
return maxTotalIncrease;
}

// maximum increase per mppt, required to calculate how much the non-shaded mppts can increase
int16_t maxIncreasePerCMppt = maxTotalIncrease / dcTotalMppts;

// maximum increase based on the non-shaded mppts
int16_t maxIncrease = maxIncreasePerCMppt * dcNonShadedMppts;

return maxIncrease;
}

uint16_t PowerLimiterSolarInverter::applyReduction(uint16_t reduction, bool)
Expand Down

0 comments on commit d828734

Please sign in to comment.