planner v2 vc. porovnani
This commit is contained in:
@@ -7,8 +7,10 @@ from datetime import datetime, timedelta, timezone
|
||||
from types import SimpleNamespace
|
||||
|
||||
from services.planning_engine import (
|
||||
DispatchResult,
|
||||
PlanningSlot,
|
||||
_dynamic_arb_floor_wh_series,
|
||||
_dispatch_result_comparison,
|
||||
_prewindow_deferral_slots,
|
||||
_slots_until_buy_le_threshold,
|
||||
_slots_until_sell_lt,
|
||||
@@ -205,6 +207,83 @@ def replace_slot(
|
||||
|
||||
|
||||
class PlanningDispatchMilpTests(unittest.TestCase):
|
||||
def test_dispatch_result_comparison_marks_changed_slots(self) -> None:
|
||||
dt = datetime(2026, 4, 3, 12, 0, tzinfo=timezone.utc)
|
||||
active = [
|
||||
DispatchResult(
|
||||
interval_start=dt,
|
||||
battery_setpoint_w=1000,
|
||||
battery_soc_target=50.0,
|
||||
grid_setpoint_w=0,
|
||||
export_limit_w=0,
|
||||
export_mode="NONE",
|
||||
deye_physical_mode="PASSIVE",
|
||||
deye_gen_cutoff_enabled=False,
|
||||
ev1_setpoint_w=None,
|
||||
ev2_setpoint_w=None,
|
||||
ev1_via_bat_w=0,
|
||||
ev2_via_bat_w=0,
|
||||
heat_pump_enabled=False,
|
||||
heat_pump_setpoint_w=0,
|
||||
pv_a_curtailed_w=0,
|
||||
expected_cost_czk=1.0,
|
||||
effective_buy_price=1.0,
|
||||
effective_sell_price=1.0,
|
||||
is_predicted_price=False,
|
||||
)
|
||||
]
|
||||
peer = [
|
||||
DispatchResult(
|
||||
interval_start=dt,
|
||||
battery_setpoint_w=2000,
|
||||
battery_soc_target=55.0,
|
||||
grid_setpoint_w=-1000,
|
||||
export_limit_w=1000,
|
||||
export_mode="PV_SURPLUS",
|
||||
deye_physical_mode="SELL",
|
||||
deye_gen_cutoff_enabled=True,
|
||||
ev1_setpoint_w=None,
|
||||
ev2_setpoint_w=None,
|
||||
ev1_via_bat_w=0,
|
||||
ev2_via_bat_w=0,
|
||||
heat_pump_enabled=False,
|
||||
heat_pump_setpoint_w=0,
|
||||
pv_a_curtailed_w=200,
|
||||
expected_cost_czk=2.0,
|
||||
effective_buy_price=1.0,
|
||||
effective_sell_price=1.0,
|
||||
is_predicted_price=False,
|
||||
)
|
||||
]
|
||||
cmp = _dispatch_result_comparison(active, 10, "v1", peer, 12, "v2")
|
||||
self.assertEqual(cmp["active"]["planner_version"], "v1")
|
||||
self.assertEqual(cmp["peer"]["planner_version"], "v2")
|
||||
self.assertEqual(cmp["diff"]["changed_slots"], 1)
|
||||
self.assertEqual(len(cmp["slot_diffs"]), 1)
|
||||
|
||||
def test_planner_version_is_recorded_in_snapshot(self) -> None:
|
||||
slots = [_slot(load=500, buy=1.0, sell=1.0, pv_a=0, pv_b=0) for _ in range(2)]
|
||||
battery = _battery()
|
||||
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, snap = solve_dispatch(
|
||||
slots,
|
||||
battery,
|
||||
hp,
|
||||
grid,
|
||||
[],
|
||||
vehicles,
|
||||
current_soc_wh=0.5 * battery.usable_capacity_wh,
|
||||
current_tuv_temp_c=50.0,
|
||||
planner_version="v2",
|
||||
)
|
||||
self.assertEqual(len(results), 2)
|
||||
self.assertEqual(snap["inputs"]["planner_version"], "v2")
|
||||
|
||||
def test_neg_sell_with_future_neg_buy_prefers_curtail_pv_a_over_export(self) -> None:
|
||||
"""
|
||||
Když:
|
||||
|
||||
Reference in New Issue
Block a user