Giter VIP home page Giter VIP logo

frequenz-api-dispatch's People

Contributors

christianparpart avatar dependabot[bot] avatar llucax avatar marenz avatar stefan-brus-frequenz avatar talwesingh avatar tiyash-basu-frequenz avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

frequenz-api-dispatch's Issues

Restructure and Cleanup of `DispatchCreateRequest` and more

What's needed?

We need to restructure the API to improve alignment with the other APIs and make it easier extendable. Moreover we need a more clear seperation of concerns.

Proposed solution

service MicrogridDispatchService {
  // Returns a list of all dispatches
-  rpc ListMicrogridDispatches(DispatchListRequest) returns (DispatchList);
+  rpc ListMicrogridDispatches(ListMicrogridDispatchRequest) 
+         returns (ListMicrogridDispatchResponse);

  // Create a new dispatch
-  rpc CreateMicrogridDispatch(DispatchCreateRequest) returns (google.protobuf.Empty);
+  rpc CreateMicrogridDispatch(CreateMicrogridDispatchRequest) 
+         returns (CreateMicrogridDispatchResponse);
  
  // Update a dispatch
-  rpc UpdateMicrogridDispatch(DispatchUpdateRequest) returns (google.protobuf.Empty);
+  rpc UpdateMicrogridDispatch(UpdateMicrogridDispatchRequest) 
+         returns (UpdateMicrogridDispatchResponse);
  
  // Get a single dispatch
-  rpc GetMicrogridDispatch(DispatchGetRequest) returns (Dispatch);
+  rpc GetMicrogridDispatch(GetMicrogridDispatchRequest) 
+         returns (GetMicrogridDispatchResponse);

  // Delete a given dispatch
  rpc DeleteMicrogridDispatch(DispatchDeleteRequest) returns (google.protobuf.Empty);
}

// Message representing one dispatch.
-//
-// Timezone Note: Timestamps are in UTC. It is the responsibility of each microgrid to translate UTC
-// to its local timezone.
message Dispatch {
-  // The dispatch identifier
-  uint64 id = 1;

-  // The microgrid identifier
-  uint64 microgrid_id = 2;

  // The dispatch type.
  // Contains user-defined information about what "type" of dispatch this is.
  // Downstream applications that consume the dispatch API are responsible for
  // understanding and processing this field.
-  string type = 3;
+  string type = 1;

-  // The creation time in UTC
-  // This is set when a dispatch is created via the create request message
-  google.protobuf.Timestamp create_time = 4;

-  // The update time in UTC
-  // This is set when a dispatch is modified via the update request message
-  google.protobuf.Timestamp update_time = 5;

-  // The start time in UTC
+  // The dispatch start time in UTC. 
+  // For reoccuring dispatches this is when the first time execution occurs. When 
+  // creating a dispatch, ensure that the starting timestamp is set to the current 
+  // time or any future time. Timestamps earlier than the current time are not allowed.
-  google.protobuf.Timestamp start_time = 6;
+  google.protobuf.Timestamp start_time = 2;

  // Duration in seconds
-  uint32 duration = 7;
+  optional uint32 duration = 3;

-  // The component selector
+  // Dispatch microgrid component selector.
-  ComponentSelector selector = 8;
+  ComponentSelector selector = 4;

-  // The "active" status
-  // An active dispatch is eligible for processing, either immediately or at a scheduled
-  // time in the future, including recurring dispatches. If a dispatch is set to
-  // inactive, it won't be processed even if it matches all other conditions, allowing
-  // for temporary disabling of dispatches without deletion.
-  bool is_active = 9;
+  bool is_active = 5;

-  // The "dry run" status
-  // A dry run dispatch is executed for logging and monitoring purposes
-  // without affecting the microgrid components. This is useful, for example,
-  // in scenarios where a user may want to test dispatch behavior without
-  // actually affecting any component states.
-  // Notably, a dispatch can be both "dry run" and "active," allowing for
-  // the system to generate logs and observe behavior without making actual changes.
-  bool is_dry_run = 10;
+  bool is_dry_run = 6;

-  // The dispatch payload
-  google.protobuf.Struct payload = 11;
+  google.protobuf.Struct payload = 7;

-  // The recurrence rule
-  RecurrenceRule recurrence = 12;
+  -  RecurrenceRule recurrence = 8;
}

+// Represents a microgrid dispatch with full details, including its ID, state and associated
+// UTC timestamps.
+message DispatchDetail {
+  // Unique identifier of the microgrid dispatch.
+  uint64 dispatch_id = 1;
+
+  // The details of the dispatch.
+  Dispatch dispatch = 2;
+
+  // UTC Timestamp when the order was created.
+  google.protobuf.Timestamp create_time = 3;
+
+  // UTC Timestamp of the last update to the order.
+  google.protobuf.Timestamp modification_time = 4;
+}

