Skip to content

Commit 70305e5

Browse files
Test pv_power formula with fallback components
Signed-off-by: Elzbieta Kotulska <[email protected]>
1 parent b51945b commit 70305e5

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed

tests/timeseries/mock_resampler.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,10 @@ def power_3_phase_senders(
196196
task.add_done_callback(self._handle_task_done)
197197
self._request_handler_task = task
198198

199+
def next_ts(self) -> None:
200+
"""Increment the timestamp."""
201+
self._next_ts = datetime.now()
202+
199203
def _handle_task_done(self, task: asyncio.Task[None]) -> None:
200204
if task.cancelled():
201205
return

tests/timeseries/test_logical_meter.py

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,69 @@ async def test_pv_power_no_pv_components(self, mocker: MockerFixture) -> None:
7777

7878
await mockgrid.mock_resampler.send_non_existing_component_value()
7979
assert (await pv_power_receiver.receive()).value == Power.zero()
80+
81+
async def test_pv_power_with_failing_meter(self, mocker: MockerFixture) -> None:
82+
"""Test the pv power formula."""
83+
mockgrid = MockMicrogrid(grid_meter=False, mocker=mocker)
84+
mockgrid.add_solar_inverters(2)
85+
86+
async with mockgrid, AsyncExitStack() as stack:
87+
pv_pool = microgrid.new_pv_pool(priority=5)
88+
stack.push_async_callback(pv_pool.stop)
89+
pv_power_receiver = pv_pool.power.new_receiver()
90+
91+
# Note: PvPowerFormula has a "nones-are-zero" rule, that says:
92+
# * if the meter value is None, it should be treated as None.
93+
# * for other components None is treated as 0.
94+
95+
expected_input_output: list[
96+
tuple[list[float | None], list[float | None], Power | None]
97+
] = [
98+
# ([meter_power], [pv_inverter_power], expected_power)
99+
#
100+
# Case 1: Both meters are available, so inverters are not used.
101+
([-1.0, -2.0], [None, -5.0], Power.from_watts(-3.0)),
102+
([-1.0, -2.0], [-10.0, -20.0], Power.from_watts(-3.0)),
103+
# Case 2: The first meter is unavailable (None).
104+
# Subscribe to the fallback inverter, but return None as the result,
105+
# according to the "nones-are-zero" rule
106+
([None, -2.0], [-10.0, -20.0], None),
107+
# Case 3: First meter is unavailable (None). Fallback inverter provides
108+
# a value.
109+
([None, -2.0], [-10.0, -20.0], Power.from_watts(-12.0)),
110+
([None, -2.0], [-11.0, -20.0], Power.from_watts(-13.0)),
111+
# Case 4: Both first meter and its fallback inverter are unavailable
112+
# (None). Return 0 according to the "nones-are-zero" rule.
113+
([None, -2.0], [None, -20.0], Power.from_watts(-2.0)),
114+
([None, -2.0], [-11.0, -20.0], Power.from_watts(-13.0)),
115+
# Case 5: Both meters are unavailable (None).
116+
# Subscribe to the fallback inverter, but return None as the result,
117+
# according "nones-are-zero" rule
118+
([None, None], [-5.0, -20.0], None),
119+
# Case 6: Both meters are unavailable (None). Fallback inverter provides
120+
# a values.
121+
([None, None], [-5.0, -20.0], Power.from_watts(-25.0)),
122+
# Case 7: All components are unavailable (None).
123+
# Return 0 according to the "nones-are-zero" rule.
124+
([None, None], [None, None], Power.from_watts(0.0)),
125+
([None, None], [-5.0, -20.0], Power.from_watts(-25.0)),
126+
# Case 8: Meters becomes available and inverter values are not used.
127+
([-10.0, None], [-5.0, -20.0], Power.from_watts(-30.0)),
128+
([-10.0, -2.0], [-5.0, -20.0], Power.from_watts(-12.0)),
129+
]
130+
131+
for idx, (meter_power, pv_inverter_power, expected_power) in enumerate(
132+
expected_input_output
133+
):
134+
await mockgrid.mock_resampler.send_meter_power(meter_power)
135+
await mockgrid.mock_resampler.send_pv_inverter_power(pv_inverter_power)
136+
mockgrid.mock_resampler.next_ts()
137+
138+
result = await pv_power_receiver.receive()
139+
assert result.value == expected_power, (
140+
f"Test case {idx} failed:"
141+
+ f" meter_power: {meter_power}"
142+
+ f" pv_inverter_power {pv_inverter_power}"
143+
+ f" expected_power: {expected_power}"
144+
+ f" actual_power: {result.value}"
145+
)

0 commit comments

Comments
 (0)