-
Notifications
You must be signed in to change notification settings - Fork 20
Open
Labels
part:actorAffects an actor ot the actors utilities (decorator, etc.)Affects an actor ot the actors utilities (decorator, etc.)part:power-managementAffects the management of battery power and distributionAffects the management of battery power and distributiontype:tech-debtImproves the project without visible changes for usersImproves the project without visible changes for users
Milestone
Description
What's needed?
We have now 2 component pool groups: the default and the shifting group (which sort of move the baseline of the default group). The code could be restructured a bit to avoid some duplication.
Proposed solution
Something like:
class PoolGroup:
algorithm: BaseAlgorithm
subscriptions: dict[...]
# Maybe more stuff could be stored directly in the group,
# like the `component_ids` and `system_bounds`, so this
# methods will need even fewer arguments, but I didn't
# check if this is feasible or not
def subscribe(...) -> None: ...
if component_ids not in self.subscriptions:
self.subscriptions[component_ids] = {
priority: self._channel_registry.get_or_create(
_Report, subcription_request.get_channel_name()
).new_sender()
}
elif priority not in self.subscriptions[component_ids]:
self.subscriptions[component_ids][priority] = (
self._channel_registry.get_or_create(
_Report, subcription_request.get_channel_name()
).new_sender()
)
def calculate_target_power(
self,
component_ids: frozenset[int],
system_bounds: ...,
*,
proposal: Proposal | None = None,
shift: Power | None = None,
must_send: bool = False,
) -> Power | None:
bounds = self._calculate_shifted_bounds(system_bounds[component_ids], shift)
return self.algorithm.calculate_target_power(
component_ids, proposal, bounds, must_send,
)
async def send_report(
self, component_ids: frozenset[int], distribution_results: ..., bounds: ..., *,
shift: Power | None = None
) -> None:
for priority, sender in self.subscriptions.get(component_ids, {}).items():
bounds = self._calculate_shifted_bounds(bounds, shift)
result = distribution_results.get(component_ids)
status = self.algorithm.get_status(component_ids, priority, bounds, result)
await sender.send(status)
def _calculate_shifted_bounds(
self, bounds: SystemBounds, shift: Power | None
) -> SystemBounds:
if shift is None:
return bounds
...
class PowerManagingActor(Actor):
def __init__(self, ...):
self._default_group = PoolGroup(...)
self._shifting_group = PoolGroup(...)
async def _run(self) -> None:
async for selected in select(...):
if ...:
...
elif selected_from(selected, self._bounds_subscription_receiver):
sub = selected.message
component_ids = sub.component_ids
priority = sub.priority
group = self._shifting_group if sub.in_shifting_group else self._default_group
group.subscribe(...)
if component_ids not in self._bound_tracker_tasks:
self._add_system_bounds_tracker(component_ids)
def _calculate_target_power(self, ...) -> Power | None:
tgt_power_shift: Power | None = None
tgt_power_default: Power | None = None
if proposal is not None:
if proposal.in_shifting_group:
bounds = self._system_bounds[component_ids]
tgt_power_shift = self._shifting_group.calculate_target_power(
component_ids, bounds, proposal=proposal, must_send=must_send,
)
tgt_power_no_shift = self._default_group.calculate_target_power(
component_ids, bounds, shift=tgt_power_shift, must_send=must_send,
)
...
async def _send_reports(self, component_ids: frozenset[int]) -> None:
if bounds is None:
_logger.warning("PowerManagingActor: No bounds for %s", component_ids)
return
self._shifting_group.send_reports(component_ids, self._distribution_results, bounds)
self._default_group.send_reports(
component_ids,
self._distribution_results,
bounds,
shift=self._shifting_group.algorithm.get_target_power(component_ids),
)Additional context
The original suggestion comes from the PR introducing the groups:
- Support power requests from shifting actors in the PowerManager #957 (comment)
- Support power requests from shifting actors in the PowerManager #957 (comment)
- Support power requests from shifting actors in the PowerManager #957 (comment)
- Support power requests from shifting actors in the PowerManager #957 (comment)
Metadata
Metadata
Assignees
Labels
part:actorAffects an actor ot the actors utilities (decorator, etc.)Affects an actor ot the actors utilities (decorator, etc.)part:power-managementAffects the management of battery power and distributionAffects the management of battery power and distributiontype:tech-debtImproves the project without visible changes for usersImproves the project without visible changes for users
Type
Projects
Status
To do