Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarify Infinite Duration Dispatch Semantics in API Documentation #221

Open
thomas-nicolai-frequenz opened this issue Dec 12, 2024 · 1 comment
Labels
part:docs Affects the documentation type:enhancement New feature or enhancement visitble to users

Comments

@thomas-nicolai-frequenz
Copy link

thomas-nicolai-frequenz commented Dec 12, 2024

What's needed?

The current documentation uses "infinite" to describe dispatch durations without a preset end time. This can mislead developers into thinking that a dispatch lasts forever with no possibility of termination. We need clearer language to convey that these durations are "indefinite," meaning they have no predetermined end but can still be ended by external conditions or updates. Additionally, the documentation should emphasize that this differs from the iCalendar standard, which typically expects a defined duration or a recurrence-based termination.

Proposed solution

Enhance the documentation in the DispatchData and DispatchMetadata definitions to explicitly describe what "infinite" (unset) durations mean and how they differ from the iCalendar standard. This should include:

  • Replace all instances of "infinite duration" with "indefinite duration" in DispatchData and related messages.
  • Add explanatory notes or admonitions to clarify that an indefinite duration means no fixed end time is currently defined, but the dispatch can be ended externally.
  • Highlight the departure from iCalendar's strict finite-duration model, ensuring readers understand why indefinite durations are supported and how to handle them in application logic.

Use cases

Here are some example use cases that come to mind:

  • A dispatch might be intended to maintain a battery’s State of Charge (SoC) at a certain level indefinitely. If the goal is just to keep the SoC stable, it might never have a reason to end.
  • Alternatively, another dispatch could also be “indefinite,” but the actor could decide to terminate it once a particular target SoC is reached, effectively giving it a natural conclusion.
  • Condition-Based Dispatch: Running a battery until it reaches a certain state-of-charge, rather than having a fixed stop time.
  • Real-Time Adaptation: Continuing a dispatch as long as grid conditions are unstable, then stopping once stability is achieved.
  • Dynamic Operational Scenarios: Operating components under indefinite dispatches that adapt to changing real-world conditions (e.g., variable renewable output) without needing pre-set end times.

Alternatives and workarounds

No response

Additional context

No response

@thomas-nicolai-frequenz thomas-nicolai-frequenz added part:❓ We need to figure out which part is affected priority:❓ We need to figure out how soon this should be addressed type:enhancement New feature or enhancement visitble to users labels Dec 12, 2024
@thomas-nicolai-frequenz
Copy link
Author

thomas-nicolai-frequenz commented Dec 12, 2024

Here is a proposed diff to address the above:

// Represents a dispatches data, including its type, start time, duration,
-// and target components.
+// and target microgrid components.
//
+// This `DispatchData` message describes a single dispatch instance. If a dispatch is set to recur, 
+// each occurrence is defined by `DispatchData` in combination with `RecurrenceRule`. 
+// Indefinite durations apply to each occurrence individually—meaning every instance of a recurring 
+// dispatch may also have no predefined end time. 
+//
+// !!! note "Indefinite Durations"
+//     This API allows dispatches to have an indefinite duration if the `duration` field
+//     is not set. Indefinite means:
+//     - There is no predefined end time known at dispatch creation.
+//     - The dispatch could, in theory, run indefinitely if no external conditions stop it.
+//     - External logic or changing conditions may end the dispatch at any time. For example, 
+//       once a certain operational goal is met (like reaching a particular state-of-charge),
+//       the dispatch may end, or it may be allowed to continue if conditions warrant it.
+//     - Indefinite durations apply to each occurrence individually—every instance of a recurring 
+//       dispatch can also be indefinite.
+//
+//     For instance, a dispatch might aim to keep a battery’s SoC stable. If conditions never
+//     change, it could theoretically run forever. Conversely, another indefinite dispatch might
+//     end as soon as a particular SoC goal is reached.
+//
+// !!! note "Recurring Indefinite Dispatches"
+//     How recurring indefinite dispatches are managed is implementation-dependent. Without
+//     additional logic, multiple indefinite occurrences could start "stacking up," potentially
+//     all running in parallel if no end condition or termination logic is applied. Implementers must 
+//     ensure that indefinite, recurring events are managed in a way that prevents resource 
+//     contention or unintended perpetual accumulation.
+//
+//     Possible strategies include (but are not limited to):
+//     - Manual Termination: Actors or external controllers monitor each occurrence and 
+//       explicitly stop it at the right time.
+//     - Automated Conditions: The system could automatically end occurrences once certain
+//       operational goals are met (e.g., a battery reaching a desired SoC).
+//     - Skipping Overlapping Occurrences: Implementations may decide not to start a new 
+//       occurrence if the previous one has not ended, preventing a stack-up scenario.
+//     - Condition-Based Recurrence: The recurrence logic can be coupled with operational 
+//       conditions so that new occurrences are only triggered if certain criteria are met, 
+//       ensuring that indefinite dispatches do not pile up unintentionally.
+//
-// Timezone Note: Timestamps are in UTC. It is the responsibility of each microgrid to translate UTC
-// to its local timezone.
+// !!! note "Timestamps" 
+//     Timestamps are in UTC. It is the responsibility of the receiver to translate UTC
+//     to respective local timezone.
+//
message DispatchData {
  // 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 = 1;

  // 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 = 2;

   // Duration in seconds
   // The duration of the dispatch in seconds. If the duration is not set, the dispatch
-  // will be considered to have an infinite duration.
+  // will be considered to have an indefinite duration.
   //
   // A duration of 0 seconds is also valid, indicating a dispatch that
   // immediately starts and ends, e.g. switching a component on and off.
+  //
+  // Indefinite durations do not guarantee an eventual end; they continue until external logic changes it.
   optional uint32 duration = 3;

// ...
}

// ...

// Represents the metadata of a dispatch
message DispatchMetadata {
  // Unique identifier of the microgrid dispatch.
  uint64 dispatch_id = 1;

  // UTC Timestamp when the order was created.
  google.protobuf.Timestamp create_time = 2;

  // UTC Timestamp of the last update to the order.
  google.protobuf.Timestamp modification_time = 3;

  // UTC Timestamp when the dispatch will stop working.
+ //
  // Will be calculated internally based on the given: start_time,
-  // duration and RecurenceRule
+  // duration and RecurrenceRule settings. If the duration is not set (indefinite duration), 
+  // there may be no calculable `end_time`. This means the dispatch does not have a 
+  // predetermined stopping point and might run indefinitely. External logic, changes in 
+  // conditions, or achieving certain operational goals may lead to its termination. If no 
+  // such terminating condition occurs, it may effectively continue "forever."
+  //
-  // None if dispatch duration time is infinite and this value can't be calculated.
+  // None if dispatch duration time is unset and this value can't be calculated.
  google.protobuf.Timestamp end_time = 4;
}

@thomas-nicolai-frequenz thomas-nicolai-frequenz added part:docs Affects the documentation and removed part:❓ We need to figure out which part is affected priority:❓ We need to figure out how soon this should be addressed labels Dec 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
part:docs Affects the documentation type:enhancement New feature or enhancement visitble to users
Projects
None yet
Development

No branches or pull requests

1 participant