@@ -24,25 +24,34 @@ uint16_t PowerLimiterSolarInverter::getMaxIncreaseWatts() const
24
24
return getConfiguredMaxPowerWatts ();
25
25
}
26
26
27
+ // 1.5% of the inverter's max power can be missing
28
+ auto maxPowerMissing = getInverterMaxPowerWatts () * 0.015 ;
29
+ auto diff = getCurrentLimitWatts () - maxPowerMissing;
30
+
31
+ // if the inverter's output is within the limit, we can increase the power
32
+ if (getCurrentOutputAcWatts () >= diff) {
33
+ return getConfiguredMaxPowerWatts () - getCurrentLimitWatts ();
34
+ }
35
+
36
+ // if we reached this point and can't use overscaling, we can't increase the power
37
+ if (!_config.UseOverscaling || _spInverter->supportsPowerDistributionLogic ()) {
38
+ return 0 ;
39
+ }
40
+
41
+ // TODO(andreasboehm): disallow overscaling until the above solution is verified
42
+ return 0 ;
43
+
27
44
// the maximum increase possible for this inverter
28
45
int16_t maxTotalIncrease = getConfiguredMaxPowerWatts () - getCurrentOutputAcWatts ();
29
46
47
+ auto expectedPowerPercentage = static_cast <float >(_config.ScalingThreshold ) / 100.0 ;
48
+
30
49
auto pStats = _spInverter->Statistics ();
31
50
std::vector<MpptNum_t> dcMppts = _spInverter->getMppts ();
32
51
size_t dcTotalMppts = dcMppts.size ();
33
52
34
53
float inverterEfficiencyFactor = pStats->getChannelFieldValue (TYPE_INV, CH0, FLD_EFF) / 100 ;
35
54
36
- // with 97% we are a bit less strict than when we scale the limit
37
- auto expectedPowerPercentage = 0.97 ;
38
-
39
- // use the scaling threshold as the expected power percentage if lower,
40
- // but only when overscaling is enabled and the inverter does not support PDL
41
- if (_config.UseOverscaling && !_spInverter->supportsPowerDistributionLogic ()) {
42
- expectedPowerPercentage = std::min (expectedPowerPercentage, static_cast <float >(_config.ScalingThreshold ) / 100.0 );
43
- }
44
-
45
- // x% of the expected power is good enough
46
55
auto expectedAcPowerPerMppt = (getCurrentLimitWatts () / dcTotalMppts) * expectedPowerPercentage;
47
56
48
57
size_t dcNonShadedMppts = 0 ;
@@ -72,23 +81,16 @@ uint16_t PowerLimiterSolarInverter::getMaxIncreaseWatts() const
72
81
return maxTotalIncrease;
73
82
}
74
83
75
- // for inverters without PDL we use the configured max power, because the limit will be divided equally across the MPPTs by the inverter.
76
- int16_t inverterMaxPower = getConfiguredMaxPowerWatts ();
77
-
78
- // for inverter with PDL or when overscaling is enabled we use the max power of the inverter because each MPPT can deliver its max power.
79
- if (_spInverter->supportsPowerDistributionLogic () || _config.UseOverscaling ) {
80
- inverterMaxPower = getInverterMaxPowerWatts ();
81
- }
84
+ // we use the inverter's max power, because each MPPT can deliver its max power individually
85
+ int16_t inverterMaxPower = getInverterMaxPowerWatts ();
82
86
83
87
int16_t maxPowerPerMppt = inverterMaxPower / dcTotalMppts;
84
88
85
89
int16_t currentPowerPerNonShadedMppt = nonShadedMpptACPowerSum / dcNonShadedMppts;
86
90
87
91
int16_t maxIncreasePerNonShadedMppt = maxPowerPerMppt - currentPowerPerNonShadedMppt;
88
92
89
- // maximum increase based on the non-shaded mppts, can be higher than maxTotalIncrease for inverters
90
- // with PDL when getConfiguredMaxPowerWatts() is less than getInverterMaxPowerWatts() divided by
91
- // the number of used/unshaded MPPTs.
93
+ // maximum increase based on the non-shaded mppts
92
94
int16_t maxIncreaseNonShadedMppts = maxIncreasePerNonShadedMppt * dcNonShadedMppts;
93
95
94
96
// maximum increase should not exceed the max total increase
0 commit comments