Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion RELEASE_NOTES.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

## Upgrading

<!-- Here goes notes on how to upgrade from previous versions, including deprecations and what they should be replaced with -->
- The minimum required version of `frequenz-microgrid-component-graph` is now `0.3.4`.

## New Features

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ dependencies = [
# changing the version
# (plugins.mkdocstrings.handlers.python.import)
"frequenz-client-microgrid >= 0.18.1, < 0.19.0",
"frequenz-microgrid-component-graph >= 0.3.2, < 0.4",
"frequenz-microgrid-component-graph >= 0.3.4, < 0.4",
"frequenz-client-common >= 0.3.6, < 0.4.0",
"frequenz-channels >= 1.6.1, < 2.0.0",
"frequenz-quantities[marshmallow] >= 1.0.0, < 2.0.0",
Expand Down
174 changes: 2 additions & 172 deletions tests/timeseries/_battery_pool/test_battery_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,7 @@
import time_machine
from frequenz.channels import Receiver, Sender
from frequenz.client.common.microgrid.components import ComponentId
from frequenz.client.microgrid.component import (
Battery,
Component,
ComponentCategory,
InverterType,
)
from frequenz.microgrid_component_graph import (
FormulaGenerationError,
InvalidGraphError,
)
from frequenz.client.microgrid.component import Battery, Component
from frequenz.quantities import Energy, Percentage, Power, Temperature
from pytest_mock import MockerFixture

Expand All @@ -46,7 +37,6 @@
from frequenz.sdk.timeseries import Bounds, ResamplerConfig2, Sample
from frequenz.sdk.timeseries._base_types import SystemBounds
from frequenz.sdk.timeseries.battery_pool import BatteryPool
from tests.utils.graph_generator import GraphGenerator

from ...timeseries.mock_microgrid import MockMicrogrid
from ...utils.component_data_streamer import MockComponentDataStreamer
Expand Down Expand Up @@ -503,10 +493,6 @@ async def run_test_battery_status_channel(
compare_messages(msg, all_pool_result)


@pytest.mark.skip(
reason="Needs to be adapted to the new component graph behavior, see "
"https://github.com/frequenz-floss/frequenz-sdk-python/issues/1345"
)
async def test_battery_pool_power(mocker: MockerFixture) -> None:
"""Test `BatteryPool.power` method."""
mockgrid = MockMicrogrid(grid_meter=True, mocker=mocker)
Expand All @@ -518,165 +504,9 @@ async def test_battery_pool_power(mocker: MockerFixture) -> None:
power_receiver = battery_pool.power.new_receiver()

# send meter power [grid_meter, battery1_meter, battery2_meter]
await mockgrid.mock_resampler.send_meter_power([100.0, 2.0, 3.0])
await mockgrid.mock_resampler.send_bat_inverter_power([20.0, 30.0])
await mockgrid.mock_resampler.send_meter_power([100.0, 20.0, 30.0])
assert (await power_receiver.receive()).value == Power.from_watts(50.0)

await mockgrid.mock_resampler.send_meter_power([100.0, -2.0, -5.0])
await mockgrid.mock_resampler.send_bat_inverter_power([-20.0, -50.0])
assert (await power_receiver.receive()).value == Power.from_watts(-70.0)

await mockgrid.mock_resampler.send_meter_power([100.0, 2.0, -5.0])
await mockgrid.mock_resampler.send_bat_inverter_power([20.0, -50.0])
assert (await power_receiver.receive()).value == Power.from_watts(-30.0)


@pytest.mark.skip(
reason="Needs to be adapted to the new component graph behavior, see "
"https://github.com/frequenz-floss/frequenz-sdk-python/issues/1345"
)
async def test_battery_pool_power_two_inverters_per_battery(
mocker: MockerFixture,
) -> None:
"""Test power method with two inverters per battery."""
gen = GraphGenerator()
bat = gen.component(ComponentCategory.BATTERY)
mockgrid = MockMicrogrid(
graph=gen.to_graph(
(ComponentCategory.METER, gen.battery_with_inverter(bat, 2))
),
mocker=mocker,
)
async with mockgrid, AsyncExitStack() as stack:
battery_pool = microgrid.new_battery_pool(priority=5)
stack.push_async_callback(battery_pool.stop)
power_receiver = battery_pool.power.new_receiver()

# send meter power [grid_meter, battery1_meter]
# Fallback formula - use only meter power, inverter and batteries are not used.
await mockgrid.mock_resampler.send_meter_power([100.0, 2.0])
await mockgrid.mock_resampler.send_bat_inverter_power([20.0, 30.0])
assert (await power_receiver.receive()).value == Power.from_watts(50.0)

await mockgrid.mock_resampler.send_meter_power([100.0, -5.0])
await mockgrid.mock_resampler.send_bat_inverter_power([-20.0, -50.0])
assert (await power_receiver.receive()).value == Power.from_watts(-70.0)

await mockgrid.mock_resampler.send_meter_power([100.0, -5.0])
await mockgrid.mock_resampler.send_bat_inverter_power([20.0, -50.0])
assert (await power_receiver.receive()).value == Power.from_watts(-30.0)


@pytest.mark.skip(
reason="Needs to be adapted to the new component graph behavior, see "
"https://github.com/frequenz-floss/frequenz-sdk-python/issues/1345"
)
async def test_batter_pool_power_two_batteries_per_inverter(
mocker: MockerFixture,
) -> None:
"""Test power method with two batteries per inverter."""
gen = GraphGenerator()
mockgrid = MockMicrogrid(
graph=gen.to_graph(
[
(
ComponentCategory.METER,
(
ComponentCategory.INVERTER,
[ComponentCategory.BATTERY, ComponentCategory.BATTERY],
),
),
(
ComponentCategory.METER,
(
ComponentCategory.INVERTER,
[ComponentCategory.BATTERY, ComponentCategory.BATTERY],
),
),
]
),
mocker=mocker,
)

async with mockgrid, AsyncExitStack() as stack:
battery_pool = microgrid.new_battery_pool(priority=5)
stack.push_async_callback(battery_pool.stop)
power_receiver = battery_pool.power.new_receiver()

# send meter power [battery1_meter, battery2_meter]
# Fallback formula - use only meter power, inverter and batteries are not used.
await mockgrid.mock_resampler.send_meter_power([100.0, 3.0])
await mockgrid.mock_resampler.send_bat_inverter_power([20.0, 30.0])
assert (await power_receiver.receive()).value == Power.from_watts(50.0)

await mockgrid.mock_resampler.send_meter_power([100.0, -5.0])
await mockgrid.mock_resampler.send_bat_inverter_power([-20.0, -50.0])
assert (await power_receiver.receive()).value == Power.from_watts(-70.0)

await mockgrid.mock_resampler.send_meter_power([3.0, -5.0])
await mockgrid.mock_resampler.send_bat_inverter_power([20.0, -50.0])
assert (await power_receiver.receive()).value == Power.from_watts(-30.0)


async def test_batter_pool_power_no_batteries(mocker: MockerFixture) -> None:
"""Test power method with no batteries."""
graph_gen = GraphGenerator()
mockgrid = MockMicrogrid(
graph=graph_gen.to_graph(
(
ComponentCategory.METER,
[
graph_gen.component(ComponentCategory.INVERTER, InverterType.SOLAR),
graph_gen.component(ComponentCategory.INVERTER, InverterType.SOLAR),
],
)
)
)
await mockgrid.start(mocker)
battery_pool = microgrid.new_battery_pool(priority=5)
power_receiver = battery_pool.power.new_receiver()

await mockgrid.mock_resampler.send_non_existing_component_value()
assert (await power_receiver.receive()).value == Power.from_watts(0)


async def test_battery_pool_power_with_no_inverters(mocker: MockerFixture) -> None:
"""Test power method with no inverters."""
with pytest.raises(InvalidGraphError):
mockgrid = MockMicrogrid(
graph=GraphGenerator().to_graph(
(ComponentCategory.METER, ComponentCategory.BATTERY)
)
)
await mockgrid.start(mocker)


async def test_battery_pool_power_incomplete_bat_request(mocker: MockerFixture) -> None:
"""Test power method when not all requested ids are behind the same inverter."""
gen = GraphGenerator()
bats = gen.components(
ComponentCategory.BATTERY, ComponentCategory.BATTERY, ComponentCategory.BATTERY
)

mockgrid = MockMicrogrid(
graph=gen.to_graph(
(
ComponentCategory.METER,
gen.batteries_with_inverter(bats, 2),
)
)
)
await mockgrid.start(mocker)

with pytest.raises(FormulaGenerationError):
# Request only two of the three batteries behind the inverters
battery_pool = microgrid.new_battery_pool(
priority=5, component_ids=set([bats[1].id, bats[0].id])
)
power_receiver = battery_pool.power.new_receiver()
await mockgrid.mock_resampler.send_bat_inverter_power([2.0])
assert (await power_receiver.receive()).value == Power.from_watts(2.0)


async def run_capacity_test( # pylint: disable=too-many-locals
fake_time: time_machine.Coordinates, setup_args: SetupArgs
Expand Down
12 changes: 1 addition & 11 deletions tests/timeseries/_ev_charger_pool/test_ev_charger_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
"""Tests for the `EVChargerPool`."""


import pytest
from frequenz.quantities import Power
from pytest_mock import MockerFixture

Expand All @@ -15,10 +14,6 @@
class TestEVChargerPool:
"""Tests for the `EVChargerPool`."""

@pytest.mark.skip(
reason="Needs to be adapted to the new component graph behavior, see "
"https://github.com/frequenz-floss/frequenz-sdk-python/issues/1345"
)
async def test_ev_power( # pylint: disable=too-many-locals
self,
mocker: MockerFixture,
Expand All @@ -31,10 +26,5 @@ async def test_ev_power( # pylint: disable=too-many-locals
ev_pool = microgrid.new_ev_charger_pool(priority=5)
power_receiver = ev_pool.power.new_receiver()

await mockgrid.mock_resampler.send_meter_power([None])
await mockgrid.mock_resampler.send_evc_power([2.0, 4.0, 10.0])
await mockgrid.mock_resampler.send_meter_power([16.0])
assert (await power_receiver.receive()).value == Power.from_watts(16.0)

await mockgrid.mock_resampler.send_meter_power([None])
await mockgrid.mock_resampler.send_evc_power([2.0, 4.0, -10.0])
assert (await power_receiver.receive()).value == Power.from_watts(-4.0)
8 changes: 2 additions & 6 deletions tests/timeseries/_formulas/test_formula_composition.py
Original file line number Diff line number Diff line change
Expand Up @@ -206,10 +206,6 @@ async def test_formula_composition_missing_bat(self, mocker: MockerFixture) -> N

assert count == 10

@pytest.mark.skip(
reason="Needs to be adapted to the new component graph behavior, see "
"https://github.com/frequenz-floss/frequenz-sdk-python/issues/1345"
)
async def test_formula_composition_min_max(self, mocker: MockerFixture) -> None:
"""Test the composition of formulas with the min and max."""
mockgrid = MockMicrogrid(grid_meter=True, mocker=mocker, num_namespaces=2)
Expand Down Expand Up @@ -237,13 +233,13 @@ async def test_formula_composition_min_max(self, mocker: MockerFixture) -> None:
assert (
str(formula_min)
== "[grid_power_min]("
+ "MIN([grid_power](COALESCE(#4, #7)), [chp_power](COALESCE(#5, #7, 0.0)))"
+ "MIN([grid_power](#4), [chp_power](COALESCE(#7, #5, 0.0)))"
+ ")"
)
assert (
str(formula_max)
== "[grid_power_max]("
+ "MAX([grid_power](COALESCE(#4, #7)), [chp_power](COALESCE(#5, #7, 0.0)))"
+ "MAX([grid_power](#4), [chp_power](COALESCE(#7, #5, 0.0)))"
+ ")"
)

Expand Down
34 changes: 1 addition & 33 deletions tests/timeseries/test_logical_meter.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

from contextlib import AsyncExitStack

import pytest
from frequenz.quantities import Power
from pytest_mock import MockerFixture

Expand Down Expand Up @@ -41,10 +40,6 @@ async def test_chp_power(self, mocker: MockerFixture) -> None:
await mockgrid.mock_resampler.send_chp_power([-12.0])
assert (await chp_power_receiver.receive()).value == Power.from_watts(-12.0)

@pytest.mark.skip(
reason="Needs to be adapted to the new component graph behavior, see "
"https://github.com/frequenz-floss/frequenz-sdk-python/issues/1345"
)
async def test_pv_power(self, mocker: MockerFixture) -> None:
"""Test the pv power formula."""
mockgrid = MockMicrogrid(grid_meter=False, mocker=mocker)
Expand All @@ -55,32 +50,5 @@ async def test_pv_power(self, mocker: MockerFixture) -> None:
stack.push_async_callback(pv_pool.stop)
pv_power_receiver = pv_pool.power.new_receiver()

await mockgrid.mock_resampler.send_meter_power([-1.0, -2.0])
await mockgrid.mock_resampler.send_pv_inverter_power([-10.0, -20.0])
await mockgrid.mock_resampler.send_meter_power([-10.0, -20.0])
assert (await pv_power_receiver.receive()).value == Power.from_watts(-30.0)

async def test_pv_power_no_meter(self, mocker: MockerFixture) -> None:
"""Test the pv power formula."""
mockgrid = MockMicrogrid(grid_meter=False, mocker=mocker)
mockgrid.add_solar_inverters(2, no_meter=True)

async with mockgrid, AsyncExitStack() as stack:
pv_pool = microgrid.new_pv_pool(priority=5)
stack.push_async_callback(pv_pool.stop)
pv_power_receiver = pv_pool.power.new_receiver()

await mockgrid.mock_resampler.send_pv_inverter_power([-1.0, -2.0])
assert (await pv_power_receiver.receive()).value == Power.from_watts(-3.0)

async def test_pv_power_no_pv_components(self, mocker: MockerFixture) -> None:
"""Test the pv power formula without having any pv components."""
async with (
MockMicrogrid(grid_meter=True, mocker=mocker) as mockgrid,
AsyncExitStack() as stack,
):
pv_pool = microgrid.new_pv_pool(priority=5)
stack.push_async_callback(pv_pool.stop)
pv_power_receiver = pv_pool.power.new_receiver()

await mockgrid.mock_resampler.send_non_existing_component_value()
assert (await pv_power_receiver.receive()).value == Power.zero()