Skip to content

Commit fc51378

Browse files
committed
Implement SetComponentPowerReactive
Signed-off-by: Leandro Lucarella <[email protected]>
1 parent 355b4fb commit fc51378

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
@@ -305,6 +305,89 @@ async def set_component_power_active( # noqa: DOC502 (raises ApiClientError ind
305305

306306
return None
307307

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

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

0 commit comments

Comments
 (0)