1010import math
1111from abc import ABC , abstractmethod
1212from collections .abc import Iterable
13- from datetime import datetime , timezone
13+ from datetime import datetime , timedelta , timezone
1414from typing import Any , Generic , Self , TypeVar
1515
1616from frequenz .channels import ChannelClosedError , Receiver
2222 InverterData ,
2323)
2424
25+ from ..._internal import _logging
2526from ..._internal ._asyncio import AsyncConstructible
2627from ..._internal ._constants import MAX_BATTERY_DATA_AGE_SEC
2728from ...microgrid import connection_manager
3334
3435_logger = logging .getLogger (__name__ )
3536
37+ _missing_data_logger = _logging .RateLimitedLogger (
38+ _logger ,
39+ timedelta (minutes = 5 ),
40+ )
41+
3642T = TypeVar ("T" , bound = ComponentData )
3743"""Type variable for component data."""
3844
@@ -120,6 +126,12 @@ async def fetch_next(self) -> ComponentMetricsData | None:
120126 data = await asyncio .wait_for (
121127 self ._receiver .receive (), self ._max_waiting_time
122128 )
129+ if _missing_data_logger .is_limiting ():
130+ _missing_data_logger .reset ()
131+ _missing_data_logger .debug (
132+ "Component %d has started sending data." , self ._component_id
133+ )
134+ _missing_data_logger .reset ()
123135
124136 except ChannelClosedError :
125137 _logger .exception (
@@ -128,7 +140,9 @@ async def fetch_next(self) -> ComponentMetricsData | None:
128140 return None
129141 except asyncio .TimeoutError :
130142 # Next time wait infinitely until we receive any message.
131- _logger .debug ("Component %d stopped sending data." , self ._component_id )
143+ _missing_data_logger .debug (
144+ "Component %d stopped sending data." , self ._component_id
145+ )
132146 return ComponentMetricsData (
133147 self ._component_id , datetime .now (tz = timezone .utc ), {}
134148 )
0 commit comments