Skip to content

Commit

Permalink
Merge branch 'hoylabs:development' into development
Browse files Browse the repository at this point in the history
  • Loading branch information
Snoopy-HSS authored Jan 3, 2025
2 parents ce75e3f + e8a5102 commit 9564bf1
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 23 deletions.
2 changes: 2 additions & 0 deletions include/PowerLimiterInverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ class PowerLimiterInverter {
void setTargetPowerState(bool enable) { _oTargetPowerState = enable; }
void setExpectedOutputAcWatts(uint16_t power) { _expectedOutputAcWatts = power; }

static char mpptName(MpptNum_t mppt);

// copied to avoid races with web UI
PowerLimiterInverterConfig _config;

Expand Down
1 change: 0 additions & 1 deletion include/PowerLimiterSolarInverter.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,4 @@ class PowerLimiterSolarInverter : public PowerLimiterInverter {
private:
uint16_t scaleLimit(uint16_t expectedOutputWatts);
void setAcOutput(uint16_t expectedOutputWatts) final;
static char mpptName(MpptNum_t mppt);
};
40 changes: 40 additions & 0 deletions src/PowerLimiterInverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -349,4 +349,44 @@ void PowerLimiterInverter::debug() const
(_oTargetPowerState.has_value()?(*_oTargetPowerState?"production":"standby"):"unchanged"),
getUpdateTimeouts()
);

MessageOutput.printf(" MPPTs AC power:");

auto pStats = _spInverter->Statistics();
float inverterEfficiencyFactor = pStats->getChannelFieldValue(TYPE_INV, CH0, FLD_EFF) / 100;
std::vector<MpptNum_t> dcMppts = _spInverter->getMppts();

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;
}

MessageOutput.printf(" %c: %.0f W",
mpptName(m), mpptPowerAC);
}

MessageOutput.printf("\r\n");
}

char PowerLimiterInverter::mpptName(MpptNum_t mppt)
{
switch (mppt) {
case MpptNum_t::MPPT_A:
return 'a';

case MpptNum_t::MPPT_B:
return 'b';

case MpptNum_t::MPPT_C:
return 'c';

case MpptNum_t::MPPT_D:
return 'd';

default:
return '?';
}
}
41 changes: 19 additions & 22 deletions src/PowerLimiterSolarInverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,31 @@ uint16_t PowerLimiterSolarInverter::getMaxIncreaseWatts() const
return maxTotalIncrease;
}

// when the current limit is less than 15% of the max power of the inverter
// the output will not match the limit as the inverters are not able to work
// with those low limits. In this case we assume that the inverter is able to
// provide more power and we return the maximum possible increase.
// thanks spcqike for creating a table that can be found here:
// https://github.com/hoylabs/OpenDTU-OnBattery/issues/1087#issuecomment-2216787552
if (getCurrentLimitWatts() < getInverterMaxPowerWatts() * 0.15) { 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;
// with 97% we are a bit less strict than when we scale the limit
auto expectedPowerPercentage = 0.97;

// use the scaling threshold as the expected power percentage if lower,
// but only when overscaling is enabled and the inverter does not support PDL
if (_config.UseOverscaling && !_spInverter->supportsPowerDistributionLogic()) {
expectedPowerPercentage = std::min(expectedPowerPercentage, static_cast<float>(_config.ScalingThreshold) / 100.0);
}

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

size_t dcNonShadedMppts = 0;
auto nonShadedMpptACPowerSum = 0.0;
Expand Down Expand Up @@ -227,23 +244,3 @@ void PowerLimiterSolarInverter::setAcOutput(uint16_t expectedOutputWatts)
setTargetPowerLimitWatts(scaleLimit(expectedOutputWatts));
setTargetPowerState(true);
}

char PowerLimiterSolarInverter::mpptName(MpptNum_t mppt)
{
switch (mppt) {
case MpptNum_t::MPPT_A:
return 'a';

case MpptNum_t::MPPT_B:
return 'b';

case MpptNum_t::MPPT_C:
return 'c';

case MpptNum_t::MPPT_D:
return 'd';

default:
return '?';
}
}

0 comments on commit 9564bf1

Please sign in to comment.