Revision 13

Scheduler Protocol

Update

In revision 13, the temporary message was added.

Revisions previous to 9 of this documentation incorrectly indicated that Terminated Event Schedule Packets and Unterminated Event Schedule Packets used 8-byte integers, and not 4-byte integers.

Overview

Each Display Driver will have its own Scheduler. Everything which wishes to schedule a sequence will do so with the scheduler. This means that nothing will talk directly to the Display Driver, only to the Scheduler.

(The scheduler's relation to the Display Driver is an implementation detail — it can be integrated into the Display Driver for performance or be a separate program which connects to it as a client for simplicity. Neither choice will affect anything in this specification.)

Scheduled Sequences

There are several different types of schedules that one might want to set:

  1. The override sequence
  2. Data Source Event triggered (Asynchronous) sequences
  3. Time-based (Synchronous) sequences
  4. The Temporary Message
  5. The default sequence

This requires a mildly complex scheduling protocol, but it should cover every concievable method of scheduling a sequence that a human being is likely to want. It will give the full power of schedulers like the one in Microsoft® Outlook®, which is generally held to be sufficient for human endeavors. In some cases it will actually give more power than that.

Order of precedence

There will be an override sequence which, if set, overrides anything else in this scheduler and displays continuously until the override sequence is changed or cleared.

Each schedule will have an assigned priority. At any given time, the highest priority message which is scheduled for that time will display. Priorities are indicated by a priority number which ranges from 1-100 with 1 being the highest priority.

Time-based (synchronous) schedules will have a default priority of 70. Data event triggered (asynchronous) schedules will have a default priority of 40.

There will be a temporary message which, if set, displays in preference to the default message but otherwise comes below all other scheduled messages. The temporary message comes with a timeout, after which the message board will revert to the default message. The temporary message is intended purely for use in ITS systems which frequently update what message is supposed to be displaying.

There will also be a default sequence which will be set at all times in case there is no scheduled sequence which should be playing.

Time-based Schedules

There are fundamentally two different types of time-based schedules. The first is a Singleton schedule, which occurs only between two distinct points in the history of the world. (For example, from July 3, 2004 at 5:04pm through November 9th, 2005 at 4:15am.) The other is a Recurrant Schedule, which occurs repetatively according to some pattern. (For example, fridays in October and November from 9pm-9am.)

Constraints on Recurrant Schedules

Recurrant schedules have a great deal of flexibility; as a result they also have a number of constraints to simplify implementation. However, these constraints are generally just limitations to sensible uses of recurrant schedules.

A recurrant schedule can indicate repetition along any of months, days of the month, days of weeks, weekdays of the month (2nd tuesday, etc.), hours, and minutes. The restrictions are that no parallel cycles may be simultaneously scheduled within the same recurrant schedule. E.g. Day of the month and weekday may not both be specified in a single recurrant schedule. Similarly, day of the month and weekday of the month is forbidden, day of week and weekday of month, etc.

Temporary Messages

Temporary messages are inteded only for use in ITS systems, and so their features are geared for that use. Temporary message schedules are not written to disk, so if the power is lost the unit will come up displaying the default message if it would otherwise have displayed the temporary message. Temporary messages come with a timeout, after which the unit reverts to its default schedule (unless overriden by a higher priority schedule, of course). The purpose of the timeout is to allow for an "out of communication" message, so that a unit will not display messages reflecting old conditions during communication loss. Temporary messages also require the specification of a library to avoid all possible confusion, since this is no more onerous for a machine than not doing it is.

Temporary messages may not be embeded in any other message. If someone wants a message to only display for (e.g.) 15 minutes at some future date, they can use a terminated schedule to achieve that effect.

Embedding Schedules

Certain types of schedules may be embedded within other types. A recurrant schedule may be embedded within a singleton schedule, so that the recurrance only happens between the singleton's start and stop dates. Also, asynchronous events may be embedded either in a singleton or recurrant schedule, so that they'll only trigger a sequence during the scheduled dates and times.

Conflicts

Schedules with different priorities will be permitted to conflict. Schedules with the same priority, however, will not be permitted to conflict, and it is the responsibility of the Scheduler to verify that they do not. For time-based schedules, this means that no two time-based schedules may overlap. (Note: if a recurrant schedule displays on MWF, a one-time schedule for a thursday would be fine, but Thu-Sat would not be (because of the conflict on friday). Similarly, two recurrant schedules, one for MWF the other for TThu would not conflict.)

The asynchronous layer is more complex. Asynchronous schedules for different event IDs must have different priorities. Schedules for the same event ID may be at the same priority, provided that they are for different event values. Of course, event-based schedules may conflict if they are embedded in time-based schedules which do not conflict.

The Default Sequence

The default sequence may be set either immediately, on some future date, or by an event. This allows one to switch defaults messages after Christmas, or when the temperature goes below some predetermined value, etc. Once the default sequence is set, it remains the default sequence until it is replaced.

The Override Sequence

The override sequence can be set at any time, and takes priority over all other messages in the scheduler. (Indeed, the scheduler is free to shut down its normal scheduling loop while there's an override sequence.) The override sequence is cleared by setting an override sequence with the title "" (that is, a zero-length title).

Sequence Identification

Sequences will be scheduled by title. This means that when the Scheduler is going to send a sequence to its Display Driver, it fetches the appropriate sequence from the Librarian. This is designed to allow one to make modifications to a sequence without having to reschedule it.

(Note: Since it is a requirement of the controller's Librarian that only one sequence with a given title can be stored at a time, there cannot be any conflicts about which sequence to display.)

(Note: the generation and notification of events is covered in the Data Sources specification.)

(Note: The above means that in order to schedule a sequence, it must first be inserted into the controller's sequence library.)

(Note: Because more than one Display Driver (and hence Scheduler) might be present on a controller, it is the responsibility of a program which wants to remove a sequence from the controller's library to ensure that it is not in use by the scheduler. As a result, if the Scheduler tries to send a sequence to the Display Controller which does not exist in the library, it should just discontinue the attempt (possibly notifying the user) but otherwise continue as normal and should not remove the sequence from its schedule (if it is a recurrant schedule).)

Displaying Notifications

In order to support low-bandwidth applications, it is necessary for notifications of the changes to the currently displaying message to be able to exclude changes which happen too frequently on a consistent basis. Right now, that means radar, but in general any sort of message change on frequent events could be problematic, and so we introduce the category of frequently changing messages. Prior to now, the way to find out what a sign was displaying was to ask the Display Driver, however it does not have the information necessary to distinguish between changes to due frequent events and other changes, so it is now necessary to use the scheduler for this purpose.

In order to accomplish this, there are two packets added. The first is the Displaying Notification Request Packet, which subscribes the listener to notifications and can include a flag to indicate that we are not interested in frequently changing events.

Temporary messages do not count as frequently changing events, even though they probably will be in practice, because an ITS system will need to know about them and further an ITS system is not a low-bandwidth application.

The Protocol

The Scheduler Protocol is a variable-length packet based protocol which is initiated by a versioning handshake.

As a design decision, instead of assigning a scheduled sequence some sort of unique identifier, a scheduled sequence is always referred to by an appropriate schedule packet. While this does increase the bandwidth used, it should not do so significantly (scheduling should not be a high-volume activity, and the difference between the full packet and a unique ID is likely only about 30 or 40 bytes anyway). By doing this, we gain the assurance that there cannot be a mistake about what schedule is being referred to; by using full information, it is not possible for there to be a synchronization error if two people are concurrently trying to modify the schedule, nor can there be any problems with incomplete transactions which are thought to be complete, etc.

Each Scheduler will find an available port to listen on and publish this information with the Information Daemon in the category "scheduler". For convenience, however, the first scheduler is on port 40701, and subsequence schedulers are on consecutive ports.

Note: Unless otherwise specified, all multi-byte integeral types are in network order (i.e. they're big-endian).

Version 2

Added the override schedule.

Version 3

Added the Default Seqeuence Query Packet so that a remote application can query the current default sequence.

Handshake

The protocol handshake works according to the Solartech Protocol Handshake & Authentication specification. The current protocol version is 3.

Normal Operation

Once the handshake has been completed, the protocol is then an asynchronous protocol where either side may send any packet at any time, though most client packets will require an immediate response from the Scheduler.

Scheduling a Sequence

In order to schedule a sequence, the client sends one of:

The Scheduler then confirms that the sequence was scheduled as requested by sending back an appropriate schedule packet. If the sequence is not valid (e.g. if it conflicts with another schedule), the Scheduler will reply with an Invalid Schedule Packet.

Canceling a Schedule

To cancel a scheduled event, the client sends a Cancellation Packet. The Scheduler then sends back an appropriate Cancellation packet as confirmation.

Information Request

When a client wants a complete listing of all scheduled sequences, it sends a Schedule Information Request Packet. The Scheduler responds with a Scheduler Information Packet.


Appendix A. Packet Definitions

The following are the packets used in this protocol:

Note: the data type "String" denotes a Java string; i.e. an unsigned short followed by that many bytes of UTF-8 data.

Time-based Singleton Terminated Packet
Byte Count Data Type Value Description
1 unsigned byte 0 Packet Type
8 long integer The date that the sequence should be loaded, specified in epoch seconds GMT.
8 long integer The date that the sequence should be removed, specified in epoch seconds GMT.
1 unsigned byte Priority
variable schedule packet Any schedule packet, including a cancellation packet, may be embedded here.
Notes:
While theoretically any schedule packet could be embedded, it would be redundant to embed a time-based singleton packet (terminated or not), and is thus not permitted.

If a Sequence Packet is embedded, this sets the sequence for the Time-based layer while this schedule is active.

Time-based Singleton Unterminated Packet
Byte Count Data Type Value Description
1 unsigned byte 1 Packet Type
8 long integer The date that the sequence should be loaded, specified in epoch seconds GMT.
variable schedule packet Any schedule packet, including a cancellation packet, may be embedded here.
Notes:
While theoretically any schedule packet could be embedded, it would be redundant to embed a time-based singleton packet (terminated or not), and is thus not permitted.

If a Sequence Packet is embedded, the sequence becomes the default sequence.

(It doesn't make any sense for an unterminated packet to have a priority, since the unterminated packet only embeds a schedule or a default sequence.)

Time-based Recurrant Packet
Byte Count Data Type Value Description
1 unsigned byte 2 Packet Type
1 unsigned byte A bitfield with flags for which of the date bitfields are significant:
bit mask meaning
0x01 month field
0x02 day of month field
0x04 weekday of month field
0x08 day of week field
0x10 hour field
0x20 minute field

Only those bitfields which are significant are included in this packet. Insignificant bitfields are considered to have every bit set and thus they only need to be included if there is some restriction desired.

2 unsigned short The month bitfield. The bitmasks are:
0x0001 January
0x0002 February
0x0004 March
0x0008 April
0x0010 May
0x0020 June
0x0040 July
0x0080 August
0x0100 September
0x0200 October
0x0400 November
0x0800 December
4 unsigned integer The day-of-month bitfield. The field corresponds to a mask of 1 << dayOfMonth, where dayOfMonth starts at 0.
4 bitfield The weekday-of-month bitfield. The mask is as follows:
0x00000001First Sunday of the month
0x00000002First Monday of the month
0x00000004First Tuesday of the month
0x00000008First Wednesday of the month
0x00000010First Thursday of the month
0x00000020First Friday of the month
0x00000040First Saturday of the month
0x00000080Second Sunday of the month
0x00000100Second Monday of the month
0x00000200Second Tuesday of the month
0x00000400Second Wednesday of the month
0x00000800Second Thursday of the month
0x00001000Second Friday of the month
0x00002000Second Saturday of the month
0x00004000Third Sunday of the month
0x00008000Third Monday of the month
0x00010000Third Tuesday of the month
0x00020000Third Wednesday of the month
0x00040000Third Thursday of the month
0x00080000Third Friday of the month
0x00100000Third Saturday of the month
0x00200000Fourth Sunday of the month
0x00400000Fourth Monday of the month
0x00800000Fourth Tuesday of the month
0x01000000Fourth Wednesday of the month
0x02000000Fourth Thursday of the month
0x04000000Fourth Friday of the month
0x08000000Fourth Saturday of the month
1 unsigned byte The day-of-week bitfield. The bitmasks are:
0x01 Sunday
0x02 Monday
0x04 Tuesday
0x08 Wednesday
0x10 Thursday
0x20 Friday
0x40 Saturday
4 integer The hour bitfield. If Hour is the hour of the day in 24 hour notation, then each hour's mask corresponds to (1 << Hour) (since 24 hour time runs from 00:00 to 23:59)
8 long integer The minute bitfield. The mask for each minute corresponds to 1 << Minute. Minute ranges from 0-59.
1 unsigned byte Priority
variable schedule packet Any schedule packet, including a cancellation packet, may be embedded here.
Notes:
While theoretically any schedule packet could be embedded, it would be redundant to embed a time-based packet (recurrant or singleton, terminated or not), and is thus not permitted.

If a Sequence Packet is embedded, while this schedule is active the embeded sequence becomes the displayed sequence for this priority level.

Day-based Recurrent Schedule Packet
Byte Count Data Type Value Description
1 unsigned byte 10 Packet Type
1 byte Cycle type:
0x00 Daily
0x01 Weekly
0x02 Monthly
4 integer Recurrence data. The use of this field depends on the type of recurrence. In daily recurrence, it's not used. For weekly recurrence, it's a bitfield where the seven least significant bits are used to indicated Sunday through Saturday. For monthly, it's a number indicating which weekday of the month (0-6, 1st Sunday - 1st Saturday, 7-13, 2nd Sunday - 2nd Saturday, etc.).
1 byte 0-23 Start Hour
1 byte 0-59 Start Minute
1 byte 0-23 Stop Hour
1 byte 0-59 Stop Minute
1 unsigned byte Priority
variable schedule packet Any suitable schedule packet may be embedded here.
Notes:
While theoretically any schedule packet could be embedded, it would be redundant to embed a time-based packet (recurrant or singleton, terminated or not), and is thus not permitted.

If a Sequence Packet is embedded, while this schedule is active the embedded sequence becomes the displayed sequence for this priority level.

Terminated Event Packet
Byte Count Data Type Value Description
1 unsigned byte 3 Packet Type
2-65,537 String The Source ID.
4 integer The minimum value of the source event for which this sequence should be displayed. (inclusive)
4 integer The maximum value of the source event for which this sequence should be displayed. (inclusive)
4 integer The duration of the event sequence, specified in milliseconds. After this time the currently scheduled sequence should be restored. (note: 4 bytes allows a maximum duration of 49 days 17 hours 2 minutes)
1 unsigned byte Priority
variable Sequence Packet The sequence to display.
Notes:
It doesn't make sense to set a schedule based on an event only for a period of time. A schedule is either in the scheduler or not at all. Getting a schedule to be in the scheduler for a period of time can be better handled by properly creating the embeded schedule and setting it with an unterminated event. Thus only sequences may be set from terminated events. The embeded sequence becomes the current sequence for the asynchronous layer while this event is active. If another terminated event is triggered while this event is running, this event is prematurely terminated and the new event becomes the current event.
Unterminated Event Packet
Byte Count Data Type Value Description
1 unsigned byte 4 Packet Type
2-65,537 String The Source ID.
4 integer The minimum value of the source event for which this sequence should be displayed. (inclusive)
4 integer The maximum value of the source event for which this sequence should be displayed. (inclusive)
variable schedule packet Any schedule packet, including a cancellation packet, may be embedded here.
Notes:
When an unterminated event is triggered, the embedded packet is treated as if it was just sent by a client. Thus all embedded packets behave as if they were sent on their own. (In particular, an embedded sequence would set the default sequence.)

(It doesn't make any sense for an unterminated packet to have a priority, since the unterminated packet only embeds a schedule or a default sequence.)

Cancellation Packet
Byte Count Data Type Value Description
1 unsigned byte 5 Packet Type
variable schedule packet A packet corresponding to the schedule to cancel is embedded in this packet. All values must match exactly for that schedule to be canceled.
Schedule Information Request Packet
Byte Count Data Type Value Description
1 unsigned byte 6 Packet Type    
Schedule Information Packet
Byte Count Data Type Value Description
1 unsigned byte 7 Packet Type
4 unsigned integer (count) The number of schedules in this scheduler.
variable Schedule Packet[count] The schedule packets representing all of the schedules in this scheduler
Sequence Packet
Byte Count Data Type Value Description
1 unsigned byte 8 Packet Type
2-65,537 String The sequence's title.
Notes:
When sent alone, this packet sets the default sequence.
Invalid Schedule Packet
Byte Count Data Type Value Description
1 unsigned byte 9 Packet Type
2-65537 String The error string. This string explains why the requested schedule is invalid.
variable schedule packet Any schedule packet, including a cancellation packet, may be embedded here.
Sign Shutdown Packet
Byte Count Data Type Value Description
1 unsigned byte 11 Packet Type
1 Unsigned Byte On/off (1==on, 0==off).
Override Sequence Packet
Byte Count Data Type Value Description
1 unsigned byte 12 Packet Type
2-65,537 Java UTF-8 String The sequence's title.
Notes:
This is a version 2 packet
When sent alone, this packet sets the override sequence. Please note that an empty (zero-length) string as the sequence title clears the override sequence.

If the override sequence packet specifies the same sequence as is currently the override sequence, the scheduler must reload the sequence (i.e. fetch it from the library again).
Override Sequence Query Packet
Byte Count Data Type Value Description
1 unsigned byte 13 Packet Type
Notes:
This is a version 2 packet
The scheduler will send an Override Sequence Packet in response.
Default Sequence Query Packet
Byte Count Data Type Value Description
1 unsigned byte 14 Packet Type
Notes:
This is a version 3 packet
The scheduler will send an Sequence Packet in response.
Display Notification Request Packet
Byte Count Data Type Value Description
1 unsigned byte 15 Packet Type
1 bitfield Flags:
0x01 Notify of Current Message
0x02 Include Changes from Frequent Events
Notes:
This is a version 11 packet.

Turns on displaying notifications.

If the Notify of Current Message flag is set, a Displaying Notification Packet is immediately sent out.

Right now, the only Frequent Event is radar, but in the future this might be dynamically calculated so that frequently used switch closures are automatically rate-limited.

Display Notification Packet
Byte Count Data Type Value Description
1 unsigned byte 16 Packet Type
1 bitfield
0x01 Caused by Frequent Event
0x02 Message Included
0x04 Sign Panel Shut Down
0x08 Message is Event
0x10 Message is time-based Schedule
0x20 Message is override
1 unsigned byte Intern Message Number
variable String (optional) the title of the message being displayed
Notes:
This is a version 11 packet.

The Caused by Frequent Event flag is 1 if a frequent event such as Radar is the reason for this message change (either to or from the frequent event message)

The Intern Included Message flag indicates whether a message included. If 1, the message is included and should be associated with the intern number; if 0 the last message defined for that intern number is the currently playing message.

Temporary Message Packet
Byte Count Data Type Value Description
1 unsigned byte 17 Packet Type
1 unsigned byte Flags
2-65537 jstring Temporary message title
2-65537 jstring Library
2 unsigned short Temporary Message Duration (in seconds)
Notes:
This is a version 18 packet.


Appendix B. Packet types

Packet Type # Packet Type
0 Time-based Singleton Terminated Packet
1 Time-based Singleton Unterminated Packet
2 Time-based Recurrant Packet
3 Terminated Event Packet
4 Unterminated Event Packet
5 Cancellation Packet
6 Schedule Information Request Packet
7 Schedule Information Packet
8 Sequence Packet
9 Invalid Schedule Packet
10 Day-based Recurrent Schedule Packet
11 Sign Shutdown Packet
12 Override Sequence Packet
13 Override Sequence Query Packet
14 Default Sequence Query Packet
15 Display Notification Request Packet
16 Display Notification Packet

Last modified: Fri Dec 03 17:32:02 Eastern Standard Time 2004