@@ -183,6 +183,9 @@ def __init__(
183183 )
184184 """The distribution algorithm used to distribute power between batteries."""
185185
186+ self ._last_set_powers : dict [ComponentId , Power ] = {}
187+ """The last power value set to each battery's inverter."""
188+
186189 @override
187190 def component_ids (self ) -> collections .abc .Set [ComponentId ]:
188191 """Return the set of component ids."""
@@ -266,29 +269,13 @@ async def _distribute_power(
266269 Result from the microgrid API.
267270 """
268271 distributed_power_value = request .power - distribution .remaining_power
269- battery_distribution : dict [frozenset [ComponentId ], Power ] = {}
270272 battery_ids : set [ComponentId ] = set ()
271- for inverter_id , dist in distribution .distribution . items () :
273+ for inverter_id in distribution .distribution :
272274 for battery_id in self ._inv_bats_map [inverter_id ]:
273275 battery_ids .add (battery_id )
274- battery_distribution [self ._inv_bats_map [inverter_id ]] = dist
275- if _logger .isEnabledFor (logging .DEBUG ):
276- _logger .debug (
277- "Distributing power %s between the batteries: %s" ,
278- distributed_power_value ,
279- ", " .join (
280- (
281- str (next (iter (cids )))
282- if len (cids ) == 1
283- else f"({ ', ' .join (str (cid ) for cid in cids )} )"
284- )
285- + f": { power } "
286- for cids , power in battery_distribution .items ()
287- ),
288- )
289276
290277 failed_power , failed_batteries = await self ._set_distributed_power (
291- distribution , self ._api_power_request_timeout
278+ request , distribution , self ._api_power_request_timeout
292279 )
293280
294281 response : Success | PartialFailure
@@ -632,12 +619,14 @@ def _get_power_distribution(
632619
633620 async def _set_distributed_power (
634621 self ,
622+ request : Request ,
635623 distribution : DistributionResult ,
636624 timeout : timedelta ,
637625 ) -> tuple [Power , set [ComponentId ]]:
638626 """Send distributed power to the inverters.
639627
640628 Args:
629+ request: Request to set the power for.
641630 distribution: Distribution result
642631 timeout: How long wait for the response
643632
@@ -652,8 +641,34 @@ async def _set_distributed_power(
652641 api .set_power (inverter_id , power .as_watts ())
653642 )
654643 for inverter_id , power in distribution .distribution .items ()
644+ if power != Power .zero ()
645+ or self ._last_set_powers .get (inverter_id ) != Power .zero ()
655646 }
656647
648+ if not tasks :
649+ if _logger .isEnabledFor (logging .DEBUG ):
650+ _logger .debug ("Not repeating 0W commands to batteries." )
651+ return Power .zero (), set ()
652+
653+ if _logger .isEnabledFor (logging .DEBUG ):
654+ battery_distribution = {
655+ self ._inv_bats_map [inverter_id ]: distribution .distribution [inverter_id ]
656+ for inverter_id in tasks
657+ }
658+ _logger .debug (
659+ "Distributing power %s between the batteries: %s" ,
660+ request .power - distribution .remaining_power ,
661+ ", " .join (
662+ (
663+ str (next (iter (cids )))
664+ if len (cids ) == 1
665+ else f"({ ', ' .join (str (cid ) for cid in cids )} )"
666+ )
667+ + f": { power } "
668+ for cids , power in battery_distribution .items ()
669+ ),
670+ )
671+
657672 _ , pending = await asyncio .wait (
658673 tasks .values (),
659674 timeout = timeout .total_seconds (),
@@ -722,6 +737,8 @@ def _parse_result(
722737 if failed :
723738 failed_power += distribution [inverter_id ]
724739 failed_batteries .update (battery_ids )
740+ else :
741+ self ._last_set_powers [inverter_id ] = distribution [inverter_id ]
725742
726743 return failed_power , failed_batteries
727744
0 commit comments