Cron jobs
The cron module (io.scadex.cron) runs jobs on a schedule. A job either runs a script in the gateway's sandbox or writes one fixed value to one tag, and every run is recorded with how it ended. This page is for engineers who set up jobs and operators who watch them.
It is built on Cronos and SQLite and declares SDK contract 1.3, which it needs for the sandbox. Its kind is processor and its capabilities are api and schedule.
Schedules
A schedule is a five-field cron expression: minute, hour, day of the month, month and day of the week. Minutes are the finest step, as in Unix cron; the shorthands Unix cron knows are accepted, and expressions with a seconds field are not. The expression is stored with its fields separated by single spaces.
Each job has its own time zone (an IANA id; UTC when none is given). Daylight saving is handled as Unix cron does: the schedule keeps the zone's wall clock, summer time included. The gateway image carries time zone data; GET /status reports timeZoneData so you can see whether it is present.
The job form offers Repeat modes (every so many minutes or hours, daily at a time on chosen days, monthly on a day) or a raw Cron expression, plus the Time zone. GET /preview?schedule&timeZone&count validates an expression and lists its next times.
Actions
action.kind | What runs |
|---|---|
script | A script in the gateway's sandbox. It reads with tag(path), writes with writeTag(path, value), logs with console.log, sees event, and may return a value. At most 64 KB of source. |
write | One fixed value written to one tag path. |
A script job runs with the module's share of the sandbox: 5 seconds of processing, 2 million statements and 32 MiB, one module script at a time across the gateway. Its writes are applied once it has finished, in order, stopping at the first that fails. See Cron scripts for the script context.
Try it in the form runs a script now and shows what it would write without writing anything, or for a write action checks that the tag exists.
Runs and outcomes
Every run is kept with when it was due (scheduledFor), why it ran (trigger: schedule, manual or catch-up), when it started and finished, what it logged, returned and wrote, and how it ended:
| Outcome | When |
|---|---|
succeeded | The action finished, and every write it asked for was made |
failed | The script threw or hit a limit, a write was refused, or the gateway stopped mid-run |
skipped | The time came while the job's previous run was still going. Runs never queue |
missed | The time passed while the gateway was down, or the scheduler fell more than a turn behind. One record covers a stretch of missed times (missedCount, missedFrom) |
A job's health is paused, invalid (its schedule no longer parses), failing, missed, healthy or new, from its last finished run.
Catch-up and pause
- After downtime a job records what it missed and, when Catch up is on (
catchUp: true), runs once for the latest missed time. Otherwise it waits for its next time. - A paused job (
enabled: false) does not run on its schedule and is not blamed for the times it was paused. It keeps its history and can still be run by hand with Run now.
Failure tag
A job can name a Failure tag (failureTag): set to true when its last run failed and false again once one succeeds, written only when that changes, so the alarm system can tell someone. See Alarms.
Audit and retention
Scheduled writes are audited as cron:<job name>. A run asked for by hand is audited as the person who asked. Either way the correlation id is cron-run-<id>.
Runs are kept for 90 days, at most 2,000 per job, in DATA_DIR/modules/io.scadex.cron/runs.db. Job definitions are module state, so they are in the gateway's backup.
Routes
All routes are under /api/v1/modules/io.scadex.cron. Viewers can read; changing, testing or running a job needs the engineer role.
| Request | Purpose |
|---|---|
GET /status | Jobs, how many are failing, running or paused, the next run, the last 24 hours, and timeZoneData |
GET /jobs, POST /jobs | The jobs, each with health, nextRunAt, lastRun, recent runs and last24h counts; create one (201) |
GET /jobs/{id}, PUT /jobs/{id}, DELETE /jobs/{id} | One job; PUT also pauses and resumes through enabled |
POST /jobs/{id}/run | Runs a job now, paused or not, and answers when it has finished |
POST /test | Tries a job's action without keeping a record: a script's writes are reported, not made |
GET /runs?job&outcome&before&limit, GET /runs/{id} | Runs newest first, and one run with its log, value and writes |
GET /preview?schedule&timeZone&count | Checks a schedule and lists its next times |
A job body has name (unique; 409 when taken), description, schedule, timeZone, enabled, catchUp, failureTag and action (kind, script or path and value). Validation errors answer 400 with a plain message. While the module is stopped these routes answer 503; see Modules.
The monitor page
Open Automation, then Cron jobs. The page appears only while the module is installed and for engineers and administrators. It shows Failing, Running now, Runs, last 24 h and Next run, the list of jobs with their health, and the runs with a filter by outcome. Selecting a job opens a side panel with Run now, Pause or Switch on, Delete, its schedule, After downtime (catches up once, or waits for its next time) and its recent runs. The form sections are Job, When it runs, What it does and When it goes wrong.
The navigation rail shows a badge with the number of failing jobs.