Skip to content

Commit 43999fe

Browse files
iboost running fixes (#1302)
* iboost running fixes #1283 * [pre-commit.ci lite] apply automatic fixes * Update customisation.md * Typo * [pre-commit.ci lite] apply automatic fixes * Typo * [pre-commit.ci lite] apply automatic fixes * Fix naming issue with iboost sensor with 2 cars * [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>
1 parent 3bc84ae commit 43999fe

File tree

4 files changed

+78
-8
lines changed

4 files changed

+78
-8
lines changed

apps/predbat/predbat.py

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2102,6 +2102,8 @@ def run_prediction(self, charge_limit, charge_window, discharge_window, discharg
21022102
self.car_charging_soc_next = pred.car_charging_soc_next
21032103
self.iboost_next = pred.iboost_next
21042104
self.iboost_running = pred.iboost_running
2105+
self.iboost_running_solar = pred.iboost_running_solar
2106+
self.iboost_running_full = pred.iboost_running_full
21052107
if save or self.debug_enable:
21062108
predict_soc_time = pred.predict_soc_time
21072109
first_charge = pred.first_charge
@@ -2623,9 +2625,9 @@ def run_prediction(self, charge_limit, charge_window, discharge_window, discharg
26232625
},
26242626
)
26252627
self.dashboard_item(
2626-
"binary_sensor." + self.prefix + "_iboost_active" + postfix,
2628+
"binary_sensor." + self.prefix + "_iboost_active",
26272629
state=self.iboost_running,
2628-
attributes={"friendly_name": "iBoost active", "icon": "mdi:water-boiler"},
2630+
attributes={"friendly_name": "iBoost active", "icon": "mdi:water-boiler", "solar": self.iboost_running_solar, "full": self.iboost_running_full},
26292631
)
26302632
self.find_spare_energy(self.predict_soc, predict_export, step, first_charge)
26312633
if self.carbon_enable:
@@ -5257,6 +5259,9 @@ def reset(self):
52575259
self.iboost_rate_threshold_export = 9999
52585260
self.iboost_plan = []
52595261
self.iboost_energy_subtract = True
5262+
self.iboost_running = False
5263+
self.iboost_running_full = False
5264+
self.iboost_running_solar = False
52605265

52615266
self.config_root = "./"
52625267
for root in CONFIG_ROOTS:
@@ -8530,7 +8535,7 @@ def execute_plan(self):
85308535

85318536
# Iboost running?
85328537
boostHolding = False
8533-
if self.iboost_enable and self.iboost_prevent_discharge and self.iboost_running and status not in ["Discharging", "Charging"]:
8538+
if self.iboost_enable and self.iboost_prevent_discharge and self.iboost_running_full and status not in ["Discharging", "Charging"]:
85348539
inverter.adjust_discharge_rate(0)
85358540
inverter.adjust_pause_mode(pause_discharge=True)
85368541
resetDischarge = False
@@ -9703,6 +9708,8 @@ def fetch_config_options(self):
97039708
self.iboost_energy_subtract = self.get_arg("iboost_energy_subtract")
97049709
self.iboost_next = self.iboost_today
97059710
self.iboost_running = False
9711+
self.iboost_running_solar = False
9712+
self.iboost_running_full = False
97069713
self.iboost_energy_today = {}
97079714
self.iboost_plan = []
97089715

apps/predbat/prediction.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,6 @@ def __init__(self, base=None, pv_forecast_minute_step=None, pv_forecast_minute10
134134
self.iboost_min_soc = base.iboost_min_soc
135135
self.iboost_solar = base.iboost_solar
136136
self.iboost_charging = base.iboost_charging
137-
self.iboost_running = base.iboost_running
138137
self.iboost_plan = base.iboost_plan
139138
self.iboost_gas = base.iboost_gas
140139
self.iboost_gas_export = base.iboost_gas_export
@@ -167,6 +166,9 @@ def __init__(self, base=None, pv_forecast_minute_step=None, pv_forecast_minute10
167166
self.load_minutes_step = load_minutes_step
168167
self.load_minutes_step10 = load_minutes_step10
169168
self.carbon_intensity = base.carbon_intensity
169+
self.iboost_running = base.iboost_running
170+
self.iboost_running_solar = base.iboost_running_solar
171+
self.iboost_running_full = base.iboost_running_full
170172

171173
# Store this dictionary in global so we can reconstruct it in the thread without passing the data
172174
PRED_GLOBAL["dict"] = self.__dict__.copy()
@@ -315,6 +317,9 @@ def run_prediction(self, charge_limit, charge_window, discharge_window, discharg
315317
self.predict_metric_best = {}
316318
self.predict_iboost_best = {}
317319
self.predict_carbon_best = {}
320+
self.iboost_running = False
321+
self.iboost_running_solar = False
322+
self.iboost_running_full = False
318323

319324
predict_export = {}
320325
predict_battery_power = {}
@@ -540,6 +545,10 @@ def run_prediction(self, charge_limit, charge_window, discharge_window, discharg
540545
iboost_freeze = True
541546
discharge_rate_now = self.battery_rate_min # 0
542547

548+
# Iboost running
549+
if iboost_amount > 0 and minute == 0:
550+
self.iboost_running_full = True
551+
543552
# Iboost load added
544553
load_yesterday += iboost_amount
545554

@@ -781,6 +790,8 @@ def run_prediction(self, charge_limit, charge_window, discharge_window, discharg
781790
iboost_pv_amount = min(pv_ac, max(self.iboost_max_power * step - iboost_amount, 0), max(self.iboost_max_energy - iboost_today_kwh - iboost_amount, 0))
782791
pv_ac -= iboost_pv_amount
783792
iboost_amount += iboost_pv_amount
793+
if iboost_pv_amount > 0 and minute == 0:
794+
self.iboost_running_solar = True
784795

785796
# Cumulative iBoost energy
786797
iboost_today_kwh += iboost_amount
@@ -790,13 +801,11 @@ def run_prediction(self, charge_limit, charge_window, discharge_window, discharg
790801
iboost_today_kwh = 0
791802

792803
# Save iBoost next prediction
793-
if minute == 0 and save in ["best", "test"]:
804+
if minute == 0:
794805
scaled_boost = (iboost_amount / step) * RUN_EVERY
795806
self.iboost_next = round(self.iboost_today + scaled_boost, 3)
796807
if iboost_amount > 0:
797808
self.iboost_running = True
798-
else:
799-
self.iboost_running = False
800809

801810
# Count battery cycles
802811
battery_cycle = battery_cycle + abs(battery_draw)

apps/predbat/unit_test.py

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ def simple_scenario(
321321
iboost_enable=False,
322322
iboost_on_discharge=False,
323323
iboost_prevent_discharge=False,
324+
assert_iboost_running=False,
325+
assert_iboost_running_solar=False,
326+
assert_iboost_running_full=False,
324327
):
325328
"""
326329
No PV, No Load
@@ -462,6 +465,15 @@ def simple_scenario(
462465
if abs(metric_keep - assert_keep) >= 0.1:
463466
print("ERROR: Metric keep {} should be {}".format(metric_keep, assert_keep))
464467
failed = True
468+
if assert_iboost_running != prediction.iboost_running:
469+
print("ERROR: iBoost running should be {}".format(assert_iboost_running))
470+
failed = True
471+
if assert_iboost_running_solar != prediction.iboost_running_solar:
472+
print("ERROR: iBoost running solar should be {}".format(assert_iboost_running_solar))
473+
failed = True
474+
if assert_iboost_running_full != prediction.iboost_running_full:
475+
print("ERROR: iBoost running full should be {}".format(assert_iboost_running_full))
476+
failed = True
465477

466478
if failed:
467479
prediction.run_prediction(charge_limit_best, charge_window_best, discharge_window_best, discharge_limit_best, pv10, end_record=(my_predbat.end_record), save="test")
@@ -1636,7 +1648,18 @@ def run_model_tests(my_predbat):
16361648
inverter_limit=2.0,
16371649
)
16381650
failed |= simple_scenario(
1639-
"iboost_pv", my_predbat, 0, 1, assert_final_metric=0, assert_final_soc=0, with_battery=False, iboost_enable=True, iboost_solar=True, assert_final_iboost=24
1651+
"iboost_pv",
1652+
my_predbat,
1653+
0,
1654+
1,
1655+
assert_final_metric=0,
1656+
assert_final_soc=0,
1657+
with_battery=False,
1658+
iboost_enable=True,
1659+
iboost_solar=True,
1660+
assert_final_iboost=24,
1661+
assert_iboost_running=True,
1662+
assert_iboost_running_solar=True,
16401663
)
16411664
failed |= simple_scenario(
16421665
"iboost_gas1",
@@ -1668,6 +1691,8 @@ def run_model_tests(my_predbat):
16681691
iboost_charging=False,
16691692
export_limit=10,
16701693
assert_final_iboost=200,
1694+
assert_iboost_running=True,
1695+
assert_iboost_running_full=True,
16711696
)
16721697
failed |= simple_scenario(
16731698
"iboost_gas3",
@@ -1700,6 +1725,8 @@ def run_model_tests(my_predbat):
17001725
iboost_charging=False,
17011726
export_limit=10,
17021727
assert_final_iboost=200,
1728+
assert_iboost_running=True,
1729+
assert_iboost_running_full=True,
17031730
)
17041731
failed |= simple_scenario(
17051732
"iboost_rate1",
@@ -1728,6 +1755,8 @@ def run_model_tests(my_predbat):
17281755
iboost_charging=False,
17291756
export_limit=10,
17301757
assert_final_iboost=200,
1758+
assert_iboost_running=True,
1759+
assert_iboost_running_full=True,
17311760
)
17321761
failed |= simple_scenario(
17331762
"iboost_rate3",
@@ -1742,6 +1771,8 @@ def run_model_tests(my_predbat):
17421771
iboost_charging=False,
17431772
export_limit=10,
17441773
assert_final_iboost=200,
1774+
assert_iboost_running=True,
1775+
assert_iboost_running_full=True,
17451776
)
17461777
failed |= simple_scenario(
17471778
"iboost_rate3",
@@ -1772,6 +1803,8 @@ def run_model_tests(my_predbat):
17721803
assert_final_iboost=12,
17731804
charge_period_divide=2,
17741805
export_limit=1,
1806+
assert_iboost_running=True,
1807+
assert_iboost_running_full=True,
17751808
)
17761809
failed |= simple_scenario(
17771810
"iboost_charge2",
@@ -1787,6 +1820,8 @@ def run_model_tests(my_predbat):
17871820
iboost_charging=True,
17881821
assert_final_iboost=100,
17891822
end_record=12 * 60,
1823+
assert_iboost_running=True,
1824+
assert_iboost_running_full=True,
17901825
)
17911826
failed |= simple_scenario(
17921827
"iboost_charge3",
@@ -1803,6 +1838,8 @@ def run_model_tests(my_predbat):
18031838
iboost_charging=True,
18041839
assert_final_iboost=100,
18051840
end_record=12 * 60,
1841+
assert_iboost_running=True,
1842+
assert_iboost_running_full=True,
18061843
)
18071844
failed |= simple_scenario(
18081845
"iboost_charge4",
@@ -1865,6 +1902,8 @@ def run_model_tests(my_predbat):
18651902
iboost_on_discharge=True,
18661903
export_limit=1,
18671904
assert_final_iboost=24,
1905+
assert_iboost_running=True,
1906+
assert_iboost_running_full=True,
18681907
)
18691908
failed |= simple_scenario(
18701909
"iboost_prevent_discharge1",
@@ -1881,6 +1920,8 @@ def run_model_tests(my_predbat):
18811920
iboost_prevent_discharge=False,
18821921
export_limit=1,
18831922
assert_final_iboost=24,
1923+
assert_iboost_running=True,
1924+
assert_iboost_running_full=True,
18841925
)
18851926
failed |= simple_scenario(
18861927
"iboost_prevent_discharge2",
@@ -1897,6 +1938,8 @@ def run_model_tests(my_predbat):
18971938
iboost_prevent_discharge=True,
18981939
export_limit=1,
18991940
assert_final_iboost=24,
1941+
assert_iboost_running=True,
1942+
assert_iboost_running_full=True,
19001943
)
19011944
failed |= simple_scenario(
19021945
"keep_discharge1",
@@ -1928,6 +1971,8 @@ def run_model_tests(my_predbat):
19281971
iboost_rate_threshold=import_rate,
19291972
iboost_charging=False,
19301973
assert_final_iboost=120,
1974+
assert_iboost_running=True,
1975+
assert_iboost_running_full=True,
19311976
)
19321977
failed |= simple_scenario(
19331978
"iboost_rate_pv1",
@@ -1943,6 +1988,8 @@ def run_model_tests(my_predbat):
19431988
iboost_charging=False,
19441989
assert_final_iboost=12,
19451990
export_limit=1,
1991+
assert_iboost_running=True,
1992+
assert_iboost_running_solar=True,
19461993
)
19471994
failed |= simple_scenario(
19481995
"iboost_rate_pv2",
@@ -1958,6 +2005,8 @@ def run_model_tests(my_predbat):
19582005
iboost_charging=False,
19592006
assert_final_iboost=12 * 1,
19602007
export_limit=2,
2008+
assert_iboost_running=True,
2009+
assert_iboost_running_solar=True,
19612010
)
19622011
failed |= simple_scenario(
19632012
"iboost_rate_pv3",
@@ -1973,6 +2022,8 @@ def run_model_tests(my_predbat):
19732022
iboost_charging=False,
19742023
assert_final_iboost=12 * 2,
19752024
export_limit=2,
2025+
assert_iboost_running=True,
2026+
assert_iboost_running_solar=True,
19762027
)
19772028

19782029
if failed:

docs/customisation.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,9 @@ You will see **input_number.predbat_iboost_today** entity which tracks the estim
500500

501501
The **binary_sensor.predbat_iboost_active** entity will be enabled when the solar diverter should be active, can be used for automations to trigger the immersion heater boost.
502502

503+
The attributes within this sensor include 'solar' which includes Solar diversion should be active and 'full' which indicates iboost should run at maximum rate (could be
504+
during a charge cycle or grid import).
505+
503506
Example template automation for controlling the solar diverter:
504507

505508
```yaml

0 commit comments

Comments
 (0)