cileni k vybiti pred ranem kdy nabiju z fve
This commit is contained in:
@@ -19,7 +19,9 @@ from services.planning_engine import (
|
||||
_in_night_battery_export_window,
|
||||
_neg_sell_day_phases,
|
||||
_neg_sell_phases_enabled,
|
||||
_neg_evening_reserve_soc_anchors,
|
||||
_pre_neg_pv_export_bundle,
|
||||
_prague_calendar_date,
|
||||
_pre_neg_buy_soc_ceiling_wh,
|
||||
_pre_neg_peak_sell_idx,
|
||||
_pre_neg_pv_export_forecast_cushion_ok,
|
||||
@@ -4093,6 +4095,52 @@ class NegSellPrepWindowV36Tests(unittest.TestCase):
|
||||
"morning before 2nd neg day should allow pre-neg export",
|
||||
)
|
||||
|
||||
def test_evening_reserve_anchor_before_neg_day(self) -> None:
|
||||
base = datetime(2026, 6, 10, 10, 0, tzinfo=ZoneInfo("Europe/Prague")).astimezone(
|
||||
timezone.utc
|
||||
)
|
||||
slots: list[PlanningSlot] = []
|
||||
for i in range(120):
|
||||
local = (base + timedelta(minutes=15 * i)).astimezone(
|
||||
ZoneInfo("Europe/Prague")
|
||||
)
|
||||
h = local.hour + local.minute / 60.0
|
||||
if local.date().day == 10:
|
||||
sell = -0.2 if h >= 14 else 2.5
|
||||
elif local.date().day == 11:
|
||||
sell = -0.2 if 9 <= h < 15 else 2.8
|
||||
else:
|
||||
sell = 2.5
|
||||
slots.append(
|
||||
PlanningSlot(
|
||||
interval_start=base + timedelta(minutes=15 * i),
|
||||
buy_price=2.0,
|
||||
sell_price=sell,
|
||||
pv_a_forecast_w=3000,
|
||||
pv_b_forecast_w=3000,
|
||||
load_baseline_w=1500,
|
||||
ev1_connected=False,
|
||||
ev2_connected=False,
|
||||
allow_charge=True,
|
||||
allow_discharge_export=True,
|
||||
)
|
||||
)
|
||||
bat = _battery(uc_wh=64_000.0, max_pct=95.0, arb_pct=20.0)
|
||||
bat.planner_neg_sell_prep_soc_percent = 80.0
|
||||
bat.planner_neg_sell_full_soc_tail_slots = 4
|
||||
_ph, _tg, _w, meta = _neg_sell_day_phases(slots, bat)
|
||||
anchors = _neg_evening_reserve_soc_anchors(slots, meta, bat)
|
||||
self.assertGreaterEqual(len(anchors), 1)
|
||||
t_a, tgt = anchors[0]
|
||||
self.assertAlmostEqual(tgt, bat.reserve_soc_wh, delta=100.0)
|
||||
self.assertEqual(_prague_calendar_date(slots[t_a]).day, 10)
|
||||
# Kotva pro den 11: večer 10.6. (i když odpoledne 10.6. už bylo sell<0).
|
||||
if len(meta["days"]) >= 2:
|
||||
day11_first = int(meta["days"][1]["first_neg_idx"])
|
||||
prev = _prague_calendar_date(slots[day11_first]) - timedelta(days=1)
|
||||
a11 = [(t, w) for t, w in anchors if _prague_calendar_date(slots[t]) == prev]
|
||||
self.assertEqual(len(a11), 1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user