Comprehensive OPC-UA Guide for Industry: Architecture, Security, Implementation

· 11 min read
11 min read
Eziwan Team
IoT Infrastructure

OPC-UA (OPC Unified Architecture) has become the standard protocol for interoperability in Industry 4.0. However, its apparent complexity still hinders many implementations. This practical guide demystifies OPC-UA: architecture, security, NodeId, Python/Node.js implementation, and cloud integration.


What Is OPC-UA and Why Does It Matter?

OPC-UA (IEC 62541) is a platform-independent communication protocol designed for the secure exchange of industrial data. Unlike its predecessor, OPC-DA (Windows-only, DCOM), OPC-UA runs on any operating system (Linux, Windows, embedded RTOS) and over any network (Ethernet, 4G, Wi-Fi).

Why OPC-UA Dominates Industry 4.0

  • Interoperability: A Siemens S7-1500 OPC-UA server can be read by any compliant client without a proprietary driver
  • Information model: Data has meaning (unit, description, history), not just a value
  • Native security: encryption, authentication, certificates—built into the protocol
  • Compliance profiles: a lightweight subset for small embedded devices
  • Pubsub & MQTT: OPC-UA Pub/Sub extension for cloud architectures (IEC 62541-14)

OPC-UA Architecture: Fundamental Concepts

Client-Server

The basic OPC-UA model is client-server:

  • OPC-UA Server: exposed by the device (PLC, HMI, data server)
  • OPC-UA Client: consumes the data (SCADA, gateway, cloud application)

A single device can act as both a server and a client at the same time (e.g., a gateway that aggregates data from multiple PLCs and exposes the consolidated data).

Address Space and NodeId

The Address Space is the information tree exposed by an OPC-UA server. Each node has a unique NodeId:

NodeId Format:

  • ns=2;i=1234 — namespace 2, integer identifier 1234
  • ns=2;s=Station_1.Pression — namespace 2, string identifier
  • ns=0;i=2258 — namespace 0 (standard), ServerStatus

Namespaces:

  • ns=0: standard OPC-UA namespace (types, methods)
  • ns=1: often the manufacturer's namespace
  • ns=2+: application namespaces (your data)

Communication Methods

ModeDescriptionUse Case
ReadOne-time read of a nodePolling every N seconds
SubscriptionSubscription to changes (MonitoredItem)Events, alarms
BrowseBrowsing the Address SpaceConfiguration, discovery
WriteWriting a valueSetpoints, commands
Method CallMethod callComplex actions
PubsubMQTT or UDP publish/subscribeLarge-scale cloud architectures

Subscriptions are the right approach for real-time monitoring: instead of polling every second, the client subscribes to a node and receives a notification only when the value changes beyond a configurable threshold (DeadbandValue).


OPC-UA Security: The Complete Guide

Security is one of OPC-UA's strengths—and also one of the sources of its complexity. Here are the key concepts.

Security Modes

ModeConfidentialityIntegrityAuthenticationUsage
NoneNoneNoneNoneTesting, isolated network
SignNoSignatureCertificateSecure network
SignAndEncryptAES-256SignatureCertificateInternet, cloud
caution

Never use SecurityMode: None in a production environment on a network accessible from the outside.

X.509 Certificates

OPC-UA uses X.509 certificates for mutual client-server authentication:

Creating a self-signed certificate for testing:

# Avec OpenSSL
openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
-keyout client_key.pem -out client_cert.pem \
-subj "/CN=EziwanGateway/O=Eziwan/C=FR" \
-extensions v3_req \
-config <(cat /etc/ssl/openssl.cnf; echo "[v3_req]"; echo "subjectAltName=URI:urn:eziwan:gateway:client")

In production: Use an internal PKI or a recognized CA. Certificates must be exchanged manually between the client and the server the first time.

User Authentication

In addition to machine certificates, OPC-UA supports user authentication:

  • Anonymous: no authentication (if allowed by the server)
  • Username/Password: application login
  • Certificate: X.509 user certificate
  • IssuedToken: JWT or Kerberos token

Implementing OPC-UA in Python

The python-opcua library (or its fork, asyncua) is the go-to choice in Python.

Installation

pip install asyncua

Python OPC-UA Client — Reading Data

