29  Scheduler

org.arl.unet.Services.SCHEDULER

29.1 Overview

Energy is a scarce resource on battery-powered underwater nodes, much of which can be wasted by keeping a node fully powered while it is idle. The SCHEDULER service manages a node’s sleep/wake cycles and the execution of scheduled tasks, allowing a node to conserve energy and still perform its duties on time.

The service supports two related capabilities:

  • Sleep/wake management. A node can be put to sleep (using a SleepReq) to conserve power, and woken at a scheduled time. Before sleeping, the agent emits an AboutToSleepNtf (carrying the next scheduled wakeup time) so that other agents can finish or defer work; on waking, it emits a WakeFromSleepNtf. A StayAwakeReq keeps the node awake for a specified period when activity is expected.
  • Task scheduling. Shell commands can be scheduled to run at specified times, in a manner similar to cron. A task is added with an AddScheduledTaskReq (or the cronadd command), specifying the command and the schedule (minute, hour, day, etc.), whether it repeats, and whether it persists across reboots. Scheduled tasks can be listed with a GetScheduleReq and removed with a RemoveScheduledTaskReq.

The default scheduler agent is accessed as scheduler.

Note

Scheduled tasks persist across reboots by default (persist defaults to true in AddScheduledTaskReq and cronadd), so repeated cronadd commands accumulate tasks in the persistent store across runs. Pass persist: false when scheduling transient tasks, or clear leftover tasks with cronrm.

29.2 Messages

Agents providing this service honor the following requests:

  • SleepReq – put the node to sleep immediately
  • StayAwakeReq – keep the node awake for a period

    Field Type Default Remarks
    seconds int 0 duration to stay awake in seconds
  • AddScheduledTaskReq – schedule a task

    Field Type Default Remarks
    cmd string command to execute
    date string *
    day string *
    hour string * hour (* for every hour)
    minute string * minute (* for every minute)
    month string *
    persist boolean true true to persist across reboots
    repeat boolean true true to repeat the task
    scheduler string
    shell string
    year string *

Most requests are answered with an AGREE once accepted (a REFUSE if invalid — e.g. sleep requested on a platform with no sleep support, or an unknown task ID; a FAILURE if something goes wrong). A GetScheduleReq is instead answered with a ScheduledTaskRsp listing the currently scheduled tasks:

  • ScheduledTaskRsp – list of scheduled tasks

    Field Type Default Remarks
    tasks object[] Any[]

Sleep/wake transitions are announced on the agent’s topic, so that any agent can prepare for them:

  • AboutToSleepNtf – node is about to sleep

    Field Type Default Remarks
    scheduledNextWakeupTime long 0 scheduled wakeup time

29.3 Parameters

  • enable :: boolean – enable scheduled execution of tasks

  • uptime :: long – time that the node has been awake (seconds)

  • idle :: long – time that the node has been idle (seconds)

  • idleTimeout :: long – idle time before the node goes to sleep (seconds, 0 to disable)

  • busy :: long – time to stay awake regardless of idleness (seconds, -1 for infinite)

    Setting busy keeps the node awake for at least that many seconds; the largest outstanding request wins, and the value counts down as time elapses. Intended for programmatic use by agents, rather than for setting manually.

  • sleepProvider :: String (nullable) – sleep provider class name (null if none available)

The busy parameter is intended for programmatic use by agents, rather than for setting manually. An agent that expects imminent activity sets busy to the number of seconds the node must stay awake, guaranteeing that the node does not sleep for at least that long. Several agents may make such requests independently, and the scheduler honors the longest outstanding one: setting busy to a value smaller than the time already promised has no effect, and reading busy back returns the remaining time the node must stay awake — which may be larger than the value just set. The value counts down as time elapses; when it reaches zero the node becomes idle, and eligible for automatic sleep once idleTimeout expires.

29.4 Commands

  • crontab – show scheduled tasks

  • cronadd – add scheduled task

    Examples:

    cronadd minute:'*/5', cmd:'log.info "demo"'   // log "demo" every 5 minutes
    cronadd hour:'9,12,15', minute:'0', cmd:'xxx' // run 'xxx' at 9am, 12pm, 3pm
    cronadd minute:'20', cmd:'xxx', repeat:false  // once at 20 mins past the hour
    cronadd scheduler: 'MySmartScheduler'         // use a custom Scheduler class
    
  • cronrm – remove scheduled tasks

    Examples:

    cronrm()                        // delete all tasks
    cronrm('9c3e972c-92c2-4538')    // delete task with ID '9c3e972c-92c2-4538'
    
  • sleep – go to sleep immediately

29.5 Examples

To schedule a task that transmits a broadcast datagram every hour on the hour, use the cronadd command from the shell, specifying the schedule fields as named arguments:

> cronadd minute:'0', cmd:'phy << new TxFrameReq()'
AGREE

The current schedule can be reviewed with crontab:

> crontab
idleTimeout : 0
----------------------------------------
[019f424e-2a61-7198-fc0a-af0236c97eae] 0 * * * * * phy << new TxFrameReq() @ Thu Jul 09 00:00:00 SGT 2026

A task is removed with cronrm, using its task ID (or with no argument to remove all tasks); here we remove the task we just added and confirm the schedule is empty again:

> cronrm '019f424e-2a61-7198-fc0a-af0236c97eae'
AGREE
> crontab
idleTimeout : 0
----------------------------------------

To keep the node awake for the next 5 minutes while you expect activity, send a StayAwakeReq:

> scheduler << new StayAwakeReq(seconds: 300)
AGREE

29.6 Implementation

29.6.1 Scheduler (scheduler)

Class Services Capabilities Availability
Scheduler SCHEDULER default stack

The default implementation is the scheduler agent, loaded as part of the default stack (Chapter 13).

29.6.1.1 How it works

The scheduler tracks how long the node has been awake (uptime) and how long it has been idle (idle). If a sleep provider is available on the platform (named by the read-only sleepProvider) and the node stays idle for longer than idleTimeout, the scheduler puts the node to sleep automatically — emitting an AboutToSleepNtf carrying the next scheduled wakeup time first, so other agents can finish or defer work, and a WakeFromSleepNtf when it wakes. The busy parameter counts down the time the node should stay awake regardless of idleness, which agents expecting imminent activity can extend so the node does not sleep mid-operation (the scheduler itself extends it when it sees ongoing transmissions and receptions). Scheduled tasks are run in a cron-like fashion: each task specifies a command and a schedule (minute, hour, day, …), whether it repeats, and whether it persists across reboots; the scheduler wakes the node in time to run each due task. Scheduled execution is only active when enable is set.

29.6.1.2 Parameters

On hardware with wake-up support, the sources that can wake the node are exposed as additional agent-specific parameters:

  • wakeOnEth – enable wakeup on Ethernet activity
  • wakeOnRS232 – enable wakeup on RS232 activity
  • wakeOnGPIO – enable wakeup on GPIO activity
  • wakeOnAcoustic – enable acoustic wakeup

29.6.1.3 Usage notes

  • Set idleTimeout to enable automatic sleep on idle nodes; leave it at 0 to keep the node always awake.
  • Keep the node busy (or use a StayAwakeReq) when you expect imminent activity, so it does not sleep mid-operation.
  • Sleep is only effective if the platform provides a sleep provider; on a node without one, sleep requests are refused, while task scheduling still works.