From 2d270f2d1c55b45b64ce25dca33fb9e0d1fe94b7 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Wed, 17 Jun 2026 10:38:30 +0200 Subject: [PATCH 1/5] draft --- packages/control/chargepoint/chargepoint.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/control/chargepoint/chargepoint.py b/packages/control/chargepoint/chargepoint.py index 80a0c009a6..bec4b1a308 100644 --- a/packages/control/chargepoint/chargepoint.py +++ b/packages/control/chargepoint/chargepoint.py @@ -384,11 +384,11 @@ def _set_failed_phase_switches() -> None: if self.data.control_parameter.state == ChargepointState.WAIT_FOR_USING_PHASES: if check_timestamp(self.data.control_parameter.timestamp_charge_start, charging_ev.ev_template.data.keep_charge_active_duration) is False: - if self.hw_supports_phase_switch() and self.failed_phase_switches_reached(): + if self.hw_supports_phase_switch() and self.failed_phase_switches_reached() is False: if phase_switch.phase_switch_thread_alive(self.num) is False: self.data.control_parameter.state = ChargepointState.PHASE_SWITCH_AWAITED + _set_failed_phase_switches() if self._is_phase_switch_required() is False: - _set_failed_phase_switches() self.data.control_parameter.state = ChargepointState.CHARGING_ALLOWED else: _set_failed_phase_switches() @@ -829,7 +829,7 @@ def cp_state_hw_support_phase_switch(self) -> bool: self.data.get.charge_state and (self.data.control_parameter.state == ChargepointState.CHARGING_ALLOWED or self.data.control_parameter.state == ChargepointState.PHASE_SWITCH_DELAY)): - return self.failed_phase_switches_reached() + return self.failed_phase_switches_reached() is False else: return False @@ -846,6 +846,6 @@ def failed_phase_switches_reached(self) -> bool: self.data.control_parameter.failed_phase_switches == 1)): self.set_state_and_log( "Keine Phasenumschaltung, da die maximale Anzahl an Fehlversuchen erreicht wurde. ") - return False - else: return True + else: + return False From 3760062e9e61950b6a1b0c94b3c7f76115209500 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Mon, 22 Jun 2026 12:38:43 +0200 Subject: [PATCH 2/5] no retry switch if disabled --- .../control/algorithm/integration_test/conftest.py | 1 + packages/control/chargepoint/chargepoint.py | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/packages/control/algorithm/integration_test/conftest.py b/packages/control/algorithm/integration_test/conftest.py index 9998c861f3..cbc98f72ff 100644 --- a/packages/control/algorithm/integration_test/conftest.py +++ b/packages/control/algorithm/integration_test/conftest.py @@ -52,6 +52,7 @@ def data_() -> None: data.data.counter_all_data.data.get.hierarchy = NESTED_HIERARCHY data.data.counter_all_data.data.config.consider_less_charging = True data.data.io_actions = IoActions() + data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches = True @dataclass diff --git a/packages/control/chargepoint/chargepoint.py b/packages/control/chargepoint/chargepoint.py index bec4b1a308..c32e88a915 100644 --- a/packages/control/chargepoint/chargepoint.py +++ b/packages/control/chargepoint/chargepoint.py @@ -335,7 +335,7 @@ def _is_phase_switch_required(self) -> bool: phase_switch_required = True if phase_switch_required: # Umschaltung fehlgeschlagen - if self.data.set.phases_to_use != self.data.get.phases_in_use: + if self.check_deviating_contactor_states(self.data.set.phases_to_use, self.data.get.phases_in_use): if data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches: if self.data.control_parameter.failed_phase_switches > self.MAX_FAILED_PHASE_SWITCHES: phase_switch_required = False @@ -343,8 +343,7 @@ def _is_phase_switch_required(self) -> bool: "Keine Phasenumschaltung, da die maximale Anzahl an Fehlversuchen erreicht wurde.") else: # Umschaltung vor Ladestart zulassen - if (self.data.set.log.imported_since_plugged != 0 and - self.data.control_parameter.failed_phase_switches > 0): + if self.data.set.log.imported_since_plugged != 0: phase_switch_required = False self.set_state_and_log( "Keine Phasenumschaltung, da wiederholtes Anstoßen der Umschaltung in den übergreifenden " @@ -384,7 +383,7 @@ def _set_failed_phase_switches() -> None: if self.data.control_parameter.state == ChargepointState.WAIT_FOR_USING_PHASES: if check_timestamp(self.data.control_parameter.timestamp_charge_start, charging_ev.ev_template.data.keep_charge_active_duration) is False: - if self.hw_supports_phase_switch() and self.failed_phase_switches_reached() is False: + if self.hw_supports_phase_switch(): if phase_switch.phase_switch_thread_alive(self.num) is False: self.data.control_parameter.state = ChargepointState.PHASE_SWITCH_AWAITED _set_failed_phase_switches() @@ -842,8 +841,9 @@ def hw_supports_phase_switch(self) -> bool: def failed_phase_switches_reached(self) -> bool: if ((data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches and self.data.control_parameter.failed_phase_switches > self.MAX_FAILED_PHASE_SWITCHES) or - (data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches is False and - self.data.control_parameter.failed_phase_switches == 1)): + # bei deaktiverter Wiederholung der Umschaltung nur den gewünschten Umschaltvorgang durchführen, + # keinen Korrekturversuch + data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches is False): self.set_state_and_log( "Keine Phasenumschaltung, da die maximale Anzahl an Fehlversuchen erreicht wurde. ") return True From ba26970b36c78b78910464bf7ab32768a87baf1e Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Wed, 24 Jun 2026 11:21:50 +0200 Subject: [PATCH 3/5] fix --- packages/control/chargepoint/chargepoint.py | 38 +++++++-------------- 1 file changed, 13 insertions(+), 25 deletions(-) diff --git a/packages/control/chargepoint/chargepoint.py b/packages/control/chargepoint/chargepoint.py index c32e88a915..4ab9a8c9b8 100644 --- a/packages/control/chargepoint/chargepoint.py +++ b/packages/control/chargepoint/chargepoint.py @@ -302,18 +302,18 @@ def check_deviating_contactor_states(self, phase_a: int, phase_b: int) -> bool: return (phase_a == 1 and phase_b in [2, 3]) or (phase_b == 1 and phase_a in [2, 3]) def _is_phase_switch_required(self) -> bool: - phase_switch_required = False if self.data.get.evse_signaling == EvseSignaling.HLC: return False - if (self.data.control_parameter.state == ChargepointState.WAIT_FOR_USING_PHASES and + elif (self.data.control_parameter.state == ChargepointState.WAIT_FOR_USING_PHASES and (self.data.set.current != 0 and self.data.set.current_prev != 0)): - phase_switch_required = False + return False # Manche EVs brauchen nach der Umschaltung mehrere Zyklen, bis sie mit den drei Phasen laden. Dann darf # nicht zwischendurch eine neue Umschaltung getriggert werden. elif ((((self.data.control_parameter.state == ChargepointState.PHASE_SWITCH_AWAITED or self.data.control_parameter.state == ChargepointState.SWITCH_OFF_DELAY) and # Nach Ablauf der Laden aktiv halten Zeit, sollte mit der vorgegebenen Phasenzahl geladen werden. - self.check_deviating_contactor_states(self.data.set.phases_to_use, self.data.get.phases_in_use)) or + self.check_deviating_contactor_states(self.data.set.phases_to_use, self.data.get.phases_in_use) and + self.failed_phase_switches_reached() is False) or # Vorgegebene Phasenzahl hat sich geändert und es wird geladen (self.check_deviating_contactor_states(self.data.set.phases_to_use, self.data.control_parameter.phases) and @@ -324,32 +324,18 @@ def _is_phase_switch_required(self) -> bool: ((self.data.set.current != 0 and self.data.get.charge_state) or (self.data.set.current != 0 and self.data.set.current_prev == 0) or self.data.set.current == 0)): - phase_switch_required = True + return True elif (self.data.control_parameter.state == ChargepointState.NO_CHARGING_ALLOWED and - (self.check_deviating_contactor_states(self.data.set.phases_to_use, self.data.get.phases_in_use) or + ((self.check_deviating_contactor_states(self.data.set.phases_to_use, self.data.get.phases_in_use) and + self.failed_phase_switches_reached() is False) or # Vorgegebene Phasenzahl hat sich geändert self.check_deviating_contactor_states(self.data.set.phases_to_use, self.data.control_parameter.phases)) and # Wenn der Ladevorgang gestartet wird, muss vor dem ersten Laden umgeschaltet werden. self.data.set.current != 0 and self.data.get.charge_state is False): - phase_switch_required = True - if phase_switch_required: - # Umschaltung fehlgeschlagen - if self.check_deviating_contactor_states(self.data.set.phases_to_use, self.data.get.phases_in_use): - if data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches: - if self.data.control_parameter.failed_phase_switches > self.MAX_FAILED_PHASE_SWITCHES: - phase_switch_required = False - self.set_state_and_log( - "Keine Phasenumschaltung, da die maximale Anzahl an Fehlversuchen erreicht wurde.") - else: - # Umschaltung vor Ladestart zulassen - if self.data.set.log.imported_since_plugged != 0: - phase_switch_required = False - self.set_state_and_log( - "Keine Phasenumschaltung, da wiederholtes Anstoßen der Umschaltung in den übergreifenden " - "Ladeeinstellungen deaktiviert wurde. Die aktuelle " - "Phasenzahl wird bis zum nächsten Lademoduswechsel beibehalten.") - return phase_switch_required + return True + else: + return False STOP_CHARGING = ", dafür wird die Ladung unterbrochen." @@ -843,7 +829,9 @@ def failed_phase_switches_reached(self) -> bool: self.data.control_parameter.failed_phase_switches > self.MAX_FAILED_PHASE_SWITCHES) or # bei deaktiverter Wiederholung der Umschaltung nur den gewünschten Umschaltvorgang durchführen, # keinen Korrekturversuch - data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches is False): + # vor Ladestart trotzdem umschalten + (data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches is False and + self.data.set.log.imported_since_plugged != 0)): self.set_state_and_log( "Keine Phasenumschaltung, da die maximale Anzahl an Fehlversuchen erreicht wurde. ") return True From 1257cbcfde42fc78e0e79727360fb87581026ba0 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Wed, 24 Jun 2026 12:18:30 +0200 Subject: [PATCH 4/5] fix --- packages/control/chargepoint/chargepoint.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/control/chargepoint/chargepoint.py b/packages/control/chargepoint/chargepoint.py index 4ab9a8c9b8..5dedf97f60 100644 --- a/packages/control/chargepoint/chargepoint.py +++ b/packages/control/chargepoint/chargepoint.py @@ -447,8 +447,7 @@ def get_phases_by_selected_chargemode(self, phases_chargemode: int) -> int: charging_ev = self.data.set.charging_ev_data if self.data.get.evse_signaling == EvseSignaling.HLC: phases = self.data.get.phases_in_use - elif ((self.data.config.auto_phase_switch_hw is False and self.data.get.charge_state) or - self.data.control_parameter.failed_phase_switches > self.MAX_FAILED_PHASE_SWITCHES): + elif self.data.config.auto_phase_switch_hw is False and self.data.get.charge_state: # Wenn keine Umschaltung verbaut ist, die Phasenzahl nehmen, mit der geladen wird. Damit werden zB auch # einphasige EV an dreiphasigen openWBs korrekt berücksichtigt. phases = self.data.get.phases_in_use or self.data.set.phases_to_use @@ -825,15 +824,16 @@ def hw_supports_phase_switch(self) -> bool: self.data.set.log.imported_since_plugged == 0)) def failed_phase_switches_reached(self) -> bool: - if ((data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches and - self.data.control_parameter.failed_phase_switches > self.MAX_FAILED_PHASE_SWITCHES) or + if (data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches and + self.data.control_parameter.failed_phase_switches > self.MAX_FAILED_PHASE_SWITCHES): # bei deaktiverter Wiederholung der Umschaltung nur den gewünschten Umschaltvorgang durchführen, # keinen Korrekturversuch - # vor Ladestart trotzdem umschalten - (data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches is False and - self.data.set.log.imported_since_plugged != 0)): self.set_state_and_log( "Keine Phasenumschaltung, da die maximale Anzahl an Fehlversuchen erreicht wurde. ") return True + elif (data.data.general_data.data.chargemode_config.pv_charging.retry_failed_phase_switches is False and + self.data.set.log.imported_since_plugged != 0): + # vor Ladestart trotzdem umschalten + return True else: return False From f39830ab77e463a97f8613a502353bd0949ca9a5 Mon Sep 17 00:00:00 2001 From: LKuemmel Date: Wed, 24 Jun 2026 12:19:46 +0200 Subject: [PATCH 5/5] clean up --- packages/control/chargepoint/chargepoint.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/packages/control/chargepoint/chargepoint.py b/packages/control/chargepoint/chargepoint.py index 5dedf97f60..7a26d31f34 100644 --- a/packages/control/chargepoint/chargepoint.py +++ b/packages/control/chargepoint/chargepoint.py @@ -384,10 +384,6 @@ def _set_failed_phase_switches() -> None: def initiate_phase_switch(self): """prüft, ob eine Phasenumschaltung erforderlich ist und führt diese durch. """ - def _set_failed_phase_switches() -> None: - # Umschaltung fehlgeschlagen - if self.data.set.phases_to_use != self.data.get.phases_in_use: - self.data.control_parameter.failed_phase_switches += 1 try: if self.data.get.evse_signaling == EvseSignaling.HLC: return