import asyncio
from asyncua import Client

async def main():
url = "opc.tcp://192.168.1.10:4840/freeopcua/server/"

async with Client(url=url) as client:
# Read a node by NodeId
node = client.get_node("ns=2;s=Station_1.Pression")
value = await node.read_value()
print(f"Pression: {value} bar")

# Read Multiple Nodes in a Batch
nodes = [
client.get_node("ns=2;s=Station_1.Pression"),
client.get_node("ns=2;s=Station_1.Debit"),
client.get_node("ns=2;s=Station_1.Defaut"),
]
values = await client.read_values(nodes)
for node, val in zip(nodes, values):
print(f" {node}: {val}")

asyncio.run(main())

OPC-UA Python Client — Subscription

import asyncio
from asyncua import Client
from asyncua.common.subscription import SubHandler

class DataChangeHandler(SubHandler):
def datachange_notification(self, node, val, data):
print(f"[CHANGE] {node} = {val}")

def event_notification(self, event):
print(f"[EVENT] {event}")

async def main():
url = "opc.tcp://192.168.1.10:4840"

async with Client(url=url) as client:
handler = DataChangeHandler()
subscription = await client.create_subscription(500, handler) # 500ms

nodes = [
client.get_node("ns=2;s=Station_1.Pression"),
client.get_node("ns=2;s=Station_1.Debit"),
]

monitored_items = await subscription.subscribe_data_change(nodes)
print("Subscriptions actives, attente changements...")

await asyncio.sleep(30) # Listen for 30 seconds
await subscription.unsubscribe(monitored_items)

asyncio.run(main())

Secure connection with a certificate

from asyncua.crypto.security_policies import SecurityPolicyBasic256Sha256
from asyncua.crypto.cert_man import CertificateManager

async def connect_secure():
client = Client("opc.tcp://192.168.1.10:4840")

await client.set_security(
SecurityPolicyBasic256Sha256,
certificate="./client_cert.der",
private_key="./client_key.pem",
server_certificate="./server_cert.der"
)

await client.connect()
# ... your operations
await client.disconnect()

Implementing OPC-UA in Node.js

The node-opcua library is the go-to choice for JavaScript/TypeScript.

npm install node-opcua

Reading Data

const opcua = require("node-opcua");

const client = opcua.OPCUAClient.create({
endpointMustExist: false,
connectionStrategy: { maxRetry: 5, initialDelay: 2000 }
});

const endpointUrl = "opc.tcp://192.168.1.10:4840";

async function main() {
await client.connect(endpointUrl);
const session = await client.createSession();

const nodeToRead = {
nodeId: "ns=2;s=Station_1.Pression",
attributeId: opcua.AttributeIds.Value
};

const dataValue = await session.read(nodeToRead);
console.log(`Pression: ${dataValue.value.value} bar`);
console.log(`Timestamp: ${dataValue.serverTimestamp}`);

await session.close();
await client.disconnect();
}

main().catch(console.error);

OPC-UA on Major Industrial Controllers

Siemens S7-1500 / S7-1200

The S7-1500 supports native OPC-UA server functionality starting with firmware version 2.0:

  • Port: 4840 (TCP)
  • Configuration in TIA Portal: Device Configuration → OPC UA → Server
  • Enable the desired nodes in the Access configuration
  • Authentication: Certificates or Username/Password

The S7-1200 has supported OPC-UA since firmware version 4.1.

Schneider Electric M580 / M340

M580: OPC-UA via the BMENOC0311 module (firmware ≥ V2.0) M340: No native OPC-UA support → Modbus TCP recommended, or an OPC-UA to Modbus gateway (e.g., Kepware KEPServerEX)

Allen-Bradley / Rockwell (EtherNet/IP)

Rockwell PLCs do not natively support OPC-UA. Options:

  • KEPServerEX (Kepware): EtherNet/IP → OPC-UA bridge
  • FactoryTalk Linx Gateway: OPC-UA server for the Rockwell ecosystem
  • Eziwan Gateway: direct EtherNet/IP/Modbus connection, REST API exposure

Beckhoff TwinCAT 3

TwinCAT 3 includes a native OPC-UA server via TF6100 (OPC-UA module). Configuration is performed via TwinCAT System Manager.

