Skip to content

Commit

Permalink
Fixes to issue with min reserve for Solis (#321)
Browse files Browse the repository at this point in the history
  • Loading branch information
fboundy authored Nov 13, 2023
1 parent 4fa21c6 commit 923f907
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 12 deletions.
32 changes: 21 additions & 11 deletions apps/predbat/predbat.py
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@
{"name": "iboost_min_power", "friendly_name": "IBoost min power", "type": "input_number", "min": 0, "max": 3500, "step": 100, "unit": "w"},
{"name": "iboost_min_soc", "friendly_name": "IBoost min soc", "type": "input_number", "min": 0, "max": 100, "step": 5, "unit": "%", "icon": "mdi:percent"},
{"name": "holiday_days_left", "friendly_name": "Holiday days left", "type": "input_number", "min": 0, "max": 28, "step": 1, "unit": "days", "icon": "mdi:clock-end"},
{"name": "forecast_plan_hours", "friendly_name": "Plan forecast hours", "type": "input_number", "min": 8, "max": 96, "step": 8, "unit": "hours", "icon": "mdi:clock-end"}
{"name": "forecast_plan_hours", "friendly_name": "Plan forecast hours", "type": "input_number", "min": 8, "max": 96, "step": 8, "unit": "hours", "icon": "mdi:clock-end"},
]

"""
Expand Down Expand Up @@ -420,6 +420,7 @@ def self_test(self, minutes_now):
def __init__(self, base, id=0, quiet=False):
self.id = id
self.base = base
self.log = self.base.log
self.charge_enable_time = False
self.charge_start_time_minutes = self.base.forecast_minutes
self.charge_start_end_minutes = self.base.forecast_minutes
Expand All @@ -433,8 +434,8 @@ def __init__(self, base, id=0, quiet=False):
self.inverter_limit = 7500.0
self.export_limit = 99999.0
self.inverter_time = None
self.reserve_percent = 4.0
self.reserve_percent_current = 4.0
self.reserve_percent = self.base.get_arg("battery_min_soc", default=4.0, index=self.id)
self.reserve_percent_current = self.base.get_arg("battery_min_soc", default=4.0, index=self.id)
self.reserve_max = 100
self.battery_rate_max_raw = 0
self.battery_rate_max_charge = 0
Expand Down Expand Up @@ -576,12 +577,20 @@ def __init__(self, base, id=0, quiet=False):
if self.rest_data:
self.reserve_percent_current = float(self.rest_data["Control"]["Battery_Power_Reserve"])
else:
self.reserve_percent_current = max(self.base.get_arg("reserve", default=0.0, index=self.id), 4.0)
self.reserve_percent_current = max(self.base.get_arg("reserve", default=0.0, index=self.id), self.base.get_arg("battery_min_soc", default=4.0, index=self.id))
self.reserve_current = self.base.dp2(self.soc_max * self.reserve_percent_current / 100.0)

# Get the expected minimum reserve value
battery_min_soc = self.base.get_arg("battery_min_soc", default=4.0, index=self.id)
self.reserve_min = self.base.get_arg("set_reserve_min", 4.0)
if self.reserve_min < battery_min_soc:
self.base.log(f"Increasing set_reserve_min from {self.reserve_min}% to battery_min_soc of {battery_min_soc}%")
self.base.expose_config("set_reserve_min", battery_min_soc)
self.reserve_min = battery_min_soc

self.base.log(f"Reserve min: {self.reserve_min}% Battery_min:{battery_min_soc}%")
if self.base.set_reserve_enable:
self.reserve_percent = max(self.base.get_arg("set_reserve_min", 4.0), 4.0)
self.reserve_percent = self.reserve_min
else:
self.reserve_percent = self.reserve_percent_current
self.reserve = self.base.dp2(self.soc_max * self.reserve_percent / 100.0)
Expand Down Expand Up @@ -5951,7 +5960,7 @@ def optimise_charge_limit(
if abs(compare_with - try_percent) <= 2:
metric -= max(0.5, self.metric_min_improvement)

# Minor weighting against charge freeze to avoid supurious ones
# Minor weighting against charge freeze to avoid supurious ones
if self.set_charge_freeze and try_soc == self.reserve:
metric += 0.01

Expand Down Expand Up @@ -6590,9 +6599,8 @@ def optimise_all_windows(self, end_record, load_minutes_step, pv_forecast_minute
for start_at_low in [False, True]:
if start_at_low:
price_set.reverse()

for price in price_set:

for price in price_set:
charge_windows = []
charge_socs = []
discharge_windows = []
Expand Down Expand Up @@ -6652,14 +6660,16 @@ def optimise_all_windows(self, end_record, load_minutes_step, pv_forecast_minute
# Do highest price first
if start_at_low:
continue

if self.calculate_best_discharge:
if not printed_set:
self.log("Optimise price set {} start_at_low {} best_price {}".format(price, start_at_low, best_price))
printed_set = True

if not self.calculate_discharge_oncharge:
hit_charge = self.hit_charge_window(self.charge_window_best, self.discharge_window_best[window_n]["start"], self.discharge_window_best[window_n]["end"])
hit_charge = self.hit_charge_window(
self.charge_window_best, self.discharge_window_best[window_n]["start"], self.discharge_window_best[window_n]["end"]
)
if hit_charge >= 0 and self.charge_limit_best[hit_charge] > 0.0:
continue
average = self.discharge_window_best[window_n]["average"]
Expand Down Expand Up @@ -8720,4 +8730,4 @@ def run_time_loop_balance(self, cb_args):
except Exception as e:
self.log("ERROR: Exception raised {}".format(e))
self.record_status("ERROR: Exception raised {}".format(e))
raise e
raise e
7 changes: 6 additions & 1 deletion ginlong_solis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ pred_bat:
- sensor.solis_battery_soc

reserve:
- number.solis_backup_mode_soc
- number.solisx_backup_mode_soc

battery_min_soc:
- sensor.solis_battery_minimum_soc

# With the Solax integration we need to press a button to send the time to
charge_discharge_update_button:
Expand Down Expand Up @@ -96,6 +99,8 @@ pred_bat:
- number.solis_timed_discharge_end_minutes


energy_control_switch:
- select.solis_energy_storage_control_switch

# Inverter max AC limit (one per inverter)
# If you have a second inverter for PV only please add the two values together
Expand Down

0 comments on commit 923f907

Please sign in to comment.