OPT-36: test_opt34 and test_ux54 scenarios keep a shortfall B does not cover
checks / unit (pull_request) Successful in 27m17s
infra-pin / fresh (pull_request) Successful in 2s

With Cheap hours B counted, A buys only what B cannot reach. The OPT-34
night scenarios use a 1.6 x larger house profile, and the ux54 tab scenarios
a 4.8 kW evening (ux54_scenarios.make(evening=)), so A still charges; the
hard-coded levels become relations.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
glenn schrooyen
2026-11-02 03:30:39 +01:00
co-authored by Claude
parent 60674e45ba
commit 6a527de851
3 changed files with 35 additions and 20 deletions
+6 -2
View File
@@ -206,7 +206,8 @@ def measure(c, now, peak_w):
def make(name, now, *, soc=(55.0, 40.0), modes=("solar_first",
"solar_first")):
"solar_first"),
evening=None):
"""The controller of scenario `name` at `now` (UTC), its cycle run once."""
assert name in SCENARIOS, name
opts = dict(BASE)
@@ -271,7 +272,10 @@ def make(name, now, *, soc=(55.0, 40.0), modes=("solar_first",
members=members, tomorrow=tomorrow)
c.solar_fc_why = None
if name != "learning":
c.house_profile = profile(now)
# OPT-36: `evening` (W) makes the dear hours' use larger than
# what a Cheap hours battery covers, so Leftover solar still buys.
c.house_profile = profile(now) if evening is None \
else profile(now, evening=evening)
if name in ("owner", "dynamic", "sunny", "periods", "learning",
"notomorrow", "cycle"):
measure(c, now, 7000.0 if name != "dynamic" else 2500.0)