Skip to content

feat(EvseManager)!: restructure charging state machine to simplify pause/resume and remove replug#1790

Merged
Pietfried merged 1 commit intomainfrom
refactor/charger-state-machine
Mar 9, 2026
Merged

feat(EvseManager)!: restructure charging state machine to simplify pause/resume and remove replug#1790
Pietfried merged 1 commit intomainfrom
refactor/charger-state-machine

Conversation

@corneliusclaussen
Copy link
Copy Markdown
Contributor

@corneliusclaussen corneliusclaussen commented Feb 4, 2026

Describe your changes

Remove WaitingForEnergy, Replug states and related session events (ChargingResumed, ReplugStarted, ReplugFinished, WaitingForEnergy). Consolidate pause handling into ChargingPausedEVSE with reason tracking
(Error, NoEnergy, UserPause) via new PauseChargingEVSEReasonEnum.

Key changes in Charger state machine:

  • Replace WaitingForEnergy state with direct transitions through ChargingPausedEVSE, which now reports multiple concurrent reasons
  • Remove evse_replug command from BSP interface and all implementations
  • Remove EvseReplugStarted/Finished events from board_support_common
  • Add configurable hlc_charge_loop_without_energy_timeout_s for ISOsessions to handle no-energy scenarios gracefully in charge loop
  • Add dc_ramp_ampere_per_second config for DC current ramping
  • Change zero_power_ignore_pause default to true for better EV compatibility
  • Introduce StoppingCharging as proper transitional state that waits for contactor open before moving to paused or finished states
  • Use atomic flags (flag_authorized, flag_transaction_active, flag_ev_plugged_in, flag_paused_by_evse) for thread-safe state

BREAKING CHANGE: Removes WaitingForEnergy, ChargingResumed, ReplugStarted, ReplugFinished session events and evse_replug BSP command. Consumers must handle ChargingPausedEVSE with reason tracking instead.

Behavioral changes:

  • EvseManager will set state F in case no EV is plugged in and EvseManager has an active error
  • The default of zero_power_ignore_pause has been changed to true because this is more compatible with real EVs. With this configuration parameter being true DC sessions will reach the charge loop in case no energy is available before the session is stopped by the EVSE after hlc_charge_loop_without_energy_timeout_s
  • In general EVerest attempts to be able/ready to restart/resume ISO15118 sessions whenever possible in case of errors, no energy or user pause

Smoke tests:

  • Add pause/resume session commands to test controller interface
  • Add comprehensive smoke tests for pause/resume and no-energy scenarios
  • Remove deprecated startup_tests.py in favor of new probe-based tests

These changes have been verified within the following test scenarios with real EVs for basic charging, ISO15118-2 AC and DC

  • No energy available at start of session
  • No energy available during session
  • User pause during session
  • User resume during session
  • Raise error before session
  • Raise/clear error during session

NOTE: The main changes of this PR are located in Charger.cpp/hpp and EvseManager.cpp/hpp. Most of changes in the other files are due to the removed types, vars and interface commands.

Issue ticket number and link

Checklist before requesting a review

  • I have performed a self-review of my code
  • I have made corresponding changes to the documentation
  • I read the contribution documentation and made sure that my changes meet its requirements

@Pietfried Pietfried force-pushed the refactor/charger-state-machine branch from 963841d to d287068 Compare February 4, 2026 17:35
@FaHaGit
Copy link
Copy Markdown
Contributor

FaHaGit commented Feb 5, 2026

evse_replug cmd is still in the EvseBoardSupport interface. Shouldn't we just remove it if no one is using it anymore?

@Pietfried
Copy link
Copy Markdown
Contributor

evse_replug cmd is still in the EvseBoardSupport interface. Shouldn't we just remove it if no one is using it anymore?

Yes I guess we will eventually remove it. This PR is still an early draft

