From 38c53252318c625f33bfd15953971c472c4c59cd Mon Sep 17 00:00:00 2001 From: Maik <83724253+Maik7@users.noreply.github.com> Date: Sat, 8 Jun 2024 10:44:12 +0200 Subject: [PATCH 1/8] Switch off lower prio appliances to switch on higher prio appliances --- .../pyscript/pv_excess_control.py | 47 ++++++++++++++++++- 1 file changed, 45 insertions(+), 2 deletions(-) diff --git a/PV_Excess_Control/pyscript/pv_excess_control.py b/PV_Excess_Control/pyscript/pv_excess_control.py index 48f97c8..20ce346 100644 --- a/PV_Excess_Control/pyscript/pv_excess_control.py +++ b/PV_Excess_Control/pyscript/pv_excess_control.py @@ -269,6 +269,7 @@ def on_time(): # ----------------------------------- go through each appliance (highest prio to lowest) --------------------------------------- # this is for determining which devices can be switched on instances = [] + switched_off_aplliance_to_switch_on_higher_prioritized_one = False for a_id, e in PvExcessControl.instances.copy().items(): inst = e['instance'] inst.switch_interval_counter += 1 @@ -286,7 +287,8 @@ def on_time(): if home_battery_level >= PvExcessControl.min_home_battery_level or not self._force_charge_battery(): # home battery charge is high enough to direct solar power to appliances, if solar power is higher than load power # calc avg based on pv excess (solar power - load power) according to specified window - avg_excess_power = int(sum(PvExcessControl.pv_history[-inst.appliance_switch_interval:]) / min([1,inst.appliance_switch_interval])) + avg_power_window = min(1,max(6,inst.appliance_switch_interval)) + avg_excess_power = int(sum(PvExcessControl.pv_history[-avg_power_window:]) / avg_power_window) log.debug(f'{log_prefix} Home battery charge is sufficient ({home_battery_level}/{PvExcessControl.min_home_battery_level} %)' f' OR remaining solar forecast is higher than remaining capacity of home battery. ' f'Calculated average excess power based on >> solar power - load power <<: {avg_excess_power} W') @@ -295,7 +297,7 @@ def on_time(): # home battery charge is not yet high enough OR battery force charge is necessary. # Only use excess power (which would otherwise be exported to the grid) for appliance # calc avg based on export power history according to specified window - avg_excess_power = int(sum(PvExcessControl.export_history[-inst.appliance_switch_interval:]) / min([1,inst.appliance_switch_interval])) + avg_excess_power = int(sum(PvExcessControl.export_history[-min(1,inst.appliance_switch_interval):]) / min([1,inst.appliance_switch_interval])) log.debug(f'{log_prefix} Home battery charge is not sufficient ({home_battery_level}/{PvExcessControl.min_home_battery_level} %), ' f'OR remaining solar forecast is lower than remaining capacity of home battery. ' f'Calculated average excess power based on >> export power <<: {avg_excess_power} W') @@ -344,6 +346,18 @@ def on_time(): else: log.debug(f'{log_prefix} Cannot switch on appliance, because appliance switch interval is not reached ' f'({inst.switch_interval_counter}/{inst.appliance_switch_interval}).') + elif (not switched_off_aplliance_to_switch_on_higher_prioritized_one) and (self.calculate_pwr_reducible(inst.appliance_priority) + avg_excess_power) >= (defined_power if inst.appliance_priority <= 500 else 0): + # excess power is sufficent by switching off lower prioritized appliance(s) + if inst.switch_interval_counter >= inst.appliance_switch_interval: + self.switch_on(inst) + inst.switch_interval_counter = 0 + switched_off_aplliance_to_switch_on_higher_prioritized_one = True + log.info(f'{log_prefix} Average Excess power will be high enough by switching off lower prioritized appliance(s). Switched on appliance.') + # "restart" history by subtracting defined power from each history value within the specified time frame + self._adjust_pwr_history(inst, -defined_power) + task.sleep(1) + if inst.dynamic_current_appliance: + _set_value(inst.appliance_current_set_entity, inst.min_current) else: log.debug(f'{log_prefix} Average Excess power not high enough to switch on appliance.') # ------------------------------------------------------------------- @@ -597,3 +611,32 @@ def _force_charge_battery(self, kwh_offset: float = 1): self.switch_off(inst) return True return False + + + def calculate_pwr_reducible(self, max_priority): + """ + Calculates the reduicible power by switching off all aplicances, which van be switched off and have a priority below max_priority + :param max_priority: see description + :return: reducible power + """ + pwr_reducible = 0 + for a_id, e in PvExcessControl.instances.copy().items(): + inst = e['instance'] + if not self.automation_activated(inst.automation_id): + continue + # Do not turn off only-on-appliances + if inst.appliance_on_only: + continue + # Do not turn off if switch interval not reached + if inst.switch_interval_counter < inst.appliance_switch_interval: + continue + if inst.appliance_priority >= max_priority: + continue + if _get_state(inst.appliance_switch) != 'on': + continue + if inst.actual_power is None: + pwr_reducible += inst.defined_current * PvExcessControl.grid_voltage * inst.phases + else: + pwr_reducible += _get_num_state(inst.actual_power) + + return pwr_reducible From 69083c0cb4020e99e4a2b418b8f98cee3efed9e3 Mon Sep 17 00:00:00 2001 From: Maik <83724253+Maik7@users.noreply.github.com> Date: Sat, 8 Jun 2024 11:04:31 +0200 Subject: [PATCH 2/8] Switch off lower prio appliances to switch on higher prio appliances --- PV_Excess_Control/pyscript/pv_excess_control.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/PV_Excess_Control/pyscript/pv_excess_control.py b/PV_Excess_Control/pyscript/pv_excess_control.py index 20ce346..c1eba9a 100644 --- a/PV_Excess_Control/pyscript/pv_excess_control.py +++ b/PV_Excess_Control/pyscript/pv_excess_control.py @@ -287,8 +287,7 @@ def on_time(): if home_battery_level >= PvExcessControl.min_home_battery_level or not self._force_charge_battery(): # home battery charge is high enough to direct solar power to appliances, if solar power is higher than load power # calc avg based on pv excess (solar power - load power) according to specified window - avg_power_window = min(1,max(6,inst.appliance_switch_interval)) - avg_excess_power = int(sum(PvExcessControl.pv_history[-avg_power_window:]) / avg_power_window) + avg_excess_power = int(sum(PvExcessControl.pv_history[-max(inst.appliance_switch_interval,1):]) / max([1,inst.appliance_switch_interval])) log.debug(f'{log_prefix} Home battery charge is sufficient ({home_battery_level}/{PvExcessControl.min_home_battery_level} %)' f' OR remaining solar forecast is higher than remaining capacity of home battery. ' f'Calculated average excess power based on >> solar power - load power <<: {avg_excess_power} W') @@ -297,7 +296,7 @@ def on_time(): # home battery charge is not yet high enough OR battery force charge is necessary. # Only use excess power (which would otherwise be exported to the grid) for appliance # calc avg based on export power history according to specified window - avg_excess_power = int(sum(PvExcessControl.export_history[-min(1,inst.appliance_switch_interval):]) / min([1,inst.appliance_switch_interval])) + avg_excess_power = int(sum(PvExcessControl.export_history[-max(1,inst.appliance_switch_interval):]) / max([1,inst.appliance_switch_interval])) log.debug(f'{log_prefix} Home battery charge is not sufficient ({home_battery_level}/{PvExcessControl.min_home_battery_level} %), ' f'OR remaining solar forecast is lower than remaining capacity of home battery. ' f'Calculated average excess power based on >> export power <<: {avg_excess_power} W') From 694ea4920702ca3aabc4d7d2b2c64e08c837ac98 Mon Sep 17 00:00:00 2001 From: Maik <83724253+Maik7@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:58:47 +0200 Subject: [PATCH 3/8] Update PV_Excess_Control/pyscript/pv_excess_control.py Co-authored-by: Carlos Sanchez --- PV_Excess_Control/pyscript/pv_excess_control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PV_Excess_Control/pyscript/pv_excess_control.py b/PV_Excess_Control/pyscript/pv_excess_control.py index c1eba9a..08f3ebc 100644 --- a/PV_Excess_Control/pyscript/pv_excess_control.py +++ b/PV_Excess_Control/pyscript/pv_excess_control.py @@ -269,7 +269,7 @@ def on_time(): # ----------------------------------- go through each appliance (highest prio to lowest) --------------------------------------- # this is for determining which devices can be switched on instances = [] - switched_off_aplliance_to_switch_on_higher_prioritized_one = False + switched_off_appliance_to_switch_on_higher_prioritized_one = False for a_id, e in PvExcessControl.instances.copy().items(): inst = e['instance'] inst.switch_interval_counter += 1 From f3fbf8636ac5947bd295dc98320087423e7bebd4 Mon Sep 17 00:00:00 2001 From: Maik <83724253+Maik7@users.noreply.github.com> Date: Sat, 8 Jun 2024 22:59:18 +0200 Subject: [PATCH 4/8] Update PV_Excess_Control/pyscript/pv_excess_control.py Co-authored-by: Carlos Sanchez --- PV_Excess_Control/pyscript/pv_excess_control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PV_Excess_Control/pyscript/pv_excess_control.py b/PV_Excess_Control/pyscript/pv_excess_control.py index 08f3ebc..2eae3e2 100644 --- a/PV_Excess_Control/pyscript/pv_excess_control.py +++ b/PV_Excess_Control/pyscript/pv_excess_control.py @@ -614,7 +614,7 @@ def _force_charge_battery(self, kwh_offset: float = 1): def calculate_pwr_reducible(self, max_priority): """ - Calculates the reduicible power by switching off all aplicances, which van be switched off and have a priority below max_priority + Calculates the reducible power by switching off all appliances, which can be switched off and have a priority below max_priority :param max_priority: see description :return: reducible power """ From 10fcdfe049b7d87fca7769c3e423f5b397480aa3 Mon Sep 17 00:00:00 2001 From: Maik <83724253+Maik7@users.noreply.github.com> Date: Sun, 16 Jun 2024 23:36:13 +0200 Subject: [PATCH 5/8] Update PV_Excess_Control/pyscript/pv_excess_control.py Co-authored-by: Carlos Sanchez --- PV_Excess_Control/pyscript/pv_excess_control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PV_Excess_Control/pyscript/pv_excess_control.py b/PV_Excess_Control/pyscript/pv_excess_control.py index 2eae3e2..e5af065 100644 --- a/PV_Excess_Control/pyscript/pv_excess_control.py +++ b/PV_Excess_Control/pyscript/pv_excess_control.py @@ -345,7 +345,7 @@ def on_time(): else: log.debug(f'{log_prefix} Cannot switch on appliance, because appliance switch interval is not reached ' f'({inst.switch_interval_counter}/{inst.appliance_switch_interval}).') - elif (not switched_off_aplliance_to_switch_on_higher_prioritized_one) and (self.calculate_pwr_reducible(inst.appliance_priority) + avg_excess_power) >= (defined_power if inst.appliance_priority <= 500 else 0): + elif (not switched_off_appliance_to_switch_on_higher_prioritized_one) and (self.calculate_pwr_reducible(inst.appliance_priority) + avg_excess_power) >= (defined_power if inst.appliance_priority <= 500 else 0): # excess power is sufficent by switching off lower prioritized appliance(s) if inst.switch_interval_counter >= inst.appliance_switch_interval: self.switch_on(inst) From 92d9af1add4fe214263b25f4f65c78d19f0d7f89 Mon Sep 17 00:00:00 2001 From: Maik <83724253+Maik7@users.noreply.github.com> Date: Sun, 16 Jun 2024 23:36:33 +0200 Subject: [PATCH 6/8] Update PV_Excess_Control/pyscript/pv_excess_control.py Co-authored-by: Carlos Sanchez --- PV_Excess_Control/pyscript/pv_excess_control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PV_Excess_Control/pyscript/pv_excess_control.py b/PV_Excess_Control/pyscript/pv_excess_control.py index e5af065..d83a01c 100644 --- a/PV_Excess_Control/pyscript/pv_excess_control.py +++ b/PV_Excess_Control/pyscript/pv_excess_control.py @@ -350,7 +350,7 @@ def on_time(): if inst.switch_interval_counter >= inst.appliance_switch_interval: self.switch_on(inst) inst.switch_interval_counter = 0 - switched_off_aplliance_to_switch_on_higher_prioritized_one = True + switched_off_appliance_to_switch_on_higher_prioritized_one = True log.info(f'{log_prefix} Average Excess power will be high enough by switching off lower prioritized appliance(s). Switched on appliance.') # "restart" history by subtracting defined power from each history value within the specified time frame self._adjust_pwr_history(inst, -defined_power) From 6517c757928c325044bff3bdb0a4da4dd8c02b7a Mon Sep 17 00:00:00 2001 From: Maik <83724253+Maik7@users.noreply.github.com> Date: Sun, 16 Jun 2024 23:46:04 +0200 Subject: [PATCH 7/8] Update pv_excess_control.py --- PV_Excess_Control/pyscript/pv_excess_control.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/PV_Excess_Control/pyscript/pv_excess_control.py b/PV_Excess_Control/pyscript/pv_excess_control.py index 30c9dc1..01d6c24 100644 --- a/PV_Excess_Control/pyscript/pv_excess_control.py +++ b/PV_Excess_Control/pyscript/pv_excess_control.py @@ -287,7 +287,7 @@ def on_time(): if home_battery_level >= PvExcessControl.min_home_battery_level or not self._force_charge_battery(): # home battery charge is high enough to direct solar power to appliances, if solar power is higher than load power # calc avg based on pv excess (solar power - load power) according to specified window - + avg_excess_power = int(sum(PvExcessControl.pv_history[-inst.appliance_switch_interval:]) / max(1,inst.appliance_switch_interval)) log.debug(f'{log_prefix} Home battery charge is sufficient ({home_battery_level}/{PvExcessControl.min_home_battery_level} %)' f' OR remaining solar forecast is higher than remaining capacity of home battery. ' f'Calculated average excess power based on >> solar power - load power <<: {avg_excess_power} W') @@ -296,7 +296,6 @@ def on_time(): # home battery charge is not yet high enough OR battery force charge is necessary. # Only use excess power (which would otherwise be exported to the grid) for appliance # calc avg based on export power history according to specified window - avg_excess_power = int(sum(PvExcessControl.export_history[-inst.appliance_switch_interval:]) / max(1,inst.appliance_switch_interval)) log.debug(f'{log_prefix} Home battery charge is not sufficient ({home_battery_level}/{PvExcessControl.min_home_battery_level} %), ' f'OR remaining solar forecast is lower than remaining capacity of home battery. ' From c0184e49c8e164dd53b66df315df82eef816e1bf Mon Sep 17 00:00:00 2001 From: Maik <83724253+Maik7@users.noreply.github.com> Date: Tue, 18 Jun 2024 00:16:22 +0200 Subject: [PATCH 8/8] Update PV_Excess_Control/pyscript/pv_excess_control.py Co-authored-by: Carlos Sanchez --- PV_Excess_Control/pyscript/pv_excess_control.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PV_Excess_Control/pyscript/pv_excess_control.py b/PV_Excess_Control/pyscript/pv_excess_control.py index 01d6c24..1bdfe91 100644 --- a/PV_Excess_Control/pyscript/pv_excess_control.py +++ b/PV_Excess_Control/pyscript/pv_excess_control.py @@ -346,7 +346,7 @@ def on_time(): log.debug(f'{log_prefix} Cannot switch on appliance, because appliance switch interval is not reached ' f'({inst.switch_interval_counter}/{inst.appliance_switch_interval}).') elif (not switched_off_appliance_to_switch_on_higher_prioritized_one) and (self.calculate_pwr_reducible(inst.appliance_priority) + avg_excess_power) >= (defined_power if inst.appliance_priority <= 500 else 0): - # excess power is sufficent by switching off lower prioritized appliance(s) + # excess power is sufficient by switching off lower prioritized appliance(s) if inst.switch_interval_counter >= inst.appliance_switch_interval: self.switch_on(inst) inst.switch_interval_counter = 0