Skip to content

Commit e2f4722

Browse files
committed
Use strong types for handling states
1 parent fb2799d commit e2f4722

1 file changed

Lines changed: 51 additions & 15 deletions

File tree

src/frequenz/client/reporting/_types.py

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,36 @@
44
"""Types for the Reporting API client."""
55

66
import math
7-
from collections.abc import Iterable, Iterator, MutableSequence
7+
from collections.abc import Iterator, MutableSequence
88
from dataclasses import dataclass
99
from datetime import datetime
10-
from typing import Callable, Generic, NamedTuple, Protocol, TypeVar
10+
from typing import Any, Callable, Generic, NamedTuple, Protocol, TypeVar, cast
1111

1212
# pylint: disable=no-name-in-module
1313
from frequenz.api.common.v1alpha8.metrics.metrics_pb2 import (
1414
MetricSample as PbMetricSample,
1515
)
16+
from frequenz.api.common.v1alpha8.microgrid.electrical_components.electrical_components_pb2 import (
17+
ElectricalComponentDiagnostic as PbElectricalComponentDiagnostic,
18+
)
19+
from frequenz.api.common.v1alpha8.microgrid.electrical_components.electrical_components_pb2 import (
20+
ElectricalComponentStateCode as PbElectricalComponentStateCode,
21+
)
22+
from frequenz.api.common.v1alpha8.microgrid.electrical_components.electrical_components_pb2 import (
23+
ElectricalComponentStateSnapshot as PbElectricalComponentStateSnapshot,
24+
)
1625
from frequenz.api.common.v1alpha8.microgrid.electrical_components.electrical_components_pb2 import (
1726
ElectricalComponentTelemetry as PbElectricalComponentTelemetry,
1827
)
28+
from frequenz.api.common.v1alpha8.microgrid.sensors.sensors_pb2 import (
29+
SensorDiagnostic as PbSensorDiagnostic,
30+
)
31+
from frequenz.api.common.v1alpha8.microgrid.sensors.sensors_pb2 import (
32+
SensorStateCode as PbSensorStateCode,
33+
)
34+
from frequenz.api.common.v1alpha8.microgrid.sensors.sensors_pb2 import (
35+
SensorStateSnapshot as PbSensorStateSnapshot,
36+
)
1937
from frequenz.api.common.v1alpha8.microgrid.sensors.sensors_pb2 import (
2038
SensorTelemetry as PbSensorTelemetry,
2139
)
@@ -46,7 +64,13 @@ class MetricSample(NamedTuple):
4664
microgrid_id: int
4765
component_id: int | str
4866
metric: str
49-
value: float
67+
value: (
68+
float
69+
| PbElectricalComponentStateCode.ValueType
70+
| PbSensorStateCode.ValueType
71+
| PbElectricalComponentDiagnostic
72+
| PbSensorDiagnostic
73+
)
5074

5175

5276
class _PbMgTelem(Protocol):
@@ -64,13 +88,20 @@ class _PbTelem(Protocol):
6488
def metric_samples(self) -> MutableSequence[PbMetricSample]:
6589
"""Return the metric samples of the telemetry item."""
6690

91+
@property
92+
def state_snapshots(self) -> MutableSequence[Any]:
93+
"""List of state snapshots associated with this telemetry item."""
94+
6795

6896
_MgTelemT = TypeVar("_MgTelemT", bound=_PbMgTelem)
6997
_TelemT = TypeVar("_TelemT", bound=_PbTelem)
98+
_StateSnapshotT = TypeVar(
99+
"_StateSnapshotT", bound=PbElectricalComponentStateSnapshot | PbSensorStateSnapshot
100+
)
70101

71102

72103
@dataclass(frozen=True)
73-
class GenericDataBatch(Generic[_MgTelemT, _TelemT]):
104+
class GenericDataBatch(Generic[_MgTelemT, _TelemT, _StateSnapshotT]):
74105
"""Base class for batches of microgrid data (components or sensors).
75106
76107
This class serves as a base for handling batches of data related to microgrid
@@ -94,9 +125,9 @@ def is_empty(self) -> bool:
94125
if not items:
95126
return True
96127
for item in items:
97-
if not item.metric_samples and not getattr(item, "states", []):
98-
return True
99-
return False
128+
if item.metric_samples or item.state_snapshots:
129+
return False
130+
return True
100131

101132
# pylint: disable=too-many-locals
102133
# pylint: disable=too-many-branches
@@ -155,23 +186,24 @@ def __iter__(self) -> Iterator[MetricSample]:
155186
ts, mid, cid, f"{met}_bound_{i}_upper", upper
156187
)
157188

158-
for state in getattr(item, "state_snapshots", []):
189+
for state in item.state_snapshots:
190+
state = cast(_StateSnapshotT, state)
159191
ts = datetime_from_proto(state.origin_time)
160192
for category, category_items in {
161-
"state": getattr(state, "states", []),
162-
"warning": getattr(state, "warnings", []),
163-
"error": getattr(state, "errors", []),
193+
"state": state.states,
194+
"warning": state.warnings,
195+
"error": state.errors,
164196
}.items():
165-
if not isinstance(category_items, Iterable):
166-
continue
167197
for s in category_items:
168198
yield MetricSample(ts, mid, cid, category, s)
169199

170200

171201
@dataclass(frozen=True)
172202
class ComponentsDataBatch(
173203
GenericDataBatch[
174-
PBReceiveMicrogridComponentsDataStreamResponse, PbElectricalComponentTelemetry
204+
PBReceiveMicrogridComponentsDataStreamResponse,
205+
PbElectricalComponentTelemetry,
206+
PbElectricalComponentStateSnapshot,
175207
]
176208
):
177209
"""Batch of microgrid components data."""
@@ -192,7 +224,11 @@ def __init__(self, data_pb: PBReceiveMicrogridComponentsDataStreamResponse):
192224

193225
@dataclass(frozen=True)
194226
class SensorsDataBatch(
195-
GenericDataBatch[PBReceiveMicrogridSensorsDataStreamResponse, PbSensorTelemetry]
227+
GenericDataBatch[
228+
PBReceiveMicrogridSensorsDataStreamResponse,
229+
PbSensorTelemetry,
230+
PbSensorStateSnapshot,
231+
]
196232
):
197233
"""Batch of microgrid sensors data."""
198234

0 commit comments

Comments
 (0)