Repository navigation
fix(loadpoint): Charge now keeps charging after a restart - #1778
Merged
Merged
Conversation
A restart restored Charge now as a pause. The saved choice needs proof that the same car is still on the charger, and the restore asked for a session ID that most chargers never report (OCPP and every bundled driver except easee_cloud). It answered "unconfirmed" and paused. A saved choice without a session ID is now checked by hardware identity alone; an observed unplug still ends it. A record with a session ID waits for the charger to report one instead of pausing, and a socket reconnect during that wait no longer saves a pause over it. A different session still pauses as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
This was referenced Oct 21, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Every update restarts Core, and a restart turned a running Charge now into a
pause. The simulator run before the beta showed it: before the restart,
11 040 W charging; 20 s later, the same charger and car,
requested_w: 0,manual_restore_unconfirmed: true, and the car stood still until someonepressed Start again. Fredrik's rule (#1772):
Charge now runs until Stop, unplug or the car stops asking; nothing else
stops it.
Cause
The saved Charge now needs proof that the same car is still on the charger.
RestoreManualHoldasked for a session ID that matches the saved one, butmost chargers never report a session ID: OCPP leaves it out of its reading
(
ocpp/handlers.gopushReading), and of the bundled drivers onlyeasee_cloudsends one. The saved record had no session ID, the restoreanswered
unconfirmed, and the controller installed a pause and stoppedtrying. It was not a race of a second, as first thought: the session ID never
arrives.
Change
go/internal/loadpoint/manual_hold_state.go,controller_hold_restore.go:alone. The same charger, still plugged in, resumes at once.
report its session instead of pausing for good. The same session resumes; a
different one pauses and asks for Start, as before.
charger's identity was unknown. A socket reconnect during the wait no
longer saves a pause over the stored choice; the next identity is checked
against the record instead.
Unchanged: an observed unplug clears the hold (
tickOne), Stop wins over arestore (
markManualExplicit), a car that stops asking releases it, and ahold saved before the charger's identity was ever known still comes back as a
pause.
No setting and no timer. The accepted risk: with a charger that has no
session ID, an unplug and a new car while Core is down is invisible, so the
new car gets Charge now until it is full, unplugged or stopped. That costs
money at worst; the fuse guard is unchanged. A time limit would protect no
hardware and would stop Charge now after a longer outage, against the rule.
Tests
TestChargeNowWaitsForSessionAfterRestart: identity before session ID,with and without a socket reconnect while waiting. Fails before
(stays at 0 W), passes after.
TestChargeNowWithoutSessionIDResumesAfterRestart: an OCPP-like chargerwithout session IDs resumes at once; unplug ends it, and neither the next
car nor a later restart inherits it. Fails before, passes after.
TestChargeNowDoesNotFollowAnotherSessionAfterRestart: a different sessionafter a restart stays paused.
easee:ABCwith no session rows inTestManualHoldRestoreRequiresHardwareAndActiveSession(nowpending) andTestManualRestrictionSurvivesRestartWithoutHardwareIdentity(samehardware keeps its 4 140 W). The cases without hardware identity still
pause.
make verify: passes (vet, all Go suites with-p 2, build).Simulator (srcfl/device-simulator, OCPP charger, 25 A, s7-25)
rerun.sh <ref> <label> s7-25from the pre-beta simulator report: OCPPcharger at 11 040 W under Charge now, house 3 A per phase, Core stopped for
20.6 s and started again. Both runs on the same base; only this commit
differs.
manual_hold,manual_restore_unconfirmed: truerequested_w11 040,manual_restore_unconfirmed: falseAfter the start the site-meter fuse guard held the car at 7.8 kW
(
fuse_limit) for about 30 s, then raised it to 11 040 W. That looks likethe guard counting the car as house load until the charger's first
MeterValues arrive, and it is not changed here. The earlier baseline in the
report (dcdbd27) shows the same pause as fc621be.
My first attempt collided with another session's rig on the shared ports and
was discarded; both runs above used their own ports.
Follow-ups, not in this PR
Availableread as an unplug could clear Charge now rightafter a charger boots; that is handled in
#1779.
turns it into a pause that asks for Start. That is deliberate in the code
(
TestManualStartWithoutHardwareCannotFollowAnotherSocket) and needs anowner decision under the same rule.
transactionID-1,session_wh0), so FTW's last order is never restored for OCPP chargersand session energy starts again from zero.
🤖 Generated with Claude Code