@Pietfried Pietfried force-pushed the refactor/charger-state-machine branch 3 times, most recently from bc8c99d to b2942cf Compare February 8, 2026 16:44
@corneliusclaussen corneliusclaussen force-pushed the refactor/charger-state-machine branch from b2942cf to 43905b8 Compare February 9, 2026 07:34
@Pietfried Pietfried force-pushed the refactor/charger-state-machine branch from afed9ab to 3bbc287 Compare February 12, 2026 11:04
@Pietfried Pietfried added the include-in-release Tag that this PR should be included in the current merge window for the upcoming release if possible label Feb 16, 2026
@Pietfried Pietfried force-pushed the refactor/charger-state-machine branch from 3bbc287 to ef9d73c Compare February 18, 2026 17:36
@corneliusclaussen corneliusclaussen force-pushed the refactor/charger-state-machine branch 2 times, most recently from 0bab031 to b36221e Compare February 24, 2026 08:27
@corneliusclaussen corneliusclaussen marked this pull request as ready for review February 27, 2026 11:31
@Pietfried Pietfried force-pushed the refactor/charger-state-machine branch from 6730bb3 to 367254c Compare February 27, 2026 11:32
@Pietfried Pietfried force-pushed the refactor/charger-state-machine branch 3 times, most recently from ea171f4 to 9481e08 Compare February 27, 2026 15:17
@Pietfried
Copy link
Copy Markdown
Contributor

Regarding RpcApi, this looks okay, and is tested by us.

Some other small remarks and nits added.

The EvseManager changes are massive, and currently not fully understood, and not part of this review.

Regarding #1682: The EVSE cannot tell the EV to pause charging (EVSENotification does not allow for this differentiation). So now the EVSE tells the EV "StopCharging", and the EV terminates the session, which is probably as correct as it can be. Yet the EvseManager stays in "EVSE Paused" until unplugged:

2026-03-06 12:02:55.819276 [INFO] evse_manager:Ev  ::                                     CAR ISO V2G CurrentDemandReq
2026-03-06 12:02:55.950353 [INFO] evse_manager:Ev  :: EVSE ISO V2G CurrentDemandRes
2026-03-06 12:02:56.054472 [INFO] evse_manager:Ev  :: EVSE IEC Charger state: Charging->StoppingCharging
2026-03-06 12:02:56.228407 [INFO] evse_manager:Ev  ::                                     CAR ISO V2G CurrentDemandReq
2026-03-06 12:02:56.322909 [INFO] evse_manager:Ev  :: EVSE ISO V2G CurrentDemandRes
2026-03-06 12:02:56.395863 [INFO] ev_manager:EvMa  :: POWER OFF iso stopped
2026-03-06 12:02:56.566788 [INFO] ev_manager:EvMa  :: Finished simulation.
2026-03-06 12:02:56.894739 [INFO] evse_manager:Ev  ::                                     CAR IEC Event CarRequestedStopPower
2026-03-06 12:02:56.905597 [INFO] ovm:OVMSimulato  :: Over voltage monitoring: stopped.
2026-03-06 12:02:56.947046 [INFO] evse_manager:Ev  :: VoltagePlausibilityMonitor, stop monitoring
2026-03-06 12:02:56.947197 [INFO] evse_manager:Ev  :: EVSE IEC DC power supply OFF
2026-03-06 12:02:56.947952 [INFO] powersupply_dc:  :: Set mode: Off ChargingPhase: Charging
2026-03-06 12:02:56.989451 [INFO] imd:IMDSimulato  :: Stopped simulated isolation monitoring
2026-03-06 12:02:57.030379 [INFO] evse_manager:Ev  ::                                     CAR ISO V2G PowerDeliveryReq
2026-03-06 12:02:57.031230 [INFO] ovm:OVMSimulato  :: Over voltage monitoring: stopped.
2026-03-06 12:02:57.071961 [INFO] evse_manager:Ev  :: EVSE IEC Event PowerOff
2026-03-06 12:02:57.072104 [INFO] evse_manager:Ev  :: EVSE IEC Charger state: StoppingCharging->EVSE Paused
2026-03-06 12:02:57.115422 [INFO] evse_manager:Ev  :: EVSE ISO V2G PowerDeliveryRes
2026-03-06 12:02:57.378951 [INFO] evse_manager:Ev  :: EVSE ISO Change HLC Limits: 22080W/55.2A, target_voltage 400, actual_voltage 0, bpt_active false

