Skip to content

Commit 9ec02a7

Browse files
committed
Implement SetComponentPowerReactive
Signed-off-by: Leandro Lucarella <[email protected]>
1 parent c217620 commit 9ec02a7

File tree

1 file changed

+83
-0
lines changed

1 file changed

+83
-0
lines changed

src/frequenz/client/microgrid/_client.py

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,89 @@ async def set_component_power_active( # noqa: DOC502 (raises ApiClientError ind
292292

293293
return None
294294

295+
async def set_component_power_reactive( # noqa: DOC502 (raises ApiClientError indirectly)
296+
self,
297+
component: ComponentId | Component,
298+
power: float,
299+
*,
300+
request_lifetime: timedelta | None = None,
301+
validate_arguments: bool = True,
302+
) -> datetime | None:
303+
"""Set the reactive power output of a component.
304+
305+
We follow the polarity specified in the IEEE 1459-2010 standard
306+
definitions, where:
307+
308+
- Positive reactive is inductive (current is lagging the voltage)
309+
- Negative reactive is capacitive (current is leading the voltage)
310+
311+
The power output is specified in VAr.
312+
313+
The return value is the timestamp until which the given power command will
314+
stay in effect. After this timestamp, the component's reactive power will
315+
be set to 0, if the API receives no further command to change it before
316+
then. By default, this timestamp will be set to the current time plus 60
317+
seconds.
318+
319+
Note:
320+
The target component may have a resolution of more than 1 VAr. E.g., an
321+
inverter may have a resolution of 88 VAr. In such cases, the magnitude of
322+
power will be floored to the nearest multiple of the resolution.
323+
324+
Performs the following sequence actions for the following component
325+
categories:
326+
327+
* TODO document missing.
328+
329+
Args:
330+
component: The component to set the output reactive power of.
331+
power: The output reactive power level, in VAr. The standard of polarity is
332+
as per the IEEE 1459-2010 standard definitions: positive reactive is
333+
inductive (current is lagging the voltage); negative reactive is
334+
capacitive (current is leading the voltage).
335+
request_lifetime: The duration, until which the request will stay in effect.
336+
This duration has to be between 10 seconds and 15 minutes (including
337+
both limits), otherwise the request will be rejected. It has
338+
a resolution of a second, so fractions of a second will be rounded for
339+
`timedelta` objects, and it is interpreted as seconds for `int` objects.
340+
If not provided, it usually defaults to 60 seconds.
341+
validate_arguments: Whether to validate the arguments before sending the
342+
request. If `True` a `ValueError` will be raised if an argument is
343+
invalid without even sending the request to the server, if `False`, the
344+
request will be sent without validation.
345+
346+
Returns:
347+
The timestamp until which the given power command will stay in effect, or
348+
`None` if it was not provided.
349+
350+
Raises:
351+
ApiClientError: If the are any errors communicating with the Microgrid API,
352+
most likely a subclass of
353+
[GrpcError][frequenz.client.microgrid.GrpcError].
354+
"""
355+
lifetime_seconds = _delta_to_seconds(request_lifetime)
356+
357+
if validate_arguments:
358+
_validate_set_power_args(power=power, request_lifetime=lifetime_seconds)
359+
360+
response = await client.call_stub_method(
361+
self,
362+
lambda: self._async_stub.SetComponentPowerReactive(
363+
microgrid_pb2.SetComponentPowerReactiveRequest(
364+
component_id=_get_component_id(component),
365+
power=power,
366+
request_lifetime=lifetime_seconds,
367+
),
368+
timeout=int(DEFAULT_GRPC_CALL_TIMEOUT),
369+
),
370+
method_name="SetComponentPowerReactive",
371+
)
372+
373+
if response.HasField("valid_until"):
374+
return conversion.to_datetime(response.valid_until)
375+
376+
return None
377+
295378

296379
def _get_component_id(component: ComponentId | Component) -> int:
297380
"""Get the component ID from a component or component ID."""

0 commit comments

Comments
 (0)