|
10 | 10 | from frequenz.client.common.microgrid.components import ComponentId |
11 | 11 | from frequenz.client.microgrid.component import ( |
12 | 12 | Component, |
13 | | - ComponentCategory, |
14 | 13 | ComponentConnection, |
15 | 14 | GridConnectionPoint, |
16 | 15 | Meter, |
|
21 | 20 |
|
22 | 21 | from frequenz.sdk import microgrid |
23 | 22 | from frequenz.sdk.timeseries import Fuse |
24 | | -from tests.utils.graph_generator import GraphGenerator |
25 | 23 |
|
26 | 24 | from ..timeseries._formulas.utils import equal_float_lists, get_resampled_stream |
27 | 25 | from ..timeseries.mock_microgrid import MockMicrogrid |
@@ -371,158 +369,3 @@ async def test_consumer_power_2_grid_meters(mocker: MockerFixture) -> None: |
371 | 369 |
|
372 | 370 | await mockgrid.mock_resampler.send_meter_power([1.0, 2.0]) |
373 | 371 | assert (await grid_recv.receive()).value == Power.from_watts(3.0) |
374 | | - |
375 | | - |
376 | | -async def test_grid_fallback_formula_without_grid_meter(mocker: MockerFixture) -> None: |
377 | | - """Test the grid power formula without a grid meter.""" |
378 | | - gen = GraphGenerator() |
379 | | - mockgrid = MockMicrogrid( |
380 | | - graph=gen.to_graph( |
381 | | - ( |
382 | | - [ |
383 | | - ComponentCategory.METER, # Consumer meter |
384 | | - ( |
385 | | - ComponentCategory.METER, # meter with 2 inverters |
386 | | - [ |
387 | | - ( |
388 | | - ComponentCategory.INVERTER, |
389 | | - [ComponentCategory.BATTERY], |
390 | | - ), |
391 | | - ( |
392 | | - ComponentCategory.INVERTER, |
393 | | - [ComponentCategory.BATTERY, ComponentCategory.BATTERY], |
394 | | - ), |
395 | | - ], |
396 | | - ), |
397 | | - (ComponentCategory.INVERTER, ComponentCategory.BATTERY), |
398 | | - ] |
399 | | - ) |
400 | | - ), |
401 | | - mocker=mocker, |
402 | | - ) |
403 | | - |
404 | | - async with mockgrid, AsyncExitStack() as stack: |
405 | | - grid = microgrid.grid() |
406 | | - stack.push_async_callback(grid.stop) |
407 | | - consumer_power_receiver = grid.power.new_receiver() |
408 | | - |
409 | | - # Note: GridPowerFormula has a "nones-are-zero" rule, that says: |
410 | | - # * if the meter value is None, it should be treated as None. |
411 | | - # * for other components None is treated as 0. |
412 | | - |
413 | | - # fmt: off |
414 | | - expected_input_output: list[ |
415 | | - tuple[list[float | None], list[float | None], Power | None] |
416 | | - ] = [ |
417 | | - # ([consumer_meter, bat1_meter], [bat1_1_inv, bat1_2_inv, bat2_inv], expected_power) |
418 | | - ([100, -200], [-300, -300, 50], Power.from_watts(-50)), |
419 | | - ([500, 100], [100, 1000, -200,], Power.from_watts(400)), |
420 | | - # Consumer meter is invalid - consumer meter has no fallback. |
421 | | - # Formula should return None as defined in nones-are-zero rule. |
422 | | - ([None, 100], [100, 1000, -200,], None), |
423 | | - ([None, -50], [100, 100, -200,], None), |
424 | | - ([500, 100], [100, 50, -200,], Power.from_watts(400)), |
425 | | - # bat1_inv is invalid. |
426 | | - # Return None and subscribe for fallback devices. |
427 | | - # Next call should return formula result with pv_inv value. |
428 | | - ([500, None], [100, 1000, -200,], None), |
429 | | - ([500, None], [100, -1000, -200,], Power.from_watts(-600)), |
430 | | - ([500, None], [-100, 200, 50], Power.from_watts(650)), |
431 | | - # Second Battery inverter is invalid. This component has no fallback. |
432 | | - # return 0 instead of None as defined in nones-are-zero rule. |
433 | | - ([2000, None], [-200, 1000, None], Power.from_watts(2800)), |
434 | | - ([2000, 1000], [-200, 1000, None], Power.from_watts(3000)), |
435 | | - # battery start working |
436 | | - ([2000, 10], [-200, 1000, 100], Power.from_watts(2110)), |
437 | | - # No primary value, start fallback formula |
438 | | - ([2000, None], [-200, 1000, 100], None), |
439 | | - ([2000, None], [-200, 1000, 100], Power.from_watts(2900)), |
440 | | - ] |
441 | | - # fmt: on |
442 | | - |
443 | | - for idx, ( |
444 | | - meter_power, |
445 | | - bat_inv_power, |
446 | | - expected_power, |
447 | | - ) in enumerate(expected_input_output): |
448 | | - await mockgrid.mock_resampler.send_meter_power(meter_power) |
449 | | - await mockgrid.mock_resampler.send_bat_inverter_power(bat_inv_power) |
450 | | - mockgrid.mock_resampler.next_ts() |
451 | | - |
452 | | - result = await consumer_power_receiver.receive() |
453 | | - assert result.value == expected_power, ( |
454 | | - f"Test case {idx} failed:" |
455 | | - + f" meter_power: {meter_power}" |
456 | | - + f" bat_inverter_power {bat_inv_power}" |
457 | | - + f" expected_power: {expected_power}" |
458 | | - + f" actual_power: {result.value}" |
459 | | - ) |
460 | | - |
461 | | - |
462 | | -async def test_grid_fallback_formula_with_grid_meter(mocker: MockerFixture) -> None: |
463 | | - """Test the grid power formula without a grid meter.""" |
464 | | - gen = GraphGenerator() |
465 | | - mockgrid = MockMicrogrid( |
466 | | - graph=gen.to_graph( |
467 | | - ( |
468 | | - ComponentCategory.METER, # Grid meter |
469 | | - [ |
470 | | - ( |
471 | | - ComponentCategory.METER, # meter with 2 inverters |
472 | | - [ |
473 | | - ( |
474 | | - ComponentCategory.INVERTER, |
475 | | - [ComponentCategory.BATTERY], |
476 | | - ), |
477 | | - ( |
478 | | - ComponentCategory.INVERTER, |
479 | | - [ComponentCategory.BATTERY, ComponentCategory.BATTERY], |
480 | | - ), |
481 | | - ], |
482 | | - ), |
483 | | - (ComponentCategory.INVERTER, ComponentCategory.BATTERY), |
484 | | - ], |
485 | | - ) |
486 | | - ), |
487 | | - mocker=mocker, |
488 | | - ) |
489 | | - |
490 | | - async with mockgrid, AsyncExitStack() as stack: |
491 | | - grid = microgrid.grid() |
492 | | - stack.push_async_callback(grid.stop) |
493 | | - consumer_power_receiver = grid.power.new_receiver() |
494 | | - |
495 | | - # Note: GridPowerFormula has a "nones-are-zero" rule, that says: |
496 | | - # * if the meter value is None, it should be treated as None. |
497 | | - # * for other components None is treated as 0. |
498 | | - |
499 | | - # fmt: off |
500 | | - expected_input_output: list[ |
501 | | - tuple[list[float | None], list[float | None], Power | None] |
502 | | - ] = [ |
503 | | - # ([grid_meter, bat1_meter], [bat1_1_inv, bat1_2_inv, bat2_inv], expected_power) |
504 | | - ([100, -200], [-300, -300, 50], Power.from_watts(100)), |
505 | | - ([-100, 100], [100, 1000, -200,], Power.from_watts(-100)), |
506 | | - ([None, 100], [100, 1000, -200,], None), |
507 | | - ([None, -50], [100, 100, -200,], None), |
508 | | - ([500, 100], [100, 50, -200,], Power.from_watts(500)), |
509 | | - ] |
510 | | - # fmt: on |
511 | | - |
512 | | - for idx, ( |
513 | | - meter_power, |
514 | | - bat_inv_power, |
515 | | - expected_power, |
516 | | - ) in enumerate(expected_input_output): |
517 | | - await mockgrid.mock_resampler.send_meter_power(meter_power) |
518 | | - await mockgrid.mock_resampler.send_bat_inverter_power(bat_inv_power) |
519 | | - mockgrid.mock_resampler.next_ts() |
520 | | - |
521 | | - result = await consumer_power_receiver.receive() |
522 | | - assert result.value == expected_power, ( |
523 | | - f"Test case {idx} failed:" |
524 | | - + f" meter_power: {meter_power}" |
525 | | - + f" bat_inverter_power {bat_inv_power}" |
526 | | - + f" expected_power: {expected_power}" |
527 | | - + f" actual_power: {result.value}" |
528 | | - ) |
0 commit comments