Skip to content

Commit e8914ae

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

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

308308
return None
309309

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

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

0 commit comments

Comments
 (0)