Skip to content

Commit 9efd5e5

Browse files
authored
Upgrade the client to v0.18.x (v0.8.0 common) (#190)
2 parents 5fffd08 + 98d8d5c commit 9efd5e5

File tree

82 files changed

+1382
-1307
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

82 files changed

+1382
-1307
lines changed

pyproject.toml

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,12 @@ classifiers = [
3636
]
3737
requires-python = ">= 3.11, < 4"
3838
dependencies = [
39-
"frequenz-api-microgrid >= 0.17.2, < 0.18.0",
39+
"frequenz-api-common >= 0.8.0, < 1.0.0",
40+
"frequenz-api-microgrid >= 0.18.0, < 0.19.0",
4041
"frequenz-channels >= 1.6.1, < 2.0.0",
4142
"frequenz-client-base >= 0.10.0, < 0.12.0",
42-
"frequenz-client-common >= 0.3.2, < 0.4.0",
43+
"frequenz-client-common >= 0.3.6, < 0.4.0",
44+
"frequenz-core >= 1.3.0, < 2.0.0",
4345
"grpcio >= 1.72.1, < 2",
4446
"protobuf >= 6.31.1, < 7",
4547
"typing-extensions >= 4.13.0, < 5",
@@ -129,6 +131,10 @@ check-yield-types = false
129131
arg-type-hints-in-docstring = false
130132
arg-type-hints-in-signature = true
131133
allow-init-docstring = true
134+
per-file-ignores = [
135+
# Ignore the max-line-length (E501) because enum values are just too long
136+
"src/frequenz/client/microgrid/metrics/_metric.py:E501",
137+
]
132138

133139
[tool.pylint.similarities]
134140
ignore-comments = ['yes']

src/frequenz/client/microgrid/_client.py

Lines changed: 114 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,17 @@
1414
from datetime import datetime, timedelta
1515
from typing import Any, assert_never
1616

17-
from frequenz.api.common.v1.metrics import bounds_pb2, metric_sample_pb2
18-
from frequenz.api.common.v1.microgrid.components import components_pb2
19-
from frequenz.api.microgrid.v1 import microgrid_pb2, microgrid_pb2_grpc
17+
from frequenz.api.common.v1alpha8.metrics import bounds_pb2, metrics_pb2
18+
from frequenz.api.common.v1alpha8.microgrid.electrical_components import (
19+
electrical_components_pb2,
20+
)
21+
from frequenz.api.microgrid.v1alpha18 import microgrid_pb2, microgrid_pb2_grpc
2022
from frequenz.channels import Receiver
2123
from frequenz.client.base import channel, client, conversion, retry, streaming
24+
from frequenz.client.base.exception import ApiClientError
2225
from frequenz.client.common.microgrid.components import ComponentId
2326
from google.protobuf.empty_pb2 import Empty
27+
from grpc.aio import AioRpcError
2428
from typing_extensions import override
2529

2630
from ._exception import ClientNotConnected
@@ -90,7 +94,8 @@ def __init__(
9094
self._component_data_broadcasters: dict[
9195
str,
9296
streaming.GrpcStreamBroadcaster[
93-
microgrid_pb2.ReceiveComponentDataStreamResponse, ComponentDataSamples
97+
microgrid_pb2.ReceiveElectricalComponentTelemetryStreamResponse,
98+
ComponentDataSamples,
9499
],
95100
] = {}
96101
self._sensor_data_broadcasters: dict[
@@ -165,10 +170,7 @@ async def get_microgrid_info( # noqa: DOC502 (raises ApiClientError indirectly)
165170
"""
166171
response = await client.call_stub_method(
167172
self,
168-
lambda: self.stub.GetMicrogridMetadata(
169-
Empty(),
170-
timeout=DEFAULT_GRPC_CALL_TIMEOUT,
171-
),
173+
lambda: self.stub.GetMicrogrid(Empty(), timeout=DEFAULT_GRPC_CALL_TIMEOUT),
172174
method_name="GetMicrogridMetadata",
173175
)
174176

@@ -217,17 +219,19 @@ async def list_components( # noqa: DOC502 (raises ApiClientError indirectly)
217219
"""
218220
response = await client.call_stub_method(
219221
self,
220-
lambda: self.stub.ListComponents(
221-
microgrid_pb2.ListComponentsRequest(
222-
component_ids=map(_get_component_id, components),
223-
categories=map(_get_category_value, categories),
222+
lambda: self.stub.ListElectricalComponents(
223+
microgrid_pb2.ListElectricalComponentsRequest(
224+
electrical_component_ids=map(_get_component_id, components),
225+
electrical_component_categories=map(
226+
_get_category_value, categories
227+
),
224228
),
225229
timeout=DEFAULT_GRPC_CALL_TIMEOUT,
226230
),
227231
method_name="ListComponents",
228232
)
229233

230-
return map(component_from_proto, response.components)
234+
return map(component_from_proto, response.electrical_components)
231235

232236
async def list_connections( # noqa: DOC502 (raises ApiClientError indirectly)
233237
self,
@@ -271,10 +275,12 @@ async def list_connections( # noqa: DOC502 (raises ApiClientError indirectly)
271275
"""
272276
response = await client.call_stub_method(
273277
self,
274-
lambda: self.stub.ListConnections(
275-
microgrid_pb2.ListConnectionsRequest(
276-
starts=map(_get_component_id, sources),
277-
ends=map(_get_component_id, destinations),
278+
lambda: self.stub.ListElectricalComponentConnections(
279+
microgrid_pb2.ListElectricalComponentConnectionsRequest(
280+
source_electrical_component_ids=map(_get_component_id, sources),
281+
destination_electrical_component_ids=map(
282+
_get_component_id, destinations
283+
),
278284
),
279285
timeout=DEFAULT_GRPC_CALL_TIMEOUT,
280286
),
@@ -283,11 +289,19 @@ async def list_connections( # noqa: DOC502 (raises ApiClientError indirectly)
283289

284290
return (
285291
conn
286-
for conn in map(component_connection_from_proto, response.connections)
292+
for conn in map(
293+
component_connection_from_proto,
294+
response.electrical_component_connections,
295+
)
287296
if conn is not None
288297
)
289298

290-
async def set_component_power_active( # noqa: DOC502 (raises ApiClientError indirectly)
299+
# pylint: disable-next=fixme
300+
# TODO: Unifi set_component_power_active and set_component_power_reactive, or at
301+
# least use a common implementation.
302+
# Return an iterator or receiver with the streamed responses instead of
303+
# returning just the first one
304+
async def set_component_power_active( # noqa: DOC503
291305
self,
292306
component: ComponentId | Component,
293307
power: float,
@@ -341,25 +355,37 @@ async def set_component_power_active( # noqa: DOC502 (raises ApiClientError ind
341355
if validate_arguments:
342356
_validate_set_power_args(power=power, request_lifetime=lifetime_seconds)
343357

344-
response = await client.call_stub_method(
345-
self,
346-
lambda: self.stub.SetComponentPowerActive(
347-
microgrid_pb2.SetComponentPowerActiveRequest(
348-
component_id=_get_component_id(component),
349-
power=power,
350-
request_lifetime=lifetime_seconds,
351-
),
352-
timeout=DEFAULT_GRPC_CALL_TIMEOUT,
353-
),
354-
method_name="SetComponentPowerActive",
355-
)
358+
method_name = "SetElectricalComponentPower"
359+
if not self.is_connected:
360+
raise ClientNotConnected(server_url=self.server_url, operation=method_name)
361+
362+
try:
363+
response = await anext(
364+
aiter(
365+
self.stub.SetElectricalComponentPower(
366+
microgrid_pb2.SetElectricalComponentPowerRequest(
367+
electrical_component_id=_get_component_id(component),
368+
power_type=microgrid_pb2.POWER_TYPE_ACTIVE,
369+
power=power,
370+
request_lifetime=lifetime_seconds,
371+
),
372+
timeout=DEFAULT_GRPC_CALL_TIMEOUT,
373+
)
374+
)
375+
)
376+
except AioRpcError as grpc_error:
377+
raise ApiClientError.from_grpc_error(
378+
server_url=self.server_url,
379+
operation=method_name,
380+
grpc_error=grpc_error,
381+
) from grpc_error
356382

357-
if response.HasField("valid_until"):
358-
return conversion.to_datetime(response.valid_until)
383+
if response.HasField("valid_until_time"):
384+
return conversion.to_datetime(response.valid_until_time)
359385

360386
return None
361387

362-
async def set_component_power_reactive( # noqa: DOC502 (raises ApiClientError indirectly)
388+
async def set_component_power_reactive( # noqa: DOC503
363389
self,
364390
component: ComponentId | Component,
365391
power: float,
@@ -419,21 +445,33 @@ async def set_component_power_reactive( # noqa: DOC502 (raises ApiClientError i
419445
if validate_arguments:
420446
_validate_set_power_args(power=power, request_lifetime=lifetime_seconds)
421447

422-
response = await client.call_stub_method(
423-
self,
424-
lambda: self.stub.SetComponentPowerReactive(
425-
microgrid_pb2.SetComponentPowerReactiveRequest(
426-
component_id=_get_component_id(component),
427-
power=power,
428-
request_lifetime=lifetime_seconds,
429-
),
430-
timeout=DEFAULT_GRPC_CALL_TIMEOUT,
431-
),
432-
method_name="SetComponentPowerReactive",
433-
)
448+
method_name = "SetElectricalComponentPower"
449+
if not self.is_connected:
450+
raise ClientNotConnected(server_url=self.server_url, operation=method_name)
434451

435-
if response.HasField("valid_until"):
436-
return conversion.to_datetime(response.valid_until)
452+
try:
453+
response = await anext(
454+
aiter(
455+
self.stub.SetElectricalComponentPower(
456+
microgrid_pb2.SetElectricalComponentPowerRequest(
457+
electrical_component_id=_get_component_id(component),
458+
power_type=microgrid_pb2.POWER_TYPE_REACTIVE,
459+
power=power,
460+
request_lifetime=lifetime_seconds,
461+
),
462+
timeout=DEFAULT_GRPC_CALL_TIMEOUT,
463+
)
464+
)
465+
)
466+
except AioRpcError as grpc_error:
467+
raise ApiClientError.from_grpc_error(
468+
server_url=self.server_url,
469+
operation=method_name,
470+
grpc_error=grpc_error,
471+
) from grpc_error
472+
473+
if response.HasField("valid_until_time"):
474+
return conversion.to_datetime(response.valid_until_time)
437475

438476
return None
439477

@@ -506,14 +544,11 @@ async def add_component_bounds( # noqa: DOC502 (Raises ApiClientError indirectl
506544
most likely a subclass of
507545
[GrpcError][frequenz.client.microgrid.GrpcError].
508546
"""
509-
extra_args = {}
510-
if validity is not None:
511-
extra_args["validity_duration"] = validity.value
512547
response = await client.call_stub_method(
513548
self,
514-
lambda: self.stub.AddComponentBounds(
515-
microgrid_pb2.AddComponentBoundsRequest(
516-
component_id=_get_component_id(component),
549+
lambda: self.stub.AugmentElectricalComponentBounds(
550+
microgrid_pb2.AugmentElectricalComponentBoundsRequest(
551+
electrical_component_id=_get_component_id(component),
517552
target_metric=_get_metric_value(target),
518553
bounds=(
519554
bounds_pb2.Bounds(
@@ -522,15 +557,15 @@ async def add_component_bounds( # noqa: DOC502 (Raises ApiClientError indirectl
522557
)
523558
for bound in bounds
524559
),
525-
**extra_args,
560+
request_lifetime=validity.value if validity else None,
526561
),
527562
timeout=DEFAULT_GRPC_CALL_TIMEOUT,
528563
),
529564
method_name="AddComponentBounds",
530565
)
531566

532-
if response.HasField("ts"):
533-
return conversion.to_datetime(response.ts)
567+
if response.HasField("valid_until_time"):
568+
return conversion.to_datetime(response.valid_until_time)
534569

535570
return None
536571

@@ -578,48 +613,43 @@ def receive_component_data_samples_stream(
578613
stream_name = f"microgrid-client-{client_id}-component-data-{key}"
579614
# Alias to avoid too long lines linter errors
580615
# pylint: disable-next=invalid-name
581-
Request = microgrid_pb2.ReceiveComponentDataStreamRequest
616+
Request = microgrid_pb2.ReceiveElectricalComponentTelemetryStreamRequest
582617
broadcaster = streaming.GrpcStreamBroadcaster(
583618
stream_name,
584619
lambda: aiter(
585-
self.stub.ReceiveComponentDataStream(
620+
self.stub.ReceiveElectricalComponentTelemetryStream(
586621
Request(
587-
component_id=_get_component_id(component),
588-
filter=Request.ComponentDataStreamFilter(
622+
electrical_component_id=_get_component_id(component),
623+
filter=Request.ComponentTelemetryStreamFilter(
589624
metrics=metrics_set
590625
),
591626
),
592627
timeout=DEFAULT_GRPC_CALL_TIMEOUT,
593628
)
594629
),
595-
lambda msg: component_data_samples_from_proto(msg.data),
630+
lambda msg: component_data_samples_from_proto(msg.telemetry),
596631
retry_strategy=self._retry_strategy,
597632
)
598633
self._component_data_broadcasters[key] = broadcaster
599634
return broadcaster.new_receiver(maxsize=buffer_size)
600635

601636

637+
# pylint: disable-next=fixme
638+
# TODO: Remove this enum, now AugmentElectricalComponentBounds takes a simple timeout as
639+
# an int.
602640
class Validity(enum.Enum):
603641
"""The duration for which a given list of bounds will stay in effect."""
604642

605-
FIVE_SECONDS = (
606-
microgrid_pb2.ComponentBoundsValidityDuration.COMPONENT_BOUNDS_VALIDITY_DURATION_5_SECONDS
607-
)
643+
FIVE_SECONDS = 5
608644
"""The bounds will stay in effect for 5 seconds."""
609645

610-
ONE_MINUTE = (
611-
microgrid_pb2.ComponentBoundsValidityDuration.COMPONENT_BOUNDS_VALIDITY_DURATION_1_MINUTE
612-
)
646+
ONE_MINUTE = 60
613647
"""The bounds will stay in effect for 1 minute."""
614648

615-
FIVE_MINUTES = (
616-
microgrid_pb2.ComponentBoundsValidityDuration.COMPONENT_BOUNDS_VALIDITY_DURATION_5_MINUTES
617-
)
649+
FIVE_MINUTES = 60 * 5
618650
"""The bounds will stay in effect for 5 minutes."""
619651

620-
FIFTEEN_MINUTES = (
621-
microgrid_pb2.ComponentBoundsValidityDuration.COMPONENT_BOUNDS_VALIDITY_DURATION_15_MINUTES
622-
)
652+
FIFTEEN_MINUTES = 60 * 15
623653
"""The bounds will stay in effect for 15 minutes."""
624654

625655

@@ -634,26 +664,30 @@ def _get_component_id(component: ComponentId | Component) -> int:
634664
assert_never(unexpected)
635665

636666

637-
def _get_metric_value(metric: Metric | int) -> metric_sample_pb2.Metric.ValueType:
667+
def _get_metric_value(metric: Metric | int) -> metrics_pb2.Metric.ValueType:
638668
"""Get the metric ID from a metric or metric ID."""
639669
match metric:
640670
case Metric():
641-
return metric_sample_pb2.Metric.ValueType(metric.value)
671+
return metrics_pb2.Metric.ValueType(metric.value)
642672
case int():
643-
return metric_sample_pb2.Metric.ValueType(metric)
673+
return metrics_pb2.Metric.ValueType(metric)
644674
case unexpected:
645675
assert_never(unexpected)
646676

647677

648678
def _get_category_value(
649679
category: ComponentCategory | int,
650-
) -> components_pb2.ComponentCategory.ValueType:
680+
) -> electrical_components_pb2.ElectricalComponentCategory.ValueType:
651681
"""Get the category value from a component or component category."""
652682
match category:
653683
case ComponentCategory():
654-
return components_pb2.ComponentCategory.ValueType(category.value)
684+
return electrical_components_pb2.ElectricalComponentCategory.ValueType(
685+
category.value
686+
)
655687
case int():
656-
return components_pb2.ComponentCategory.ValueType(category)
688+
return electrical_components_pb2.ElectricalComponentCategory.ValueType(
689+
category
690+
)
657691
case unexpected:
658692
assert_never(unexpected)
659693

src/frequenz/client/microgrid/_delivery_area.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import enum
77
from dataclasses import dataclass
88

9-
from frequenz.api.common.v1.grid import delivery_area_pb2
9+
from frequenz.api.common.v1alpha8.grid import delivery_area_pb2
1010

1111

1212
@enum.unique

src/frequenz/client/microgrid/_delivery_area_proto.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import logging
77

8-
from frequenz.api.common.v1.grid import delivery_area_pb2
8+
from frequenz.api.common.v1alpha8.grid import delivery_area_pb2
99

1010
from ._delivery_area import DeliveryArea, EnergyMarketCodeType
1111
from ._util import enum_from_proto

src/frequenz/client/microgrid/_lifetime_proto.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
"""Loading of Lifetime objects from protobuf messages."""
55

6-
from frequenz.api.common.v1.microgrid import lifetime_pb2
6+
from frequenz.api.common.v1alpha8.microgrid import lifetime_pb2
77
from frequenz.client.base.conversion import to_datetime
88

99
from ._lifetime import Lifetime

0 commit comments

Comments
 (0)