Rest the meter just below zero, not at zero
The deadband is a one-way ratchet: any resting point inside it holds indefinitely. Import and export are separate registers on the meter, so a loop resting at +14 W bills 0.34 kWh/day while behaving perfectly. target_grid_w (default -10 W) moves that residue onto the export register. Worst billed rest point drops from 15 W to under 5 W. Behaviour is unchanged at target_grid_w: 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
1b85eb41ad
commit
5184a2cfc2
@@ -97,6 +97,26 @@ for i in range(12):
|
||||
check(f"converges within deadband in {cycles} cycles (<=6)", cycles <= 6)
|
||||
check("no overshoot past the load", actual <= load + T.deadband_w)
|
||||
|
||||
print("grid bias: the deadband must not rest on the import register")
|
||||
# The billed asymmetry: import and export are separate registers, so a resting
|
||||
# point inside the deadband on the import side is paid for every second it
|
||||
# holds. 14 W held all day is 0.34 kWh.
|
||||
T0 = Tuning(target_grid_w=0.0)
|
||||
TB = Tuning(target_grid_w=-10.0)
|
||||
check("unbiased, +14 W import rests forever",
|
||||
compute(500.0, 14.0, 500.0, T0).reason == "deadband")
|
||||
d = compute(500.0, 14.0, 500.0, TB)
|
||||
check("biased, the same +14 W is corrected", d.reason != "deadband" and d.target_w > 500.0)
|
||||
check("biased, a small export rests", compute(500.0, -10.0, 500.0, TB).reason == "deadband")
|
||||
check("biased, the band still ends before -25 W",
|
||||
compute(500.0, -30.0, 500.0, TB).reason != "deadband")
|
||||
# Worst-case billed leak: the band is [bias - deadband, bias + deadband], so it
|
||||
# drops from 15 W to 5 W. Set target_grid_w to -deadband_w to remove it entirely,
|
||||
# at the cost of giving that much away as export.
|
||||
check("worst billed rest point falls from 15 W to under 5 W",
|
||||
compute(500.0, 4.9, 500.0, TB).reason == "deadband"
|
||||
and compute(500.0, 5.0, 500.0, TB).reason != "deadband")
|
||||
|
||||
print()
|
||||
if fails:
|
||||
print(f"{len(fails)} FAILED: {', '.join(fails)}")
|
||||
|
||||
Reference in New Issue
Block a user