2026-03-06 12:02:57.521421 [INFO] iso15118_charge  :: Welding-phase started
2026-03-06 12:02:57.522204 [INFO] evse_manager:Ev  ::                                     CAR ISO V2G WeldingDetectionReq
2026-03-06 12:02:57.649190 [INFO] evse_manager:Ev  :: EVSE ISO V2G WeldingDetectionRes
2026-03-06 12:02:58.219201 [INFO] evse_manager:Ev  ::                                     CAR ISO V2G WeldingDetectionReq
2026-03-06 12:02:58.263414 [INFO] evse_manager:Ev  :: EVSE ISO V2G WeldingDetectionRes
2026-03-06 12:02:58.809687 [INFO] evse_manager:Ev  ::                                     CAR ISO V2G WeldingDetectionReq
2026-03-06 12:02:58.949833 [INFO] evse_manager:Ev  :: EVSE ISO V2G WeldingDetectionRes
2026-03-06 12:02:59.446305 [INFO] evse_manager:Ev  ::                                     CAR ISO V2G WeldingDetectionReq
2026-03-06 12:02:59.583584 [INFO] evse_manager:Ev  :: EVSE ISO V2G WeldingDetectionRes
2026-03-06 12:03:00.089562 [INFO] evse_manager:Ev  ::                                     CAR ISO V2G SessionStopReq

2026-03-06 12:03:00.187670 [INFO] iso15118_charge  :: Closing TCP connection
2026-03-06 12:03:00.247408 [INFO] evse_manager:Ev  :: EVSE ISO V2G SessionStopRes

2026-03-06 12:03:05.190676 [INFO] iso15118_charge  :: TCP connection closed gracefully
2026-03-06 12:03:05.239345 [INFO] evse_manager:Ev  :: EVSE ISO D-LINK_TERMINATE.req
2026-03-06 12:03:05.239656 [INFO] evse_manager:Ev  :: EVSE IEC Set PWM Off
2026-03-06 12:03:05.326758 [INFO] evse_manager:Ev  :: EVSE ISO SLAC UNMATCHED
2026-03-06 12:03:05.327292 [INFO] evse_manager:Ev  :: EVSE ISO D-LINK_READY (false)

Closing the TCP Session and moving to EVSEPaused is the intended here. With the changes in this PR, a call of resume_charging would change from EVSEPaused->PrepareCharging, which would turn on the 5% PWM again, signaling to the EV that a new SLAC and TCP Session can start.

@Pietfried Pietfried requested review from SebaLukas and barsnick March 6, 2026 12:23
@Pietfried Pietfried force-pushed the refactor/charger-state-machine branch from 51a2be2 to bcc7d75 Compare March 6, 2026 12:47
Copy link
Copy Markdown
Contributor

@barsnick barsnick left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks okay, One comment left @SebaLukas.

Comment thread modules/EVSE/EvseManager/Charger.cpp
Comment thread modules/EVSE/EvseManager/Charger.cpp
Comment thread modules/EVSE/EvseManager/EvseManager.cpp
SebaLukas
SebaLukas previously approved these changes Mar 6, 2026
barsnick
barsnick previously approved these changes Mar 6, 2026
@Pietfried Pietfried force-pushed the refactor/charger-state-machine branch from 8e20b4a to ed787a5 Compare March 6, 2026 14:24
Pietfried
Pietfried previously approved these changes Mar 6, 2026
@Pietfried Pietfried enabled auto-merge March 6, 2026 14:25
hikinggrass
hikinggrass previously approved these changes Mar 6, 2026
djchhp
djchhp previously approved these changes Mar 9, 2026
…ause/resume and remove replug

Remove WaitingForEnergy, Replug states and related session events
(ChargingResumed, ReplugStarted, ReplugFinished, WaitingForEnergy).
Consolidate pause handling into ChargingPausedEVSE with reason tracking
(Error, NoEnergy, UserPause) via new PauseChargingEVSEReasonEnum.

Key changes in Charger state machine:
- Replace WaitingForEnergy state with direct transitions through
  ChargingPausedEVSE, which now reports multiple concurrent reasons
