Skip to content
Merged
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
89 changes: 89 additions & 0 deletions tests/test_component.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# License: MIT
# Copyright © 2022 Frequenz Energy-as-a-Service GmbH

"""Tests for the microgrid component wrapper."""

import pytest

# pylint: disable=no-name-in-module
from frequenz.api.common.components_pb2 import ComponentCategory

# pylint: enable=no-name-in-module
import frequenz.client.microgrid._component as cp


def test_component_category_from_protobuf() -> None:
"""Test the creating component category from protobuf."""
assert (
cp.component_category_from_protobuf(
ComponentCategory.COMPONENT_CATEGORY_UNSPECIFIED
)
== cp.ComponentCategory.NONE
)

assert (
cp.component_category_from_protobuf(ComponentCategory.COMPONENT_CATEGORY_GRID)
== cp.ComponentCategory.GRID
)

assert (
cp.component_category_from_protobuf(ComponentCategory.COMPONENT_CATEGORY_METER)
== cp.ComponentCategory.METER
)

assert (
cp.component_category_from_protobuf(
ComponentCategory.COMPONENT_CATEGORY_INVERTER
)
== cp.ComponentCategory.INVERTER
)

assert (
cp.component_category_from_protobuf(
ComponentCategory.COMPONENT_CATEGORY_BATTERY
)
== cp.ComponentCategory.BATTERY
)

assert (
cp.component_category_from_protobuf(
ComponentCategory.COMPONENT_CATEGORY_EV_CHARGER
)
== cp.ComponentCategory.EV_CHARGER
)

assert cp.component_category_from_protobuf(666) == cp.ComponentCategory.NONE # type: ignore

with pytest.raises(ValueError):
cp.component_category_from_protobuf(ComponentCategory.COMPONENT_CATEGORY_SENSOR)


# pylint: disable=invalid-name
def test_Component() -> None:
"""Test the component category."""
c0 = cp.Component(0, cp.ComponentCategory.GRID)
assert c0.is_valid()

c1 = cp.Component(1, cp.ComponentCategory.GRID)
assert c1.is_valid()

c4 = cp.Component(4, cp.ComponentCategory.METER)
assert c4.is_valid()

c5 = cp.Component(5, cp.ComponentCategory.INVERTER)
assert c5.is_valid()

c6 = cp.Component(6, cp.ComponentCategory.BATTERY)
assert c6.is_valid()

c7 = cp.Component(7, cp.ComponentCategory.EV_CHARGER)
assert c7.is_valid()

invalid_grid_id = cp.Component(-1, cp.ComponentCategory.GRID)
assert not invalid_grid_id.is_valid()

invalid_type = cp.Component(666, -1) # type: ignore
assert not invalid_type.is_valid()

another_invalid_type = cp.Component(666, 666) # type: ignore
assert not another_invalid_type.is_valid()
92 changes: 92 additions & 0 deletions tests/test_component_data.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# License: MIT
# Copyright © 2022 Frequenz Energy-as-a-Service GmbH

"""Tests for the microgrid component data."""

from datetime import datetime, timezone

import pytest

# pylint: disable=no-name-in-module
from frequenz.api.common.metrics.electrical_pb2 import AC
from frequenz.api.common.metrics_pb2 import Bounds, Metric
from frequenz.api.microgrid.inverter_pb2 import (
COMPONENT_STATE_DISCHARGING,
Data,
Error,
Inverter,
State,
)
from frequenz.api.microgrid.microgrid_pb2 import ComponentData as PbComponentData
from google.protobuf.timestamp_pb2 import Timestamp

# pylint: enable=no-name-in-module
from frequenz.client.microgrid import ComponentData, InverterData


def test_component_data_abstract_class() -> None:
"""Verify the base class ComponentData may not be instantiated."""
with pytest.raises(TypeError):
# pylint: disable=abstract-class-instantiated
ComponentData(0, datetime.now(timezone.utc)) # type: ignore


def test_inverter_data() -> None:
"""Verify the constructor for the InverterData class."""
seconds = 1234567890

raw = PbComponentData(
id=5,
ts=Timestamp(seconds=seconds),
inverter=Inverter(
state=State(component_state=COMPONENT_STATE_DISCHARGING),
errors=[Error(msg="error message")],
data=Data(
dc_battery=None,
dc_solar=None,
temperature=None,
ac=AC(
frequency=Metric(value=50.1),
power_active=Metric(
value=100.2,
system_exclusion_bounds=Bounds(lower=-501.0, upper=501.0),
system_inclusion_bounds=Bounds(lower=-51_000.0, upper=51_000.0),
),
phase_1=AC.ACPhase(
current=Metric(value=12.3),
voltage=Metric(value=229.8),
power_active=Metric(value=33.1),
),
phase_2=AC.ACPhase(
current=Metric(value=23.4),
voltage=Metric(value=230.0),
power_active=Metric(value=33.3),
),
phase_3=AC.ACPhase(
current=Metric(value=34.5),
voltage=Metric(value=230.2),
power_active=Metric(value=33.8),
),
),
),
),
)

inv_data = InverterData.from_proto(raw)
assert inv_data.component_id == 5
assert inv_data.timestamp == datetime.fromtimestamp(seconds, timezone.utc)
assert ( # pylint: disable=protected-access
inv_data._component_state == COMPONENT_STATE_DISCHARGING
)
assert inv_data._errors == [ # pylint: disable=protected-access
Error(msg="error message")
]
assert inv_data.frequency == pytest.approx(50.1)
assert inv_data.active_power == pytest.approx(100.2)
assert inv_data.active_power_per_phase == pytest.approx((33.1, 33.3, 33.8))
assert inv_data.current_per_phase == pytest.approx((12.3, 23.4, 34.5))
assert inv_data.voltage_per_phase == pytest.approx((229.8, 230.0, 230.2))
assert inv_data.active_power_inclusion_lower_bound == pytest.approx(-51_000.0)
assert inv_data.active_power_inclusion_upper_bound == pytest.approx(51_000.0)
assert inv_data.active_power_exclusion_lower_bound == pytest.approx(-501.0)
assert inv_data.active_power_exclusion_upper_bound == pytest.approx(501.0)
28 changes: 28 additions & 0 deletions tests/test_connection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# License: MIT
# Copyright © 2022 Frequenz Energy-as-a-Service GmbH

"""Tests for the microgrid Connection type."""

from frequenz.client.microgrid import Connection


# pylint: disable=invalid-name
def test_Connection() -> None:
"""Test the microgrid Connection type."""
c00 = Connection(0, 0)
assert not c00.is_valid()

c01 = Connection(0, 1)
assert c01.is_valid()

c10 = Connection(1, 0)
assert not c10.is_valid()

c11 = Connection(1, 1)
assert not c11.is_valid()

c12 = Connection(1, 2)
assert c12.is_valid()

c21 = Connection(2, 1)
assert c21.is_valid()
Loading