diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index bd794953..a9f508a8 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -2,35 +2,15 @@ ## Summary -While the new TargetCategory class supports subtypes, only reading them is currently available; setting subtypes will be introduced in a future release. + ## Upgrading -* `TargetComponents` was reworked. It now is a type alias for `TargetIds | TargetCategories`: - * `TargetIds` can be used to specify one or more specific target IDs: - * `TargetIds(1, 2, 3)` or - * `TargetIds(ComponentIds(1), ComponentIds(2), ComponentIds(3))` - * `TargetCategories` can be used to specify one or more target categories: - * `TargetCategories(ComponentCategory.BATTERY, ComponentCategory.INVERTER)` -* Dispatch ids and microgrid ids are no longer simple `int` types but are now wrapped in `DispatchId` and `MicrogridId` classes, respectively. This allows for better type safety and clarity in the codebase. + ## New Features -* With the new `TargetCategory` class (providing `.category` and `.type`) we can now specify subtypes of the categories: - * `ComponentCategory.BATTERY` uses `BatteryType` with possible values: `LI_ION`, `NA_ION` - * `ComponentCategory.INVERTER` uses `InverterType` with possible values: `BATTERY`, `SOLAR`, `HYBRID` - * `ComponentCategory.EV_CHARGER` uses `EvChargerType`: with possible values `AC`, `DC`, `HYBRID` - * A few examples on how to use the new `TargetCategory`: - * `TargetCategory(BatteryType.LI_ION)` - * `category` is `ComponentCategory.BATTERY` - * `type` is `BatteryType.LI_ION` - * `TargetCategory(ComponentCategory.BATTERY)` - * `category` is `ComponentCategory.BATTERY` - * `type` is `None` - * `TargetCategories(InverterType.SOLAR)` - * `category` is `ComponentCategory.INVERTER` - * `type` is `InverterType.SOLAR` - +* `Dispatch.started_at(now: datetime)` was added as alternative to the `started` property for when users want to use the same `now` for multiple calls, ensuring deterministic return values with respect to the same `now`. ## Bug Fixes diff --git a/src/frequenz/client/dispatch/test/_service.py b/src/frequenz/client/dispatch/test/_service.py index f43ebc23..4192b2fc 100644 --- a/src/frequenz/client/dispatch/test/_service.py +++ b/src/frequenz/client/dispatch/test/_service.py @@ -46,6 +46,8 @@ NONE_KEY = "none" """Key that has no access to any resources in the FakeService.""" +_logger = logging.getLogger(__name__) + class FakeService: """Dispatch mock service for testing.""" @@ -178,7 +180,7 @@ async def StreamMicrogridDispatches( receiver = self._stream_channel.new_receiver() async for message in receiver: - logging.debug("Received message: %s", message) + _logger.debug("Received message: %s", message) if message.microgrid_id == MicrogridId(request.microgrid_id): response = StreamMicrogridDispatchesResponse( event=message.event.event.value, diff --git a/src/frequenz/client/dispatch/types.py b/src/frequenz/client/dispatch/types.py index 07d81a53..e330c221 100644 --- a/src/frequenz/client/dispatch/types.py +++ b/src/frequenz/client/dispatch/types.py @@ -427,6 +427,26 @@ def started(self) -> bool: return False now = datetime.now(tz=timezone.utc) + return self.started_at(now) + + def started_at(self, now: datetime) -> bool: + """Check if the dispatch has started. + + A dispatch is considered started if the current time is after the start + time but before the end time. + + Recurring dispatches are considered started if the current time is after + the start time of the last occurrence but before the end time of the + last occurrence. + + Args: + now: time to use as now + + Returns: + True if the dispatch is started + """ + if not self.active: + return False if now < self.start_time: return False