diff --git a/backend/services/planning_engine.py b/backend/services/planning_engine.py index 54b997f..fecf53e 100644 --- a/backend/services/planning_engine.py +++ b/backend/services/planning_engine.py @@ -613,10 +613,12 @@ def solve_dispatch( + heat_pump.rated_heating_power_w ) - # Záporný prodej (sell < 0): nevybíjet baterii do sítě pro arbitráž. - # Export v tomto okně může vzniknout jen z přebytku FVE (pv_a/pv_b), ne z bd. + # Záporný prodej (sell < 0): baterii v tomhle okně nevybíjíme (dump má proběhnout předtím). + # Export v okně sell<0 může vzniknout jen z přebytku FVE (pv_a/pv_b). Výjimka: EV-via-battery + # (pokud by bylo připojené a požadovalo výkon) – to kryjeme přes bd >= ev_via_bat. if s.sell_price < 0: prob += w_arb[t] == 0 + prob += bd[t] <= pulp.lpSum(ev_via_bat[e][t] for e in range(EV)) soc_prev_expr = current_soc_wh if t == 0 else soc[t - 1] arb_t = arb_floor_series[t] diff --git a/backend/tests/test_planning_dispatch_milp.py b/backend/tests/test_planning_dispatch_milp.py index 3a718c1..6bbcc59 100644 --- a/backend/tests/test_planning_dispatch_milp.py +++ b/backend/tests/test_planning_dispatch_milp.py @@ -516,6 +516,8 @@ class PlanningDispatchMilpTests(unittest.TestCase): self.assertEqual(len(results), 3) # V sell<0 slotu bez FVE a bez zátěže nesmí být export (to by muselo být z baterie). self.assertGreaterEqual(results[1].grid_setpoint_w, 0) + # A zároveň nesmí být baterie ve výboji (dump musí proběhnout předtím). + self.assertGreaterEqual(results[1].battery_setpoint_w, 0) def test_grid_import_soft_cap_penalizes_breaker_overdraw(self) -> None: """