diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 54763b2..f4e3192 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -12,6 +12,7 @@ * This release now supports the sdk up to rc2000. * Less logs are now on `INFO` level, and more on `DEBUG` level, making the output less verbose. +* Changed the type of `DispatchInfo.components` from `list[int] | list[ComponentCategory]` to `list[ComponentId] | list[ComponentCategory]`, where `ComponentId` is imported from `frequenz.client.microgrid`. ## Bug Fixes diff --git a/pyproject.toml b/pyproject.toml index 0e9545a..b0b1cfb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ dependencies = [ # Make sure to update the version for cross-referencing also in the # mkdocs.yml file when changing the version here (look for the config key # plugins.mkdocstrings.handlers.python.import) - "frequenz-sdk >= 1.0.0-rc1302, < 1.0.0-rc2000", + "frequenz-sdk >= 1.0.0-rc2000, < 1.0.0-rc2100", "frequenz-channels >= 1.6.1, < 2.0.0", "frequenz-client-dispatch >= 0.10.1, < 0.11.0", ] diff --git a/src/frequenz/dispatch/_actor_dispatcher.py b/src/frequenz/dispatch/_actor_dispatcher.py index 8b1bfbe..cc0deb9 100644 --- a/src/frequenz/dispatch/_actor_dispatcher.py +++ b/src/frequenz/dispatch/_actor_dispatcher.py @@ -8,16 +8,23 @@ from collections.abc import Callable from dataclasses import dataclass from datetime import timedelta -from typing import Any, Awaitable +from typing import Any, Awaitable, cast from frequenz.channels import Broadcast, Receiver, Sender, select -from frequenz.client.dispatch.types import TargetComponents +from frequenz.client.common.microgrid.components import ComponentCategory +from frequenz.client.microgrid import ComponentId from frequenz.sdk.actor import Actor, BackgroundService from ._dispatch import Dispatch _logger = logging.getLogger(__name__) +TargetComponents = list[ComponentId] | list[ComponentCategory] +"""One or more target components specifying which components a dispatch targets. + +It can be a list of component IDs or a list of categories. +""" + @dataclass(frozen=True, kw_only=True) class DispatchInfo: @@ -46,7 +53,6 @@ class ActorDispatcher(BackgroundService): import asyncio from typing import override from frequenz.dispatch import Dispatcher, ActorDispatcher, DispatchInfo - from frequenz.client.dispatch.types import TargetComponents from frequenz.client.common.microgrid.components import ComponentCategory from frequenz.channels import Receiver, Broadcast, select, selected_from from frequenz.sdk.actor import Actor, run @@ -236,10 +242,21 @@ def start(self) -> None: """Start the background service.""" self._tasks.add(asyncio.create_task(self._run())) + def _get_target_components_from_dispatch( + self, dispatch: Dispatch + ) -> TargetComponents: + if all(isinstance(comp, int) for comp in dispatch.target): + # We've confirmed all elements are integers, so we can cast. + int_components = cast(list[int], dispatch.target) + return [ComponentId(cid) for cid in int_components] + # If not all are ints, then it must be a list of ComponentCategory + # based on the definition of ClientTargetComponents. + return cast(list[ComponentCategory], dispatch.target) + async def _start_actor(self, dispatch: Dispatch) -> None: """Start the actor the given dispatch refers to.""" dispatch_update = DispatchInfo( - components=dispatch.target, + components=self._get_target_components_from_dispatch(dispatch), dry_run=dispatch.dry_run, options=dispatch.payload, _src=dispatch, diff --git a/tests/test_managing_actor.py b/tests/test_managing_actor.py index a08207c..bdf1646 100644 --- a/tests/test_managing_actor.py +++ b/tests/test_managing_actor.py @@ -18,6 +18,7 @@ from frequenz.client.dispatch.recurrence import Frequency, RecurrenceRule from frequenz.client.dispatch.test.client import FakeClient from frequenz.client.dispatch.test.generator import DispatchGenerator +from frequenz.client.microgrid import ComponentId from frequenz.sdk.actor import Actor from pytest import fixture @@ -152,6 +153,7 @@ async def test_simple_start_stop( active=True, dry_run=False, duration=duration, + target=[1, 10, 15], start_time=now, payload={"test": True}, type="UNIT_TEST", @@ -169,7 +171,7 @@ async def test_simple_start_stop( event = test_env.actor(1).initial_dispatch assert event.options == {"test": True} - assert event.components == dispatch.target + assert event.components == [ComponentId(1), ComponentId(10), ComponentId(15)] assert event.dry_run is False assert test_env.actor(1).is_running is True