register 340 -omezovani vyrkonu pv pole (home-01)
This commit is contained in:
104
backend/tests/test_control_exporter_reg340.py
Normal file
104
backend/tests/test_control_exporter_reg340.py
Normal file
@@ -0,0 +1,104 @@
|
||||
"""Deye reg 340 (max solar power) z plánu a capu z DB."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
from services.control.exporter_monolith import (
|
||||
OperatingModeInfo,
|
||||
_DictRecord,
|
||||
_build_setpoints,
|
||||
compute_pv_a_reg340_max_solar_w,
|
||||
deye_reg_triggers_self_sustain_after_verify_exhaust,
|
||||
)
|
||||
|
||||
|
||||
def _auto_mode() -> OperatingModeInfo:
|
||||
return OperatingModeInfo(
|
||||
mode_code="AUTO",
|
||||
battery_mode="auto",
|
||||
grid_mode="auto",
|
||||
ev_enabled=True,
|
||||
heat_pump_enabled_def=True,
|
||||
loxone_mode_value=0,
|
||||
)
|
||||
|
||||
|
||||
def _pi_base(**kwargs: object) -> _DictRecord:
|
||||
d: dict[str, object] = {
|
||||
"grid_setpoint_w": 0,
|
||||
"battery_setpoint_w": 0,
|
||||
"battery_soc_target_pct": None,
|
||||
"heat_pump_enabled": False,
|
||||
"effective_sell_price": 1.0,
|
||||
"pv_a_forecast_solver_w": 8000,
|
||||
"pv_a_curtailed_w": 0,
|
||||
}
|
||||
d.update(kwargs)
|
||||
return _DictRecord(d)
|
||||
|
||||
|
||||
class ComputePvAReg340Tests(unittest.TestCase):
|
||||
def test_full_cap_when_no_curtail(self) -> None:
|
||||
self.assertEqual(compute_pv_a_reg340_max_solar_w(10_000, 8000, 0), 10_000)
|
||||
|
||||
def test_curtailed_value(self) -> None:
|
||||
self.assertEqual(compute_pv_a_reg340_max_solar_w(10_000, 8000, 2000), 6000)
|
||||
|
||||
def test_clamped_to_cap_when_forecast_high(self) -> None:
|
||||
self.assertEqual(compute_pv_a_reg340_max_solar_w(10_000, 12_000, 0), 10_000)
|
||||
|
||||
def test_curtail_floor_zero(self) -> None:
|
||||
self.assertEqual(compute_pv_a_reg340_max_solar_w(10_000, 1000, 5000), 0)
|
||||
|
||||
|
||||
class BuildSetpointsReg340Tests(unittest.TestCase):
|
||||
def test_deye_with_cap_sets_pv_a_allowed(self) -> None:
|
||||
sp = _build_setpoints(
|
||||
_auto_mode(),
|
||||
_pi_base(pv_a_forecast_solver_w=8000, pv_a_curtailed_w=2000),
|
||||
pv_a_cap_w=10_000,
|
||||
inverter_manufacturer="Deye",
|
||||
)
|
||||
assert sp is not None
|
||||
self.assertEqual(sp.pv_a_allowed_w, 6000)
|
||||
|
||||
def test_skipped_when_cap_zero(self) -> None:
|
||||
sp = _build_setpoints(
|
||||
_auto_mode(),
|
||||
_pi_base(),
|
||||
pv_a_cap_w=0,
|
||||
inverter_manufacturer="Deye",
|
||||
)
|
||||
assert sp is not None
|
||||
self.assertIsNone(sp.pv_a_allowed_w)
|
||||
|
||||
def test_skipped_for_non_deye(self) -> None:
|
||||
sp = _build_setpoints(
|
||||
_auto_mode(),
|
||||
_pi_base(),
|
||||
pv_a_cap_w=10_000,
|
||||
inverter_manufacturer="Foo",
|
||||
)
|
||||
assert sp is not None
|
||||
self.assertIsNone(sp.pv_a_allowed_w)
|
||||
|
||||
def test_self_sustain_no_pv_a_allowed(self) -> None:
|
||||
mode = OperatingModeInfo(
|
||||
mode_code="SELF_SUSTAIN",
|
||||
battery_mode="x",
|
||||
grid_mode="x",
|
||||
ev_enabled=False,
|
||||
heat_pump_enabled_def=False,
|
||||
loxone_mode_value=0,
|
||||
)
|
||||
sp = _build_setpoints(
|
||||
mode, None, pv_a_cap_w=10_000, inverter_manufacturer="Deye"
|
||||
)
|
||||
assert sp is not None
|
||||
self.assertIsNone(sp.pv_a_allowed_w)
|
||||
|
||||
|
||||
class Reg340VerifyPolicyTests(unittest.TestCase):
|
||||
def test_reg340_not_critical_for_self_sustain(self) -> None:
|
||||
self.assertFalse(deye_reg_triggers_self_sustain_after_verify_exhaust(340))
|
||||
Reference in New Issue
Block a user