Developers/Programming
Python scripts
The ctx API, startup, screen-open and button events, and periodic tasks.
2 min read
Scripts are project files scripts/<name>.py. Edit them in Studio (Scripts and tasks), with highlighting and syntax checks, or from an external editor.
Events
| Event | ctx.event |
When |
|---|---|---|
| Startup | startup |
Once when Runtime starts, in the configured order |
| Screen open | screen_open |
When opening or navigating to the screen |
| Button | button |
Run script action |
| Periodic task | task:<id> |
Every period, after the previous run finished |
The ctx API
# Consistent snapshot taken when this run started.
if ctx.quality("Pump1.running") == "good":
running = ctx.read("Pump1.running")
print(f"Pump 1: {running}")
# State kept between runs of this script while Runtime is alive.
ctx.state["executions"] = ctx.state.get("executions", 0) + 1
# Request a write; validated and applied when the script ends without errors.
if ctx.read("Tank.level") > 90.0:
ctx.write("Pump1.setpoint", 50.0)
| Member | Description |
|---|---|
ctx.read(name) |
Value; raises if quality is not good |
ctx.quality(name) |
good, uncertain or bad |
ctx.write(name, value) |
Queues a write (max 1000 per run) |
ctx.state |
JSON-serialisable dict per script |
ctx.event |
Event that triggered the run |
ctx.screen |
Source screen; empty for startup and tasks |
If the script raises, its writes and ctx.state changes are discarded. print() output and errors appear in Executions.
Configuration
{
"startup": ["startup"],
"timeout_seconds": 10,
"tasks": [
{"id": "quality", "script": "check_quality", "interval_ms": 5000, "enabled": true}
]
}
Stored in automation.json. A screen adds "on_open": ["screen_open"]; a button "action": "script", "script": "name".
Execution
- Every run uses a fresh Python process, with a 0.1 to 300 s limit (10 by default).
- Events are serialised: a slow script delays others but never blocks Qt or acquisition.
- Tasks never overlap and don't catch up on missed periods.
Trusted code
The separate process allows cancellation but is not a sandbox. Scripts run with the user's permissions and can import any installed library.
Example: start counter
# scripts/count_starts.py — task every 1000 ms
running = ctx.read("Pump1.running")
was_running = ctx.state.get("was_running", False)
if running and not was_running:
ctx.write("Pump1.starts", ctx.read("Pump1.starts") + 1)
ctx.state["was_running"] = running
Runtime language
ctx.language returns the current language. ctx.set_language() accepts a declared project language and applies the change after the script succeeds and its commands are validated.
if ctx.language == "es":
ctx.set_language("en")