Node Configuration Reference
Most nodes in a pipeline are one of three shapes, and every node of a shape takes the same config fields whatever protocol it speaks. A Kafka consume node and an OPC UA read node differ in which function they call, not in how the node itself is configured.
- Connector function node (
connected.<protocol>.<operation>) — calls one function on one connection: read a register, publish a message, run a query. - Read group (
connected.<protocol>.readgroup) — calls several read functions on one connection and returns their results together. - Connector trigger (
trigger.<protocol>) — starts the pipeline when a message arrives on a connection.
What each node does is documented on its protocol's own page. What every node of that shape accepts is the table below, generated from the contract the pipeline validator enforces.
A connector node's arguments are the parameters of the function it
calls, and they vary per function. The designer's form fills them from
the function's own schema; the fields below are the node's, not the
function's.
Configuration reference
The fields below are generated from the node's config contract, so they match what the pipeline validator enforces and what the designer's form offers.
connected.function
| Field | Type | Required | Default | Values | Description |
|---|---|---|---|---|---|
connectionId | string | no | — | — | ID of the connection the function belongs to; the designer always sets it. When absent the engine resolves it from the function on every run (a cached lookup) — set it so the node routes directly |
functionId | string | yes | — | — | ID of the connector function to execute. The operation (publish, query, write, …) and its template parameters live on the function — manage_functions get shows them |
args | object | no | — | — | Arguments for the function's template parameters, keyed by parameter name — the keys come from the chosen function (manage_functions get shows them; values accept expressions such as {{ $input[0].result.temperature }} or {{ $node["Read"].result.id }}). Every value is resolved at run time and passed to the function |
data | any | no | — | accepts an expression | Optional value handed to the function as input.data. A string is resolved as an expression first; any other JSON value passes through unchanged. Leave it out unless the function's template reads it |
timeoutOverride | integer | no | — | at least 1 | Per-request timeout for this node in MILLISECONDS (the designer's field is in seconds and multiplies by 1000). Shortens the deadline only — it can never extend past the node, pipeline, connection or function timeouts |
storeForwardMode | string | no | — | on_failure, always, off | Store-and-forward for output (write) operations: on_failure (the default when absent) calls the connector directly and buffers only after a failure; always buffers every write and delivers it asynchronously; off never buffers. Ignored by read operations |
freshness | string | no | — | at least 0 | How long a buffered write is still worth delivering, as a duration such as "60s" or "5m": a payload older than this is dropped instead of delivered late. Empty = always deliver. Only matters when storeForwardMode can buffer |
deliveryOrder | string | no | — | ordered, relaxed | Delivery discipline of the store-and-forward buffer: ordered delivers strictly in sequence, relaxed lets independent payloads overtake a stuck one. Empty = the connector's default |
allowLateInput | boolean | no | — | — | Let this write run when the value that started the run was late: a reading older than the UNS late threshold when it arrived, as a gateway replaying its buffer after an outage produces. Off (the default), a write the connector declares realtime or time-bounded (PLC control writes, setpoints, notifications) is refused in such a run and the log says when the value was measured and received; tolerant writes (storage, historians) always run. Only for a pipeline that must act on replayed data |
debugMode | boolean | no | — | — | Frontend-only switch the designer persists; the engine does not read it |
connected.readgroup
| Field | Type | Required | Default | Values | Description |
|---|---|---|---|---|---|
connectionId | string | yes | — | — | ID of the connection whose functions are read — all functions in the group must belong to it |
selectionMode | string | no | — | manual, readAll, byLabels | How functions are chosen: manual lists them in functions; readAll reads every read function on the connection (set readAll: true as well); byLabels reads every function whose labels match functionLabels. Absent = readAll when readAll is true, else manual |
readAll | boolean | no | false | — | true reads every read-type function on the connection and ignores functions and functionLabels. This is the flag the executor reads; keep it in step with selectionMode |
functions | object[] | no | — | — | The functions to read when selecting manually, in order. Required (at least one) when readAll is false and functionLabels is empty; ignored otherwise. functionIds and aliases must be unique |
functionLabels | object | no | — | — | Label selector for byLabels: label key to a string or a list of strings, e.g. {"area": ["line1", "line2"], "env": "prod"} — AND across keys, OR within a key. Resolved against the connection's functions on every run. A value of any other type is ignored with a warning in the run output |
allowEmpty | boolean | no | false | — | true lets readAll or byLabels succeed with an empty result when no function matches; false (default) fails the node, treating an empty selection as a misconfiguration |
executionMode | string | no | parallel | parallel, sequential | parallel reads all functions at once (bounded by maxConcurrency); sequential reads them one after another in list order |
continueOnError | boolean | no | true | — | true records a failed read in the output and carries on; false fails the whole node as soon as any function fails |
coalesce | boolean | no | true | — | Modbus only, parallel mode only: true merges adjacent register reads into fewer protocol requests (the gap allowed is set on the connection); false issues one request per function. Other protocols ignore it |
outputMode | string | no | always | always, onChange | always emits every read on every run; onChange emits only successful reads whose value changed since the previous run (failed reads always pass through) and buffers the run when nothing changed |
dedupMaxKeys | integer | no | — | 1–10000 | onChange only: how many functions' last values are tracked for change detection before the least-recently-updated is evicted. Default 1000 when absent |
maxConcurrency | integer | no | — | at least 0 | parallel mode only: upper bound on functions read at the same time. 0 (default) means unlimited — except BACnet, which caps at 16 to protect its single UDP socket |
timeoutOverride | integer | no | — | at least 1 | Per-request timeout for this node in MILLISECONDS, applied to every read in the group. Shortens the deadline only — it can never extend past the node, pipeline, connection or function timeouts |
debugMode | boolean | no | — | — | Frontend-only switch the designer persists; the engine does not read it |
trigger.connector
| Field | Type | Required | Default | Values | Description |
|---|---|---|---|---|---|
connectionId | string | yes | — | — | ID of the connection the trigger listens on |
functionId | string | yes | — | — | ID of the function that receives data on that connection — the subscribe (MQTT, NATS, OPC UA monitor, …), consume (RabbitMQ, Kafka, Kinesis, …) or receive (Azure IoT Hub) function whose config says what to listen to |
enabled | boolean | no | true | — | false keeps the node in the pipeline but never registers its subscription, so the pipeline is not started by it |
triggerMode | string | no | always | always, onChange | always starts a run on every message; onChange starts one only when the payload differs from the last one seen (per topic/subject where the protocol has one). Honoured by the broker triggers; the sampling triggers (opcua, opcda, ignition, fanuc, piwebapi, pisystem, twincat, iec104) fire on every sample regardless — each value carries its own timestamp, so no two payloads are ever equal |
dedupMaxKeys | integer | no | — | 1–10000 | onChange only: how many topics/subjects' last payloads are tracked before the least-recently-updated is evicted. Default 1000 when absent |
testData | any | no | — | — | Sample payload used as the trigger's result when the pipeline runs in the sandbox (test run); any JSON value. Ignored by the live subscription |
sandboxQuality | string | no | — | good, uncertain, bad | Sandbox (test run) only: the quality band the sample trigger reports in _metadata.quality — good, uncertain or bad — so a quality-aware pipeline can be tested before it meets a real device. Empty uses the good sample. Ignored by the live subscription; triggers whose metadata carries no quality make no statement |
outputData | any | no | — | — | Payload used when the trigger is fired by hand from the designer (Fire button); any JSON value. Ignored by the live subscription |
connectionName | string | no | — | — | Display name of the connection, persisted by some designer forms next to connectionId; the engine does not read it |
functionName | string | no | — | — | Display name of the function, persisted by some designer forms next to functionId; the engine does not read it |