Skip to content

Commit 63cd246

Browse files
authored
Add support for bounds in client (frequenz-floss#98)
Bounds can now be requested via the client and are provided through the flat iterator. They can be identified via their category `metric_bound[i]_{upper,lower}`. Each individual bound is provided as its own sample. Support for states and bound is also added to the CLI tool via the `--bounds` flag. Fixes frequenz-floss#20.
2 parents 0c1cdb6 + 7d29e6f commit 63cd246

File tree

3 files changed

+44
-1
lines changed

3 files changed

+44
-1
lines changed

RELEASE_NOTES.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@
1313
* States can now be requested via the client and are provided through the flat iterator.
1414
They can be identified via their category `state`, `warning` and `error`, respectively.
1515
Each individual state is provided as its own sample.
16+
* Bounds can now be requested via the client and are provided through the flat iterator.
17+
They can be identified via their category `metric_bound[i]_{upper,lower}`.
18+
Each individual bound is provided as its own sample.
1619

17-
* Support for states is also added to the CLI tool via the `--states` flag.
20+
* Support for states and bound is also added to the CLI tool via the `--states` and `--bounds` flag, respectively.
1821

1922
## Bug Fixes
2023

src/frequenz/client/reporting/__main__.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ def main() -> None:
3939
action="store_true",
4040
help="Include states in the output",
4141
)
42+
parser.add_argument(
43+
"--bounds",
44+
action="store_true",
45+
help="Include bounds in the output",
46+
)
4247
parser.add_argument(
4348
"--start",
4449
type=datetime.fromisoformat,
@@ -72,6 +77,7 @@ def main() -> None:
7277
args.end,
7378
args.resolution,
7479
states=args.states,
80+
bounds=args.bounds,
7581
service_address=args.url,
7682
key=args.key,
7783
fmt=args.format,
@@ -88,6 +94,7 @@ async def run(
8894
end_dt: datetime,
8995
resolution: int,
9096
states: bool,
97+
bounds: bool,
9198
service_address: str,
9299
key: str,
93100
fmt: str,
@@ -102,6 +109,7 @@ async def run(
102109
end_dt: end datetime
103110
resolution: resampling resolution in sec
104111
states: include states in the output
112+
bounds: include bounds in the output
105113
service_address: service address
106114
key: API key
107115
fmt: output format
@@ -129,6 +137,7 @@ def data_iter() -> AsyncIterator[MetricSample]:
129137
end_dt=end_dt,
130138
resolution=resolution,
131139
include_states=states,
140+
include_bounds=bounds,
132141
)
133142

134143
if fmt == "iter":

src/frequenz/client/reporting/_client.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,23 @@ def __iter__(self) -> Iterator[MetricSample]:
9898
metric=met,
9999
value=value,
100100
)
101+
for i, bound in enumerate(msample.bounds):
102+
if bound.lower:
103+
yield MetricSample(
104+
timestamp=ts,
105+
microgrid_id=mid,
106+
component_id=cid,
107+
metric=f"{met}_bound_{i}_lower",
108+
value=bound.lower,
109+
)
110+
if bound.upper:
111+
yield MetricSample(
112+
timestamp=ts,
113+
microgrid_id=mid,
114+
component_id=cid,
115+
metric=f"{met}_bound_{i}_upper",
116+
value=bound.upper,
117+
)
101118
for state in cdata.states:
102119
ts = state.sampled_at.ToDatetime()
103120
for name, category in {
@@ -145,6 +162,7 @@ async def list_single_component_data(
145162
end_dt: datetime,
146163
resolution: int | None,
147164
include_states: bool = False,
165+
include_bounds: bool = False,
148166
) -> AsyncIterator[MetricSample]:
149167
"""Iterate over the data for a single metric.
150168
@@ -156,6 +174,7 @@ async def list_single_component_data(
156174
end_dt: The end date and time.
157175
resolution: The resampling resolution for the data, represented in seconds.
158176
include_states: Whether to include the state data.
177+
include_bounds: Whether to include the bound data.
159178
160179
Yields:
161180
A named tuple with the following fields:
@@ -169,6 +188,7 @@ async def list_single_component_data(
169188
end_dt=end_dt,
170189
resolution=resolution,
171190
include_states=include_states,
191+
include_bounds=include_bounds,
172192
):
173193
for entry in batch:
174194
yield entry
@@ -183,6 +203,7 @@ async def list_microgrid_components_data(
183203
end_dt: datetime,
184204
resolution: int | None,
185205
include_states: bool = False,
206+
include_bounds: bool = False,
186207
) -> AsyncIterator[MetricSample]:
187208
"""Iterate over the data for multiple microgrids and components.
188209
@@ -194,6 +215,7 @@ async def list_microgrid_components_data(
194215
end_dt: The end date and time.
195216
resolution: The resampling resolution for the data, represented in seconds.
196217
include_states: Whether to include the state data.
218+
include_bounds: Whether to include the bound data.
197219
198220
Yields:
199221
A named tuple with the following fields:
@@ -210,6 +232,7 @@ async def list_microgrid_components_data(
210232
end_dt=end_dt,
211233
resolution=resolution,
212234
include_states=include_states,
235+
include_bounds=include_bounds,
213236
):
214237
for entry in batch:
215238
yield entry
@@ -225,6 +248,7 @@ async def _list_microgrid_components_data_batch(
225248
end_dt: datetime,
226249
resolution: int | None,
227250
include_states: bool = False,
251+
include_bounds: bool = False,
228252
) -> AsyncIterator[ComponentsDataBatch]:
229253
"""Iterate over the component data batches in the stream.
230254
@@ -238,6 +262,7 @@ async def _list_microgrid_components_data_batch(
238262
end_dt: The end date and time.
239263
resolution: The resampling resolution for the data, represented in seconds.
240264
include_states: Whether to include the state data.
265+
include_bounds: Whether to include the bound data.
241266
242267
Yields:
243268
A ComponentsDataBatch object of microgrid components data.
@@ -262,7 +287,13 @@ def dt2ts(dt: datetime) -> PBTimestamp:
262287
if include_states
263288
else PBIncludeOptions.FilterOption.FILTER_OPTION_EXCLUDE
264289
)
290+
incl_bounds = (
291+
PBIncludeOptions.FilterOption.FILTER_OPTION_INCLUDE
292+
if include_bounds
293+
else PBIncludeOptions.FilterOption.FILTER_OPTION_EXCLUDE
294+
)
265295
include_options = PBIncludeOptions(
296+
bounds=incl_bounds,
266297
states=incl_states,
267298
)
268299

0 commit comments

Comments
 (0)