Skip to main content

OPC-UA Source Node

info

The OPC-UA Source is currently configured through the ZephFlow SDK and DAG YAML rather than the visual workflow builder. See the ZephFlow OPC-UA Source reference for the SDK configuration keys and a full DAG example. The fields below describe the same settings.

Quick Reference

Endpoint URL The OPC-UA server endpoint to connect to. ex: opc.tcp://plc-host:4840

Monitored Nodes The OPC-UA variables to subscribe to. Each needs a namespace index, an identifier, and an identifier type.

Security Policy None for an unencrypted channel, or Basic256Sha256 to sign and encrypt.

Username / Password (optional) Leave blank to connect anonymously.

Publishing / Sampling Interval How often the server publishes changes and samples each variable, in milliseconds. Default: 1000 each.

Advanced settings — Server Queue Size, Inbound Queue Capacity, Offer Timeout, Shutdown Grace, and Request Timeout tune buffering and connection behavior; the defaults suit most deployments.

Overview

The OPC-UA Source node subscribes to variables on an OPC-UA server and emits one record per data-change notification. It targets industrial automation data — PLCs, SCADA systems, and historians that expose an OPC-UA endpoint.

It is subscription-based rather than polling: you name the variables ("nodes") you care about, and the server pushes a notification only when a value actually changes. Each notification becomes a record carrying the value, its OPC-UA status code, and both the source and server timestamps, so bad-quality reads stay visible downstream instead of silently arriving as values.

Unlike other source nodes there is no encoding type to choose. OPC-UA is a typed protocol, so values arrive already structured and are mapped into a fixed record shape.

Configuration

FieldDescriptionRequiredDefault
Endpoint URLThe OPC-UA server endpoint. Must start with opc.tcp:// (e.g. opc.tcp://plc-host:4840).Yes
Monitored NodesThe OPC-UA variables to subscribe to. At least one is required. See Monitored Nodes.Yes
Security PolicyNone for an unencrypted channel, or Basic256Sha256 to sign and encrypt.NoNone
UsernameUsername for a username identity. Leave blank to connect anonymously.No
PasswordPassword. Only valid together with a username.No
Publishing Interval (ms)How often the server publishes accumulated changes for the subscription.No1000
Sampling Interval (ms)How often the server samples each monitored variable.No1000
Server Queue SizeServer-side queue depth per monitored variable, buffering changes between publishes.No10
Inbound Queue CapacitySize of the bounded buffer between the OPC-UA callback and the workflow loop.No10000
Offer Timeout (ms)How long to wait for room in a full inbound queue before dropping the notification.No1000
Shutdown Grace (ms)On shutdown, how long to wait for the queue to drain before forcing exit.No5000
Request Timeout (ms)OPC-UA request timeout.No5000

Monitored Nodes

Each monitored node identifies one OPC-UA variable with three values:

FieldDescriptionRequired
Namespace IndexThe variable's namespace index on the server. Must be 0 or greater.Yes
IdentifierThe node identifier, interpreted according to the identifier type.Yes
Identifier TypeNumeric, String, GUID, or Opaque.Yes

The identifier type determines how the identifier is read:

Identifier TypeExpected formatExample
NumericAn unsigned integer2258
StringAny string, used as-isMachine1.Temperature
GUIDA UUID09087e15-1e1f-4c40-b76e-4e5c8b1a0f3a
OpaqueBase64-encoded bytesAQIDBA==

Identifiers are checked when the workflow is validated, so a Numeric identifier that isn't a number, or a malformed GUID, is caught before the workflow runs.

Record Shape

Each data-change notification produces one record:

{
"node_id": "ns=2;s=Machine1.Temperature",
"namespace_index": 2,
"identifier": "Machine1.Temperature",
"value": 21.4,
"status_code": 0,
"status_good": true,
"source_timestamp_ms": 1753280531318,
"server_timestamp_ms": 1753280531402,
"received_at_ms": 1753280531455
}
FieldDescription
node_idThe full NodeId in OPC-UA's parseable form
namespace_indexNamespace index of the variable
identifierThe variable's identifier as a string
valueThe value read, or empty when the notification carried none
status_codeRaw OPC-UA status code
status_goodtrue only when a status code is present and good
source_timestamp_msWhen the source sampled the value, in epoch milliseconds
server_timestamp_msWhen the server observed the value, in epoch milliseconds
received_at_msWhen this workflow received the notification

Check status_good before using value. OPC-UA reports bad-quality reads as notifications with a non-good status, and this node passes them through rather than dropping them. Add a filter node on $.status_good == true when you only want trustworthy readings.

Note that records arrive one per variable per change, not as a combined row per device. If you need several tags together, correlate them with a downstream processing node.

Security

Setting Security Policy to Basic256Sha256 signs and encrypts the channel. In this mode the node generates an ephemeral self-signed client certificate in memory at startup, and accepts the server's certificate without verifying it.

warning

With Basic256Sha256, the channel is encrypted but the server's identity is not verified — there is no certificate pinning, so this does not protect against a man-in-the-middle between the workflow and the endpoint. Use it on trusted networks and treat the Endpoint URL as the trust boundary.

Because the client certificate is regenerated on every start, servers that require a pre-registered and trusted client certificate will reject the connection.

The node connects to an endpoint offering the configured policy, so the server must actually advertise it.

Handling Backpressure

OPC-UA gives the consumer no flow control here, so the inbound queue absorbs bursts. When it fills, the node waits up to the Offer Timeout for room; if none frees up, the notification is dropped and counted in the opcua_dropped_count metric.

Sustained drops mean the workflow can't keep up with how fast tags are changing. Either raise Inbound Queue Capacity to ride out bursts, or raise Sampling Interval / Publishing Interval to slow the incoming rate.