Repository navigation
fix(planner): count a departure miss only above half a minimum run - #1533
Conversation
Energyplan now rounds an EV need below one minimum charging run to the nearest whole run (srcfl/energyplan#62). A need of at most half a run counts as met, so the plan starts no charger for it. ValidatePlan counted every miss above 1 Wh, so the plan view would show that need as a missed departure. departureMissWh computes the same threshold from what Core sends: half the energy of the smallest allowed step for MinChargeSeconds at the charge efficiency (0.9 when unset), and at least 1 Wh. For a 4140 W step and 300 s this is 155.25 Wh. A car that is charging at plan start keeps 1 Wh, since the worker then keeps its exact target. The threshold applies to every plan ValidatePlan replays, Core DP fallback included. docs/energyplan-contract.md states the rule. 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. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: f26154f376
ℹ️ 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".
| // is planned when its prices arrive. | ||
| if lp.TargetSoC > 0 && i == lp.TargetSlotIdx { | ||
| if missing := max(0, lp.TargetSoC-evSoC[lp.ID]) * lp.CapacityWh; missing > 1 { | ||
| if missing := max(0, lp.TargetSoC-evSoC[lp.ID]) * lp.CapacityWh; missing > lp.departureMissWh() { |
There was a problem hiding this comment.
Apply the half-run tolerance only to initially small needs
When an EV starts with a normal multi-run need but the plan finishes slightly short—for example, a 10 kWh need with 100 Wh still missing—Energyplan never rounds that original need to zero, yet this comparison applies the half-run threshold to the final residual and removes the real departure shortfall. Determine whether the initial target - initial energy qualified for rounding; otherwise retain the 1 Wh threshold so an unmet requested target remains visible.
AGENTS.md reference: AGENTS.md:L22-L23
Useful? React with 👍 / 👎.
One of a pair with srcfl/energyplan#66 (private), which rounds an EV need below one minimum charging run to the nearest whole run. Merge them together. Part of srcfl/energyplan#62.
Problem
Energyplan now treats an EV need of at most half a minimum charging run as met and starts no charger for it.
ValidatePlancounted every departure miss above 1 Wh, so the plan view would show such a need as a missed departure.Rule
One run R stores the smallest allowed step for
Charging.MinChargeSecondsat the charge efficiency Core sends (0.9 when unset). Core counts a departure miss only above max(1 Wh, R/2). A car that is charging at plan start (Charging.InitialCharging) keeps 1 Wh, since the worker keeps its exact target then. Without a minimum run the threshold stays 1 Wh.For the home box (4140 W smallest step, 300 s, 0.9) R = 310.5 Wh and the threshold is 155.25 Wh.
Change
go/internal/mpc/charging_periods.go:departureMissWhholds the threshold, with a doc comment naming the Energyplan rule.go/internal/mpc/external_optimizer.go:ValidatePlanuses it instead of the fixed 1 Wh.docs/energyplan-contract.md: one new paragraph after thecharging_periodsparagraph states the rule. It is byte-identical with the Energyplan copy in the paired PR.Core's own DP planner does not change. The threshold applies to every plan
ValidatePlanreplays, so a Core DP fallback or shadow plan that misses by half a run or less no longer shows a miss either.Tests
TestDepartureMissFollowsEnergyplanNeedRounding: 155.25 Wh for the home box, also with an unset efficiency and steps fromMinChargeW; 1 Wh without a minimum run, for a car charging at plan start, without a charging step, and for a run below 2 Wh.TestValidatePlanCountsADepartureMissOnlyAboveHalfARun: a car that cannot charge misses 149, 150 and 151 Wh against a 150 Wh threshold; only 151 Wh counts. A 2 Wh miss counts for a car charging at plan start and without a minimum run; 1 Wh does not.make verify: passes on f26154f (tests, compose migration, container boundary, release workflow, native solver tests, vet, build).Notes
chargingto a worker that lacks thecharging_periodsfeature. That worker keeps the 1 Wh rule while Core uses half a run. The pinned worker has the feature.max_energy_whequal to the target, so Core's cars never round up; the 253 Wh need from srcfl/energyplan#62 keeps its exact target. The Energyplan PR lists the options.external_optimizer.go,charging_periods.goor the contract. This branch is rebased on docs: let gap_satisfied cover the fleet search too #1532, which edited the contract's status table.🤖 Generated with Claude Code