Skip to content

Runs and problems

A script that acts while nobody is watching cannot be answered for without a log. The dock along the bottom of the script page is what somebody opens at 08:00 to find out what happened at 03:00.

Every line is one run: when it started, how long it took, whether it succeeded and why it ran. Unfolded, it shows what was written, what the script printed and — if it failed — the message with the line in the code.

The log shows facts. Every write appears with its outcome: reached the machine, recorded here, or failed. What a script merely would write exists in the dry run and nowhere else.

The causes, and two of them are not runs of the script at all:

Cause Means
tag changed a bound tag was written
clock the cyclic trigger
scheduled a due point in time
missed - the instance was not running the time was due and nobody was there. Not caught up
watchdog: no run arrived the clock noticed a cyclic script had stopped
system event start, shutdown, connection
by hand somebody pressed Run

The log is bounded. The last 200 runs per script are kept, older ones are removed. The page states the number. A script firing every second produces 86,400 rows a day — unbounded, the largest table in the instance would be a debugging aid. Individual runs therefore do not appear in the audit trail either; what appears there is who changed the script.

Watching live. Beside the tabs, Live in diagnostics appears once the diagnostics panel is switched on in this browser (see Operation, logs and diagnostics). It opens the panel filtered to this script and shows what a run you started prints with print(). With the panel switched off, the link is not there.

When triggers arrive faster than the script runs

Section titled “When triggers arrive faster than the script runs”

Triggers arrive at the speed of a machine, a script runs at the speed of a Python process. Between them sits a queue per script, and it is bounded. When it is full the oldest entry falls out — the value least likely to still matter.

What is lost is counted and shown, on the leaf in the tree and in the list:

  • waiting — what is queued right now.
  • triggers dropped — the script is slower than its source. That number is the sign that something does not fit, not a blemish.
  • runs refused by the ceiling — the rate limit took effect.

Only one run happens at a time per script; different scripts run alongside each other.

Under Limits stands how many runs per minute may happen at most. The default is 120. That is the cap for the case that is not a loop: one script triggered a thousand times a second by a fast machine.

Against a loop itself — a script writes a tag, that write triggers a script — something else applies: every write carries the chain of what caused it. A script appearing twice in that chain has its run refused, and named.

This is what stands out about the code without it having run:

  • Syntax errors, with the line.
  • Not found here: … — an import that names neither a script here nor a module we are sure Python brings along. That can be perfectly right: a plant may have Python packages TrakState knows nothing about. Which is why it says “not found here” and not “does not exist”.

If it says No problems, the imports resolve and the code parses. Whether it does the right thing is something only the dry run says.

If this instance has no trigger loop, the page says so at the top: nothing runs by itself, scripts can be edited and run by hand. The Enabled switch then promises nothing it cannot deliver.