10
10
import math
11
11
from abc import ABC , abstractmethod
12
12
from collections .abc import Iterable
13
- from datetime import datetime , timezone
13
+ from datetime import datetime , timedelta , timezone
14
14
from typing import Any , Generic , Self , TypeVar
15
15
16
16
from frequenz .channels import ChannelClosedError , Receiver
22
22
InverterData ,
23
23
)
24
24
25
+ from ..._internal import _logging
25
26
from ..._internal ._asyncio import AsyncConstructible
26
27
from ..._internal ._constants import MAX_BATTERY_DATA_AGE_SEC
27
28
from ...microgrid import connection_manager
33
34
34
35
_logger = logging .getLogger (__name__ )
35
36
37
+ _missing_data_logger = _logging .RateLimitedLogger (
38
+ _logger ,
39
+ timedelta (minutes = 5 ),
40
+ )
41
+
36
42
T = TypeVar ("T" , bound = ComponentData )
37
43
"""Type variable for component data."""
38
44
@@ -120,6 +126,12 @@ async def fetch_next(self) -> ComponentMetricsData | None:
120
126
data = await asyncio .wait_for (
121
127
self ._receiver .receive (), self ._max_waiting_time
122
128
)
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 ()
123
135
124
136
except ChannelClosedError :
125
137
_logger .exception (
@@ -128,7 +140,9 @@ async def fetch_next(self) -> ComponentMetricsData | None:
128
140
return None
129
141
except asyncio .TimeoutError :
130
142
# 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
+ )
132
146
return ComponentMetricsData (
133
147
self ._component_id , datetime .now (tz = timezone .utc ), {}
134
148
)
0 commit comments