zasadni uprava LP planneru
Some checks failed
CI and deploy / migration-check (push) Failing after 24s
CI and deploy / deploy (push) Has been skipped

This commit is contained in:
Dusan Vojacek
2026-05-21 11:18:09 +02:00
parent d984716f69
commit 08f1b6741a
7 changed files with 330 additions and 123 deletions

View File

@@ -1290,5 +1290,74 @@ class TerminalSocShadowTests(unittest.TestCase):
)
class SpreadGuardHome01EconomicsTests(unittest.TestCase):
"""Regrese: sell≪buy (VT) nesmí vést k PV exportu + masivnímu grid importu ve stejném slotu."""
def test_loss_making_morning_and_vt_slot_avoid_export_and_grid_charge(self) -> None:
from test_planning_charge_slot_selection import (
_battery as mask_battery,
_select_charge_slots,
_select_discharge_export_slots,
)
base = datetime(2026, 5, 21, 8, 0, tzinfo=timezone.utc)
raw: list[tuple[float, float, int, int]] = [
(1.55, 0.01, 6_000, 2_000),
(1.55, 0.01, 6_500, 2_000),
(1.49, -0.04, 0, 3_500),
(0.86, 0.01, 0, 3_500),
(0.86, 0.01, 0, 3_500),
(0.86, 0.01, 5_000, 2_000),
]
slots: list[PlanningSlot] = []
for i, (buy, sell, pv, load) in enumerate(raw):
slots.append(
PlanningSlot(
interval_start=base + timedelta(minutes=15 * i),
buy_price=buy,
sell_price=sell,
pv_a_forecast_w=0,
pv_b_forecast_w=pv,
load_baseline_w=load,
ev1_connected=False,
ev2_connected=False,
is_predicted_price=False,
)
)
mb = mask_battery(uc_wh=64_000.0)
soc0 = 0.31 * mb.usable_capacity_wh
charge = _select_charge_slots(slots, mb, soc0)
discharge = _select_discharge_export_slots(slots, mb, soc0)
for t, s in enumerate(slots):
s.allow_charge = t in charge
s.allow_discharge_export = t in discharge
battery = _battery(uc_wh=64_000.0, terminal_soc_value_factor=0.9)
hp = SimpleNamespace(rated_heating_power_w=0, tuv_min_temp_c=45.0, tuv_target_temp_c=55.0)
grid = SimpleNamespace(max_import_power_w=20_000, max_export_power_w=20_000)
vehicles = [
SimpleNamespace(max_charge_power_w=0, battery_capacity_kwh=1.0, default_target_soc_pct=80.0),
SimpleNamespace(max_charge_power_w=0, battery_capacity_kwh=1.0, default_target_soc_pct=80.0),
]
results, _ms, _ = solve_dispatch(
slots,
battery,
hp,
grid,
[None, None],
vehicles,
soc0,
50.0,
operating_mode="AUTO",
)
self.assertEqual(len(results), len(slots))
morning = results[0]
vt_before_nt = results[2]
self.assertLessEqual(morning.grid_setpoint_w, slots[0].load_baseline_w + 500)
self.assertNotEqual(morning.export_mode, "PV_SURPLUS")
self.assertLessEqual(vt_before_nt.grid_setpoint_w, 4_000)
self.assertLessEqual(vt_before_nt.battery_setpoint_w, 2_000)
if __name__ == "__main__":
unittest.main()