Repository navigation
fix(ev): resume after a 0 W standdown and span the Overview car notice - #1187
Conversation
Easee treats dynamicChargerCurrent=0 as a sticky user pause. When the loadpoint offer returns, send ev_resume before ev_set_current. The plugged-in car notice is a direct child of the 12-column Overview grid and must span the row, or it wraps a word per line. Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_d2d1c8e9-1f04-43cd-80ef-71bea3eeff68) |
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. |
The failed-goal replan test records each charger send. ev_resume on the 0 W → manual Start edge is not the setpoint under test. Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 729ff94381
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // starts current. Skip the first command of a process (prevKnown | ||
| // false): that is not a standdown we issued. | ||
| if haveOffer { | ||
| c.resumeAfterZeroOffer(ctx, lpCfg, prevW, prevKnown, offerW) |
There was a problem hiding this comment.
Apply the new clamp before resuming OCPP chargers
When an OCPP charger previously accepted a higher rate and the post-standdown offer is lower (for example, after a fuse clamp), this bare ev_resume is routed to ocpp.Server.Command, which restores the last non-zero amperage before the following ev_set_current applies the new limit. Because the resume call waits for profile confirmation, the charger can draw at the stale higher rate during that interval, defeating the hardware-protection clamp; resume must carry the already-clamped offer or otherwise avoid restoring the old rate on this path.
AGENTS.md reference: AGENTS.md:L35-L37
Useful? React with 👍 / 👎.
| if w, ok := cmd["power_w"].(float64); ok { | ||
| offerW, haveOffer = w, true | ||
| c.manager.setCommandedForManual(lpCfg.ID, w, cmdReason, manualCommandUpdatedAt) |
There was a problem hiding this comment.
Retain the resume edge until resume succeeds
When ev_resume fails transiently but the subsequent ev_set_current succeeds, the manager has already been changed from 0 W to the positive offer here. The next tick therefore sees prevW > 0 and never retries ev_resume; on the sticky-pause chargers this change targets, the car remains paused for the entire positive plan interval until another zero edge or unplug occurs. Track a pending resume independently or clear it only after the resume succeeds.
Useful? React with 👍 / 👎.
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_7f346b03-f7b3-4c19-91ce-0e9fccc03257) |
miravoss26
left a comment
There was a problem hiding this comment.
Fixes a real field-reported bug: Easee treats a 0 A dynamicChargerCurrent write as a sticky user-pause, so a later non-zero ev_set_current alone never reopens the contactor. resumeAfterZeroOffer now sends ev_resume first whenever the previous commanded value was known and ≤0 and the new offer is >0 — correctly skips the very first command of a process (prevKnown=false) so it's not misread as resuming a standdown FTW never issued.
Verified the ordering in tickOne: previousCommanded reads CommandedW/CommandedKnown before setCommandedForManual overwrites it, and resumeAfterZeroOffer fires before the actual ev_set_current send — matches the test assertions (sender.calls[1].action == "ev_resume", [2] == "ev_set_current"). TestTickResumesChargerWhenOfferReturns and TestTickFirstPositiveOfferDoesNotResume cover the two edges directly; the two updated dispatch-safety tests confirm exactly one ev_resume on the stale-meter-recovery paths. The mpc test adjustment (filtering non-ev_set_current actions before asserting on sent power) is a sensible accommodation, not a weakened assertion.
CSS/HTML part (#charging-notices spanning the full grid) is low-risk and unrelated to the dispatch change; no issue there. All CI green, no secrets/new deps/authz changes.
Safe to merge from my read.
Field report 2026-09-07 (Easee + Audi e-tron on v3.1.3-beta.1): a 0 W loadpoint offer writes Easee
dynamicChargerCurrent = 0, which the app shows as Temporary charging limit 0 A / “user paused”. The contactor stays open, the car sees no voltage, and a later non-zeroev_set_currentdoes not resume. Overview also squeezed the plugged-in car notice into one of twelve grid columns.What changed
ev_resumeand thenev_set_current.#charging-noticesis a full-width Overview banner instead of a one-word-wide column.Out of scope
paused_state) insrcfl/device-drivers.ev_resume(we have not issued a 0 W standdown in this run).Tests
go test ./internal/loadpoint/node --test web/dashboard-simplification.test.mjsNote
Medium Risk
Changes live EV charger command sequencing on a safety-critical path; behavior is gated and well-tested but mis-timed resume could still affect charging recovery.
Overview
Fixes Easee-style chargers that treat a 0 W limit as a sticky user pause: when FTW had previously commanded 0 W and the next tick offers power again, dispatch now sends
ev_resumebeforeev_set_current. The first positive offer after process start still skips resume (no prior standdown in this run).On Overview, the plugged-in car notice is a dedicated
#charging-noticeshost that spans the full 12-column grid (replacing a one-column squeeze). Styling moves from inline JS to CSS (flex layout, hidden state, mobile grid placement). Tests cover the 0 W → offer edge, stale site-meter recovery, and dashboard ordering/CSS expectations.Reviewed by Cursor Bugbot for commit 9414c97. Bugbot is set up for automated code reviews on this repo. Configure here.