Skip to content

Commit

Permalink
Bug in HTML report row span, change to model related to metric keep a… (
Browse files Browse the repository at this point in the history
#1706)

* Bug in HTML report row span, change to model related to metric keep and export

* Remove debug text left over, add unit test

* [pre-commit.ci lite] apply automatic fixes

---------

Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
  • Loading branch information
springfall2008 and pre-commit-ci-lite[bot] authored Dec 8, 2024
1 parent 76b3cf1 commit 8d60e9f
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 20 deletions.
30 changes: 28 additions & 2 deletions apps/predbat/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -584,11 +584,15 @@ def publish_html_plan(self, pv_forecast_minute_step, pv_forecast_minute_step10,

for try_minute in range(minute_start, minute_end, PREDICT_STEP):
charge_window_n = self.in_charge_window(self.charge_window_best, try_minute)
if charge_window_n >= 0 and self.charge_limit_best[charge_window_n] == 0:
charge_window_n = -1
if charge_window_n >= 0:
break

for try_minute in range(minute_start, minute_end, PREDICT_STEP):
export_window_n = self.in_charge_window(self.export_window_best, try_minute)
if export_window_n >= 0 and self.export_limits_best[export_window_n] == 100:
export_window_n = -1
if export_window_n >= 0:
break

Expand All @@ -599,7 +603,18 @@ def publish_html_plan(self, pv_forecast_minute_step, pv_forecast_minute_step10,
in_span = False

if charge_window_n >= 0 and not in_span:
rowspan = int((self.charge_window_best[charge_window_n]["end"] - minute) / 30)
charge_end_minute = self.charge_window_best[charge_window_n]["end"]
discharge_intersect = -1
for try_minute in range(minute_start, charge_end_minute, PREDICT_STEP):
discharge_intersect = self.in_charge_window(self.export_window_best, try_minute)
if discharge_intersect >= 0 and self.export_limits_best[discharge_intersect] == 100:
discharge_intersect = -1
if discharge_intersect >= 0:
break
if discharge_intersect >= 0:
charge_end_minute = min(charge_end_minute, self.export_window_best[discharge_intersect]["start"])

rowspan = int((charge_end_minute - minute) / 30)
if rowspan > 1 and (export_window_n < 0):
in_span = True
start_span = True
Expand All @@ -608,7 +623,18 @@ def publish_html_plan(self, pv_forecast_minute_step, pv_forecast_minute_step10,
rowspan = 0

if export_window_n >= 0 and not in_span:
rowspan = int((self.export_window_best[export_window_n]["end"] - minute) / 30)
export_end_minute = self.export_window_best[export_window_n]["end"]
charge_intersect = -1
for try_minute in range(minute_start, export_end_minute, PREDICT_STEP):
charge_intersect = self.in_charge_window(self.charge_window_best, try_minute)
if charge_intersect >= 0 and self.charge_limit_best[charge_intersect] == 0:
charge_intersect = -1
if charge_intersect >= 0:
break
if charge_intersect >= 0:
export_end_minute = min(export_end_minute, self.charge_window_best[charge_intersect]["start"])

rowspan = int((export_end_minute - minute) / 30)
start = self.export_window_best[export_window_n]["start"]
if start <= minute and rowspan > 1 and (charge_window_n < 0):
in_span = True
Expand Down
8 changes: 6 additions & 2 deletions apps/predbat/plan.py
Original file line number Diff line number Diff line change
Expand Up @@ -418,12 +418,16 @@ def scenario_summary_state(self, record_time):
charge_window_n = -1
for try_minute in range(this_minute_absolute, minute_absolute + 30, 5):
charge_window_n = self.in_charge_window(self.charge_window_best, try_minute)
if charge_window_n >= 0 and self.charge_limit_best[charge_window_n] == 0:
charge_window_n = -1
if charge_window_n >= 0:
break

export_window_n = -1
for try_minute in range(this_minute_absolute, minute_absolute + 30, 5):
export_window_n = self.in_charge_window(self.export_window_best, try_minute)
if export_window_n >= 0 and self.export_limits_best[export_window_n] == 100:
export_window_n = -1
if export_window_n >= 0:
break

Expand All @@ -433,7 +437,7 @@ def scenario_summary_state(self, record_time):
soc_percent_min = min(soc_percent, soc_percent_end)

if charge_window_n >= 0 and export_window_n >= 0:
value = "Chrg/Dis"
value = "Chrg/Exp"
elif charge_window_n >= 0:
charge_target = self.charge_limit_best[charge_window_n]
if charge_target == self.reserve:
Expand Down Expand Up @@ -1371,7 +1375,7 @@ def optimise_export(self, window_n, record_charge_windows, try_charge_limit, cha

window_size = try_export_window[window_n]["end"] - start
window_key = str(int(this_export_limit)) + "_" + str(window_size)
window_results[window_key] = metric
window_results[window_key] = [metric, cost]

if all_n:
min_improvement_scaled = self.metric_min_improvement_export
Expand Down
3 changes: 1 addition & 2 deletions apps/predbat/prediction.py
Original file line number Diff line number Diff line change
Expand Up @@ -583,9 +583,8 @@ def run_prediction(self, charge_limit, charge_window, export_window, export_limi
export_limit = self.export_limit * step

discharge_min = self.reserve
use_keep = self.best_soc_keep if four_hour_rule else self.reserve
if export_window_n >= 0:
discharge_min = max(self.soc_max * export_limits[export_window_n] / 100.0, self.reserve, use_keep, self.best_soc_min)
discharge_min = max(self.soc_max * export_limits[export_window_n] / 100.0, self.reserve, self.best_soc_min)

if not self.set_export_freeze_only and (export_window_n >= 0) and export_limits[export_window_n] < 100.0 and (soc - step * self.battery_rate_max_discharge_scaled) > discharge_min:
# Discharge enable
Expand Down
40 changes: 26 additions & 14 deletions apps/predbat/unit_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -896,13 +896,31 @@ def run_execute_test(

def run_single_debug(my_predbat, debug_file):
print("**** Running debug test {} ****\n".format(debug_file))
re_do_rates = True

reset_inverter(my_predbat)
my_predbat.read_debug_yaml(debug_file)
my_predbat.config_root = "./"
my_predbat.save_restore_dir = "./"
my_predbat.fetch_config_options()

if re_do_rates:
my_predbat.combine_export_slots = False # XXX: This is a hack to make the test pass
# Find discharging windows
if my_predbat.rate_export:
my_predbat.high_export_rates, lowest, highest = my_predbat.rate_scan_window(my_predbat.rate_export, 5, my_predbat.rate_export_cost_threshold, True)
# Update threshold automatically
if my_predbat.rate_high_threshold == 0 and lowest <= my_predbat.rate_export_max:
my_predbat.rate_export_cost_threshold = lowest

# Find charging windows
if my_predbat.rate_import:
# Find charging window
my_predbat.low_rates, lowest, highest = my_predbat.rate_scan_window(my_predbat.rate_import, 5, my_predbat.rate_import_cost_threshold, False)
# Update threshold automatically
if my_predbat.rate_low_threshold == 0 and highest >= my_predbat.rate_min:
my_predbat.rate_import_cost_threshold = highest

end_record = my_predbat.end_record
print("minutes_now {}".format(my_predbat.minutes_now))
failed = False
Expand All @@ -915,18 +933,14 @@ def run_single_debug(my_predbat, debug_file):
my_predbat.prediction = Prediction(my_predbat, pv_step, pv_step, load_step, load_step)
my_predbat.debug_enable = True

charge_limit_best = my_predbat.charge_limit_best
charge_window_best = my_predbat.charge_window_best
export_window_best = my_predbat.export_window_best
export_limits_best = my_predbat.export_limits_best

failed = False
my_predbat.log("********ORIGINAL PLAN********")
metric, import_kwh_battery, import_kwh_house, export_kwh, soc_min, soc, soc_min_minute, battery_cycle, metric_keep, final_iboost, final_carbon_g = my_predbat.run_prediction(
charge_limit_best, charge_window_best, export_window_best, export_limits_best, False, end_record=end_record, save="best"
my_predbat.charge_limit_best, my_predbat.charge_window_best, my_predbat.export_window_best, my_predbat.export_limits_best, False, end_record=my_predbat.end_record, save="best"
)
# Save plan
# Pre-optimise all plan
my_predbat.charge_limit_percent_best = calc_percent_limit(charge_limit_best, my_predbat.soc_max)
my_predbat.charge_limit_percent_best = calc_percent_limit(my_predbat.charge_limit_best, my_predbat.soc_max)
my_predbat.update_target_values()
my_predbat.publish_html_plan(pv_step, pv10_step, load_step, load10_step, end_record)
open("plan_orig.html", "w").write(my_predbat.html_plan)
Expand Down Expand Up @@ -956,18 +970,15 @@ def run_single_debug(my_predbat, debug_file):

# Optimise windows
best_metric, best_cost, best_keep, best_cycle, best_carbon, best_import = my_predbat.optimise_all_windows(metric, metric_keep, debug_mode=True)
charge_limit_best = my_predbat.charge_limit_best
export_limits_best = my_predbat.export_limits_best
charge_window_best = my_predbat.charge_window_best
export_window_best = my_predbat.export_window_best

# Predict
my_predbat.log("********RAW PLAN********")
metric, import_kwh_battery, import_kwh_house, export_kwh, soc_min, soc, soc_min_minute, battery_cycle, metric_keep, final_iboost, final_carbon_g = my_predbat.run_prediction(
charge_limit_best, charge_window_best, export_window_best, export_limits_best, False, end_record=end_record, save="best"
my_predbat.charge_limit_best, my_predbat.charge_window_best, my_predbat.export_window_best, my_predbat.export_limits_best, False, end_record=my_predbat.end_record, save="best"
)

# Save plan
my_predbat.charge_limit_percent_best = calc_percent_limit(charge_limit_best, my_predbat.soc_max)
my_predbat.charge_limit_percent_best = calc_percent_limit(my_predbat.charge_limit_best, my_predbat.soc_max)
my_predbat.update_target_values()
my_predbat.publish_html_plan(pv_step, pv10_step, load_step, load10_step, end_record)
open("plan_raw.html", "w").write(my_predbat.html_plan)
Expand All @@ -993,8 +1004,9 @@ def run_single_debug(my_predbat, debug_file):
my_predbat.charge_limit_percent_best = calc_percent_limit(my_predbat.charge_limit_best, my_predbat.soc_max)

# Predict
my_predbat.log("********FINAL PLAN*******")
metric, import_kwh_battery, import_kwh_house, export_kwh, soc_min, soc, soc_min_minute, battery_cycle, metric_keep, final_iboost, final_carbon_g = my_predbat.run_prediction(
charge_limit_best, charge_window_best, export_window_best, export_limits_best, False, end_record=end_record, save="best"
my_predbat.charge_limit_best, my_predbat.charge_window_best, my_predbat.export_window_best, my_predbat.export_limits_best, False, end_record=my_predbat.end_record, save="best"
)

my_predbat.publish_html_plan(pv_step, pv10_step, load_step, load10_step, end_record)
Expand Down

0 comments on commit 8d60e9f

Please sign in to comment.