@@ -112,6 +112,8 @@ def __init__(
112
112
set ()
113
113
)
114
114
115
+ self ._fetchers : dict [int , ComponentMetricFetcher ] = {}
116
+
115
117
@classmethod
116
118
def name (cls ) -> str :
117
119
"""Get name of the method.
@@ -166,28 +168,29 @@ async def stop(self) -> None:
166
168
await asyncio .gather (
167
169
* [cancel_and_await (self ._send_task ), cancel_and_await (self ._update_task )]
168
170
)
171
+ for fetcher in self ._fetchers .values ():
172
+ fetcher .stop ()
169
173
170
- async def _create_data_fetchers (self ) -> dict [ int , ComponentMetricFetcher ] :
174
+ async def _create_data_fetchers (self ) -> None :
171
175
fetchers : dict [int , ComponentMetricFetcher ] = {
172
176
cid : await LatestBatteryMetricsFetcher .async_new (cid , metrics )
173
177
for cid , metrics in self ._metric_calculator .battery_metrics .items ()
174
178
}
179
+ self ._fetchers .update (fetchers )
175
180
inverter_fetchers = {
176
181
cid : await LatestInverterMetricsFetcher .async_new (cid , metrics )
177
182
for cid , metrics in self ._metric_calculator .inverter_metrics .items ()
178
183
}
179
- fetchers .update (inverter_fetchers )
180
- return fetchers
184
+ self ._fetchers .update (inverter_fetchers )
181
185
182
- def _remove_metric_fetcher (
183
- self , fetchers : dict [int , ComponentMetricFetcher ], component_id : int
184
- ) -> None :
186
+ def _remove_metric_fetcher (self , component_id : int ) -> None :
185
187
_logger .error (
186
188
"Removing component %d from the %s formula." ,
187
189
component_id ,
188
190
self ._result_channel ._name , # pylint: disable=protected-access
189
191
)
190
- fetchers .pop (component_id )
192
+ fetcher = self ._fetchers .pop (component_id )
193
+ fetcher .stop ()
191
194
192
195
def _metric_updated (self , new_metrics : ComponentMetricsData ) -> bool :
193
196
cid = new_metrics .component_id
@@ -197,11 +200,11 @@ def _metric_updated(self, new_metrics: ComponentMetricsData) -> bool:
197
200
198
201
async def _update_and_notify (self ) -> None :
199
202
"""Receive component metrics and send notification when they change."""
200
- fetchers = await self ._create_data_fetchers ()
203
+ await self ._create_data_fetchers ()
201
204
202
205
self ._pending_data_fetchers = {
203
206
asyncio .create_task (fetcher .fetch_next (), name = str (cid ))
204
- for cid , fetcher in fetchers .items ()
207
+ for cid , fetcher in self . _fetchers .items ()
205
208
}
206
209
while len (self ._pending_data_fetchers ) > 0 :
207
210
done , self ._pending_data_fetchers = await asyncio .wait (
@@ -210,7 +213,7 @@ async def _update_and_notify(self) -> None:
210
213
for item in done :
211
214
metrics = item .result ()
212
215
if metrics is None :
213
- self ._remove_metric_fetcher (fetchers , int (item .get_name ()))
216
+ self ._remove_metric_fetcher (int (item .get_name ()))
214
217
continue
215
218
if self ._metric_updated (metrics ):
216
219
self ._update_event .set ()
@@ -220,7 +223,7 @@ async def _update_and_notify(self) -> None:
220
223
self ._cached_metrics [cid ] = metrics
221
224
# Add fetcher back to the processing list.
222
225
self ._pending_data_fetchers .add (
223
- asyncio .create_task (fetchers [cid ].fetch_next (), name = str (cid ))
226
+ asyncio .create_task (self . _fetchers [cid ].fetch_next (), name = str (cid ))
224
227
)
225
228
226
229
async def _send_on_update (self , min_update_interval : timedelta ) -> None :
0 commit comments