Repository navigation
Conversation
Many P1 meters report phase current in whole amperes (DSMR 31.7.0), so a phase can carry up to 1 A more than l*_a shows. At the fuse rating that phase sat over In with no end. Take each phase's current as at least its power over its measured voltage (|P| <= V*I), when the reading has both and the phase powers add up to the total. The measured voltage keeps a high grid from reading as extra current; a voltage outside 0.8-1.2 x nominal bounds nothing. 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 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
Many P1 meters report phase current in whole amperes.
p1_dsmrandzuidwijk_p1pass DSMR1-0:31.7.0straight through asl1_a. Core reads each phase's magnitude only froml*_a. A truncating meter hides up to 1 A, a rounding meter up to 0.5 A.With a 0.5 A margin that stayed under the fuse rating. #1914 makes the margin 0 by default. The car then fills a phase until the meter reads the rating, and the real phase sits up to 1 A over In with no end: longer than the I²t rule allows.
A review of #1914 (on a5cdeae, the whole fuse stack) measured it in the site sim, with exact phase and total power and only the amps quantised. 16 A fuse, the car asks 16 A, last 20 of 30 min:
The same meters report each phase's power (
l*_w) and voltage (l*_v). Both drivers emit them.Change
go/internal/control/fuse_heat.go,phaseCurrentsA: a phase's current is at least its power over its measured voltage, since |P| ≤ V·I. This applies when:l*_vfor the phase, within 0.8 to 1.2 × the fuse's nominal voltage, andThe measured voltage matters. Dividing by the nominal 230 V reads high on a 240 V grid (16 A reads 16.7 A), and that acts as a hidden margin. A voltage outside the band is a driver or scale fault and bounds nothing. A meter without
l*_vreads as before.Everything that reads
phaseCurrentsAgets the bound: the fuse heat model, the car's per-phase fuse line and its battery-yield check, andSitePhasesfor the one-phase car check. Onmasterthe battery's fuse relief (perPhaseOverageReadingW) andphaseImbalanceAstill readl*_aalone. #1891 moves battery relief ontophaseCurrentsA, so it gets the bound once the fuse stack lands. This PR does not changephaseImbalanceA.Tests
TestPhaseCurrentsReadWholeAmpMetersFromPhasePower: a meter that reads 16 A while its power shows 16.6 A at 230 V reads 16.6 A, as import and as export. On a 240 V grid, 16 A at 3840 W stays 16 A. No phase voltage, a voltage off scale (23 V), phase powers against the total, or a reactive load (power below V·I): each readsl*_aas before.TestEVHardLimitCutsWhatAWholeAmpMeterHides: a whole-ampere meter at 26 A carrying 26.9 A gets the cut a meter showing 26.9 A gets. A 26.0 A phase on a 240 V grid gets the 26.0 A cut.fuse_heat.go), both fail: "truncated 16.6 A: [16 1 1]" and "whole-ampere meter cap 8970.0 W, exact meter 8349.0 W". With the power divided by the nominal voltage instead, both fail on the 240 V case (16.70 A; cap 8190 W against 8970 W).git archive).l*_vadded to the sim meter (both local probes, not committed): L1 ends at 15.60 A (truncating) and 15.45 A (rounding) at margin 0, 0 s over In. The full control package passes there withl*_von every sim reading, apart from the probe file.go test -race -count=1 ./internal/controlpasses (159 s).make verifyexits 0. gofmt is clean on the touched files.origin/master: no planning docs; telemetry reads 134, none added; brand cleanup passes; both helper unit suites pass.Risk
Low. The bound only raises a phase's current, and only to what the meter's own power and voltage prove. Fuse protection can only act sooner. A meter whose power and voltage disagree with its current (wrong scale, wrong phase order) could make Core cut more than it needs; the voltage band and the add-up check reject the scale faults I know of. Meters without phase voltage see no change.
Merge order
Base
master. It does not depend on the fuse stack and merges cleanly into #1910 and #1914. Land it before #1914, which makes margin 0 the default. #1919 also touchesfuse_heat.goand merges cleanly with this. #1789 rewritesphaseCurrentsAintoSitePhaseCurrents; whichever lands later must carry the bound across.🤖 Generated with Claude Code