Skip to content

Commit 8f3fb2e

Browse files
Use fuse in GridMetadata
This commit uses a Fuse object to represent the max current limit in component metadata in the internal layer that parses component objects obtained directly from the Microgrid API. This makes the abstraction of fuses one level deeper, increasing the chances of the `grid_connection.py` file being more stable in the future if/when further changes are introduced in the Microgrid API. Signed-off-by: Tiyash Basu <[email protected]>
1 parent a0b5b70 commit 8f3fb2e

File tree

5 files changed

+38
-14
lines changed

5 files changed

+38
-14
lines changed

src/frequenz/sdk/microgrid/component/_component.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
import frequenz.api.microgrid.grid_pb2 as grid_pb
1313
import frequenz.api.microgrid.inverter_pb2 as inverter_pb
1414

15+
from ...timeseries import Current
16+
from ..fuse import Fuse
17+
1518

1619
class ComponentType(Enum):
1720
"""A base class from which individual component types are derived."""
@@ -110,21 +113,23 @@ def _component_category_from_protobuf(
110113
class ComponentMetadata:
111114
"""Base class for component metadata classes."""
112115

116+
fuse: Fuse | None = None
117+
"""The fuse at the grid connection point."""
118+
113119

114120
@dataclass(frozen=True)
115121
class GridMetadata(ComponentMetadata):
116122
"""Metadata for a grid connection point."""
117123

118-
max_current: float
119-
"""maximum current rating of the grid connection point in amps."""
120-
121124

122125
def _component_metadata_from_protobuf(
123126
component_category: components_pb.ComponentCategory.ValueType,
124127
component_metadata: grid_pb.Metadata,
125128
) -> GridMetadata | None:
126129
if component_category == components_pb.ComponentCategory.COMPONENT_CATEGORY_GRID:
127-
return GridMetadata(float(component_metadata.rated_fuse_current))
130+
max_current = Current.from_amperes(component_metadata.rated_fuse_current)
131+
fuse = Fuse(max_current)
132+
return GridMetadata(fuse)
128133

129134
return None
130135

src/frequenz/sdk/microgrid/grid.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from dataclasses import dataclass
1212
from typing import Iterable, Optional
1313

14-
from ..timeseries import Current
1514
from .component import Component
1615
from .component._component import ComponentCategory
1716
from .fuse import Fuse
@@ -36,7 +35,8 @@ def initialize(components: Iterable[Component]) -> None:
3635
3736
Raises:
3837
RuntimeError: If there is more than 1 grid connection point in the
39-
microgrid.
38+
microgrid, or if the grid connection point is not initialized,
39+
or if the grid connection point does not have a fuse.
4040
"""
4141
global _GRID # pylint: disable=global-statement
4242

@@ -57,8 +57,14 @@ def initialize(components: Iterable[Component]) -> None:
5757
f"Expected at most one grid connection, got {grid_connections_count}"
5858
)
5959
else:
60-
max_current = grid_connections[0].metadata.max_current # type: ignore
61-
fuse = Fuse(Current.from_amperes(max_current))
60+
if grid_connections[0].metadata is None:
61+
raise RuntimeError("Grid metadata is None")
62+
63+
fuse = grid_connections[0].metadata.fuse
64+
65+
if fuse is None:
66+
raise RuntimeError("Grid fuse is None")
67+
6268
_GRID = Grid(fuse)
6369

6470

tests/microgrid/test_client.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
InverterType,
2727
MeterData,
2828
)
29+
from frequenz.sdk.microgrid.fuse import Fuse
2930
from frequenz.sdk.timeseries import Current
3031

3132
from . import mock_api
@@ -125,13 +126,16 @@ async def test_components(self) -> None:
125126
Current.from_amperes(123.0),
126127
)
127128

129+
grid_max_current = Current.from_amperes(123.0)
130+
grid_fuse = Fuse(grid_max_current)
131+
128132
assert set(await microgrid.components()) == {
129133
Component(100, ComponentCategory.NONE),
130134
Component(
131135
101,
132136
ComponentCategory.GRID,
133137
None,
134-
GridMetadata(max_current=123.0),
138+
GridMetadata(fuse=grid_fuse),
135139
),
136140
Component(104, ComponentCategory.METER),
137141
Component(105, ComponentCategory.INVERTER, InverterType.NONE),

tests/microgrid/test_graph.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
GridMetadata,
2525
InverterType,
2626
)
27+
from frequenz.sdk.microgrid.fuse import Fuse
28+
from frequenz.sdk.timeseries import Current
2729

2830
from .mock_api import MockGrpcServer, MockMicrogridServicer
2931

@@ -821,6 +823,9 @@ async def test_refresh_from_api(self) -> None:
821823
servicer.set_connections([(101, 111), (111, 131)])
822824
await graph.refresh_from_api(client)
823825

826+
grid_max_current = Current.zero()
827+
grid_fuse = Fuse(grid_max_current)
828+
824829
# Note: we need to add GriMetadata as a dict here, because that's what
825830
# the ComponentGraph does too, and we need to be able to compare the
826831
# two graphs.
@@ -829,7 +834,7 @@ async def test_refresh_from_api(self) -> None:
829834
101,
830835
ComponentCategory.GRID,
831836
None,
832-
asdict(GridMetadata(max_current=0.0)), # type: ignore
837+
asdict(GridMetadata(fuse=grid_fuse)), # type: ignore
833838
),
834839
Component(111, ComponentCategory.METER),
835840
Component(131, ComponentCategory.EV_CHARGER),
@@ -855,12 +860,13 @@ async def test_refresh_from_api(self) -> None:
855860
)
856861
servicer.set_connections([(707, 717), (717, 727), (727, 737), (717, 747)])
857862
await graph.refresh_from_api(client)
863+
858864
expected = {
859865
Component(
860866
707,
861867
ComponentCategory.GRID,
862868
None,
863-
asdict(GridMetadata(max_current=0.0)), # type: ignore
869+
asdict(GridMetadata(fuse=grid_fuse)), # type: ignore
864870
),
865871
Component(717, ComponentCategory.METER),
866872
Component(727, ComponentCategory.INVERTER, InverterType.NONE),

tests/microgrid/test_grid.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,12 @@ async def test_grid() -> None:
3131

3232
# validate that the microgrid initialization fails when there are multiple
3333
# grid connection points.
34+
fuse_current = Current.from_amperes(123.0)
35+
fuse = Fuse(fuse_current)
36+
3437
components = [
35-
Component(1, ComponentCategory.GRID, None, GridMetadata(123.0)),
36-
Component(2, ComponentCategory.GRID, None, GridMetadata(345.0)),
38+
Component(1, ComponentCategory.GRID, None, GridMetadata(fuse)),
39+
Component(2, ComponentCategory.GRID, None, GridMetadata(fuse)),
3740
Component(3, ComponentCategory.METER),
3841
]
3942

@@ -48,7 +51,7 @@ async def test_grid() -> None:
4851

4952
# validate that microgrids with one grid connection are accepted.
5053
components = [
51-
Component(1, ComponentCategory.GRID, None, GridMetadata(123.0)),
54+
Component(1, ComponentCategory.GRID, None, GridMetadata(fuse)),
5255
Component(2, ComponentCategory.METER),
5356
]
5457

0 commit comments

Comments
 (0)