Repository navigation
fix(prediction): count each charging car's energy once in the house load - #5315
Merged
Merged
Conversation
The per-car loop added car_amount_premium - the running total across cars - to the load for every car, so with cars charging in the same step the first was counted once per car (two 7 kWh cars modelled 21 kWh, three 42 kWh). Add each car's own energy instead, in both engines; car_amount_premium keeps its other job as the energy the car-rate premium applies to. Kernel parity 15 -> 16. Fixes #5313 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
springfall2008
marked this pull request as ready for review
September 30, 2026 07:30
springfall2008
added a commit
that referenced
this pull request
Oct 2, 2026
…0-01 docs(debug-journal): fold in the 2026-10-01 queue slice (9 candidates); mark GH#5313 fixed by PR #5315, GH#5136 by PR #5293, GH#5222 by PR #5283, the iog-slot-io-adjusted row by PR #5304, GH#5068 reworked by PRs #5309/#5314; add the dynamic-load car cancel row and the GH#2649/#5302/#5324 findings
gcoan
pushed a commit
to gcoan/batpred
that referenced
this pull request
Oct 3, 2026
…); mark GH#5313 fixed by PR springfall2008#5315, GH#5136 by PR springfall2008#5293, GH#5222 by PR springfall2008#5283, the iog-slot-io-adjusted row by PR springfall2008#5304, GH#5068 reworked by PRs springfall2008#5309/springfall2008#5314; add the dynamic-load car cancel row and the GH#2649/springfall2008#5302/springfall2008#5324 findings Co-Authored-By: Claude Code <noreply@anthropic.com>
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.
This is an automated draft PR generated from issue #5313 — a maintainer should review it before merging.
Fixes #5313
Summary
When two or more cars charged in the same prediction step, the planner added
car_amount_premium, the running total of car energy across the cars, to the house load once per car. The first car was therefore counted once for every car: two 7 kWh cars modelled 21 kWh and three modelled 42 kWh.Each car now adds its own energy (
car_load_scale / car_charging_loss), in bothprediction.pyandprediction_kernel.cpp.car_amount_premiumstill accumulates as before, because its other use is correct: it is the energy the car-rate premium applies to, capped at the grid import.The kernel parity revision is bumped 15 → 16 in both the
.cppandprediction_kernel.py, and the kernel's "mirrors the Python engine exactly" note is replaced.Only users with
car_energy_reported_loadOn (the default) and two or more cars charging at overlapping times see a change. Cars outside the CT clamp go throughcar_load_energy_bypass, which already counted each car once and is untouched.Testing
multi_car_loadtest (tests/test_multi_car_load.py, registered inTEST_REGISTRY). It runs 1, 2 and 3 cars at 7 kW for an hour with no PV, no house load and an empty battery, atcar_charging_loss1.0 and 0.9, in both the Python engine and the C++ kernel. It asserts that grid import is 7 kWh per car and that the cost matches, and it checks the kernel really ran (kernel_handle), so the kernel leg cannot pass on the Python fallback.coverage/cases/random_results.json, updated). Only the two scenarios where two cars' slots overlap moved: 5 (metric −345) and 14 (metric −511). Scenarios 1 and 7 also have two cars, but their slots don't overlap, and they are unchanged, as are all the single-car and car-free scenarios (18 of 20)../run_pre_commitpasses: pre-commit is clean and the quick suite passes, includingkernel_parity,modelanddebug_cases.Notes
kernel-binariesjob rebuilds and commits them. Locally the harness built a fresh kernel.impact(run_prediction)reports MEDIUM with 5 direct callers. The signature is unchanged and behaviour changes only for two or more cars charging in the same step withcar_energy_reported_loadOn.car_amount_premiumis a misleading name, since it holds all reported car energy in the step and not just energy above the import rate. Renaming it would touch the premium pricing and the kernel for no behaviour change, so it is out of scope here.switch.predbat_car_energy_reported_loadOff avoids the double count, but it also takes the car's energy out of the modelled import and cost entirely. The car is treated as outside the CT clamp and only reduces export credit.🤖 Generated with Claude Code