Output Datasources
An output datasource writes data out to an external system — a PLC, broker, or control application. Use Output Mapping to map prediction channels to a destination tag or column; you can also send a payload directly with an on-demand test write.
Supported outputs
Section titled “Supported outputs”| Protocol | Capability |
|---|---|
| OPC-UA | Write to a node (synchronous) |
| MQTT | Publish to a topic at QoS 1, retain off by default |
| CSV | Append rows to a rotating file — one column per mapped tag, plus timestamp_utc |
Configure an output
Section titled “Configure an output”-
Create the output
Section titled “Create the output”Go to Datasources → Output, click + Create, and pick the protocol.
-
Fill the connection config
Section titled “Fill the connection config”Each protocol has its own fields. Secret fields are masked as
***after saving.{"endpoint": "opc.tcp://your-plc-host:4840","securityPolicy": "None","authentication": "Anonymous"}{"broker": "mqtt://your-broker-host:1883","port": 1883,"clientId": "plc-sink","userName": "your-username","password": "your-password"}There’s no Base Topic or subscription QoS field here — those describe what an MQTT input subscribes to, and the form only shows fields this direction uses. The topic a prediction publishes to comes from its Output Mapping tag, not a connection field. Prediction publishes always use QoS 1 (see below); a Test Write payload can still set its own
qos(0–2, default 0 — see below).{"outputDirectory": "/data/output","baseFilename": "predictions","rotationMaxSizeMb": 500}Writes rotating files under the configured directory — one column per mapped output tag, plus a
timestamp_utccolumn. -
Map output channels
Section titled “Map output channels”Open Output Mapping on the row and map at least one prediction channel to a destination tag — an MQTT topic, a CSV column, or an OPC-UA node address. The mapped tag is the sink-native address verbatim: an MQTT tag of
testpublishes to the topictest, with no prefix added. -
Save and enable
Section titled “Save and enable”Save the output, then enable it. An output must be enabled before it will deliver predictions or accept a test write.
MQTT publish: QoS 1 and throughput
Section titled “MQTT publish: QoS 1 and throughput”The MQTT sink publishes at QoS 1, not QoS 0. At QoS 0 the broker acknowledges nothing, so a dropped message — most often a topic an ACL denies — still returns a successful write with no notification; QoS 1 gets a real acknowledgment (or a reason code) back from the broker.
retain stays false: a retained message replays to every future subscriber, so a
dashboard opened hours later would read a stale value as current — a deliberate,
per-deployment choice rather than a guessable default.
MQTT: reconnect, client ids, and Test Connection diagnostics
Section titled “MQTT: reconnect, client ids, and Test Connection diagnostics”The MQTT sink reconnects with backoff after the broker drops the connection — a publish- only connection has nothing to re-subscribe, so recovery is just the reconnect itself. Without it, a transient outage used to be permanent.
An explicit Client ID is now role-suffixed (<id>-in for an input, <id>-out for
an output) at connect time. This applies to every saved config, including one still
storing the old shared aiboard default — so an input and output built from the
same config no longer evict each other off the broker, and no edit is needed for
that pairing. A blank id still auto-generates a unique id.
Eviction (SessionTakenOver) still happens if you explicitly reuse one Client ID across
two datasources of the same role (two inputs, or two outputs), or if an external
MQTT client connects with the same id as one of your datasources — give each a distinct
value, or clear the field, in that case.
Test Connection classifies socket-level failures instead of showing a raw exception
name: unreachable/refused/DNS failures map to connect_failed, and a cancelled connect
maps to timeout. In Docker, localhost is the backend container, not your
machine — the most common cause of a broker that’s reachable from your desktop client
but not from AIBOARD. Use the broker’s service name instead (e.g. mqtt://mosquitto:1883
in the lab).
Security modes
Section titled “Security modes”Output connections use the same security fields and ladder as inputs —
Insecure for the bench, TLS with credentials for staging, mutual
certificate authentication for production. Certificates are read from the
/certs mount. See
Security modes: Insecure, TLS, and Secure
for the per-protocol field tables; they apply verbatim to outputs.
Two output-specific notes:
- MQTT publishes at QoS 1 on the production path so a broker that drops a message (an ACL-denied topic is the classic case) surfaces as a failure instead of a silent success. Give the sink’s account publish rights on exactly the mapped topics.
- CSV outputs write inside the jailed output directory only; rotation caps disk use. Secure the volume, not the protocol.
Send a test write
Section titled “Send a test write”Test writes are sent through the API — POST /api/datasources/output/{id}/test-write,
admin only. There is no Test Write button in the UI. Each sink validates its own payload
shape: MQTT wants a topic, CSV wants columns/values, and OPC-UA wants a writes
array. Use the matching example below.
{ "writes": [ { "nodeId": "ns=2;s=Temperature", "value": 42.5 } ]}{ "topic": "devices/plc/setpoint", "setpoint": 65.0, "mode": "heating"}{ "columns": ["setpoint", "mode"], "values": [65.0, "heating"]}A successful write returns a success result; a protocol error returns a message such
as OPC UA: node not found or MQTT: publish refused.
If something goes wrong
Section titled “If something goes wrong”| Symptom | Likely cause |
|---|---|
connect_failed on Test Connection | Broker/endpoint unreachable, refused, or DNS failure — check network path, host, and port (MQTT 1883, OPC-UA 4840). In Docker, localhost means the backend container, not your machine. |
timeout on Test Connection | The connect attempt was cancelled before finishing — check network path and port. |
Enable fails with no_output_tags_mapped | Map at least one output channel to a tag first via Output Mapping. |
| Datasource disabled error | Enable the output before sending a test write. |
Node not found (OPC-UA) | Check the NodeId format and that the node exists on the server. |
Admin only (403) | Test writes require an admin account. |
| Two MQTT inputs (or two outputs) keep disconnecting each other | Both share the same explicit Client ID — clear one or give each a distinct value. An MQTT input and output on the same config are unaffected: each is auto-suffixed (-in/-out) at connect time, including on an older aiboard default. |
See the Troubleshooting runbook for more.