Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multi-inverter tweaks #1820

Merged
merged 2 commits into from
Dec 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 14 additions & 15 deletions apps/predbat/execute.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,8 @@ def execute_plan(self):
inverter.adjust_discharge_rate(0)
resetDischarge = False

target_soc = max(self.charge_limit_percent_best[0] if self.charge_limit_percent_best[0] != self.reserve else self.soc_percent, self.reserve, self.best_soc_min)
can_freeze_charge = True

# Can only freeze charge if all inverters have an SOC above the reserve
can_freeze_charge = True
for check in self.inverters:
if check.soc_kw < inverter.reserve:
can_freeze_charge = False
Expand Down Expand Up @@ -166,21 +164,18 @@ def execute_plan(self):
else:
# We can only hold charge if a) we have a way to hold the charge level on the reserve or with a pause feature
# and the current charge level is above the target for all inverters
can_hold_charge = self.charge_limit_percent_best[0] != self.reserve
can_hold_charge = True
target_soc = self.charge_limit_percent_best[0] if self.charge_limit_best[0] != self.reserve else self.soc_percent
target_soc = max(target_soc, self.best_soc_min, inverter.reserve)
for check in self.inverters:
if check.soc_percent < target_soc:
can_hold_charge = False
break
if not check.inv_has_timed_pause and (check.reserve_max < check.soc_percent):
can_hold_charge = False
break
if self.set_soc_enable and can_hold_charge and self.soc_percent >= target_soc:
status = "Hold charging"
self.log(
"Inverter {} Hold charging as soc {}% is above target {}% ({}%) set_discharge_during_charge {}".format(inverter.id, inverter.soc_percent, self.charge_limit_percent_best[0], target_soc, self.set_discharge_during_charge)
)
self.log("Inverter {} Hold charging as soc {}% is above target {}% set_discharge_during_charge {}".format(inverter.id, inverter.soc_percent, target_soc, self.charge_limit_percent_best[0], self.set_discharge_during_charge))

if (self.charge_limit_percent_best[0] < 100.0) and (abs(self.soc_percent - self.charge_limit_percent_best[0]) <= 1.0):
if (target_soc < 100.0) and (abs(inverter.soc_percent - target_soc) <= 1.0):
# If we are within 1% of the target but not at 100% then we can hold charge
# otherwise keep charging enabled
if self.set_soc_enable and ((self.set_reserve_enable and self.set_reserve_hold and inverter.reserve_max >= inverter.soc_percent) or inverter.inv_has_timed_pause):
Expand Down Expand Up @@ -437,14 +432,18 @@ def execute_plan(self):
self.log("Resetting charging SOC as we are not charging and inverter_soc_reset is enabled")
self.adjust_battery_target_multi(inverter, 100.0, isCharging, isExporting)
elif isCharging:
self.log("Setting charging SOC to {} as per target".format(self.charge_limit_percent_best[0]))
self.adjust_battery_target_multi(inverter, self.charge_limit_percent_best[0], isCharging, isExporting)
target_soc = self.charge_limit_percent_best[0] if self.charge_limit_best[0] != self.reserve else self.soc_percent
target_soc = max(target_soc, self.best_soc_min, inverter.reserve)
self.log("Setting charging SOC to {} as per target".format(target_soc))
self.adjust_battery_target_multi(inverter, target_soc, isCharging, isExporting)
elif not inverter.inv_has_target_soc:
self.log("Setting charging SOC to 0 as we are not charging and inverter doesn't support target soc")
self.adjust_battery_target_multi(inverter, 0, isCharging, isExporting)
else:
self.log("Setting charging SOC to {} as per target for when charge window starts".format(self.charge_limit_percent_best[0]))
self.adjust_battery_target_multi(inverter, self.charge_limit_percent_best[0], isCharging, isExporting)
target_soc = self.charge_limit_percent_best[0] if self.charge_limit_best[0] != self.reserve else self.soc_percent
target_soc = max(target_soc, self.best_soc_min, inverter.reserve)
self.log("Setting charging SOC to {} as per target for when charge window starts".format(target_soc))
self.adjust_battery_target_multi(inverter, target_soc, isCharging, isExporting)
else:
if not inverter.inv_has_target_soc:
# If the inverter doesn't support target soc and soc_enable is on then do that logic here:
Expand Down
18 changes: 9 additions & 9 deletions apps/predbat/unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2313,7 +2313,7 @@ def run_execute_tests(my_predbat):
assert_charge_time_enable=True,
set_charge_window=True,
set_export_window=True,
assert_status="Charging",
assert_status="Hold charging",
assert_charge_start_time_minutes=-1,
assert_charge_end_time_minutes=my_predbat.minutes_now + 60,
soc_kw=5,
Expand Down Expand Up @@ -3042,7 +3042,7 @@ def run_execute_tests(my_predbat):
assert_status="Charging",
assert_reserve=0,
assert_soc_target=10,
assert_immediate_soc_target=10,
assert_immediate_soc_target=0.5,
assert_charge_start_time_minutes=-1,
assert_charge_end_time_minutes=my_predbat.minutes_now + 60,
)
Expand All @@ -3059,10 +3059,10 @@ def run_execute_tests(my_predbat):
assert_charge_time_enable=True,
soc_kw=2,
assert_pause_discharge=False,
assert_status="Charging",
assert_status="Hold charging",
assert_reserve=0,
assert_soc_target_array=[10, 40],
assert_immediate_soc_target=10,
assert_immediate_soc_target=20,
assert_charge_start_time_minutes=-1,
assert_charge_end_time_minutes=my_predbat.minutes_now + 60,
soc_kw_array=[0, 2],
Expand All @@ -3080,10 +3080,10 @@ def run_execute_tests(my_predbat):
assert_charge_time_enable=True,
soc_kw=2,
assert_pause_discharge=False,
assert_status="Charging",
assert_status="Hold charging",
assert_reserve=0,
assert_soc_target_array=[40, 10],
assert_immediate_soc_target=10,
assert_immediate_soc_target=20,
assert_charge_start_time_minutes=-1,
assert_charge_end_time_minutes=my_predbat.minutes_now + 60,
soc_kw_array=[2, 0],
Expand All @@ -3101,10 +3101,10 @@ def run_execute_tests(my_predbat):
assert_charge_time_enable=True,
soc_kw=0.75,
assert_pause_discharge=False,
assert_status="Charging",
assert_status="Hold charging",
assert_reserve=0,
assert_soc_target_array=[10, 10],
assert_immediate_soc_target=10,
assert_immediate_soc_target=8,
assert_charge_start_time_minutes=-1,
assert_charge_end_time_minutes=my_predbat.minutes_now + 60,
soc_kw_array=[0.5, 0.25],
Expand All @@ -3122,7 +3122,7 @@ def run_execute_tests(my_predbat):
assert_charge_time_enable=True,
soc_kw=1,
assert_pause_discharge=False,
assert_status="Charging",
assert_status="Hold charging",
assert_reserve=0,
assert_soc_target_array=[10, 15],
assert_immediate_soc_target=10,
Expand Down
Loading