diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 16eee9c..13a995c 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -6,10 +6,13 @@ This release adds support for retrieving microgrid electrical component connecti ## Upgrading -No migration required. This is a backward-compatible feature addition. +- The `get_microgrid` and `list_microgrid_electrical_components` methods now expect an argument of type `MicrogridId`, instead of an `int`. +- The `PvInverter` type has been renamed to `SolarInverter`, to be compatible with the microgrid api client. ## New Features +- This exposes the abstract `Battery`, `EvCharger` and `Inverter` types. + ### Component Connections API * **New `ComponentConnection` class**: Introduced to represent connections between electrical components in a microgrid @@ -18,4 +21,4 @@ No migration required. This is a backward-compatible feature addition. ## Bug Fixes - \ No newline at end of file + diff --git a/src/frequenz/client/assets/_client.py b/src/frequenz/client/assets/_client.py index f071166..23b39ff 100644 --- a/src/frequenz/client/assets/_client.py +++ b/src/frequenz/client/assets/_client.py @@ -14,6 +14,8 @@ from frequenz.api.assets.v1 import assets_pb2, assets_pb2_grpc from frequenz.client.base import channel from frequenz.client.base.client import BaseApiClient, call_stub_method +from frequenz.client.common.microgrid import MicrogridId +from frequenz.client.common.microgrid.electrical_components import ElectricalComponentId from ._microgrid import Microgrid from ._microgrid_proto import microgrid_from_proto @@ -87,7 +89,7 @@ def stub(self) -> assets_pb2_grpc.PlatformAssetsAsyncStub: return self._stub # type: ignore async def get_microgrid( # noqa: DOC502 (raises ApiClientError indirectly) - self, microgrid_id: int + self, microgrid_id: MicrogridId ) -> Microgrid: """ Get the details of a microgrid. @@ -105,7 +107,7 @@ async def get_microgrid( # noqa: DOC502 (raises ApiClientError indirectly) response = await call_stub_method( self, lambda: self.stub.GetMicrogrid( - assets_pb2.GetMicrogridRequest(microgrid_id=microgrid_id), + assets_pb2.GetMicrogridRequest(microgrid_id=int(microgrid_id)), timeout=DEFAULT_GRPC_CALL_TIMEOUT, ), method_name="GetMicrogrid", @@ -114,7 +116,7 @@ async def get_microgrid( # noqa: DOC502 (raises ApiClientError indirectly) return microgrid_from_proto(response.microgrid) async def list_microgrid_electrical_components( - self, microgrid_id: int + self, microgrid_id: MicrogridId ) -> list[ElectricalComponent]: """ Get the electrical components of a microgrid. @@ -129,7 +131,7 @@ async def list_microgrid_electrical_components( self, lambda: self.stub.ListMicrogridElectricalComponents( assets_pb2.ListMicrogridElectricalComponentsRequest( - microgrid_id=microgrid_id, + microgrid_id=int(microgrid_id), ), timeout=DEFAULT_GRPC_CALL_TIMEOUT, ), @@ -142,9 +144,9 @@ async def list_microgrid_electrical_components( async def list_microgrid_electrical_component_connections( self, - microgrid_id: int, - source_component_ids: Iterable[int] = (), - destination_component_ids: Iterable[int] = (), + microgrid_id: MicrogridId, + source_component_ids: Iterable[ElectricalComponentId] = (), + destination_component_ids: Iterable[ElectricalComponentId] = (), ) -> list[ComponentConnection | None]: """ Get the electrical component connections of a microgrid. @@ -161,9 +163,9 @@ async def list_microgrid_electrical_component_connections( The electrical component connections of the microgrid. """ request = assets_pb2.ListMicrogridElectricalComponentConnectionsRequest( - microgrid_id=microgrid_id, - source_component_ids=source_component_ids, - destination_component_ids=destination_component_ids, + microgrid_id=int(microgrid_id), + source_component_ids=(int(c) for c in source_component_ids), + destination_component_ids=(int(c) for c in destination_component_ids), ) response = await call_stub_method( diff --git a/src/frequenz/client/assets/electrical_component/__init__.py b/src/frequenz/client/assets/electrical_component/__init__.py index 7b30f3c..1fec94f 100644 --- a/src/frequenz/client/assets/electrical_component/__init__.py +++ b/src/frequenz/client/assets/electrical_component/__init__.py @@ -4,6 +4,7 @@ """Electrical component types.""" from ._battery import ( + Battery, BatteryType, LiIonBattery, NaIonBattery, @@ -22,6 +23,7 @@ from ._ev_charger import ( AcEvCharger, DcEvCharger, + EvCharger, EvChargerType, HybridEvCharger, UnrecognizedEvCharger, @@ -32,8 +34,9 @@ from ._inverter import ( BatteryInverter, HybridInverter, + Inverter, InverterType, - PvInverter, + SolarInverter, UnrecognizedInverter, UnspecifiedInverter, ) @@ -53,6 +56,7 @@ __all__ = [ "Chp", "CryptoMiner", + "Battery", "BatteryType", "LiIonBattery", "NaIonBattery", @@ -66,6 +70,7 @@ "Electrolyzer", "AcEvCharger", "DcEvCharger", + "EvCharger", "EvChargerType", "HybridEvCharger", "UnrecognizedEvCharger", @@ -74,8 +79,9 @@ "Hvac", "BatteryInverter", "HybridInverter", + "Inverter", "InverterType", - "PvInverter", + "SolarInverter", "UnrecognizedInverter", "UnspecifiedInverter", "Meter", diff --git a/src/frequenz/client/assets/electrical_component/_connection.py b/src/frequenz/client/assets/electrical_component/_connection.py index 83bdf48..ee94ee5 100644 --- a/src/frequenz/client/assets/electrical_component/_connection.py +++ b/src/frequenz/client/assets/electrical_component/_connection.py @@ -6,7 +6,7 @@ import dataclasses from datetime import datetime, timezone -from frequenz.client.common.microgrid.components import ComponentId +from frequenz.client.common.microgrid.electrical_components import ElectricalComponentId from .._lifetime import Lifetime @@ -38,14 +38,14 @@ class ComponentConnection: when and how the microgrid infrastructure has been modified. """ - source: ComponentId + source: ElectricalComponentId """The unique identifier of the component where the connection originates. This is aligned with the direction of current flow away from the grid connection point, or in case of islands, away from the islanding point. """ - destination: ComponentId + destination: ElectricalComponentId """The unique ID of the component where the connection terminates. This is the component towards which the current flows. diff --git a/src/frequenz/client/assets/electrical_component/_connection_proto.py b/src/frequenz/client/assets/electrical_component/_connection_proto.py index 2f545d5..11c7d61 100644 --- a/src/frequenz/client/assets/electrical_component/_connection_proto.py +++ b/src/frequenz/client/assets/electrical_component/_connection_proto.py @@ -8,7 +8,7 @@ from frequenz.api.common.v1alpha8.microgrid.electrical_components import ( electrical_components_pb2, ) -from frequenz.client.common.microgrid.components import ComponentId +from frequenz.client.common.microgrid.electrical_components import ElectricalComponentId from .._lifetime import Lifetime from .._lifetime_proto import lifetime_from_proto @@ -63,8 +63,10 @@ def component_connection_from_proto_with_issues( `None` if the protobuf message is completely invalid and a `ComponentConnection` cannot be created. """ - source_component_id = ComponentId(message.source_electrical_component_id) - destination_component_id = ComponentId(message.destination_electrical_component_id) + source_component_id = ElectricalComponentId(message.source_electrical_component_id) + destination_component_id = ElectricalComponentId( + message.destination_electrical_component_id + ) if source_component_id == destination_component_id: major_issues.append( f"connection ignored: source and destination are the same ({source_component_id})", diff --git a/src/frequenz/client/assets/electrical_component/_electrical_component_proto.py b/src/frequenz/client/assets/electrical_component/_electrical_component_proto.py index c7468e7..3c5f77d 100644 --- a/src/frequenz/client/assets/electrical_component/_electrical_component_proto.py +++ b/src/frequenz/client/assets/electrical_component/_electrical_component_proto.py @@ -47,7 +47,7 @@ BatteryInverter, HybridInverter, InverterType, - PvInverter, + SolarInverter, UnrecognizedInverter, UnspecifiedInverter, ) @@ -320,12 +320,15 @@ def electrical_component_from_proto_with_issues( inverter_enum_to_class: dict[ InverterType, type[ - UnspecifiedInverter | BatteryInverter | PvInverter | HybridInverter + UnspecifiedInverter + | BatteryInverter + | SolarInverter + | HybridInverter ], ] = { InverterType.UNSPECIFIED: UnspecifiedInverter, InverterType.BATTERY: BatteryInverter, - InverterType.PV: PvInverter, + InverterType.SOLAR: SolarInverter, InverterType.HYBRID: HybridInverter, } inverter_type = enum_proto.enum_from_proto( @@ -335,7 +338,7 @@ def electrical_component_from_proto_with_issues( case ( InverterType.UNSPECIFIED | InverterType.BATTERY - | InverterType.PV + | InverterType.SOLAR | InverterType.HYBRID ): if inverter_type is InverterType.UNSPECIFIED: diff --git a/src/frequenz/client/assets/electrical_component/_inverter.py b/src/frequenz/client/assets/electrical_component/_inverter.py index 3306d0b..0b7e45e 100644 --- a/src/frequenz/client/assets/electrical_component/_inverter.py +++ b/src/frequenz/client/assets/electrical_component/_inverter.py @@ -25,7 +25,7 @@ class InverterType(enum.Enum): BATTERY = electrical_components_pb2.INVERTER_TYPE_BATTERY """The inverter is a battery inverter.""" - PV = electrical_components_pb2.INVERTER_TYPE_PV + SOLAR = electrical_components_pb2.INVERTER_TYPE_PV """The inverter is a solar inverter.""" HYBRID = electrical_components_pb2.INVERTER_TYPE_HYBRID @@ -106,10 +106,10 @@ class BatteryInverter(Inverter): @dataclasses.dataclass(frozen=True, kw_only=True) -class PvInverter(Inverter): - """A PV inverter.""" +class SolarInverter(Inverter): + """A Solar inverter.""" - type: Literal[InverterType.PV] = InverterType.PV + type: Literal[InverterType.SOLAR] = InverterType.SOLAR """The type of this inverter. Note: @@ -150,7 +150,7 @@ class UnrecognizedInverter(Inverter): InverterTypes: TypeAlias = ( UnspecifiedInverter | BatteryInverter - | PvInverter + | SolarInverter | HybridInverter | UnrecognizedInverter ) diff --git a/tests/client_test_cases/list_microgrid_electrical_component_connections/success_case.py b/tests/client_test_cases/list_microgrid_electrical_component_connections/success_case.py index bca3736..45b93bc 100644 --- a/tests/client_test_cases/list_microgrid_electrical_component_connections/success_case.py +++ b/tests/client_test_cases/list_microgrid_electrical_component_connections/success_case.py @@ -12,7 +12,7 @@ electrical_components_pb2, ) from frequenz.client.base.conversion import to_timestamp -from frequenz.client.common.microgrid.components import ComponentId +from frequenz.client.common.microgrid.electrical_components import ElectricalComponentId from frequenz.client.assets import Lifetime from frequenz.client.assets.electrical_component import ComponentConnection @@ -50,12 +50,12 @@ def assert_client_result(actual_result: Any) -> None: """Assert that the client result matches the expected connections list.""" assert list(actual_result) == [ ComponentConnection( - source=ComponentId(1), - destination=ComponentId(2), + source=ElectricalComponentId(1), + destination=ElectricalComponentId(2), ), ComponentConnection( - source=ComponentId(2), - destination=ComponentId(3), + source=ElectricalComponentId(2), + destination=ElectricalComponentId(3), operational_lifetime=Lifetime(start=lifetime_start), ), ]