|
3 | 3 |
|
4 | 4 | """Test the logical component for calculating high level producer metrics.""" |
5 | 5 |
|
| 6 | +import asyncio |
6 | 7 | from contextlib import AsyncExitStack |
7 | 8 |
|
8 | 9 | from frequenz.quantities import Power |
@@ -114,59 +115,66 @@ async def test_producer_fallback_formula(self, mocker: MockerFixture) -> None: |
114 | 115 |
|
115 | 116 | # fmt: off |
116 | 117 | expected_input_output: list[ |
117 | | - tuple[list[float | None], list[float | None], list[float | None], Power | None] |
| 118 | + tuple[float, list[float | None], list[float | None], list[float | None], Power | None] |
118 | 119 | ] = [ |
119 | | - # ([pv_meter_power], [pv_inverter_power], [chp_power], expected_power) |
| 120 | + # (test number, [pv_meter_power], [pv_inverter_power], [chp_power], expected_power) |
| 121 | + # Case 1: All components are available |
120 | 122 | # Add power from meters and chp |
121 | | - ([-1.0, -2.0], [None, -200.0], [300], Power.from_watts(297.0)), |
122 | | - ([-1.0, -10], [-100.0, -200.0], [400], Power.from_watts(389.0)), |
| 123 | + (1.1, [-1.0, -2.0], [None, -200.0], [300], Power.from_watts(297.0)), |
| 124 | + (1.2, [-1.0, -10], [-100.0, -200.0], [400], Power.from_watts(389.0)), |
123 | 125 | # Case 2: The first meter is unavailable (None). |
124 | 126 | # Subscribe to the fallback inverter, but return None as the result, |
125 | 127 | # according to the "nones-are-zero" rule |
126 | | - ([None, -2.0], [-100, -200.0], [400], None), |
| 128 | + (2.1, [None, -2.0], [-100, -200.0], [400], None), |
127 | 129 | # Case 3: First meter is unavailable (None). Fallback inverter provides |
128 | 130 | # a value. |
129 | 131 | # Add second meter, first inverter and chp power |
130 | | - ([None, -2.0], [-100, -200.0], [400], Power.from_watts(298.0)), |
131 | | - ([None, -2.0], [-50, -200.0], [300], Power.from_watts(248.0)), |
| 132 | + (3.1, [None, -2.0], [-100, -200.0], [400], Power.from_watts(298.0)), |
| 133 | + (3.2, [None, -2.0], [-50, -200.0], [300], Power.from_watts(248.0)), |
132 | 134 | # Case 4: Both first meter and its fallback inverter are unavailable |
133 | 135 | # (None). Return 0 from failing component according to the |
134 | 136 | # "nones-are-zero" rule. |
135 | | - ([None, -2.0], [None, -200.0], [300], Power.from_watts(298.0)), |
136 | | - ([None, -10.0], [-20.0, -200.0], [300], Power.from_watts(270.0)), |
| 137 | + (4.1, [None, -2.0], [None, -200.0], [300], Power.from_watts(298.0)), |
| 138 | + (4.2, [None, -10.0], [-20.0, -200.0], [300], Power.from_watts(270.0)), |
137 | 139 | # Case 5: CHP is unavailable. Return 0 from failing component |
138 | 140 | # according to the "nones-are-zero" rule. |
139 | | - ([None, -10.0], [-20.0, -200.0], [None], Power.from_watts(-30.0)), |
| 141 | + (5.1, [None, -10.0], [-20.0, -200.0], [None], Power.from_watts(-30.0)), |
140 | 142 | # Case 6: Both meters are unavailable (None). Subscribe for fallback inverter |
141 | | - ([None, None], [-20.0, -200.0], [None], None), |
142 | | - ([None, None], [-20.0, -200.0], [None], Power.from_watts(-220.0)), |
143 | | - ([None, None], [None, -200.0], [None], Power.from_watts(-200.0)), |
| 143 | + (6.1, [None, None], [-20.0, -200.0], [None], None), |
| 144 | + (6.2, [None, None], [-20.0, -200.0], [None], Power.from_watts(-220.0)), |
| 145 | + (6.3, [None, None], [None, -200.0], [None], Power.from_watts(-200.0)), |
144 | 146 | # Case 7: All components are unavailable (None). Return 0 according to the |
145 | 147 | # "nones-are-zero" rule. |
146 | | - ([None, None], [None, None], [None], Power.from_watts(0)), |
147 | | - ([None, None], [None, None], [None], Power.from_watts(0)), |
148 | | - ([None, None], [None, None], [300.0], Power.from_watts(300.0)), |
149 | | - ([-200.0, None], [None, -100.0], [50.0], Power.from_watts(-250.0)), |
150 | | - ([-200.0, -200.0], [-10.0, -20.0], [50.0], Power.from_watts(-350.0)), |
| 148 | + (7.1, [None, None], [None, None], [None], Power.from_watts(0)), |
| 149 | + (7.2, [None, None], [None, None], [None], Power.from_watts(0)), |
| 150 | + (7.3, [None, None], [None, None], [300.0], Power.from_watts(300.0)), |
| 151 | + (7.4, [-200.0, None], [None, -100.0], [50.0], Power.from_watts(-250.0)), |
| 152 | + (7.5, [-200.0, -200.0], [-10.0, -20.0], [50.0], Power.from_watts(-350.0)), |
151 | 153 | # Case 8: Meter is unavailable, start fallback formula. |
152 | | - ([None, -200.0], [-10.0, -100.0], [50.0], None), |
153 | | - ([None, -200.0], [-10.0, -100.0], [50.0], Power.from_watts(-160)), |
| 154 | + (8.1, [None, -200.0], [-10.0, -100.0], [50.0], None), |
| 155 | + (8.2, [None, -200.0], [-10.0, -100.0], [50.0], Power.from_watts(-160)), |
154 | 156 |
|
155 | 157 | ] |
156 | 158 | # fmt: on |
157 | 159 |
|
158 | | - for idx, ( |
| 160 | + for ( |
| 161 | + idx, |
159 | 162 | meter_power, |
160 | 163 | pv_inverter_power, |
161 | 164 | chp_power, |
162 | 165 | expected_power, |
163 | | - ) in enumerate(expected_input_output): |
| 166 | + ) in expected_input_output: |
| 167 | + print( |
| 168 | + f"\n----------------------------------------------------\nTEST CASE {idx}" |
| 169 | + ) |
164 | 170 | await mockgrid.mock_resampler.send_chp_power(chp_power) |
165 | 171 | await mockgrid.mock_resampler.send_meter_power(meter_power) |
166 | 172 | await mockgrid.mock_resampler.send_pv_inverter_power(pv_inverter_power) |
167 | 173 | mockgrid.mock_resampler.next_ts() |
| 174 | + await asyncio.sleep(0.1) |
168 | 175 |
|
169 | 176 | result = await producer_power_receiver.receive() |
| 177 | + print(f">>>>> result: {result}") |
170 | 178 | assert result.value == expected_power, ( |
171 | 179 | f"Test case {idx} failed:" |
172 | 180 | + f" meter_power: {meter_power}" |
|
0 commit comments