phase switch: reset reserved power if vehicle is unplugged during phase switch#3303
phase switch: reset reserved power if vehicle is unplugged during phase switch#3303LKuemmel wants to merge 1 commit intoopenWB:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Fixes reserved-power accounting around automatic phase switching, especially when charging stops mid-switch/unplug events, to prevent reserved_surplus from getting “stuck” and skewing available surplus calculations.
Changes:
- Split phase-switch cleanup into
reset_phase_switch_delay()(delay phase) andreset_phase_switch()(performing phase). - Invoke phase-switch cleanup during
_process_charge_stop()before resettingcontrol_parameter. - Update mode/submode-change handling to call
reset_phase_switch_delay()instead of the previous reset method.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 4 comments.
| File | Description |
|---|---|
packages/control/ev/ev.py |
Introduces separate reset functions for delay vs. performing phase-switch states and adjusts reserved-surplus release logic/logging. |
packages/control/chargepoint/chargepoint.py |
Calls EV phase-switch reset on charge stop (before control parameter reset) and updates mode/submode-change reset behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| self.data.set.rfid) | ||
| self.data.set.ocpp_transaction_id = None | ||
| # muss vor dem Zurücksetzen der control parameter aufgerufen werden | ||
| self.data.set.charging_ev_data.reset_phase_switch(self.data.control_parameter) |
There was a problem hiding this comment.
In _process_charge_stop() you call reset_phase_switch() before resetting the control parameters, but Ev.reset_phase_switch() only releases reserved_surplus for PERFORMING_PHASE_SWITCH. If the EV is unplugged while control_parameter.state == PHASE_SWITCH_DELAY (1→multi-phase delay), the reserved power added in Ev.auto_phase_switch() will not be released, which can skew reserved_surplus as long as other EVs are still plugged in. Consider extending the reset to also handle PHASE_SWITCH_DELAY (or call reset_phase_switch_delay() here as well) and release exactly the amount that was reserved.
| self.data.set.charging_ev_data.reset_phase_switch(self.data.control_parameter) | |
| self.data.set.charging_ev_data.reset_phase_switch(self.data.control_parameter) | |
| self.data.set.charging_ev_data.reset_phase_switch_delay(self.data.control_parameter) |
| if control_parameter.state == ChargepointState.PHASE_SWITCH_DELAY and control_parameter.phases == 1: | ||
| # Wenn der Timer läuft, ist den Control-Parametern die alte Phasenzahl hinterlegt. | ||
| if control_parameter.phases == 1: | ||
| reserved = control_parameter.required_current * \ | ||
| 3 * 230 - self.ev_template.data.max_current_single_phase * 230 | ||
| data.data.counter_all_data.get_evu_counter().data.set.reserved_surplus -= reserved | ||
| log.debug( | ||
| "Zurücksetzen der reservierten Leistung für die Phasenumschaltung. reservierte Leistung: " + | ||
| str(data.data.counter_all_data.get_evu_counter().data.set.reserved_surplus)) | ||
| # bei der Umschaltung 3p1p wird keine Leistung reserviert | ||
| evu_counter = data.data.counter_all_data.get_evu_counter() | ||
| reserved = control_parameter.required_current * \ | ||
| 3 * 230 - self.ev_template.data.max_current_single_phase * 230 | ||
| evu_counter.data.set.reserved_surplus -= reserved | ||
| log.debug(f"Zurücksetzen von {reserved}W reservierter Leistung für die Phasenumschaltung. " |
There was a problem hiding this comment.
reset_phase_switch_delay() recomputes the reserved power with control_parameter.required_current * 3 * 230 - max_current_single_phase * 230 and then subtracts it without clamping. This does not match the reservation logic in auto_phase_switch() (which reserves max(0, min_current * max_phases * 230 - max_current_single_phase * 230)), and it can even become negative (which would increase reserved_surplus when subtracting). Please compute/release the same value that was originally reserved (including max(0, …)), and avoid hard-coding 3 phases if 2-phase hardware is supported.
| """ Zurücksetzen der Zeitstempel und reservierten Leistung. | ||
|
|
There was a problem hiding this comment.
The docstring of reset_phase_switch_delay() says it resets timestamps ("Zurücksetzen der Zeitstempel"), but the method currently only adjusts reserved_surplus and does not touch timestamp_phase_switch_buffer_start / timestamp_last_phase_switch. Either update the docstring to reflect the actual behavior or reset the relevant timestamps/state here to avoid misleading documentation.
| """ Zurücksetzen der Zeitstempel und reservierten Leistung. | |
| """ Zurücksetzen der für die Phasenumschaltverzögerung reservierten Leistung. | |
| Zeitstempel werden hier nicht zurückgesetzt. |
| # muss vor dem Zurücksetzen der control parameter aufgerufen werden | ||
| self.data.set.charging_ev_data.reset_phase_switch(self.data.control_parameter) | ||
| self.reset_control_parameter_at_charge_stop() |
There was a problem hiding this comment.
This change introduces new behavior on charge stop: releasing reserved phase-switch power via charging_ev_data.reset_phase_switch(control_parameter). There are already unit tests covering _process_charge_stop(), but none assert that reserved_surplus is correctly released when unplugging during PERFORMING_PHASE_SWITCH (and, after fixing, during PHASE_SWITCH_DELAY). Please add a focused test to prevent regressions in reserved-power accounting.
https://forum.openwb.de/viewtopic.php?p=142234#p142234