// Message to create a new dispatch with the given attributes
-message DispatchCreateRequest {
+message CreateMicrogridDispatchRequest {
  // The microgrid identifier
  uint64 microgrid_id = 1;

-  // The type of dispatch
-  string type = 2;
+  // The details of the dispatch being created.
+  Dispatch dispatch = 2;

-  // The start time
-  // When creating a dispatch, ensure that the starting timestamp is set to
-  // the current time or any future time.
-  // Timestamps earlier than the current time are not allowed.
-  google.protobuf.Timestamp start_time = 3;

-  // Duration in seconds
-  uint32 duration = 4;

-  // The component selector
-  ComponentSelector selector = 5;

-  // The "active" status
-  bool is_active = 6;

-  // The "dry run" status
-  bool is_dry_run = 7;

-  // The dispatch payload
-  google.protobuf.Struct payload = 8;

-  // The recurrence rule
-  RecurrenceRule recurrence = 9;
}

+// Represents the server's response after a new dispatch has been successfully
+// created for a specific microgrid.
+//
+// This response provides essential details about the newly created dispatch, such
+// as the unique dispatch ID and the state of the dispatch.
+message CreateMicrogridDispatchResponse {
+  // ID of the microgrid the dispatch belongs to.
+  uint64 microgrid_id = 1;
+
+  // Details of the newly created microgrid dispatch.
+  DispatchDetail dispatch_detail = 2;
+}

// Message for listing dispatches for a given microgrid, and an optional filter
-message DispatchListRequest {
+message ListMicrogridDispatchRequest {
  // ...
}

-// A list of dispatches
+// Response from listing dispatches for a given microgrid.
-message DispatchList {
+message ListMicrogridDispatchResponse {
+  // ID of the microgrid the list of dispatches belongs to.
+  uint64 microgrid_id = 1;
+  
-  // The dispatches
+  // List of all dispatches with their details.
-   repeated Dispatch dispatches = 1;
+  repeated DispatchDetail dispatch_detail = 2;
}

-// Message to get a single dispatch by its ID
+// // Request to retrieve a single dispatch for a given microgrid.
-message DispatchGetRequest {
+message GetMicrogridDispatchRequest {
+  // ID of the microgrid the dispatch belongs to.
+  uint64 gridpool_id = 1;
  
  // The dispatch identifier
-  uint64 id = 1;
+  uint64 dispatch_id = 2;
}

+// Response from requesting order details for a specific order.
+message GetMicrogridDispatchResponse {
+  // ID of the microgrid the dispatch belongs to.
+  uint64 microgrid_id = 1;
+
+  // Details of the retrieved dispatch.
+  DispatchDetail dispatch_detail = 2;
+}

-// Message to update the dispatch with the given ID, with the given attributes
+// Request to update an existing dispatch for a given microgrid.
-message DispatchRequest {
+message UpdateMicrogridDispatchRequest {
  // Message containing the updated dispatch attributes
  message DispatchUpdate {
      // ...
  }
  
+  // ID of the microgrid the dispatch belongs to.
+  uint64 microgrid_id = 1;
+  
   // The dispatch identifier
-  uint64 id = 1;
+  uint64 dispatch_id = 2;

  // Field mask specifying which fields should be updated
-  google.protobuf.FieldMask update_mask = 2;
+  google.protobuf.FieldMask update_mask = 3;

  // The updated dispatch attributes
-  DispatchUpdate update = 3;
+  DispatchUpdate update = 4;
}

+// Response from updating an existing dispatch for a given microgrid.
+message UpdateMicrogridDispatchResponse {
+  // ID of the microgrid the dispatch belongs to.
+  uint64 microgrid_id = 1;
+
+  // Details of the updated dispatch.
+  DispatchDetail dispatch_detail = 2;
+}

Use cases

No response

Alternatives and workarounds

No response

Additional context

Additional change to the duration field that can be incorporated into this PR is #162 and #151

Extend duration documentation

What's needed?

We need to improve the documentation for the duration parameter as shown below:

Proposed solution

message Dispatch {
  // ...

-  // Duration in seconds
+  // Duration of the dispatch in seconds. 
+  //
+  // !!! note
+  //     This field manages how long the dispatch lasts:
+  //     - `null` value indicates an infinite duration, meaning the dispatch continues indefinitely.
+  //     - A value of `0` indicates a one-time execution, which does not repeat or persist.
+  //     - Positive values specify the duration in seconds for which the dispatch should be active.
+  //
+  //     Example of how to set duration
+  //         duration_seconds: { value: 3600 } // Duration of 1 hour
+  //         duration_seconds: null // Infinite duration
+  //         duration_seconds: { value: 0 } // One-time execution
- //  uint32 duration = 7;
+ //  optional uint32 duration_seconds = 7;
}

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Add example to documentation of "payload" field

What's needed?

The "payload" field could use some clarification as to what it's for.

Proposed solution

Proposed documentation example:

// Message representing one dispatch.
//
// Timezone Note: Timestamps are in UTC. It is the responsibility of each microgrid to translate UTC
// to its local timezone.
message Dispatch {
  // ... [other fields] ...

  // The dispatch payload
  // This field is used to carry additional, user-defined data relevant to the dispatch.
  //
  // The payload typically contains a JSON object with settings that dictate how the dispatch should be processed.
  // This provides the flexibility to include a variety of dispatch parameters without altering the API structure.
  //
  // The payload is expected to follow a specific format that the downstream applications consuming the dispatch API
  // are responsible for understanding and processing.
  //
  // Example JSON payload:
  // {
  //   "settings": {
  //     "power_max": 10,   // Maximum power level for the dispatch (in kW)
  //     "soc_min": 20,     // Minimum state of charge for battery storage (in %)
  //     "soc_max": 80      // Maximum state of charge for battery storage (in %)
  //   }
  // }
  //
  // In this example, a microgrid could use this payload to set operational parameters such as the maximum power output
  // of a solar PV array or the charge/discharge limits of a battery storage system. This flexibility allows the microgrid
  // to dynamically adjust its behavior based on the current needs or conditions, such as optimizing battery usage or
  // limiting PV output during low demand periods.
  google.protobuf.Struct payload = 11;

  // ... [other fields] ...
}

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Reoccurrence end time and duration both need to be supported

What's needed?

Right now we only support a start and end time for a dispatch request but there also needs to be a duration depending on the dispatch type.

Proposed solution

Support duration in the Dispatch message:

-  // The end time in UTC
+  // Duration in seconds
- google.protobuf.Timestamp end_time = 7;
+ uint32 duration = 7;

Move the end_time from the Dispatch message to the RecurrenceRule message:

  // On which month(s) of the year does the event occur
  repeated uint32 bymonths = 8;

+  // The end time in UTC
+  optional google.protobuf.Timestamp end_time = 9;

Use cases

  1. Discharging a battery for 30min once.
  2. Charging a battery for 30min but repeat it every day until a given end date.

Alternatives and workarounds

No response

Additional context

No response

Add Dispatch State

What's needed?

We need to be able to report the dispatch state.

Proposed solution

+// Enum DispatchState represents different stages of a dispatch's lifecycle, including its retrieval 
+// and execution states.
+enum DispatchState {
+  // UNKNOWN: Default status, unknown or not specified.
+  DISPATCH_STATE_UNKNOWN = 0;
+  
+  // PENDING_RETRIEVAL: Dispatch is created and waiting to be retrieved by the controller.
+  // This state is also set when an existing dispatch is updated, requiring re-retrieval to 
+  // incorporate changes.
+  DISPATCH_STATE_PENDING_RETRIEVAL = 1; 
+  
+  // RETRIEVED: Dispatch has been retrieved by the controller.
+  DISPATCH_STATE_RETRIEVED = 2;
+  
+  // STARTED: Dispatch has started execution.
+  DISPATCH_STATE_STARTED = 3;
+  
+  // COMPLETED: Dispatch has been executed and completed.
+  DISPATCH_STATE_COMPLETED = 4;
+
+  // WAITING: Dispatch is waiting to start its next scheduled execution.
+  DISPATCH_STATE_WAITING = 5;
+}

// Represents a microgrid dispatch with full details, including its ID, state and associated
// UTC timestamps.
message DispatchDetail {
  // Unique identifier of the microgrid dispatch.
  uint64 dispatch_id = 1;

  // The details of the dispatch.
  Dispatch dispatch = 2;

+  // Details of the dispatch current state.
+  DispatchState state = 3;

  // UTC Timestamp when the order was created.
-  google.protobuf.Timestamp create_time = 3;
+  google.protobuf.Timestamp create_time = 4;

  // UTC Timestamp of the last update to the order.
-  google.protobuf.Timestamp modification_time = 4;
+  google.protobuf.Timestamp modification_time = 5;
}

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Remove `create_time` field from update request

What happened?

The create time field should not be able to be altered via API after a dispatch has been created

What did you expect instead?

No create_time field on the update request

Affected version(s)

No response

Affected part(s)

The protocol buffer definition files (part:protobuf)

Extra information

No response

Use FieldMasks and fix `optional` keyword usage

What's needed?

In order to support partial updates of objects, and potentially also partial getting of objects, the API should start using FieldMasks. FieldMasks provide a way of stating explicitly which fields are to be retrieved via the Get, or which fields are to be touched via the Update.

Proposed solution

The DispatchUpdateRequest needs to support field masks and optional keyword.

+ import "google/protobuf/field_mask.proto";

// Message to update the dispatch with the given ID, with the given attributes
message DispatchUpdateRequest {
  // The dispatch identifier
  uint64 id = 1;

-  // The start time
-  // When updating a dispatch, ensure that the starting timestamp is set to
-  // the current time or any future time.
-  // Timestamps earlier than the current time are not allowed.
-  google.protobuf.Timestamp start_time = 2;

-  // The end time
-  google.protobuf.Timestamp end_time = 3;

-  // The component selector
-  ComponentSelector selector = 4;

-  // The "active" status
-  optional bool is_active = 5;

-  // The "dry run" status
-  optional bool is_dry_run = 6;

-  // The dispatch payload
-  google.protobuf.Struct payload = 7;

-  // The recurrence rule
-  RecurrenceRule recurrence = 8;

+  // Field mask specifying which fields should be updated
+  google.protobuf.FieldMask update_mask = 2;

+  // The fields that can be updated
+  DispatchUpdatableFields updatable_fields = 3;
}

+ // Fields that can be updated for a dispatch
+ message DispatchUpdatableFields {
+   // The start time
+   // When updating a dispatch, ensure that the starting timestamp is set to
+   // the current time or any future time.
+   // Timestamps earlier than the current time are not allowed.
+   google.protobuf.Timestamp start_time = 1;

+   // The end time
+   google.protobuf.Timestamp end_time = 2;

+   // The component selector
+   ComponentSelector selector = 3;

+   // The "active" status
+   optional bool is_active = 4;

+   // The "dry run" status
+   optional bool is_dry_run = 5;

+   // The dispatch payload
+   google.protobuf.Struct payload = 6;

+   // The recurrence rule
+   RecurrenceRule recurrence = 7;
+ }

Use cases

No response

Alternatives and workarounds

No response

Additional context

Further readings how to apply field masks can be found here [1] [2]

Rust also supports field masks.

Add `update_time` field to Dispatch message

What's needed?

Update time is required to keep track of when a dispatch was last updated, mainly for caching purposes. It should be updated whenever an update request message touches on a dispatch, and set to the same timestamp as create_time when the dispatch is created.

Proposed solution

No response

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Remove the HTTP proxy gateway URLs

What's needed?

The google HTTP proxy definitions like:

    option (google.api.http) = {
      patch: "/v1/dispatches"
    };

Are not required by the dispatch API.

Proposed solution

Simply remove them.

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Adjust documentation according to Dart style guide & mkdocs admonitions

What's needed?

The documentation should be adjusted according to:

Proposed solution

Here is a draft on how to adjust the protobuf specification.

// Frequenz Dispatch Automation API
//
// This API automates the process of electricity dispatches for microgrids, streamlining 
// the complex task of electricity dispatching to manage local electricity supply 
// and demand efficiently.

// !!! note
// The primary audience for this API includes application developers in the 
// energy sector focusing on microgrid electricity flow optimization.
//

// ... (rest of the general comments remain unchanged)

// Service providing operations for dispatching electricity to microgrid components.
service MicrogridDispatchService {
  // Lists all existing dispatches.
  rpc ListMicrogridDispatches(DispatchListRequest) returns (DispatchList);
  
  // Creates a new dispatch.
  rpc CreateMicrogridDispatch(DispatchCreateRequest) returns (google.protobuf.Empty);

  // ... (rest of the rpcs remain unchanged)
}

// Represents a single electricity dispatch.
//
// !!! note
// All timestamps are in UTC. Microgrids must translate UTC to local timezones.
//
message Dispatch {
  // Identifier for the dispatch.
  uint64 id = 1;

  // Identifier for the microgrid involved in this dispatch.
  uint64 microgrid_id = 2;

  // Type of the dispatch, user-defined.
  // Downstream applications should understand and process this field accordingly.
  string type = 3;

  // ... (rest of the fields remain unchanged)
}

// ... (rest of the messages remain unchanged)

// Defines the rules for when and how a dispatch should re-occur.
//
// !!! note
// Timestamps are in UTC. It's each microgrid's responsibility to translate UTC to its local timezone.
//
message RecurrenceRule {
  // Frequency specifier of the recurring dispatch.
  Frequency freq = 1;

  // ... (rest of the fields remain unchanged)
}

// ... (rest of the messages remain unchanged)

Use cases

Correct documentation creation with mkdocs and following a unified standards.

Alternatives and workarounds

No response

Additional context

No response

Extend the dispatch API to allow filtering of reoccurring and non-reoccurring dispatches by their end time

What's needed?

Can the filtering be extended to allow filtering by end time and duration in order to determine if a dispatch has finished or not?

Proposed solution

+ // Enum for the type of dispatch based on its recurrence.
+ enum RecurrenceType {
+   // UNSPECIFIED: Recurrence type is not specified.
+   RECURRENCE_TYPE_UNSPECIFIED = 0;
  
+   // NON_RECURRING: Dispatches that do not recur.
+   RECURRENCE_TYPE_NON_RECURRING = 1;
  
+   // RECURRING: Dispatches that recur.
+   RECURRENCE_TYPE_RECURRING = 2;               
+ }

// Filter parameter for specifying multiple time intervals
message TimeIntervalFilter {
-  // Filter by start_time >= this timestamp
+  // Filter by time >= this timestamp.
-  google.protobuf.Timestamp start_from = 1;
+  google.protobuf.Timestamp from = 1;

-  // Filter by start_time < this timestamp
+  // Filter by time < this timestamp.
-  google.protobuf.Timestamp start_to = 2;
+  google.protobuf.Timestamp to = 2;

-  // Filter by recurrence.end_criteria.until >= this timestamp
-  google.protobuf.Timestamp end_from = 3;

-  // Filter by recurrence.end_criteria.until < this timestamp
-  google.protobuf.Timestamp end_to = 4;
}

// Parameters for filtering the dispatch list
message DispatchFilter {
-  // Filter by component ID or category
+  // Optional filter by component ID or category.
  repeated ComponentSelector selectors = 1;

-  // Filter by time interval
-  // If no interval is provided, all dispatches starting from the
-  // current timestamp will be included.
-  TimeIntervalFilter time_interval = 2;

-  // Filter by active status
+  // Optional filter by active status.
  // If this field is not set, dispatches of any active status will be included.
-  optional bool is_active = 3;
+  optional bool is_active = 2;

-  // Filter by dry run status
+  // Optional filter by dry run status.
  // If this field is not set, dispatches of any dry run status will be included.
-  optional bool is_dry_run = 4;
+  optional bool is_dry_run = 3;

+  // Optional filter by reoccurring and none-reoccurring dispatches.
+ // If not specified both types will be returned.
+  optional RecurrenceType recurrence_type = 4;

+  // Optional filter by start time.
+  // If no interval is provided, all dispatches will be returned.
+  TimeIntervalFilter start_time_interval = 5;

+  // Optional filter by end time
+  // Filter dispatches based on their explicit or estimated end time.
+  TimeIntervalFilter end_time_interval = 6;

+  // Optional filter by update time
+  TimeIntervalFilter update_time_interval = 7;
}

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Documentation: dry run and the state of being active are not mutually exclusive

What's needed?

Improved documentation for using is_active and is_dry_run properties. The properties is_dry_run and the state of being active are not mutually exclusive. For example, there might be the case where a dispatch is being executed repeatedly as a dry run, because a developer does not want any changes to be written anywhere, but still wants to see the logs. The developer could then want to deactivate this dry run dispatch for some time.

Proposed solution

Enhance the documentation of the is_active and is_dry_run properties in the Dispatch message.

message Dispatch {
  // ... 

  // The "active" status
  // An active dispatch is eligible for processing, either immediately or at a scheduled time in the future, 
  // including recurring dispatches. If a dispatch is set to inactive, it won't be processed even
  // if it matches all other conditions, allowing for temporary disabling of
  // dispatches without deletion.
  bool is_active = 9;

  // The "dry run" status
  // A dry run dispatch is executed for logging and monitoring purposes 
  // without affecting the microgrid components. This is useful, for example,
  // in scenarios where a user may want to test dispatch behavior without
  // actually affecting any component states.
  // Notably, a dispatch can be both "dry run" and "active," allowing for 
  // the system to generate logs and observe behavior without making actual changes.
  bool is_dry_run = 10;

  // ... 
}

Use cases

Improved documentation

Alternatives and workarounds

No response

Additional context

No response

Add UTC timestamp remarks

What's needed?

Indication that the UTC timestamps are translated to the microgrids local timezone.

Proposed solution

Add timezone clarification notes to the Dispatch and RecurrenceRule message as drafted below:

// Message representing one dispatch
// Note: Timestamps are in UTC. Each microgrid is responsible for translating the UTC timestamp to its local time.
message Dispatch {
  // ... existing fields ...

  // The creation time in UTC
  // This is set when a dispatch is created via the create request message
  google.protobuf.Timestamp create_time = 4;

  // The update time in UTC
  // This is set when a dispatch is modified via the update request message
  google.protobuf.Timestamp update_time = 5;

  // The start time in UTC
  google.protobuf.Timestamp start_time = 6;

  // The end time in UTC
  google.protobuf.Timestamp end_time = 7;

  // ... existing fields ...

  // The recurrence rule
  RecurrenceRule recurrence = 12;
}

// Ruleset governing when and how a dispatch should re-occur
//
// Timezone Note: Timestamps are in UTC. It is the responsibility of each microgrid to translate UTC 
// to its local timezone.
//
// This definition tries to adhere closely to the iCalendar specification (RFC 5545),
// particularly for recurrence rules. For advanced use-cases or further clarifications,
// refer to RFC 5545.
//
message RecurrenceRule {
  // ... existing fields ...
}

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Reoccurring dispatches

What's needed?

What is need is the ability to request reoccurring dispatch requests. By reoccurring I mean the ability to schedule reoccurring events like e.g. that every Monday morning a battery should be charged.

For the start we need the ability to repeat a dispatch request in a given interval or at certain times. Here is a list of feature we will need

  1. Repeat every day at a given time
  2. Repeat at certain day every n week.
  3. Repeat every hour
    ...

Proposed solution

Extend the dispatch message to have an optional repeats field. Based upon @llucax suggestion to take some inspiration from the iCal standard an extension of the current protofbuf spec could look like the following:

  // import "google/protobuf/timestamp.proto";

message RecurrenceRule {
  enum Frequency {
    HOURLY = 0;
    DAILY = 1;
    WEEKLY = 2;
    MONTHLY = 3;
    YEARLY = 4;
  }

  Frequency freq = 1;          // Frequency of recurrence
  sint32 interval = 2;         // Interval between each freq
  sint32 count = 3;            // Number of occurrences
  google.protobuf.Timestamp until = 4;  // A date-time specifying end of recurrence
  repeated sint32 byhour = 5;       // Hour of the day
  repeated sint32 byday = 6;        // Day of the week
  repeated sint32 bymonthday = 7;   // Day of the month
  repeated sint32 byyearday = 8;    // Day of the year
  repeated sint32 byweekno = 9;     // Week number of the year
  repeated sint32 bymonth = 10;     // Month of the year
  repeated sint32 bysetpos = 11;    // Position in the set of recurrence instances
  bool wkst = 12;                   // The day that the workweek starts
}

message DispatchRequest {  // example dispatch request message
  string id = 1;  // Dispatch ID
  google.protobuf.Timestamp start = 2; // Start time of the event
  google.protobuf.Timestamp end = 3;   // End time of the event
  RecurrenceRule rrule = 4;    // Recurrence rule for this dispatch request
}

If until or count isn't set, the dispatch request will repeat indefinitely.

The start and end fields represent the time span of the event, whether it's repeating or not. If the event is a one-off event, start and end must specify the exact date and time of the event, because there's no recurrence rule to determine any other occurrences. If the event is a repeating event, start and end specify the time span of the event for the first occurrence. The recurrence rule then uses that start time as the base for determining subsequent occurrences.

For example, if there is a dispatch request that starts at "2023-06-13T00:00:00" (midnight at the start of June 13th, 2023) and ends at "2023-06-13T04:00:00" (4am on the same day), and the RecurrenceRule specifies DAILY frequency, the result will be a repeating dispatch request that occurs every day from midnight to 4am, starting on June 13th, 2023.

The start and end fields, combined with the RecurrenceRule, are used to define the entire sequence of occurrences for a repeating event. However, in each individual occurrence, the start and end still just specify the time span of that occurrence.

Here are some examples on how it might work:

Example 1: Request dispatch once without reoccurrence

To schedule a dispatch request that just runs once on e.g. the next Monday, there would be no reoccurrence rule and the start date being set to when the dispatch is suppose to start, same with the end date.

Example 2: Dispatch request to reoccur at a given interval 0:30, 1:30, 2:30 etc.

If something repeats every hour on the half-hour mark, the RecurrenceRule would be set to HOURLY frequency and byminute set to 30. The start time of the event should be set to the first occurrence time, such as "0:30". byminute would have to be set to 30, which means the event happens on the half-hour of every hour.

Example 3: Repeating every day from 0:00a to 4:00a

In this case, freq is set to DAILY, which means the event repeats every day. start is set to the time when the event starts (e.g., "0:00"), and end is set to the time when the event ends (e.g., "4:00"). interval needs to be set to 1 in RecurrenceRule to make it repeat daily without skipping any day.

Example 4: Repeating every day at 10a and 2p

If there is a dispatch request to be repeated every day, but it only happens at 10 AM and 2 PM. In that case, one would set the freq field to DAILY and the byhour field to [10, 14]. This indicates that the event occurs every day at both 10 AM and 2 PM.

Use cases

  1. Schedule to charge a battery at a certain point in time on a daily basis.
  2. Run certain services repeatedly at a certain point in time.

Alternatives and workarounds

An app would have to create each individual dispatch request on a reoccurring basis.

Additional context

https://datatracker.ietf.org/doc/html/rfc5545#section-3.3.10

Streaming rpc method

What's needed?

We need an additional RPC method that supports streaming of dispatches for a microgrid.

Proposed solution

Add a new RPC called StreamMicrogridDispatches:

service MicrogridDispatchService {
  // Returns a list of all dispatches
  rpc ListMicrogridDispatches(DispatchListRequest) returns (DispatchList);

+  // Streaming RPC for receiving dispatch updates for a given microgrid
+  rpc StreamMicrogridDispatches(StreamMicrogridDispatchesRequest) returns (stream StreamMicrogridDispatchesResponse);

  // Create a new dispatch
  rpc CreateMicrogridDispatch(DispatchCreateRequest) returns (google.protobuf.Empty);

  // Update a dispatch
  rpc UpdateMicrogridDispatch(DispatchUpdateRequest) returns (google.protobuf.Empty);

  // Get a single dispatch
  rpc GetMicrogridDispatch(DispatchGetRequest) returns (Dispatch);

  // Delete a given dispatch
  rpc DeleteMicrogridDispatch(DispatchDeleteRequest) returns (google.protobuf.Empty);
}

+// 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.
+ message StreamMicrogridDispatchesRequest {
+   // ID of the microgrid to subscribe to
+   uint64 microgrid_id = 1;  
+ }

+ // Response to a subscription request for a stream of microgrid dispatches.
+ // Real-time information on dispatches affecting a certain microgrid are pushed through this response.
+ message StreamMicrogridDispatchesResponse {
+   // Dispatch record returned. 
+   Dispatch dispatch = 1;       
+ }

Use cases

An actor would like to receive any scheduled dispatches as soon as they are created or updated.

Alternatives and workarounds

Polling.

Additional context

No response

Renames `dispatches` to `dispatch_list`

What's needed?

In order to align with the other API specs its suggested to rename dispatches to dispatch_list.

Proposed solution

No response

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Do not allow updating dispatch `type`

What's needed?

Remove support for changing the dispatch type after creation.

Proposed solution

// Message to update the dispatch with the given ID, with the given attributes
message DispatchUpdateRequest {
  // Message containing the updated dispatch attributes
  message DispatchUpdate {
       ...
    }

-    // The type of dispatch
-    optional string type = 1;

Use cases

A user should not be able to change the dispatch type after creation as this would mean handing over an existing dispatch from one actor to another.

Alternatives and workarounds

Delete dispatch and create a new one instead of trying to update the type of an existing dispatch.

Additional context

No response

Requirements for FCR balancing actor

What's needed?

This is a tracking issue for the addition of a new settings type for FCR balancing dispatches. Requirements still need to be gathered.

Proposed solution

No response

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Return dispatch on `CreateMicrogridDispatch` and `UpdateMicrogridDispatch` request

What's needed?

When requesting a new dispatch the id of the dispatch and its properties are not being returned. Same for the update request. In both cases we should follow Googles best practise guidlines and not just return an Empty message.

Proposed solution

  // Create a new dispatch
-  rpc CreateMicrogridDispatch(DispatchCreateRequest) returns (google.protobuf.Empty);
+  rpc CreateMicrogridDispatch(DispatchCreateRequest) returns (Dispatch);

  // Update a dispatch
-  rpc UpdateMicrogridDispatch(DispatchUpdateRequest) returns (google.protobuf.Empty);
+  rpc UpdateMicrogridDispatch(DispatchUpdateRequest) returns (Dispatch);

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Remove ability to update microgrid_id for a `DispatchUpdateRequest`

What's needed?

Currently its possible to change the microgrid id of a dispatch request. This should not be possible. If a dispatch has been assigned to a wrong microgrid the entire dispatch should be deleted and a new one being created.

Proposed solution

// Message to update the dispatch with the given ID, with the given attributes
message DispatchUpdateRequest {
  // The dispatch identifier
  uint64 id = 1;

-  // The microgrid identifier
-  optional uint64 microgrid_id = 2;

  ...
}

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Restructure RPC methods

What's needed?

As discussed we wan't to restructure the API in a way that it can more easily extendible in the future and doesn't break backwards compatibility.

Proposed solution

The proposed changes to the Protobuf definition are:

service MicrogridDispatchService {
  // Returns a list of all dispatches
-  rpc ListMicrogridDispatches(DispatchListRequest) returns (DispatchList);
+ rpc ListMicrogridDispatches(ListMicrogridDispatchesRequest) returns (ListMicrogridDispatchesResponse);

  // Create a new dispatch
-  rpc CreateMicrogridDispatch(DispatchCreateRequest) returns (google.protobuf.Empty);
+  rpc CreateMicrogridDispatch(CreateMicrogridDispatchRequest) returns (CreateMicrogridDispatchResponse);

  // Update a dispatch
-  rpc UpdateMicrogridDispatch(DispatchUpdateRequest) returns (google.protobuf.Empty);
+  rpc UpdateMicrogridDispatch(UpdateMicrogridDispatchRequest) returns (UpdateMicrogridDispatchResponse);

  // Get a single dispatch
-  rpc GetMicrogridDispatch(DispatchGetRequest) returns (Dispatch);
+  rpc GetMicrogridDispatch(GetMicrogridDispatchRequest) returns (GetMicrogridDispatchResponse);

  // Delete a given dispatch
-  rpc DeleteMicrogridDispatch(DispatchDeleteRequest) returns (google.protobuf.Empty);
+  rpc DeleteMicrogridDispatch(DeleteMicrogridDispatchRequest) returns (DeleteMicrogridDispatchResponse);
}

Use cases

Keeping backwards compatibility in case we need to extend the API.

Alternatives and workarounds

New API version.

Additional context

No response

Improve `payload` documentation

What's needed?

Extend the documentation for the payload parameter as shown below:

  • Creates a new dispatch with the specified payload.
  • Note: The payload must conform to the following constraints:
    • Maximum nesting depth of 5. Payloads with structures nested deeper than this will be rejected.
    • Payloads must be valid according to the JSON structure.

Proposed solution

message Dispatch {
  // ...
  
  
  // The dispatch payload.
+  // 
+  // Note!!! 
+  //     The payload field allows for flexible JSON data to be associated with this dispatch.
+  //     The payload must adhere to the following constraints:
+  //      - Maximum JSON nesting depth: 5 levels. 
+  //      - The data should not contain executable code or scripts.
+  //      - Ensure all data is properly sanitized and encoded.
+  //      - The total size of the payload should not exceed 50 KB.
  google.protobuf.Struct payload = 11;

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Allow only filtering by one microgrid_id

What's needed?

Currently its possible to request dispatches for multiple microgrids. This should be limited to one microgrid. Moreover, filtering by a list of dispatch ids should also be removed as the use case is uncertain right now. Same applies to a few more filters that have uncertain use cases.

Filtering by start_time should also be enhanced so that all current and future dispatches are being returned if no start_time is being given.

Proposed solution

message DispatchFilter {
-  // Filter by dispatch ID
-  repeated uint64 ids = 1;

  // Filter by microgrid ID
-  repeated uint64 microgrid_ids = 2;
+  uint64 microgrid_id = 1;

-  // Filter by dispatch type
-  repeated string types = 3;

  // Filter by component ID or category
-  repeated DispatchComponentSelector selectors = 4;
+  repeated DispatchComponentSelector selectors = 2;

  // Filter by time interval
+  // If start_from is not provided only current and future dispatches will be returned
-  TimeIntervalFilter time_interval = 5;
+  TimeIntervalFilter time_interval = 3;

  // Filter by "active" status
-  optional bool is_active = 6;

  // Filter by "dry run" status
-  optional bool is_dry_run = 7;
}

Use cases

What is mostly needed is for a dispatch actor to be able to receive the list of current dispatches. This requires to be able to request any current and future dispatches. In some cases it might also be necessary to retrieve past dispatches but this wouldn't be the default use case.

Alternatives and workarounds

No response

Additional context

No response

Improve documentation on Modifying Recurrence

What's needed?

Modifications to the recurrence of a dispatch, from recurring to non-recurring or the other way around are prohibited. Currently this isn't indicated in the protobuf definition and needs improving.

Proposed solution

message Dispatch {
  // ..

+  // Recurrence is immutable once set. Attempting to change a dispatch from recurring to non-recurring,
+  // or from non-recurring to recurring, after creation is prohibited and will result in an error.
  RecurrenceRule recurrence = 12;  

// ...
}

-// Message to update the dispatch with the given ID, with the given attributes
+// DispatchUpdateRequest defines the request structure for updating an existing dispatch.
+//
+// This request is restricted to ensure that the recurrence nature of the dispatch cannot be altered
+// from recurring to non-recurring or vice versa after creation. If such a change is attempted, the API 
+// will return an error stating that modifying the recurrence nature of a dispatch is not allowed.
+//
+// This policy helps maintain the integrity and consistency of dispatch scheduling.
message DispatchUpdateRequest {
   // ...
}

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Support Pagination on `ListMicrogridDispatches`

What's needed?

Google advises to use pagination by default on all list requests. If not being done early on introducing this later would be a breaking change.

Proposed solution

Extend ListMicrogridDispatches rpc to use pagination by default:

// Service providing operations related to dispatching microgrid components.
service MicrogridDispatchService {
  // Returns a list of all dispatches
-  rpc ListMicrogridDispatches(DispatchListRequest) returns (DispatchList);
+  rpc ListMicrogridDispatches(DispatchListRequest) returns (DispatchListResponse);
// Message for listing dispatches for a given microgrid, and an optional filter
message DispatchListRequest {
  // The microgrid ID
  uint64 microgrid_id = 1;

  // Additional filter parameters
  DispatchFilter filter = 2;
  
+ // maximum number of results to be returned
+ int32 page_size = 3;

+ // identifies a specific page of the list results
+ string page_token = 4;
}
// A list of dispatches
- message DispatchList {
+ message DispatchListResponse {
  // The dispatches
  repeated Dispatch dispatches = 1;

+ // The pagination token to retrieve the next page of results. 
+ // If the value is "", it means no further results for the request. Pass the value of response's 
+ // next_page_token in the subsequent ListMicrogridDispatches method call in page_token field.
+ string next_page_token = 2;
}

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Improve UTC timestamp documentation

What's needed?

// Filter parameter for specifying multiple time intervals
message TimeIntervalFilter {
- // Filter by start_time >= this timestamp
+  // Filter by start_time >= this timestamp in UTC
  google.protobuf.Timestamp start_from = 1;

- // Filter by start_time < this timestamp
+ // Filter by start_time < this timestamp in UTC
  google.protobuf.Timestamp start_to = 2;

- // Filter by recurrence.end_time >= this timestamp
+ // Filter by recurrence.end_time >= this timestamp in UTC
  google.protobuf.Timestamp end_from = 3;

- // Filter by recurrence.end_time < this timestamp
+ // Filter by recurrence.end_time < this timestamp in UTC
  google.protobuf.Timestamp end_to = 4;
}

// ... no changes

message RecurrenceRule {
  // ... no changes

  // When this dispatch should end.
  // A dispatch can either recur a fixed number of times, or until a given timestamp.
-  // If this field is not set, the dispatch will recur indefinitely.bool
+  // If this field is not set, the dispatch will recur indefinitely.
  EndCriteria end_criteria = 3;

  // ... no changes
}

// Message to create a new dispatch with the given attributes
message DispatchCreateRequest {
  // ... no changes

- // The start time
+ // The start time in UTC
  // When creating a dispatch, ensure that the starting timestamp is set to
  // the current time or any future time.
  // Timestamps earlier than the current time are not allowed.
  google.protobuf.Timestamp start_time = 3;

  // ... no changes
}

// Message to update the dispatch with the given ID, with the given attributes
message DispatchUpdateRequest {
    // ... no changes
   
-   // The start time
+   // The start time in UTC
    // When updating a dispatch, ensure that the starting timestamp is set to
    // the current time or any future time.
    // Timestamps earlier than the current time are not allowed.
    google.protobuf.Timestamp start_time = 2;
    
    // ... no changes
}

Proposed solution

No response

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Enhance `DispatchFilter` to support filtering based on `is_active` and `is_dry_run` statuses

What's needed?

We want to support filtering dispatches based on their is_active and is_dry_run statuses.

Proposed solution

Extend the DispatchFilter message to support filtering by is_active and is_dry_run statuses.

// Parameters for filtering the dispatch list
message DispatchFilter {
  // Filter by component ID or category
  repeated DispatchComponentSelector selectors = 1;

  // Filter by time interval
  // If no interval is provided, all dispatches starting from the
  // current timestamp will be included.
  TimeIntervalFilter time_interval = 2;

  // Filter by active status
  // If this field is not set, dispatches of any active status will be included.
  optional bool is_active = 3;

  // Filter by dry run status
  // If this field is not set, dispatches of any dry run status will be included.
  optional bool is_dry_run = 4;
}

Use cases

Receiving list of active and none-active microgrid dispatch events.

Alternatives and workarounds

Receiving the entire list and filtering on the receiving end.

Additional context

No response

Add instructions on how this repo can be used

What's needed?

Looking at this repo, I have not the slightest idea how it is supposed to be used.
I found no examples, no python files and no explanations on how the .proto definitions would end up being used in actual
python code.

Proposed solution

No response

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

File header documentation is not rendered by mkdocs

What happened?

Sadly the file-level documentation is not rendered at all by pseudomuto/protoc-gen-doc.

Since this is very important info it would be nice to include it somewhere else. Maybe as part of the service block documentation?

What did you expect instead?

File header documentation should be moved to the service documentation until the issue is fixed upstream.

Affected version(s)

No response

Affected part(s)

Documentation (part:docs)

Extra information

Rename `DispatchService` to `MicrogridDispatchService`

What's needed?

In order to give the service more context whats it about I'd suggest to rename the service from DispatchService to MicrogridDispatchService or MicrogridDispatchService.

Proposed solution

Please rename service and extend the documentation above. Here is a draft:

// Frequenz Dispatch Automation API
//
// Overview:
// The API serves to automate the process of electricity dispatches for microgrids.
// In the context of the energy industry, a 'dispatch' refers to the act of routing electrical power 
// between different components within a microgrid or between a microgrid and the main grid.
// This could be for the purpose of supply (sending electricity to the grid or components within the microgrid),
// or demand (drawing electricity from the grid or from other components like batteries and solar arrays).
//
// Objective:
// The primary objective of this API is to streamline and automate the complex task of electricity dispatching,
// making it easier to manage local electricity supply and demand efficiently.
//
// Key Features:
// - Dispatching Electricity: Comprehensive CRUD operations for dispatching microgrid components.
// - Automation: Support for one-time as well as recurring dispatches based on flexible recurrence rules.
// - Fine-grained control: Dispatch individual microgrid components or entire component categories.
//
// Example Use Cases:
// - Charging or discharging a battery based on optimal time-of-use rates.
// - Limiting the output of a Photovoltaic (PV) array during periods of low demand.
// - Invoking Frequency Containment Reserves (FCR) or Automatic Frequency Restoration Reserves (aFRR) to 
//    support grid operations.
// - Adjusting the output of electric vehicle charging stations to match grid availability or to avoid peak pricing.
//
// Target Audience:
// This API is designed for application developers in the energy sector who focus on the tasks of optimizing microgrid
// electricity flows. Its design aims to be as developer-friendly as possible, requiring no prior knowledge in 
// electrical engineering and systems.
//
// License:
// ...

Also renaming the service and rpc methods is suggested:

// Service providing operations related to dispatching microgrid components.
- service DispatchService {
+ service MicrogridDispatchService {
  // Returns a list of all dispatches
-   rpc ListDispatches(DispatchListRequest) returns (DispatchList);
+   rpc ListMicrogridDispatches(DispatchListRequest) returns (DispatchList);

  // Create a new dispatch
-   rpc CreateDispatch(DispatchCreateRequest) returns (google.protobuf.Empty);
+   rpc CreateMicrogridDispatch(DispatchCreateRequest) returns (google.protobuf.Empty);

  // Update a dispatch
-   rpc UpdateDispatch(DispatchUpdateRequest) returns (google.protobuf.Empty);
+   rpc UpdateMicrogridDispatch(DispatchUpdateRequest) returns (google.protobuf.Empty);

  // Get a single dispatch
-   rpc GetDispatch(DispatchGetRequest) returns (Dispatch);
+   rpc GetMicrogridDispatch(DispatchGetRequest) returns (Dispatch);

  // Delete a given dispatch
-   rpc DeleteDispatch(DispatchDeleteRequest) returns (google.protobuf.Empty);
+  rpc DeleteMicrogridDispatch(DispatchDeleteRequest) returns (google.protobuf.Empty);
}

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Header documentation and package versioning

What's needed?

-// Dispatch gRPC API definition.
-//
-// Copyright:
-// Copyright 2022 Frequenz Energy-as-a-Service GmbH
-//
-// License:
-// All rights reserved.
-
-// protolint:disable MAX_LINE_LENGTH
+// Copyright 2023 Frequenz Energy-as-a-Service GmbH
+//
+// Licensed under the MIT License (the "License");
+// you may not use this file except in compliance with the License.

...

- package frequenz.api.dispatch;
+ package frequenz.dispatch.v1;

+// Service providing operations related to dispatching microgrid components.
service DispatchService {
...

@tiyash-basu-frequenz @llucax FYI

Proposed solution

Applying the provided patch as needed.

Use cases

No response

Alternatives and workarounds

No response

Additional context

This is also being introduced for the Microgrid API:
frequenz-floss/frequenz-api-microgrid#77

Document error response behavior

What's needed?

The error conditions that can arise for each type of request should be documented, as should the expected behavior of the server, including the expected response code.

rename fcr_prequal_settings to avoid cryptic short-names

What happened?

Please let us not use cryptic, less-intuitive, and unwell defined namings.

What did you expect instead?

This member should be named by its full meaning, e.g. fcr_prequalification_settings or simply fcr_prequalification, because in that part it is already clear that we're referring to settings.

Affected version(s)

No response

Affected part(s)

The protocol buffer definition files (part:protobuf), The python bindings (part:python)

Extra information

NB: this can be made backwards compatible by simply keeping the assigned index number ( = 1)

Adding GetDispatch and DeleteDispatch message

What's needed?

Looking for a way to retrieve a single dispatch request instead of the entire list but also the ability to delete a dispatch request.

Proposed solution

// Dispatch gRPC API definition.
...
// Message to update the dispatch with the given ID, with the given attributes
message DispatchUpdateRequest {
  ...
}

+ // Message to get a dispatch by its ID
+ message DispatchGetRequest {
+   // The dispatch identifier
+   uint64 id = 1;
+ }
+ 
+ // Message to delete a dispatch by its ID
+ message DispatchDeleteRequest {
+   // The dispatch identifier
+   uint64 id = 1;
+ }

service DispatchService {
  ...

  // Update a dispatch
  rpc UpdateDispatch(DispatchUpdateRequest) returns (google.protobuf.Empty) {
    ...
  }

+ // Get a dispatch
+ rpc GetDispatch(DispatchGetRequest) returns (Dispatch) {}
+ 
+ // Delete a dispatch
+ rpc DeleteDispatch(DispatchDeleteRequest) returns (google.protobuf.Empty) {}
}
...

Use cases

Retrieving a single dispatch request instead of the entire list but also being able to remove a dispatch request.

Alternatives and workarounds

No response

Additional context

No response

Extend `DispatchListRequest` and `DispatchListResponse` to support ordering and pagination.

What's needed?

We need to extend the DispatchListRequest message to support ordering by "start time," "create time," or "last update time".

Proposed solution

+import "frequenz/api/common/v1/pagination/pagination_info.proto";
+import "frequenz/api/common/v1/pagination/pagination_params.proto";

service MicrogridDispatchService {
  // Returns a list of all dispatches
-  rpc ListMicrogridDispatches(DispatchListRequest) returns (DispatchList);
+  rpc ListMicrogridDispatches(DispatchListRequest) returns (DispatchListResponse);
  
  // ...
}  

+// Enum for the fields to by sorted by.
+enum SortField {
+  // UNSPECIFIED: Default, unspecified sort field.
+  SORT_FIELD_UNSPECIFIED = 0;  
+
+  // START_TIME: Sort by start time of the dispatch.
+  SORT_FIELD_START_TIME = 1;  
+
+  // CREATE_TIME: Sort by creation time of the dispatch.
+  SORT_FIELD_CREATE_TIME = 2; 
+
+  // MODIFICATION_TIME: Sort by last update time of the dispatch.
+  SORT_FIELD_LAST_MODIFICATION_TIME = 3; 
+
+  // END_TIME: Sort by end time of the dispatch.
+  SORT_FIELD_END_TIME = 4; 
+}

+// Enum for sort order.
+enum SortOrder {
+  // UNSPECIFIED: Default, unspecified sort order.
+  SORT_ORDER_UNSPECIFIED = 0;  
+
+  // ASCENDING: Results are returned in ascending order.
+  SORT_ORDER_ASCENDING = 1;
+
+  // DESCENDING: Results are returned in descending order.
+  SORT_ORDER_DESCENDING = 2;              
+}

+ // Message defining parameters for sorting list requests.
+ //
+ // Example Usage:
+ // To retrieve dispatches sorted by creation time in descending order:
+ // sort_options: { field: CREATE_TIME, order: DESCENDING }
+ //
+message SortOptions {
+  // Optional field by which to sort the results.
+  SortField sort_field = 1;
+
+  // Optional Order in which to sort the results.
+  SortOrder sort_order = 2;               
+}

-// Message for listing dispatches for a given microgrid, and an optional filter
+// Message for listing dispatches for a given microgrid.
+// 
+// Allows retrieval of dispatches for a specified microgrid with optional filtering and sorting.
+// Sorting can be specified by setting 'sort_field' and 'sort_order'. If no sorting is specified,
+// the results will be returned by their create time in a descending order.
message DispatchListRequest {
  // The microgrid ID.
  uint64 microgrid_id = 1;          
  
- // Additional filter parameters
+ // Optional filters to apply to the dispatch list.         
  DispatchFilter filter = 2;            
+       
+ // Sorting options for the results.
+ SortOptions sort_options = 3;

+ // Pagination parameters.
+ frequenz.api.common.v1.pagination.PaginationParams pagination_params = 4; 
}

-// A list of dispatches
+ // Response from listing dispatches for a given microgrid.
-message DispatchList {
+message DispatchListResponse {
-  // The dispatches
+  // List of all dispatches with their details.
  repeated Dispatch dispatches = 1;

+  // Metadata for pagination, including token for next page to retrieve.
+  frequenz.api.common.v1.pagination.PaginationInfo pagination_info = 2;  
}

Use cases

No response

Alternatives and workarounds

No response

Additional context

No response

Extend `ListMicrogridDispatches` to support receiving dispatches by last modification time

What's needed?

Currently there is no way to just receive dispatches by their last update time. @Marenz requested the following: "It would also be useful to receive dispatches once they have been updated"

Proposed solution

Extending the DispatchFilter so it would also support querying by update_time:

// Message for listing dispatches for a given microgrid, and an optional filter
message DispatchListRequest {
  // The microgrid ID
  uint64 microgrid_id = 1;

  // Additional filter parameters
  DispatchFilter filter = 2;
}

// Parameters for filtering the dispatch list
message DispatchFilter {
-  // Filter by component ID or category
+ // Optional filter by component ID or category
  repeated ComponentSelector selectors = 1;

-  // Filter by dispatch start time interval
-  // If no interval is provided, all dispatches starting from the
-  // current timestamp will be included.
+  // Optional filter by time interval
+  // Dispatches will be filtered based on the start_time of the dispatch request. 
+  // If no interval is provided, all dispatches starting from the current timestamp will be included.
-  TimeIntervalFilter time_interval = 2;
+  TimeIntervalFilter start_time_interval = 2;

-  // Filter by active status
+  // Optional filter by active status
  // If this field is not set, dispatches of any active status will be included.
  optional bool is_active = 3;

-  // Filter by dry run status
+  // Optional filter by dry run status  
  // If this field is not set, dispatches of any dry run status will be included.
  optional bool is_dry_run = 4;

+  // Optional filter by update time.
+  // Include only dispatches updated after this UTC timestamp.
+  google.protobuf.Timestamp modified_since = 5;
}

Use cases

To ensure users don't miss updates, such as changes to a dispatch's start time, it's essential to allow filtering by the last update time. The update_time_interval filter addresses this need by enabling users to identify dispatches recently modified.

Alternatives and workarounds

No response

Additional context

No response

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.