From d4d5ac99e632bbfe733af25195d91fa874751a7c Mon Sep 17 00:00:00 2001 From: fboundy Date: Mon, 19 Feb 2024 18:30:56 +0000 Subject: [PATCH 1/3] Fix bug in automatic Octopus tariff detection --- apps/pv_opt/pv_opt.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/apps/pv_opt/pv_opt.py b/apps/pv_opt/pv_opt.py index 313e2a6..4099c58 100644 --- a/apps/pv_opt/pv_opt.py +++ b/apps/pv_opt/pv_opt.py @@ -602,22 +602,25 @@ def _load_contract(self): )["attributes"].get(BOTTLECAP_DAVE["tariff_code"], None) self.rlog( - f" Found {imp_exp} entity {entity}: Tariff code: {tariff_code} Average Rate: {average_rate} GBP/kWh" + f" Found {imp_exp} entity {entity}: Tariff code: {tariff_code}" ) tariffs = {x: None for x in IMPEXP} for imp_exp in IMPEXP: + self.log(f">>>{imp_exp}: {entities[imp_exp]}") if len(entities[imp_exp]) > 0: - tariff_code = self.get_state( - entity, attribute="all" - )["attributes"].get(BOTTLECAP_DAVE["tariff_code"], None) - - if tariff_code is not None: - tariffs[imp_exp] = pv.Tariff( - tariff_code, export=(imp_exp == "export"), host=self - ) - if "AGILE" in tariff_code: - self.agile = True + for entity in entities[imp_exp]: + tariff_code = self.get_state( + entity, attribute="all" + )["attributes"].get(BOTTLECAP_DAVE["tariff_code"], None) + self.log(f">>> {tariff_code}") + + if tariff_code is not None: + tariffs[imp_exp] = pv.Tariff( + tariff_code, export=(imp_exp == "export"), host=self + ) + if "AGILE" in tariff_code: + self.agile = True self.contract = pv.Contract( "current", From 1fd74aa908f54b7dba054dbe7b3f098dc3ebae4c Mon Sep 17 00:00:00 2001 From: fboundy Date: Mon, 19 Feb 2024 19:17:00 +0000 Subject: [PATCH 2/3] Prevent divide by zero error on power tolerance --- apps/pv_opt/pv_opt.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/apps/pv_opt/pv_opt.py b/apps/pv_opt/pv_opt.py index 4099c58..0bc38ba 100644 --- a/apps/pv_opt/pv_opt.py +++ b/apps/pv_opt/pv_opt.py @@ -1717,9 +1717,10 @@ def _create_windows(self): self.windows = pd.concat([windows, self.windows]).sort_values("start") tolerance = self.get_config("forced_power_group_tolerance") - self.windows["forced"] = ( - (self.windows["forced"] / tolerance).round(0) * tolerance - ).astype(int) + if tolerance > 0: + self.windows["forced"] = ( + (self.windows["forced"] / tolerance).round(0) * tolerance + ).astype(int) self.windows["soc"] = self.windows["soc"].round(0).astype(int) self.windows["soc_end"] = self.windows["soc_end"].round(0).astype(int) From 1506c6ef64188249f0acb1f538df52bad527cb71 Mon Sep 17 00:00:00 2001 From: fboundy Date: Mon, 19 Feb 2024 19:17:48 +0000 Subject: [PATCH 3/3] 3.8.10 --- README.md | 2 +- apps/pv_opt/pv_opt.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3ef349f..9d2c299 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# PV Opt: Home Assistant Solar/Battery Optimiser v3.8.9 +# PV Opt: Home Assistant Solar/Battery Optimiser v3.8.10 Solar / Battery Charging Optimisation for Home Assistant. This appDaemon application attempts to optimise charging and discharging of a home solar/battery system to minimise cost electricity cost on a daily basis using freely available solar forecast data from SolCast. This is particularly beneficial for Octopus Agile but is also benefeficial for other time-of-use tariffs such as Octopus Flux or simple Economy 7. diff --git a/apps/pv_opt/pv_opt.py b/apps/pv_opt/pv_opt.py index 0bc38ba..a79a2ae 100644 --- a/apps/pv_opt/pv_opt.py +++ b/apps/pv_opt/pv_opt.py @@ -20,7 +20,7 @@ # USE_TARIFF = True -VERSION = "3.8.9" +VERSION = "3.8.10" DEBUG = False DATE_TIME_FORMAT_LONG = "%Y-%m-%d %H:%M:%S%z"