From 3d008207f0d0b3e8b1856f39a2f9c10a6cb9169c Mon Sep 17 00:00:00 2001 From: Trefor Southwell <48591903+springfall2008@users.noreply.github.com> Date: Wed, 31 Jan 2024 08:27:20 +0000 Subject: [PATCH 1/4] Support adjustment to existing rates in override --- apps/predbat/predbat.py | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/apps/predbat/predbat.py b/apps/predbat/predbat.py index 2e9f8cd77..cce467c98 100644 --- a/apps/predbat/predbat.py +++ b/apps/predbat/predbat.py @@ -2225,7 +2225,7 @@ def press_and_poll_button(self, entity_id): self.base.record_status(f"Warn: Inverter {self.id} Trying to press {entity_id} didn't complete") return False - def rest_readData(self, api="readData"): + def rest_readData(self, api="readData", retry=True): """ Get inverter status @@ -2244,9 +2244,13 @@ def rest_readData(self, api="readData"): if "Control" in json: return json else: - self.base.log("WARN: Inverter {} read bad REST data from {} - REST will be disabled".format(self.id, url)) - self.base.record_status("Inverter {} read bad REST data from {} - REST will be disabled".format(self.id, url), had_errors=True) - return None + if retry: + # If this is the first call in error then try to re-read the data + return self.rest_runAll() + else: + self.base.log("WARN: Inverter {} read bad REST data from {} - REST will be disabled".format(self.id, url)) + self.base.record_status("Inverter {} read bad REST data from {} - REST will be disabled".format(self.id, url), had_errors=True) + return None else: self.base.log("WARN: Inverter {} unable to read REST data from {} - REST will be disabled".format(self.id, url)) self.base.record_status("Inverter {} unable to read REST data from {} - REST will be disabled".format(self.id, url), had_errors=True) @@ -2256,7 +2260,7 @@ def rest_runAll(self, old_data=None): """ Updated and get inverter status """ - new_data = self.rest_readData(api="runAll") + new_data = self.rest_readData(api="runAll", retry=False) if new_data: return new_data else: @@ -5210,8 +5214,18 @@ def basic_rates(self, info, rtype, prev=None): self.record_status("Bad date {} provided in energy rates".format(this_rate["date"]), had_errors=True) continue - rate = this_rate.get("rate", 0.0) + # Support increment to existing rates (for override) + if "rate" in this_rate: + rate = this_rate.get("rate", 0.0) + rate_increment = False + elif "rate_increment" in this_rate: + rate = this_rate.get("rate_increment", 0.0) + rate_increment = True + + # Resolve any sensor links rate = self.resolve_arg("rate", rate, 0.0) + + # Ensure the end result is a float try: rate = float(rate) except ValueError: @@ -5223,7 +5237,7 @@ def basic_rates(self, info, rtype, prev=None): start_minutes = max(self.minutes_to_time(start, midnight), 0) end_minutes = min(self.minutes_to_time(end, midnight), 24 * 60 - 1) - self.log("Adding rate {} => {} to {} @ {} date {}".format(this_rate, self.time_abs_str(start_minutes), self.time_abs_str(end_minutes), rate, date)) + self.log("Adding rate {} => {} to {} @ {} date {} increment {}".format(this_rate, self.time_abs_str(start_minutes), self.time_abs_str(end_minutes), rate, date, rate_increment)) # Make end > start if end_minutes <= start_minutes: @@ -5238,14 +5252,18 @@ def basic_rates(self, info, rtype, prev=None): # Store rates against range if end_minutes >= 0 and start_minutes < max_minute: for minute in range(start_minutes, end_minutes): + minute_mod = minute % max_minute if (not date) or (minute >= 0 and minute < max_minute): - rates[minute % max_minute] = rate + if rate_increment: + rates[minute_mod] = rates.get(minute % max_minute, 0.0) + rate + else: + rates[minute_mod] = rate if load_scaling is not None: - self.load_scaling_dynamic[minute % max_minute] = load_scaling + self.load_scaling_dynamic[minute_mod] = load_scaling if not date and not prev: - rates[(minute % max_minute) + max_minute] = rate + rates[minute_mod + max_minute] = rate if load_scaling is not None: - self.load_scaling_dynamic[(minute % max_minute) + max_minute] = load_scaling + self.load_scaling_dynamic[minute_mod + max_minute] = load_scaling return rates From 098b1fbaf958d5c475d2ad2cde6bad436e69b7d9 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 08:28:57 +0000 Subject: [PATCH 2/4] [pre-commit.ci lite] apply automatic fixes --- apps/predbat/predbat.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/predbat/predbat.py b/apps/predbat/predbat.py index cce467c98..ecf0566dc 100644 --- a/apps/predbat/predbat.py +++ b/apps/predbat/predbat.py @@ -5237,7 +5237,11 @@ def basic_rates(self, info, rtype, prev=None): start_minutes = max(self.minutes_to_time(start, midnight), 0) end_minutes = min(self.minutes_to_time(end, midnight), 24 * 60 - 1) - self.log("Adding rate {} => {} to {} @ {} date {} increment {}".format(this_rate, self.time_abs_str(start_minutes), self.time_abs_str(end_minutes), rate, date, rate_increment)) + self.log( + "Adding rate {} => {} to {} @ {} date {} increment {}".format( + this_rate, self.time_abs_str(start_minutes), self.time_abs_str(end_minutes), rate, date, rate_increment + ) + ) # Make end > start if end_minutes <= start_minutes: From 24d0d58729cccbb367e91b5334f83b67b73ab524 Mon Sep 17 00:00:00 2001 From: Trefor Southwell <48591903+springfall2008@users.noreply.github.com> Date: Wed, 31 Jan 2024 08:36:11 +0000 Subject: [PATCH 3/4] Update energy-rates.md --- docs/energy-rates.md | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/docs/energy-rates.md b/docs/energy-rates.md index 87be876bd..833605b23 100644 --- a/docs/energy-rates.md +++ b/docs/energy-rates.md @@ -200,8 +200,25 @@ rates_import_override: Would say that during a 1 hour period at 5:30-6:30pm on 21st of Jan set the import rate to 150p and assume our load will be 80% of normal (20% lower). -**date** is in the date format of "YYYY-MM-DD" e.g. "2023-09-09", **start** and **end** in "HH:MM:SS" time format e.g. "12:30:00", and **rate** in pence. -**load_scaling** is a factor, where 1.0 would be no change, 0.8 is 80% of nominal. +You can also make relative adjustments to your energy rates, e.g. if you want to avoid exporting during peak periods to improve your energy +saving session results you could make a relative adjustment your export rates using **rate_increment**. +The reason not to just set **rate** is then when an energy saving session is active you do not want to ignore the higher export take. + +In this example we subtract 10p from our export rate during the period that saving sessions normally fall within and thus steer Predbat away from +force exporting during that time. The saving session will still work correctly as a 10p adjustment on rates >100p will have little/no impact. + +```yaml +rates_export_override: + - start: '17:00:00' + end: '19:00:00' + rate_increment: -10 +``` + +You can also use rate_increment with load_scaling, e.g. a rate_increment of 0 can be used to just apply load scaling to certain defined periods. + +- **date** is in the date format of "YYYY-MM-DD" e.g. "2023-09-09", **start** and **end** in "HH:MM:SS" time format e.g. "12:30:00", and **rate** in pence. +- **load_scaling** is a factor, where 1.0 would be no change, 0.8 is 80% of nominal. +- **rate_increment** is the number of pence to add to the reported energy rates during this period ## Rate offsets From 4506ee1d7b06e51209ff588de54e423e8413b60d Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Wed, 31 Jan 2024 08:36:53 +0000 Subject: [PATCH 4/4] [pre-commit.ci lite] apply automatic fixes --- docs/energy-rates.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/energy-rates.md b/docs/energy-rates.md index 833605b23..382894e16 100644 --- a/docs/energy-rates.md +++ b/docs/energy-rates.md @@ -200,7 +200,7 @@ rates_import_override: Would say that during a 1 hour period at 5:30-6:30pm on 21st of Jan set the import rate to 150p and assume our load will be 80% of normal (20% lower). -You can also make relative adjustments to your energy rates, e.g. if you want to avoid exporting during peak periods to improve your energy +You can also make relative adjustments to your energy rates, e.g. if you want to avoid exporting during peak periods to improve your energy saving session results you could make a relative adjustment your export rates using **rate_increment**. The reason not to just set **rate** is then when an energy saving session is active you do not want to ignore the higher export take.