From d32220bdf2704574032d41e0c847614715e0e96c Mon Sep 17 00:00:00 2001 From: Trefor Southwell <48591903+springfall2008@users.noreply.github.com> Date: Fri, 12 Jan 2024 21:43:32 +0000 Subject: [PATCH 1/4] Fix time window wrap issue, predbat restore automation https://github.com/springfall2008/batpred/issues/608 --- apps/predbat/predbat.py | 80 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 72 insertions(+), 8 deletions(-) diff --git a/apps/predbat/predbat.py b/apps/predbat/predbat.py index cf1620113..80768157d 100644 --- a/apps/predbat/predbat.py +++ b/apps/predbat/predbat.py @@ -8812,7 +8812,7 @@ def execute_plan(self): self.log("Move on charge window start time to avoid wrap - new start {}".format(self.time_abs_str(minutes_start))) # Check if start is within 24 hours of now and end is in the future - if ((minutes_start - self.minutes_now) < (24 * 60)) and minutes_end > self.minutes_now: + if ((minutes_start - self.minutes_now) < (24 * 60)) and (minutes_end > self.minutes_now): charge_start_time = self.midnight_utc + timedelta(minutes=minutes_start) charge_end_time = self.midnight_utc + timedelta(minutes=minutes_end) self.log( @@ -8855,13 +8855,17 @@ def execute_plan(self): if (self.minutes_now < minutes_end) and ( (minutes_start - self.minutes_now) <= self.set_window_minutes or (inverter.charge_start_time_minutes - self.minutes_now) <= self.set_window_minutes ): - # We must re-program if we are about to start a new charge window or the currently configured window is about to start or has started - self.log( - "Configuring charge window now (now {} target set_window_minutes {} charge start time {}".format( - self.time_abs_str(self.minutes_now), self.set_window_minutes, self.time_abs_str(minutes_start) + if ((minutes_start - self.minutes_now) > self.set_window_minutes) and (minutes_end - self.minutes_now) >= 24*60: + self.log("Charge window would wrap, disabling until later") + inverter.disable_charge_window() + else: + # We must re-program if we are about to start a new charge window or the currently configured window is about to start or has started + self.log( + "Configuring charge window now (now {} target set_window_minutes {} charge start time {}".format( + self.time_abs_str(self.minutes_now), self.set_window_minutes, self.time_abs_str(minutes_start) + ) ) - ) - inverter.adjust_charge_window(charge_start_time, charge_end_time, self.minutes_now) + inverter.adjust_charge_window(charge_start_time, charge_end_time, self.minutes_now) else: self.log( "Not setting charging window yet as not within the window (now {} target set_window_minutes {} charge start time {}".format( @@ -8874,7 +8878,7 @@ def execute_plan(self): inverter.charge_end_time_minutes = minutes_end elif ((minutes_start - self.minutes_now) >= (24 * 60)) and (inverter.charge_start_time_minutes - self.minutes_now) <= self.set_window_minutes: # No charging require in the next 24 hours - self.log("No charge window required, disabling before the start") + self.log("No charge window required for 24-hours, disabling before the start") inverter.disable_charge_window() else: self.log("No change to charge window yet, waiting for schedule.") @@ -10166,6 +10170,64 @@ def dashboard_item(self, entity, state, attributes): if entity not in self.dashboard_index: self.dashboard_index.append(entity) + def save_settings(self): + """ + Save current predbat settings + """ + basename = "/predbat_restore_settings.yaml" + filename = None + text = "" + text += "alias: \"Restore Predbat settings from {}\"\n".format(self.time_abs_str(self.minutes_now)) + text += "mode: single\n" + text += "trigger: []\n" + text += "condition: []\n" + text += "action:\n" + for root in CONFIG_ROOTS: + if os.path.exists(root): + filename = root + basename + if filename: + enable_list = [None] + for item in CONFIG_ITEMS: + enable = item.get("enable", None) + if enable and enable not in enable_list: + enable_list.append(enable) + + for try_enable in enable_list: + for item in CONFIG_ITEMS: + entity = item["entity"] + enable = item.get("enable", None) + + if entity == "select.predbat_update": + # Do not restore predbat version + continue + + if enable == try_enable and self.user_config_item_enabled(item): + value = item.get("value", None) + if value: + if item["type"] == "input_number": + text += " - service: input_number.set_value\n" + text += " target:\n" + text += " entity_id: {}\n".format(entity) + text += " data:\n" + text += " value: {}\n".format(value) + elif item["type"] == "switch": + if value: + text += " - service: switch.turn_on\n" + else: + text += " - service: switch.turn_off\n" + text += " target:\n" + text += " entity_id: {}\n".format(entity) + text += " data: {}\n" + elif item["type"] == "select": + text += " - service: select.select_option\n" + text += " target:\n" + text += " entity_id: {}\n".format(entity) + text += " data:\n" + text += " option: \"{}\"\n".format(value) + with open(filename, "w") as file: + file.write(text) + self.log("Wrote settings to {}".format(filename)) + def create_debug_yaml(self): """ Write out a debug info yaml @@ -10625,6 +10687,7 @@ def update_time_loop(self, cb_args): try: self.update_pred(scheduled=False) self.create_entity_list() + self.save_settings() except Exception as e: self.log("ERROR: Exception raised {}".format(e)) self.record_status("ERROR: Exception raised {}".format(e)) @@ -10655,6 +10718,7 @@ def run_time_loop(self, cb_args): self.prediction_started = False if config_changed: self.create_entity_list() + self.save_settings() self.prediction_started = False def run_time_loop_balance(self, cb_args): From f18ee31e947a1cac074e325df9549492dee78e55 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 21:45:03 +0000 Subject: [PATCH 2/4] [pre-commit.ci lite] apply automatic fixes --- apps/predbat/predbat.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/predbat/predbat.py b/apps/predbat/predbat.py index 80768157d..b6a34b8f4 100644 --- a/apps/predbat/predbat.py +++ b/apps/predbat/predbat.py @@ -8855,7 +8855,7 @@ def execute_plan(self): if (self.minutes_now < minutes_end) and ( (minutes_start - self.minutes_now) <= self.set_window_minutes or (inverter.charge_start_time_minutes - self.minutes_now) <= self.set_window_minutes ): - if ((minutes_start - self.minutes_now) > self.set_window_minutes) and (minutes_end - self.minutes_now) >= 24*60: + if ((minutes_start - self.minutes_now) > self.set_window_minutes) and (minutes_end - self.minutes_now) >= 24 * 60: self.log("Charge window would wrap, disabling until later") inverter.disable_charge_window() else: @@ -10177,7 +10177,7 @@ def save_settings(self): basename = "/predbat_restore_settings.yaml" filename = None text = "" - text += "alias: \"Restore Predbat settings from {}\"\n".format(self.time_abs_str(self.minutes_now)) + text += 'alias: "Restore Predbat settings from {}"\n'.format(self.time_abs_str(self.minutes_now)) text += "mode: single\n" text += "trigger: []\n" text += "condition: []\n" @@ -10198,7 +10198,7 @@ def save_settings(self): enable = item.get("enable", None) if entity == "select.predbat_update": - # Do not restore predbat version + # Do not restore predbat version continue if enable == try_enable and self.user_config_item_enabled(item): @@ -10223,7 +10223,7 @@ def save_settings(self): text += " target:\n" text += " entity_id: {}\n".format(entity) text += " data:\n" - text += " option: \"{}\"\n".format(value) + text += ' option: "{}"\n'.format(value) with open(filename, "w") as file: file.write(text) self.log("Wrote settings to {}".format(filename)) From 98632b9ff05e95718a59e06032952cfb2adb5b98 Mon Sep 17 00:00:00 2001 From: Trefor Southwell <48591903+springfall2008@users.noreply.github.com> Date: Fri, 12 Jan 2024 21:54:35 +0000 Subject: [PATCH 3/4] Fix to state save code --- apps/predbat/predbat.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/predbat/predbat.py b/apps/predbat/predbat.py index b6a34b8f4..0836d059a 100644 --- a/apps/predbat/predbat.py +++ b/apps/predbat/predbat.py @@ -8855,7 +8855,7 @@ def execute_plan(self): if (self.minutes_now < minutes_end) and ( (minutes_start - self.minutes_now) <= self.set_window_minutes or (inverter.charge_start_time_minutes - self.minutes_now) <= self.set_window_minutes ): - if ((minutes_start - self.minutes_now) > self.set_window_minutes) and (minutes_end - self.minutes_now) >= 24 * 60: + if ((minutes_start - self.minutes_now) > self.set_window_minutes) and (minutes_end - self.minutes_now) >= 24*60: self.log("Charge window would wrap, disabling until later") inverter.disable_charge_window() else: @@ -10177,7 +10177,7 @@ def save_settings(self): basename = "/predbat_restore_settings.yaml" filename = None text = "" - text += 'alias: "Restore Predbat settings from {}"\n'.format(self.time_abs_str(self.minutes_now)) + text += "alias: \"Restore Predbat settings from {}\"\n".format(self.time_abs_str(self.minutes_now)) text += "mode: single\n" text += "trigger: []\n" text += "condition: []\n" @@ -10198,12 +10198,12 @@ def save_settings(self): enable = item.get("enable", None) if entity == "select.predbat_update": - # Do not restore predbat version + # Do not restore predbat version continue if enable == try_enable and self.user_config_item_enabled(item): value = item.get("value", None) - if value: + if value is not None: if item["type"] == "input_number": text += " - service: input_number.set_value\n" text += " target:\n" @@ -10223,7 +10223,7 @@ def save_settings(self): text += " target:\n" text += " entity_id: {}\n".format(entity) text += " data:\n" - text += ' option: "{}"\n'.format(value) + text += " option: \"{}\"\n".format(value) with open(filename, "w") as file: file.write(text) self.log("Wrote settings to {}".format(filename)) From d153ea97395d30d51736e5010efdacf243ff6686 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci-lite[bot]" <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com> Date: Fri, 12 Jan 2024 21:55:19 +0000 Subject: [PATCH 4/4] [pre-commit.ci lite] apply automatic fixes --- apps/predbat/predbat.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/predbat/predbat.py b/apps/predbat/predbat.py index 0836d059a..ff0e3720a 100644 --- a/apps/predbat/predbat.py +++ b/apps/predbat/predbat.py @@ -8855,7 +8855,7 @@ def execute_plan(self): if (self.minutes_now < minutes_end) and ( (minutes_start - self.minutes_now) <= self.set_window_minutes or (inverter.charge_start_time_minutes - self.minutes_now) <= self.set_window_minutes ): - if ((minutes_start - self.minutes_now) > self.set_window_minutes) and (minutes_end - self.minutes_now) >= 24*60: + if ((minutes_start - self.minutes_now) > self.set_window_minutes) and (minutes_end - self.minutes_now) >= 24 * 60: self.log("Charge window would wrap, disabling until later") inverter.disable_charge_window() else: @@ -10177,7 +10177,7 @@ def save_settings(self): basename = "/predbat_restore_settings.yaml" filename = None text = "" - text += "alias: \"Restore Predbat settings from {}\"\n".format(self.time_abs_str(self.minutes_now)) + text += 'alias: "Restore Predbat settings from {}"\n'.format(self.time_abs_str(self.minutes_now)) text += "mode: single\n" text += "trigger: []\n" text += "condition: []\n" @@ -10198,7 +10198,7 @@ def save_settings(self): enable = item.get("enable", None) if entity == "select.predbat_update": - # Do not restore predbat version + # Do not restore predbat version continue if enable == try_enable and self.user_config_item_enabled(item): @@ -10223,7 +10223,7 @@ def save_settings(self): text += " target:\n" text += " entity_id: {}\n".format(entity) text += " data:\n" - text += " option: \"{}\"\n".format(value) + text += ' option: "{}"\n'.format(value) with open(filename, "w") as file: file.write(text) self.log("Wrote settings to {}".format(filename))