Time Service Access in Scripts

The time and scheduling functionality of the CSW Time Service are available to script writers. Time Service DSL provides access to the Time Service module provided by CSW. This DSL exposes the following API calls to script writers to access time and schedule tasks.

Time Access

Time Service provides access to both TAI and UTC time that is synchronized at the telescope site with time on all the other computers and also with absolute time provided by a GPS system.

Time access calls are made available to all scripts. Access to some time functionality requires the import of kotlin.time packages.

Access UTC Time with utcTimeNow

The utcTimeNow Time Service utility returns the current UTC time. The time value returned is a CSW UTCTime type, which is an absolute time value.

Kotlin
val currentUtcTime = utcTimeNow()

Access TAI Time with taiTimeNow

The taiTimeNow Time Service utility returns the current TAI time. The time value returned is a CSW TAITime type, which is an absolute time value.

Kotlin
val currentTaiTime = taiTimeNow()

Access UTC time in the Future with utcTimeAfter

The utcTimeAfter Time Service utility provides an absolute UTC time some amount of time from now in the future. The value provided is a duration such as “1 hour”. The returned value is an absolute UTCTime type. The following example shows provides UTC time 1 hour from now.

Kotlin
val utcTime = utcTimeAfter(1.hours)

Access TAI Time in the Future with taiTimeAfter

The taiTimeAfter Time Service utility provides an absolute TAI time some amount of time from now in the future. The value provided is a duration. The returned value is an absolute TAITime type. The following example shows provides TAI time 1 hour from now.

Kotlin
val taiTime = taiTimeAfter(1.hours)

Scheduling with Time Service

The Time Service DSL provides script access to the CSW scheduling library allowing scripts to schedule one-off and periodic tasks. Access to the Time Service scheduling functionality is provided in the script writing environment with no extra imports.

Using scheduleOnce

The scheduleOnce Time Service DSL allows scheduling a task in a script once at the specified absolute UTC or TAI time. The function schedules the task and returns a handle that can be used to cancel the execution of the task if it has not yet executed. The task is a callback which will be executed in thread safe way.

The following example shows an onSetup handler of a script extracting a scheduled time from a Setup command and then uses the scheduleOnce to send a motion command to a Galil Assembly at the scheduled time.

Kotlin
val scheduleTimeKey = utcTimeKey("scheduledTime")
val schedulePrefix = "esw.test"
val galilAssembly = Assembly(TCS, "galil")

//Usage inside handlers - schedule tasks while handling setup/observe commands
onSetup("schedule-once") { command ->
    val scheduledTime = command(scheduleTimeKey)
    val probeCommand = Setup(schedulePrefix, "scheduledOffset", command.obsId)

    scheduleOnce(scheduledTime.head()) {
        galilAssembly.submit(probeCommand)
    }
}

Using scheduleOnceFromNow

Often, it is necessary to schedule a task in the future some amount of time from now. The scheduleOnceFromNow API allows scheduling non periodic task in script after a specified duration. The task is a callback which will be executed in thread-safe way. This API takes a time Duration type after which task will be scheduled.

The following example shows the scheduling of a task after 1 hour from now. The function takes a duration and returns a handle which can be used to cancel the execution of the task if it has not yet executed.

Kotlin
scheduleOnceFromNow(1.hours) {
    publishEvent(SystemEvent("LGSF", "publish.success"))
}

Using schedulePeriodically

The schedulePeriodically API allows scheduling a task to execute periodically at a given interval. It is also possible to provide the start time otherwise the task will be executed immediately. The provided task is a callback, which will be executed in thread-safe way.

Initially, the task is executed once immediately / on start time and then followed by periodic execution of the task at the requested period. This function returns a handle that can be used to cancel the execution of further tasks.

The following examples show the scheduling of a task in onSetup handlers. The second usage demos using time provided in a parameter as start time. Tasks run every 5 seconds after start time until stopped.

Kotlin
val offsetTimeKey = utcTimeKey("offsetTime")
val offsetPrefix = "esw.offset"
val assemblyForOffset = Assembly(TCS, "galil")

onSetup("schedule-periodically") { command ->
    val probeCommand = Setup(schedulePrefix, "scheduledOffset", command.obsId)

    schedulePeriodically(interval = 5.seconds) {
        assemblyForOffset.submit(probeCommand)
    }
}

onSetup("schedule-periodically-with-start-time") { command ->
    val scheduledTime = command(offsetTimeKey)
    val probeCommand = Setup(schedulePrefix, "scheduledOffset", command.obsId)

    // *** schedule with start time ***
    schedulePeriodically(scheduledTime.head(), interval = 5.seconds) {
        assemblyForOffset.submit(probeCommand)
    }
}

Using schedulePeriodicallyFromNow

The schedulePeriodicallyFromNow API is like schedulePeriodically but takes a duration as the start time rather than an absolute time. Initially, the task is executed once after a delay from the current time specified by the duration time. This execution is followed by periodic execution of the task at the requested period. The task is a callback which will be executed in thread-safe way. This function returns a handle that can be used to cancel the execution of further tasks.

The following example shows scheduling the publishing of an Event after 1 hour from now and then publishes an Event periodically with a 10 second period until cancelled.

Kotlin
schedulePeriodicallyFromNow(1.hours, 10.seconds) {
    publishEvent(SystemEvent("LGSF", "publish.success"))
}
Limits of Scheduling

The script environment for scheduling tasks should not be relied upon for very short periods or low jitter applications.

Source code for above examples