1414
1515import asyncio
1616import logging
17- import time
1817from asyncio .tasks import ALL_COMPLETED
1918from collections import abc
2019from collections .abc import Iterable
21- from dataclasses import dataclass
2220from datetime import timedelta
2321from math import isnan
24- from typing import Any , Self , TypeVar , cast
22+ from typing import Any , TypeVar , cast
2523
2624import grpc
2725from frequenz .channels import Peekable , Receiver , Sender
5149_logger = logging .getLogger (__name__ )
5250
5351
54- @dataclass
55- class _CacheEntry :
56- """Represents an entry in the cache with expiry time."""
57-
58- inv_bat_pair : InvBatPair
59- """The inverter and adjacent battery data pair."""
60-
61- expiry_time : int
62- """The expiration time (taken from the monotonic clock) of the cache entry."""
63-
64- @classmethod
65- def from_ttl (
66- cls , inv_bat_pair : InvBatPair , ttl : timedelta = timedelta (hours = 2.5 )
67- ) -> Self :
68- """Initialize a CacheEntry instance from a TTL (Time-To-Live).
69-
70- Args:
71- inv_bat_pair: the inverter and adjacent battery data pair to cache.
72- ttl: the time a cache entry is kept alive.
73-
74- Returns:
75- this class instance.
76- """
77- return cls (inv_bat_pair , time .monotonic_ns () + int (ttl .total_seconds () * 1e9 ))
78-
79- def has_expired (self ) -> bool :
80- """Check whether the cache entry has expired.
81-
82- Returns:
83- whether the cache entry has expired.
84- """
85- return time .monotonic_ns () >= self .expiry_time
86-
87-
8852def _get_all (source : dict [int , frozenset [int ]], keys : abc .Set [int ]) -> set [int ]:
8953 """Get all values for the given keys from the given map.
9054
@@ -180,10 +144,6 @@ def __init__(
180144 max_data_age_sec = 10.0 ,
181145 )
182146
183- self ._cached_metrics : dict [frozenset [int ], _CacheEntry | None ] = {
184- bat_ids : None for bat_ids in self ._bat_bats_map .values ()
185- }
186-
187147 def _get_bounds (
188148 self ,
189149 pairs_data : list [InvBatPair ],
@@ -254,13 +214,13 @@ async def _run(self) -> None: # pylint: disable=too-many-locals
254214 async for request in self ._requests_receiver :
255215 try :
256216 pairs_data : list [InvBatPair ] = self ._get_components_data (
257- request .batteries , request . include_broken_batteries
217+ request .batteries
258218 )
259219 except KeyError as err :
260220 await self ._result_sender .send (Error (request = request , msg = str (err )))
261221 continue
262222
263- if not pairs_data and not request . include_broken_batteries :
223+ if not pairs_data :
264224 error_msg = (
265225 "No data for at least one of the given "
266226 f"batteries { str (request .batteries )} "
@@ -390,24 +350,10 @@ def _get_power_distribution(
390350 ]:
391351 unavailable_inv_ids = unavailable_inv_ids .union (inverter_ids )
392352
393- if request .include_broken_batteries and not available_bat_ids :
394- return self .distribution_algorithm .distribute_power_equally (
395- request .power .as_watts (), unavailable_inv_ids
396- )
397-
398353 result = self .distribution_algorithm .distribute_power (
399354 request .power .as_watts (), inv_bat_pairs
400355 )
401356
402- if request .include_broken_batteries and unavailable_inv_ids :
403- additional_result = self .distribution_algorithm .distribute_power_equally (
404- result .remaining_power , unavailable_inv_ids
405- )
406-
407- for inv_id , power in additional_result .distribution .items ():
408- result .distribution [inv_id ] = power
409- result .remaining_power = 0.0
410-
411357 return result
412358
413359 def _check_request (
@@ -526,15 +472,11 @@ def _get_components_pairs(
526472 {k : frozenset (v ) for k , v in inv_invs_map .items ()},
527473 )
528474
529- def _get_components_data (
530- self , batteries : abc .Set [int ], include_broken : bool
531- ) -> list [InvBatPair ]:
475+ def _get_components_data (self , batteries : abc .Set [int ]) -> list [InvBatPair ]:
532476 """Get data for the given batteries and adjacent inverters.
533477
534478 Args:
535479 batteries: Batteries that needs data.
536- include_broken: whether all batteries in the batteries set in the
537- request must be used regardless the status.
538480
539481 Raises:
540482 KeyError: If any battery in the given list doesn't exists in microgrid.
@@ -544,11 +486,7 @@ def _get_components_data(
544486 """
545487 pairs_data : list [InvBatPair ] = []
546488
547- working_batteries = (
548- batteries
549- if include_broken
550- else self ._all_battery_status .get_working_batteries (batteries )
551- )
489+ working_batteries = self ._all_battery_status .get_working_batteries (batteries )
552490
553491 for battery_id in working_batteries :
554492 if battery_id not in self ._battery_receivers :
@@ -579,12 +517,6 @@ def _get_components_data(
579517 inverter_ids : frozenset [int ] = self ._bat_inv_map [next (iter (battery_ids ))]
580518
581519 data = self ._get_battery_inverter_data (battery_ids , inverter_ids )
582- if not data and include_broken :
583- cached_entry = self ._cached_metrics [battery_ids ]
584- if cached_entry and not cached_entry .has_expired ():
585- data = cached_entry .inv_bat_pair
586- else :
587- data = None
588520 if data is None :
589521 _logger .warning (
590522 "Skipping battery set %s because at least one of its messages isn't correct." ,
@@ -669,9 +601,7 @@ def nan_metric_in_list(data: list[DataType], metrics: list[str]) -> bool:
669601 )
670602 return None
671603
672- inv_bat_pair = InvBatPair (AggregatedBatteryData (battery_data ), inverter_data )
673- self ._cached_metrics [battery_ids ] = _CacheEntry .from_ttl (inv_bat_pair )
674- return inv_bat_pair
604+ return InvBatPair (AggregatedBatteryData (battery_data ), inverter_data )
675605
676606 async def _create_channels (self ) -> None :
677607 """Create channels to get data of components in microgrid."""
0 commit comments