Skip to content

test(site): an import ceiling and two equal batteries in the site pack - #1837

Merged
frahlg merged 3 commits into
masterfrom
test/site-ceiling-two-batteries
Oct 25, 2026
Merged

frahlg merged 3 commits into
masterfrom
test/site-ceiling-two-batteries

Conversation

@frahlg

@frahlg frahlg commented Oct 25, 2026 •

Copy link
Copy Markdown
Member

Why

Tonight's beta carries #1828 (an idle car starts on the hour's slack under the import ceiling) and #1814 (interchangeable batteries share the plan's total). The site pack had no case for either. Its house also plans with Core DP, which refuses two batteries, while a beta box plans with Energyplan.

Test-only: go/test/site. No Core change, no changeset.

What

  • s16-25, import ceiling (the help report behind fix(control): an idle car starts on the hour's slack under the import ceiling #1828). 25 A, house 1.3 kW, the battery held idle at its floor, POST /api/peak_import_ceiling 4 500 W, Charge now 16 A. House plus the car's 4 140 W minimum is above the ceiling. Core counts the part of an hour before its first reading at the ceiling, so the case starts in an hour's first 4 minutes or waits for :56, then runs one whole clock hour and 3 minutes. Criteria:
    • the car starts on the hour's room before :45;
    • every clock hour's recorded import averages at most the ceiling + 1 %;
    • the next hour stops the car within 60 s;
    • while held, it says import_limit in 90 % of samples and never fuse_limit;
    • the fuse holds.
  • s17-25, two equal batteries (Rann's site behind fix(control): interchangeable batteries share the plan's total #1814). Two hybrids with 10 kWh at 74 % and 60 %, house 3 kW, no PV, Energyplan with a 6 h horizon. Energyplan puts each quarter's discharge on one battery, as on Rann's site. Over its usual 48 h it keeps both batteries for the dearest hours. Today that was Monday evening at 40–60 öre, so the current quarter stayed idle and Core's per-battery path never ran. Over 6 h the batteries hold more than the house needs, so the plan discharges now. The case still waits up to an hour for a quarter the plan discharges, then runs 15 minutes. Every 30 s it saves the plan's order for each battery in plan.jsonl. Criteria:
    • Energyplan's plan moves the batteries in half the polls. This is the setup check, tolerated: the day's prices decide;
    • while the fleet moves 500 W or more, each battery takes at least a quarter of it 90 % of the time;
    • while the plan moves them, the charge gap shrinks by more than 0.2 points;
    • the fuse holds.
  • FTW_SITE_ENGINE=core|energyplan picks the planner for a whole run. Default core, as before. For energyplan the run directory links optimizer/native/bundle, where FTW looks for the worker. Only a run with Energyplan gets the link, so Core DP runs keep today's behaviour.
  • The house record now keeps phase_w (site power) and a second battery (inverter2). /api/loadpoints reads manual.limit_reason.

Evidence

All runs: device-simulator a3030d3, drivers 219c462e, on the M5 laptop. Each Core is built from the commit named.

Case Core Verdict What the record shows
s16 master 69700f41 pass Car starts 12:24:39, 1 479 s into the hour. Hour means: 12:00 3 982 W against 4 500 W; 11:00 1 300 W and 13:00 1 351 W (partial hours). Stops 2 s after 13:00. 1 415 held seconds, every one import_limit, none fuse_limit. Worst phase 8.5 A.
s16 0c8eaef9, before #1828 fail: the car never starts Hour 13:00 mean 1 300 W, the house alone; 3 377 of 3 387 held seconds say import_limit. This is the help report.
s17 master 69700f41 pass The plan moves the batteries in 31 of 31 polls, all on one battery (−3 000 W / 0 W). Core gives 1 684 / 1 341 W, which is 69:55, the energy each holds above 5 %. Gap 14.0 → 13.1 points.
s17 1883582e, before #1814 fail: each battery takes a quarter 3 015 / 0 W for all 900 s, as on Rann's site. The gap shrank here too (13.6 → 6.1), because the plan happened to name the fuller battery; only the share catches the fault.
Full set without s16 and s17, FTW_SITE_ENGINE=energyplan master 69700f41 24 pass, 4 known, 0 fail The known four are s2, s5, s5s and s13, the same four as Core DP on 16c4ad09. 85 min in three lanes.

go vet ./test/site/ and go test ./test/site/ (the unit tests; TestSite skips without FTW_SITE) pass.

Timing: s16 runs about 65 min, longest first in its lane. Started between :04 and :56 it first waits for :56. s17 runs 17 min when the plan discharges at once, and up to 77 min when it does not.

Not here

🤖 Generated with Claude Code

frahlg and others added 2 commits October 25, 2026 11:52
s16 runs Charge now under a 4.5 kW hourly import ceiling with house and
the car's minimum above it (#1828). s17 runs two equal batteries under
Energyplan (#1814). FTW_SITE_ENGINE picks the planner for a whole run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
@frahlg frahlg added the no-changeset PR intentionally exempt from the changeset requirement (dev tooling / non-shipping) label Oct 25, 2026
Over 48 h Energyplan keeps both batteries for tomorrow's dearer evening and
the plan's current quarter stays idle, so Core's per-battery path never ran.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Fredrik Ahlgren <fredrik@sourceful-labs.com>
@frahlg
frahlg marked this pull request as ready for review October 25, 2026 13:42
@frahlg
frahlg merged commit 53b5a87 into master Oct 25, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

no-changeset PR intentionally exempt from the changeset requirement (dev tooling / non-shipping)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant