Skip to content

Commit 5a57078

Browse files
authored
Merge pull request #152 from tomquist/add-mixed-mode-priority-support
Add support for mixed-mode
2 parents 2effa5f + 4092966 commit 5a57078

1 file changed

Lines changed: 112 additions & 1 deletion

File tree

HoymilesZeroExport.py

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -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+
154250
def 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!
447552
def 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+
455566
def GetMinWattFromAllInverters():
456567
minWatt = 0
457568
for i in range(INVERTER_COUNT):

0 commit comments

Comments
 (0)