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
- Repeat every day at a given time
- Repeat at certain day every n week.
- 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
- Schedule to charge a battery at a certain point in time on a daily basis.
- 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