@@ -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
309392def _get_component_id (component : ComponentId | Component ) -> int :
310393 """Get the component ID from a component or component ID."""
0 commit comments