11# License: MIT
22# Copyright © 2022 Frequenz Energy-as-a-Service GmbH
3- """Class that stores pool of batteries and manage them."""
3+
4+ """Class that tracks the status of pool of components."""
45
56
67import asyncio
@@ -62,50 +63,52 @@ def __post_init__(self) -> None:
6263 self .sender = channel .new_sender ()
6364
6465
65- class BatteryPoolStatus :
66- """Track status of the batteries .
66+ class ComponentPoolStatusTracker :
67+ """Track status of components of a given category .
6768
68- Send set of working and uncertain batteries, when the any battery change status.
69+ Send set of working and uncertain components, when the status of any of the tracked
70+ components changes.
6971 """
7072
71- def __init__ ( # noqa: DOC502 (RuntimeError is raised indirectly by BatteryStatus )
73+ def __init__ ( # noqa: DOC502 (RuntimeError raised from BatteryStatusTracker )
7274 self ,
73- battery_ids : set [int ],
74- battery_status_sender : Sender [ComponentStatus ],
75+ component_ids : set [int ],
76+ component_status_sender : Sender [ComponentStatus ],
7577 max_data_age_sec : float ,
7678 max_blocking_duration_sec : float ,
7779 ) -> None :
78- """Create BatteryPoolStatus instance.
80+ """Create ComponentPoolStatusTracker instance.
7981
8082 Args:
81- battery_ids : set of batteries ids that should be stored in pool .
82- battery_status_sender : The sender used for sending the status of the
83- batteries in the pool .
84- max_data_age_sec: If component stopped sending data, then
85- this is the maximum time when its last message should be considered as
86- valid. After that time, component won't be used until it starts sending
87- data.
83+ component_ids : set of component ids whose status is to be tracked .
84+ component_status_sender : The sender used for sending the status of the
85+ tracked components .
86+ max_data_age_sec: If a component stops sending data, then this is the
87+ maximum time for which its last message should be considered as
88+ valid. After that time, the component won't be used until it starts
89+ sending data.
8890 max_blocking_duration_sec: This value tell what should be the maximum
8991 timeout used for blocking failing component.
9092
9193 Raises:
92- RuntimeError: If any battery has no adjacent inverter.
94+ RuntimeError: When managing batteries, if any battery has no adjacent
95+ inverter.
9396 """
94- # At first no battery is working, we will get notification when they start
97+ # At first no component is working, we will get notification when they start
9598 # working.
9699 self ._current_status = ComponentStatus (working = set (), uncertain = set ())
97100
98- # Channel for sending results of requests to the batteries
99- set_power_result_channel = Broadcast [SetPowerResult ]("battery_request_status " )
101+ # Channel for sending results of requests to the components.
102+ set_power_result_channel = Broadcast [SetPowerResult ]("component_request_status " )
100103 self ._set_power_result_sender = set_power_result_channel .new_sender ()
101104
102105 self ._batteries : dict [str , BatteryStatusTracker ] = {}
103106
104- # Receivers for individual battery statuses are needed to create a `MergeNamed`
105- # object.
107+ # Receivers for individual components statuses are needed to create a
108+ # `MergeNamed` object.
106109 receivers : dict [str , Receiver [Status ]] = {}
107110
108- for battery_id in battery_ids :
111+ for battery_id in component_ids :
109112 channel = _ComponentStatusChannelHelper (battery_id )
110113 receivers [channel .name ] = channel .receiver
111114
@@ -119,20 +122,16 @@ def __init__( # noqa: DOC502 (RuntimeError is raised indirectly by BatteryStatu
119122 ),
120123 )
121124
122- self ._battery_status_channel = MergeNamed [Status ](
125+ self ._component_status_channel = MergeNamed [Status ](
123126 ** receivers ,
124127 )
125128
126- self ._task = asyncio .create_task (self ._run (battery_status_sender ))
129+ self ._task = asyncio .create_task (self ._run (component_status_sender ))
127130
128131 async def join (self ) -> None :
129- """Await for the battery pool, and return when the task completes.
132+ """Wait and return when the instance's task completes.
130133
131- It will not terminate the program while BatteryPool is working.
132- BatteryPool can be stopped with the `stop` method.
133- This method is not needed in source code, because BatteryPool is owned
134- by the internal code.
135- It is needed only when user needs to run his own instance of the BatteryPool.
134+ It will not terminate the instance, which can be done with the `stop` method.
136135 """
137136 await self ._task
138137
@@ -146,69 +145,70 @@ async def stop(self) -> None:
146145 for tracker in self ._batteries .values ()
147146 ],
148147 )
149- await self ._battery_status_channel .stop ()
148+ await self ._component_status_channel .stop ()
150149
151- async def _run (self , battery_status_sender : Sender [ComponentStatus ]) -> None :
152- """Start tracking batteries status.
150+ async def _run (self , component_status_sender : Sender [ComponentStatus ]) -> None :
151+ """Start tracking component status.
153152
154153 Args:
155- battery_status_sender : The sender used for sending the status of the
156- batteries in the pool.
154+ component_status_sender : The sender used for sending the status of the
155+ components in the pool.
157156 """
158157 while True :
159158 try :
160- await self ._update_status (battery_status_sender )
159+ await self ._update_status (component_status_sender )
161160 except Exception as err : # pylint: disable=broad-except
162161 _logger .error (
163- "BatteryPoolStatus failed with error: %s. Restarting." , err
162+ "ComponentPoolStatus failed with error: %s. Restarting." , err
164163 )
165164
166165 async def _update_status (
167- self , battery_status_sender : Sender [ComponentStatus ]
166+ self , component_status_sender : Sender [ComponentStatus ]
168167 ) -> None :
169- """Wait for any battery to change status and update status.
168+ """Wait for any component to change status and update status.
170169
171170 Args:
172- battery_status_sender : Sender to send the current status of the batteries .
171+ component_status_sender : Sender to send the current status of components .
173172 """
174- async for channel_name , status in self ._battery_status_channel :
175- battery_id = self ._batteries [channel_name ].battery_id
173+ async for channel_name , status in self ._component_status_channel :
174+ component_id = self ._batteries [channel_name ].battery_id
176175 if status == Status .WORKING :
177- self ._current_status .working .add (battery_id )
178- self ._current_status .uncertain .discard (battery_id )
176+ self ._current_status .working .add (component_id )
177+ self ._current_status .uncertain .discard (component_id )
179178 elif status == Status .UNCERTAIN :
180- self ._current_status .working .discard (battery_id )
181- self ._current_status .uncertain .add (battery_id )
179+ self ._current_status .working .discard (component_id )
180+ self ._current_status .uncertain .add (component_id )
182181 elif status == Status .NOT_WORKING :
183- self ._current_status .working .discard (battery_id )
184- self ._current_status .uncertain .discard (battery_id )
182+ self ._current_status .working .discard (component_id )
183+ self ._current_status .uncertain .discard (component_id )
185184
186- await battery_status_sender .send (self ._current_status )
185+ await component_status_sender .send (self ._current_status )
187186
188187 async def update_status (
189- self , succeed_batteries : set [int ], failed_batteries : set [int ]
188+ self , succeed_components : set [int ], failed_components : set [int ]
190189 ) -> None :
191- """Notify which batteries succeed and failed in the request.
190+ """Notify which components succeed and failed in the request.
191+
192+ Components that failed will be considered as broken and will be temporarily
193+ blocked for some time.
192194
193- Batteries that failed will be considered as broken and will be blocked for
194- some time.
195- Batteries that succeed will be unblocked.
195+ Components that succeed will be unblocked.
196196
197197 Args:
198- succeed_batteries: Batteries that succeed request
199- failed_batteries: Batteries that failed request
198+ succeed_components: Components that succeed request
199+ failed_components: Components that failed request
200200 """
201201 await self ._set_power_result_sender .send (
202- SetPowerResult (succeed_batteries , failed_batteries )
202+ SetPowerResult (succeed_components , failed_components )
203203 )
204204
205- def get_working_batteries (self , batteries : abc .Set [int ]) -> set [int ]:
206- """From the given set of batteries get working.
205+ def get_working_components (self , components : abc .Set [int ]) -> set [int ]:
206+ """From the given set of components, return only working ones .
207207
208208 Args:
209- batteries : Set of batteries
209+ components : Set of component IDs.
210210
211211 Returns:
212- Subset with working batteries .
212+ IDs of subset with working components .
213213 """
214- return self ._current_status .get_working_components (batteries )
214+ return self ._current_status .get_working_components (components )
0 commit comments