Wago / Phoenix Contact / Pilz

Most modern PLCs from these manufacturers support OPC-UA. Check the firmware and enable the server in the network configuration.


OPC-UA PubSub: The Extension for the Cloud

OPC-UA PubSub (IEC 62541-14) is the extension that makes OPC-UA compatible with cloud-based IoT architectures:

  • Publisher: The device publishes its data to a Message-Oriented Middleware
  • Subscriber: The cloud or SCADA system subscribes to the data stream

Supported transport protocols:

  • AMQP (port 5672)
  • MQTT (port 1883 or 8883) — the most widely used in IoT
  • UDP Multicast (local network)

Encodings:

  • JSON (human-readable, easy to debug)
  • UADP (binary, compact, embedded)

Example of an OPC-UA PubSub JSON message:

{
"MessageId": "abc123",
"PublisherId": "urn:station1:plc",
"DataSetWriterId": 1,
"MetaDataVersion": {"MajorVersion": 1, "MinorVersion": 0},
"Timestamp": "2026-08-14T10:30:00.000Z",
"Payload": {
"Station_1.Pression": {"Value": 4.2, "StatusCode": 0, "SourceTimestamp": "2026-08-14T10:29:59.950Z"},
"Station_1.Debit": {"Value": 125.3, "StatusCode": 0, "SourceTimestamp": "2026-08-14T10:29:59.950Z"}
}
}

Migration from OPC-DA to OPC-UA

If you have systems running OPC-DA (OPC Classic, Windows DCOM), migrating to OPC-UA offers:

  • Elimination of the Windows/DCOM dependency
  • Compatibility with Linux, Raspberry Pi, and Linux-based PLCs
  • Encryption (not available in OPC-DA)
  • Direct internet access (not possible with DCOM without a complex VPN)

Migration tool: OPC UA Wrapper (e.g., Kepware) creates an OPC UA server that exposes data from an existing OPC DA server, enabling a phased migration.


OPC-UA with the Eziwan Gateway

The Eziwan Gateway includes an OPC-UA client capable of connecting to the OPC-UA servers on your devices:

  • Siemens S7-1500 OPC-UA connection (port 4840)
  • Connection to any IEC 62541-compliant OPC-UA server
  • Support for None, Sign, and SignAndEncrypt security modes
  • Configuration of NodeIDs in the cloud interface (automatic browsing of the address space)
  • Data transmission to the Eziwan cloud platform via MQTT/TLS

Key benefit: You don't need to write an OPC-UA client yourself. The gateway handles this and exposes a REST API to your SCADA or ERP system.


FAQ — OPC-UA

Is OPC-UA more complex than Modbus? Yes, but it’s justified for multi-vendor installations and Industry 4.0 projects. For an installation with 2–3 PLCs from the same manufacturer, Modbus TCP may be sufficient. OPC-UA is the way to go when you have heterogeneous equipment, safety requirements, or ERP/MES interoperability needs.

Does port 4840 need to be open on my firewall? In a "zero-inbound-port" architecture (such as Eziwan), the gateway initiates the connection to the OPC-UA server internally. No ports are open to the outside. The encrypted VPN tunnel carries the data to the cloud.

Can OPC-UA replace MQTT in an IoT architecture? OPC-UA PubSub with MQTT transport combines the best of both worlds: OPC-UA’s semantic information model with MQTT’s lightness and scalability. This is the direction taken by the Industry 4.0 reference frameworks (Industry 4.0 Architecture Reference Model, IDS-R).

What performance can you expect from an embedded OPC-UA server? A Siemens S7-1500 CPU 1515 can process ~10,000 OPC-UA read nodes per second. For less powerful PLCs (M221, small WAGO models), limit OPC-UA polling to 100–500 nodes per second. Subscriptions are much more efficient than polling for large volumes.

Are there any free OPC-UA servers available for testing? Yes: ProsysOPC UA Simulation Server (free, Windows), Node-RED with node-red-contrib-opcua (free, cross-platform), python-opcua in server mode (example in the GitHub documentation). These allow you to test a client without a physical PLC.


Further Reading

Need help connecting your OPC-UA servers to the cloud? Request a free demo — our team will guide you from proof of concept through deployment.


Additional Resources