Pipelines
A pipeline is a directed graph of nodes that moves and transforms data. Where the namespace answers "what is this value?", a pipeline answers "what should happen to it?"
When to use a pipeline
| Situation | Use |
|---|---|
| Show a live value on a screen | A binding — no pipeline needed |
| React to a button press on a screen | An event action |
| Move data on a schedule or an event, reliably | A pipeline |
| Transform, enrich, aggregate before storing | A pipeline |
| Expose an HTTP endpoint other systems call | A pipeline (REST ingress) |
| Bridge one protocol to another | A pipeline, or a second binding for simple cases |
| Server-side logic invoked from a screen | A Gateway script |
The distinguishing property of a pipeline is reliability: writes it performs are covered by store-and-forward — buffered on outage, replayed in order, quarantined on permanent failure. A script write is immediate and fails to its caller.
Anatomy
| Concept | Meaning |
|---|---|
| Node | One step. Has a type, a configuration, optional code, and input/output ports. |
| Connection (wire) | Passes a message from one node's output to another's input. |
| Message | The envelope travelling the graph: a payload plus metadata and context. |
| Trigger | What starts execution — a schedule, an inbound HTTP request, a tag change, a message on the bus, a manual run. |
| Execution | One traversal of the graph, logged and inspectable. |
The message
Every node receives a message and returns one. In scripts you see two things:
| Name | Contents |
|---|---|
payload | The primary data — what the previous node produced. |
message | The full envelope: payload plus metadata, correlation identifiers and context. |
def transform(payload, message):
# payload — the data
# message — the envelope, including where it came from
return {"value": payload["value"] * 2}
Return the value you want the next node to receive.
Node categories
| Category | Nodes |
|---|---|
| Common | Inject, Link, RBE (Filter), Switch, Timer |
| Realtime | Industrial I/O, Alarm |
| Datasource | SQL Query, MongoDB, QuestDB |
| Transform | Python Script, Batch Transform, Array Iterator, Join |
| AI | AI |
| Notification | Send Email, Telegram, WhatsApp, On-Call Roster |
| API | REST API, HTTP Response |
| Message Bus 1.0.8 | Message In, Message Out, Message Reply |
| Output | Debug, Catch |
→ Node reference for every node's configuration.
Execution model
- Execution is graph-driven, not line-by-line: a node runs when a message arrives on its input.
- A node with several outbound wires fans out — every downstream branch receives the message.
- Switch is the exception: it has one output per rule, and a message leaves by the outputs whose rules matched. A branch that did not fire is skipped, and the skip cascades.
- Array Iterator splits an array into one message per item; Join collects them back.
- Batch Transform processes items of a collection in parallel.
- Timer is the only node that defers. It never blocks the graph: it hands a deadline to the runtime and returns, and the run that fires later is an independent one — which is how a repeating timer works in a graph that forbids cycles.
- Errors are logged against the execution, and the branch stops. Other branches continue.
Pipeline lifecycle
| State | Meaning |
|---|---|
| Stopped | Not listening, not scheduled. |
| Running | Triggers are armed; the graph executes when they fire. |
| Error | Started but a node failed fatally; see the execution log. |
| Action | Permission |
|---|---|
| Start or stop a pipeline, or all of them | Start/Stop Pipeline |
| Execute once, now | Execute Pipeline |
| Trigger a single node | Execute Pipeline |
| See runtime state | authenticated |
A pipeline is also enabled/disabled as configuration. Disabling stops it and keeps it from being started by "start all" — the right way to shelve a pipeline without deleting it.
The canvas
| Control | Does | Shortcut |
|---|---|---|
| Undo / Redo | Step back and forward through your edits | ⌘/Ctrl+Z · ⌘/Ctrl+Shift+Z |
| Zoom out / Zoom in | Ctrl/⌘ + scroll | |
| The zoom percentage | Click it to reset to 100% | |
| Zoom to fit | Frame the whole graph |
New in 1.0.4 — the controls are on the canvas itself, and undo and redo grey out when there is nothing to step to, so the canvas says what is available rather than leaving you to try it.
Multi-touch pinch to zoom and two-finger pan work on a touch screen. New in 1.0.1
Editing safely
Pipelines are optimistically locked with a server-managed revision. Saving carries the revision you loaded; a concurrent save by someone else is rejected rather than silently overwriting. Two engineers editing the same pipeline get a conflict to resolve, not a lost afternoon.
Cross-pipeline communication
| Mechanism | Use |
|---|---|
| Link nodes | Send messages between pipelines of the same project without wiring them into one graph. |
| Message bus 1.0.8 | Send by subject to any pipeline, screen or script that listens — and ask for a reply. Message In, Message Out, Message Reply. |
| Variables | Shared key/value state readable and writable from any pipeline or script. |
| Tags | The most decoupled option — one pipeline writes an internal tag, another subscribes. |
→ Message bus · Variables
Link or message bus? A Link joins two of your pipelines by node: the receiver names the sender, and nothing else can hear it. The bus joins anything to anything by subject: the sender does not know who listens, a screen's button or a script can send too, and a request gets an answer back. Reach for a Link for a fixed hand-off; reach for the bus when the receiver should be replaceable or the sender is not a pipeline.
Changed in 1.0.8 The project is now part of a Link's address. An ingress Link listening to an egress Link in another project stops receiving after the upgrade, without an error. Replace such a pair with Message Out (Send to: All projects) and Message In.
Observability
| What | Where |
|---|---|
| Per-execution log | The execution log panel (needs View Execution Logs) |
| Per-node results | The execution log panel, per node (needs View Execution Logs) |
| Live node status | Node badges on the canvas, pushed over the telemetry bus |
| Whether a node's connection is up | The status line under the node — see below |
| Ad-hoc inspection | The Debug node → the Debug panel |
Clearing logs requires Clear Execution Logs; they are diagnostic data, not the audit journal.
The connection status under a node New in 1.0.7
Every node that names a connection — an Industrial I/O read, a SQL Query, a Telegram receiver — carries a small square and a few words under the card, saying whether that connection is up. Before, a node told you which connection it used and nothing about its state, so a pipeline full of nodes bound to a dead device looked exactly like one that was working. That is worst for a trigger node: one whose connection is down and one that simply has not been sent anything are both blank.
The two indicators answer different questions. The round badge in the node's corner is the last run — running, succeeded, failed. The square underneath is the connection behind it, and it changes whether or not the pipeline runs.
Changed in 1.0.8 The exception is a notification node — Send Email, Telegram, WhatsApp. Its line answers "is this node sending or receiving right now?", which has an answer only while the pipeline runs, so it is shown only then. On a stopped pipeline it kept reading receiving · 12 in from the bot's last state, which looked like the stopped node was still live. A database or device node keeps its line at design time: seeing that connection is down before you press Start is the point.
| Square | Caption | Means |
|---|---|---|
| Green | connected | The connection is up. Only this status ever says connected. |
| Green | receiving · 12 in · 5 out | Up and traffic is flowing — the counts are what prove the node has done something. |
| Green | connected · waiting | Up, and nothing has arrived yet. |
| Amber | checking… | A check is in progress and has not answered. |
| Amber | retrying | Lost, and reconnecting. |
| Yellow | no recent data | Nothing heard for longer than expected — not yet a failure, and deliberately not connected. |
| Orange | backing off | Failing repeatedly, so attempts are paused for a while. |
| Red | error, or a specific failure | Failed. Hover for the full message. |
| Grey | disabled | The connection is switched off, and a node using it will fail. |
| Grey | not checked | Nobody has asked it anything yet — a new connection has not failed. |
The caption is the glance; the full sentence is in the tooltip. For a Telegram bot the red case not polling is told apart from a plain error, because it has its own fix: enable the bot. 1.0.8 The captions token in use elsewhere and updates not arriving are gone — both fired on a healthy bot, during its own restart, and made it flicker between connected and failed. → Telegram status
The status is the same one the Connections list shows, and every node bound to one connection shares it, so a canvas with eighty nodes on four connections costs four subscriptions, not eighty.
Permissions
| Action | Permission |
|---|---|
| View pipelines | View Pipelines |
| Create | Create Pipeline |
| Edit | Edit Pipeline |
| Delete | Delete Pipeline |
| Execute once | Execute Pipeline |
| Start/stop | Start/Stop Pipeline |
| Export | Export Pipeline |
| Import | Import Pipeline |
| View execution logs | View Execution Logs |
| Clear execution logs | Clear Execution Logs |
In this section
| Page | Contents |
|---|---|
| Node reference | Every node type and its configuration |
| Execution & triggering | How and when a pipeline runs, and how to debug it |
| Variables | Shared state across pipelines and scripts |
| REST endpoints | Publishing HTTP APIs from a pipeline |