- Remove evse_replug command from BSP interface and all implementations
- Remove EvseReplugStarted/Finished events from board_support_common
- Add configurable hlc_charge_loop_without_energy_timeout_s for ISO
  sessions to handle no-energy scenarios gracefully in charge loop
- Add dc_ramp_ampere_per_second config for DC current ramping
- Change zero_power_ignore_pause default to true for better EV compatibility
- Introduce StoppingCharging as proper transitional state that waits
  for contactor open before moving to paused or finished states
- Use atomic flags (flag_authorized, flag_transaction_active,
  flag_ev_plugged_in, flag_paused_by_evse) for thread-safe state

BREAKING CHANGE: Removes WaitingForEnergy, ChargingResumed,
ReplugStarted, ReplugFinished session events and evse_replug BSP
command. Consumers must handle ChargingPausedEVSE with reason
tracking instead.

Smoke tests:
- Add pause/resume session commands to test controller interface
- Add comprehensive smoke tests for pause/resume and no-energy scenarios
- Remove deprecated startup_tests.py in favor of new probe-based tests

Signed-off-by: Piet Gömpel <pietgoempel@gmail.com>
Signed-off-by: Cornelius Claussen <cc@pionix.de>
Signed-off-by: Sebastian Lukas <sebastian.lukas@pionix.de>
@Pietfried Pietfried dismissed stale reviews from djchhp, hikinggrass, barsnick, SebaLukas, and themself via 43e61d9 March 9, 2026 07:56
@Pietfried Pietfried force-pushed the refactor/charger-state-machine branch from ed787a5 to 43e61d9 Compare March 9, 2026 07:56
@Pietfried
Copy link
Copy Markdown
Contributor

@djchhp @barsnick @hikinggrass @SebaLukas reviews were dismissed due to rebase and a test hash file update, so your approval is required once again

@Pietfried Pietfried added this pull request to the merge queue Mar 9, 2026
Merged via the queue into main with commit 27673e1 Mar 9, 2026
19 of 22 checks passed
@Pietfried Pietfried deleted the refactor/charger-state-machine branch March 9, 2026 10:04
ThatsLucas pushed a commit to ThatsLucas/everest-core that referenced this pull request Apr 13, 2026
…ause/resume and remove replug (EVerest#1790)

Remove WaitingForEnergy, Replug states and related session events
(ChargingResumed, ReplugStarted, ReplugFinished, WaitingForEnergy).
Consolidate pause handling into ChargingPausedEVSE with reason tracking
(Error, NoEnergy, UserPause) via new PauseChargingEVSEReasonEnum.

Key changes in Charger state machine:
- Replace WaitingForEnergy state with direct transitions through
  ChargingPausedEVSE, which now reports multiple concurrent reasons
- Remove evse_replug command from BSP interface and all implementations
- Remove EvseReplugStarted/Finished events from board_support_common
- Add configurable hlc_charge_loop_without_energy_timeout_s for ISO
  sessions to handle no-energy scenarios gracefully in charge loop
- Add dc_ramp_ampere_per_second config for DC current ramping
- Change zero_power_ignore_pause default to true for better EV compatibility
- Introduce StoppingCharging as proper transitional state that waits
  for contactor open before moving to paused or finished states
- Use atomic flags (flag_authorized, flag_transaction_active,
  flag_ev_plugged_in, flag_paused_by_evse) for thread-safe state

BREAKING CHANGE: Removes WaitingForEnergy, ChargingResumed,
ReplugStarted, ReplugFinished session events and evse_replug BSP
command. Consumers must handle ChargingPausedEVSE with reason
tracking instead.

Smoke tests:
- Add pause/resume session commands to test controller interface
- Add comprehensive smoke tests for pause/resume and no-energy scenarios
- Remove deprecated startup_tests.py in favor of new probe-based tests

Signed-off-by: Piet Gömpel <pietgoempel@gmail.com>
Signed-off-by: Cornelius Claussen <cc@pionix.de>
Signed-off-by: Sebastian Lukas <sebastian.lukas@pionix.de>
Co-authored-by: Piet Gömpel <pietgoempel@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

include-in-release Tag that this PR should be included in the current merge window for the upcoming release if possible

Projects

None yet

7 participants