TARIFF-24 round 2: a usable solar forecast replaces the "no weather" x1.5 (AUDIT-02 F1)

With battery modes on, the price gap a mode needs was always widened x1.5 by
Uncertainty.NO_WEATHER, even with a solar forecast read, so a 0.08 day/night
gap never traded at the shipped cycle cost. The doubt is now added only when
no usable forecast is read (solar_fc is None, the day plan's own test), in the
run plan (_price_runs), the charge gate (_mode_roles) and Home's mirror
(homeview.trade_verdict). The rule is one helper, arbitrage.weather_uncertainty();
the modes-off trade path (main.py cycle) keeps its literal NO_WEATHER.

DOCS "Battery modes" sentence, CHANGELOG 0.19.1 line and the DECISIONS note
follow. Tests: test_tariff24_weather.py.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
glenn schrooyen
2026-10-28 15:08:21 +01:00
co-authored by Claude
parent 230ba0b57a
commit 382b0ea411
7 changed files with 409 additions and 9 deletions
+2 -2
View File
@@ -2250,7 +2250,7 @@ class Controller:
required = price_required_spread(
arbitrage.threshold_eur_kwh(self.o),
price_uncertainty_of(plan.read.product)
| {Uncertainty.NO_WEATHER})
| arbitrage.weather_uncertainty(True, self.solar_fc))
ref = self._ref_cheap
if ref is not None and now - ref.end > REF_CHEAP_KEEP:
ref = self._ref_cheap = None
@@ -2329,7 +2329,7 @@ class Controller:
return plan.arbitrage(
peak_guard_active=active,
min_spread_eur_kwh=arbitrage.threshold_eur_kwh(self.o),
uncertainty=frozenset({Uncertainty.NO_WEATHER}),
uncertainty=arbitrage.weather_uncertainty(True, self.solar_fc),
now=now).match(
allowed=lambda _v: True, refused=lambda _v: False)
if guard is not None and plan is not None and runs is not None: