@@ -151,9 +151,108 @@ def SetLimitWithPriority(pLimit):
151151 SetLimitWithPriority .LastLimitAck = False
152152 raise
153153
154+ def SetLimitMixedModeWithPriority (pLimit ):
155+ try :
156+ if not hasattr (SetLimitMixedModeWithPriority , "LastLimit" ):
157+ SetLimitMixedModeWithPriority .LastLimit = CastToInt (0 )
158+ if not hasattr (SetLimitMixedModeWithPriority , "LastLimitAck" ):
159+ SetLimitMixedModeWithPriority .LastLimitAck = bool (False )
160+
161+ if (SetLimitMixedModeWithPriority .LastLimit == CastToInt (pLimit )) and SetLimitMixedModeWithPriority .LastLimitAck :
162+ logger .info ("Inverterlimit was already accepted at %s Watt" ,CastToInt (pLimit ))
163+ return
164+ if (SetLimitMixedModeWithPriority .LastLimit == CastToInt (pLimit )) and not SetLimitMixedModeWithPriority .LastLimitAck :
165+ logger .info ("Inverterlimit %s Watt was previously not accepted by at least one inverter, trying again..." ,CastToInt (pLimit ))
166+
167+ logger .info ("setting new limit to %s Watt" ,CastToInt (pLimit ))
168+ SetLimitMixedModeWithPriority .LastLimit = CastToInt (pLimit )
169+ SetLimitMixedModeWithPriority .LastLimitAck = True
170+ if (CastToInt (pLimit ) <= GetMinWattFromAllInverters ()):
171+ pLimit = 0 # set only minWatt for every inv.
172+ RemainingLimit = CastToInt (pLimit )
173+
174+ # Handle non-battery inverters first
175+ if RemainingLimit >= GetMaxInverterWattFromAllNonBatteryInverters ():
176+ nonBatteryInvertersLimit = GetMaxInverterWattFromAllNonBatteryInverters ()
177+ else :
178+ nonBatteryInvertersLimit = RemainingLimit
179+
180+ for i in range (INVERTER_COUNT ):
181+ if not AVAILABLE [i ] or HOY_BATTERY_MODE [i ]:
182+ continue
183+
184+ # Calculate proportional limit for non-battery inverters
185+ nonBatteryMaxWatt = sum (HOY_MAX_WATT [i ] for i in range (INVERTER_COUNT ) if not HOY_BATTERY_MODE [i ] and AVAILABLE [i ])
186+ Factor = HOY_MAX_WATT [i ] / nonBatteryMaxWatt
187+ NewLimit = CastToInt (nonBatteryInvertersLimit * Factor )
188+
189+ # Apply the calculated limit to the inverter
190+ NewLimit = ApplyLimitsToSetpointInverter (i , NewLimit )
191+ if HOY_COMPENSATE_WATT_FACTOR [i ] != 1 :
192+ logger .info ('Ahoy: Inverter "%s": compensate Limit from %s Watt to %s Watt' , NAME [i ], CastToInt (NewLimit ), CastToInt (NewLimit * HOY_COMPENSATE_WATT_FACTOR [i ]))
193+ NewLimit = CastToInt (NewLimit * HOY_COMPENSATE_WATT_FACTOR [i ])
194+ NewLimit = ApplyLimitsToMaxInverterLimits (i , NewLimit )
195+
196+ if (NewLimit == CastToInt (CURRENT_LIMIT [i ])) and LASTLIMITACKNOWLEDGED [i ]:
197+ continue
198+
199+ LASTLIMITACKNOWLEDGED [i ] = True
200+
201+ DTU .SetLimit (i , NewLimit )
202+ if not DTU .WaitForAck (i , SET_LIMIT_TIMEOUT_SECONDS ):
203+ SetLimitMixedModeWithPriority .LastLimitAck = False
204+ LASTLIMITACKNOWLEDGED [i ] = False
205+
206+ # Adjust RemainingLimit based on what was assigned to non-battery inverters
207+ RemainingLimit -= nonBatteryInvertersLimit
208+
209+ # Then handle battery inverters based on priority
210+ for j in range (1 , 6 ):
211+ batteryMaxWattSamePrio = GetMaxWattFromAllBatteryInvertersSamePrio (j )
212+ if batteryMaxWattSamePrio <= 0 :
213+ continue
214+
215+ if RemainingLimit >= batteryMaxWattSamePrio :
216+ LimitPrio = batteryMaxWattSamePrio
217+ else :
218+ LimitPrio = RemainingLimit
219+ RemainingLimit = RemainingLimit - LimitPrio
220+
221+ for i in range (INVERTER_COUNT ):
222+ if (not HOY_BATTERY_MODE [i ]):
223+ continue
224+ if (not AVAILABLE [i ]) or (not HOY_BATTERY_GOOD_VOLTAGE [i ]):
225+ continue
226+ if HOY_BATTERY_PRIORITY [i ] != j :
227+ continue
228+ Factor = HOY_MAX_WATT [i ] / batteryMaxWattSamePrio
229+ NewLimit = CastToInt (LimitPrio * Factor )
230+ NewLimit = ApplyLimitsToSetpointInverter (i , NewLimit )
231+ if HOY_COMPENSATE_WATT_FACTOR [i ] != 1 :
232+ logger .info ('Ahoy: Inverter "%s": compensate Limit from %s Watt to %s Watt' , NAME [i ], CastToInt (NewLimit ), CastToInt (NewLimit * HOY_COMPENSATE_WATT_FACTOR [i ]))
233+ NewLimit = CastToInt (NewLimit * HOY_COMPENSATE_WATT_FACTOR [i ])
234+ NewLimit = ApplyLimitsToMaxInverterLimits (i , NewLimit )
235+
236+ if (NewLimit == CastToInt (CURRENT_LIMIT [i ])) and LASTLIMITACKNOWLEDGED [i ]:
237+ continue
238+
239+ LASTLIMITACKNOWLEDGED [i ] = True
240+
241+ DTU .SetLimit (i , NewLimit )
242+ if not DTU .WaitForAck (i , SET_LIMIT_TIMEOUT_SECONDS ):
243+ SetLimitMixedModeWithPriority .LastLimitAck = False
244+ LASTLIMITACKNOWLEDGED [i ] = False
245+ except :
246+ logger .error ("Exception at SetLimitMixedModeWithPriority" )
247+ SetLimitMixedModeWithPriority .LastLimitAck = False
248+ raise
249+
154250def SetLimit (pLimit ):
155251 try :
156- if not GetMixedMode () and GetBatteryMode () and GetPriorityMode ():
252+ if GetMixedMode ():
253+ SetLimitMixedModeWithPriority (CastToInt (pLimit ))
254+ return
255+ if GetBatteryMode () and GetPriorityMode ():
157256 SetLimitWithPriority (CastToInt (pLimit ))
158257 return
159258
@@ -443,6 +542,12 @@ def GetMaxWattFromAllInvertersSamePrio(pPriority):
443542 maxWatt = maxWatt + HOY_MAX_WATT [i ]
444543 return maxWatt
445544
545+ def GetMaxWattFromAllBatteryInvertersSamePrio (pPriority ):
546+ return sum (
547+ HOY_MAX_WATT [i ] for i in range (INVERTER_COUNT )
548+ if AVAILABLE [i ] and HOY_BATTERY_GOOD_VOLTAGE [i ] and HOY_BATTERY_MODE [i ] and HOY_BATTERY_PRIORITY [i ] == pPriority
549+ )
550+
446551# Max possible Watts (physically) - Inverter Specification!
447552def GetMaxInverterWattFromAllInverters ():
448553 maxWatt = 0
@@ -452,6 +557,12 @@ def GetMaxInverterWattFromAllInverters():
452557 maxWatt = maxWatt + HOY_INVERTER_WATT [i ]
453558 return maxWatt
454559
560+ def GetMaxInverterWattFromAllNonBatteryInverters ():
561+ return sum (
562+ HOY_INVERTER_WATT [i ] for i in range (INVERTER_COUNT )
563+ if AVAILABLE [i ] and not HOY_BATTERY_MODE [i ] and HOY_BATTERY_GOOD_VOLTAGE [i ]
564+ )
565+
455566def GetMinWattFromAllInverters ():
456567 minWatt = 0
457568 for i in range (INVERTER_COUNT ):
0 commit comments