diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 17459f5..9a74dc3 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -3,3 +3,9 @@ ## Summary This is the v1.0.0 release. It is equivalent to v1.0.0-rc3 and introduces a period of API stabilization. + +## New Features + +- Added `HostDispatchService`, a controller-facing service for listing, + getting, and streaming microgrid dispatches, plus reporting dispatch execution + status. diff --git a/proto/frequenz/api/dispatch/v1/dispatch.proto b/proto/frequenz/api/dispatch/v1/dispatch.proto index a52e295..a367eab 100644 --- a/proto/frequenz/api/dispatch/v1/dispatch.proto +++ b/proto/frequenz/api/dispatch/v1/dispatch.proto @@ -84,6 +84,42 @@ service MicrogridDispatchService { rpc DeleteMicrogridDispatch(DeleteMicrogridDispatchRequest) returns (DeleteMicrogridDispatchResponse); } +// HostDispatchService provides controller-facing dispatch operations for microgrid controllers. +// +// !!! note "API Consumers" +// This API is intended to be consumed exclusively by microgrid controllers. +// Application-level clients and user-facing applications must not access this service directly. +// Use `MicrogridDispatchService` for cloud/app-facing CRUD operations. +// +// !!! note "Authentication" +// All endpoints require authentication via controller-specific API credentials (controller API key +// and secret). Application API keys are not accepted. +// +// !!! note "Access" +// This service is only available on the internal/VPN network. +service HostDispatchService { + // Returns a list of dispatches for a given microgrid. + // + // Controllers use this to fetch the full set of active/incoming dispatches for their microgrid, + // for example on startup or after a reconnection. + rpc ListMicrogridDispatches(ListMicrogridDispatchesRequest) returns (ListMicrogridDispatchesResponse); + + // Streaming RPC for receiving dispatch updates for a given microgrid. + // + // Controllers subscribe to this stream to receive real-time notifications about new, updated, + // or deleted dispatches affecting their microgrid. + rpc StreamMicrogridDispatches(StreamMicrogridDispatchesRequest) returns (stream StreamMicrogridDispatchesResponse); + + // Get a single dispatch by its ID. + rpc GetMicrogridDispatch(GetMicrogridDispatchRequest) returns (GetMicrogridDispatchResponse); + + // Reports the execution status of a dispatch back to the service. + // + // Controllers use this to communicate whether a dispatch was successfully executed, is pending, + // failed, or was skipped. Status reporting enables the cloud to track dispatch lifecycle end-to-end. + rpc ReportMicrogridDispatchStatus(ReportMicrogridDispatchStatusRequest) returns (ReportMicrogridDispatchStatusResponse); +} + // Subscribe to a stream of microgrid dispatch requests. // This method provides real-time updates on newly or updated dispatch requests for edge-based // realtime decision making. @@ -765,6 +801,97 @@ message GetMicrogridDispatchResponse { Dispatch dispatch = 2; } +// Request to report the execution status of a dispatch. +message ReportMicrogridDispatchStatusRequest { + // The microgrid ID that the dispatch belongs to + uint64 microgrid_id = 1; + + // The dispatch identifier + uint64 dispatch_id = 2; + + // The status of the dispatch execution + DispatchStatus status = 3; + + // Optional human-readable message providing additional context (e.g., error details) + string message = 4; + + // Optional client-generated idempotency token. + // + // !!! important + // The idempotency token must be generated by the client (microgrid controller). + // Use a unique value per distinct status report. + // If retrying the exact same report (e.g., due to connectivity issues), reuse the same token. + string idempotency_token = 5; +} + +// Response for reporting a dispatch execution status. +message ReportMicrogridDispatchStatusResponse { + // The microgrid ID that the dispatch belongs to + uint64 microgrid_id = 1; + + // The dispatch identifier + uint64 dispatch_id = 2; + + // Whether the status report was accepted + bool accepted = 3; +} + +// Represents the execution status of a dispatch. +// +// !!! example "PENDING" +// A `SET_POWER` dispatch targeting `component_id: 42` with `start_time` in 10 minutes is +// received by the controller. The edge app schedules it but has not yet applied it to hardware. +// Status: `PENDING`. +// +// !!! example "ACTIVE" +// The dispatch's `start_time` arrives. The `BatteryPowerDispatcher` reads the payload +// `target_power_w: 50000` and sends the command to the inverter. The dispatch is now actively +// being enforced on hardware. Status: `ACTIVE`. +// +// !!! example "COMPLETED" +// After `duration: 3600` seconds, the dispatch's time window ends. The inverter has been +// holding 50 kW for the full hour with no errors. The edge app stops applying it and reports +// success. Status: `COMPLETED`. +// +// !!! example "FAILED" +// The edge app attempts to apply `target_power_w: 50000` but the inverter is in error state +// or the Modbus connection drops mid-execution. The actor attempted execution and failed. +// Status: `FAILED`. +// +// !!! example "SKIPPED" +// An aFRR dispatch and a peak-shaving dispatch overlap in the same time window. The merge +// strategy selects one and drops the other, so the dropped dispatch is never sent to hardware. +// Or a dispatch targets `category: BATTERY` but all batteries are at 100% SoC and can't +// accept charge. Status: `SKIPPED`. +// +// !!! example "CANCELLED" +// A `SET_POWER` dispatch is actively running (ACTIVE). The user deletes it via the UI or +// updates it setting `is_active: false`. The edge app receives the stream event, stops +// executing, and reports back that it no longer applies the dispatch. Status: `CANCELLED`. +// +enum DispatchStatus { + // UNSPECIFIED: Default, unspecified status. + DISPATCH_STATUS_UNSPECIFIED = 0; + + // PENDING: The dispatch is queued and waiting to be executed. + DISPATCH_STATUS_PENDING = 1; + + // ACTIVE: The dispatch is currently being executed. + DISPATCH_STATUS_ACTIVE = 2; + + // COMPLETED: The dispatch was executed successfully. + DISPATCH_STATUS_COMPLETED = 3; + + // FAILED: The dispatch execution failed. + DISPATCH_STATUS_FAILED = 4; + + // SKIPPED: The dispatch was skipped (e.g., due to conflicting higher-priority dispatch). + DISPATCH_STATUS_SKIPPED = 5; + + // CANCELLED: The dispatch was cancelled before or during execution. + DISPATCH_STATUS_CANCELLED = 6; +} + // Message to delete a single dispatch by its ID message DeleteMicrogridDispatchRequest { // The microgrid ID that the dispatch belongs to