Skip to content

Triggers

The trigger decides when a script runs — and with it, whether a plant is touched at 03:00 with nobody watching. It sits in the properties column, with an explaining sentence under the selection.

There are seven kinds. Six make a script run; the seventh says that it never does.

Every write to one of the selected tags is a chance to run — each write, not each screen update. Pick at least one tag; otherwise the script sits there looking configured and never fires.

Three refinements, each behind a tick box, all off by default:

Condition. A comparison against the value, for example > 80. It fires at the moment the condition becomes true — not again and again while it stays true. A threshold that fires at 81, 82 and 83 is not a threshold, it is a stream. The value is read as JSON where it can be: 42 is a number, true is a truth value, anything else is text. Quotes force text.

Settle time. For a value that jitters, the interesting moment is the one where it stops. It fires once nothing has moved for that long. Between 50 ms and one hour.

Quality change. A source falling over does not change a number — it stops standing behind it. This makes that an event too: became unusable, became usable again, or both.

At a fixed rate, counted from when it was armed — not from the hour. Between 250 ms and 24 hours. If you want the clock, use Schedule.

A cyclic script that stops is the quietest failure there is: nothing errors, no value turns bad, the plant simply stops being told things. The watchdog has two halves, and neither covers the other:

Heartbeat tag. Each run writes a counter here. A PLC can watch from outside and go safe when the number stops moving. This half still works when we are the failure — a wedged service, a dead host.

Grace period. No completed run for this long is filed as a missed run. This half works when the instance is fine and the script is not: a saturated queue, a run that hangs on every tick. It must be at least one and a half times the interval and never less than 500 ms — closer than that, it reports a miss whenever a run takes a moment longer than usual.

Alarm tag. Set to true on a missed run and back to false on the next completed run. It needs a grace period, or nothing ever decides that a run is missing.

On the clock the plant runs by: every N minutes, every N hours at minute X, daily at 06:00, on chosen weekdays at 06:00. “Every 15 minutes” lands on :00, :15, :30, :45 — an interval, by contrast, counts from when it was armed.

Only minute counts that divide an hour evenly are allowed: 1, 2, 3, 5, 6, 10, 15, 20, 30. Anything else would leave a short slot at the hour.

Inside a script, the same clock is system.time.plant_now(). datetime.now() is not that clock — it is the zone of the machine the script runs on, so a script started at “06:00” that then asks for the time itself would compute against its own trigger.

A run missed while the instance was down is not caught up. It is recorded as missed. A setpoint meant for 08:00 must not arrive at 08:12.

Something the instance itself did, not something a value did:

  • The instance started — after the connectors are up, never while the way out to the machines is still closed.
  • The instance is stopping — before it goes down, while writing still works.
  • A connection was lost — a source stopped answering.
  • A connection came back — the moment to re-send what could not be sent.

Once for every new file in one folder of the file store — uploaded on the Files page, sent by a machine with an API token, written by the assistant or by another script. A file moved into the folder counts as arrived, too. The script gets the file as params["file_id"] (with params["folder"] and params["name"]).

  • Folder — only this folder, not the ones below it; empty means the top level. Chat/, Users/ and Sessions/ are not allowed: they hold what belongs to one person or one conversation, which scripts cannot see.
  • Name pattern — optional, shell-style: *.zip, export-*.csv. Case is ignored.

Once per file. A run that succeeded is remembered; the same file is not handed to the script again. Files that arrive while the instance is down are picked up when it starts, and a file whose signal got lost is found within a minute. A run that failed is tried again after a restart or once the script is saved — not every minute. Only files that arrived after the script was created count: switching an importer on for a folder that already holds a year of deliveries does not start a year of runs — run it by hand for those.

The rate ceiling applies as for every trigger. Make the script itself safe to run twice with system.file.claim() — see The script interface.

It runs when somebody presses Run now. That is how a script is tried before it is trusted with a machine.

The trigger that never fires. See Libraries.

  • The Enabled switch only means something runs by itself if this instance has a trigger loop at all. If it has none, the page says so: scripts can then be edited and run by hand, nothing more.
  • A copy is always switched off, whatever the original was.
  • A trigger setting the server would refuse is reported while you type, beneath the field it belongs to — with the number that would be allowed.