SGT SGT Systems Limited
Integration & API · Protocol Reference · v1.0

OPC UA Connection Walkthrough

End-to-end OPC UA primer: information model, address space, security modes, discovery, and a working opcua-asyncio client.

Updated May 24, 2026
20 views

What OPC UA Is

OPC UA (Open Platform Communications Unified Architecture, IEC 62541) is the modern, cross-platform successor to OPC Classic. Where OPC Classic was built on Microsoft DCOM and effectively Windows-only, OPC UA is a binary or HTTPS-based protocol that runs anywhere — Linux, embedded ARM, microcontrollers, PLC firmware. For SGT Systems it's the standard way to extract data from modern PLCs, SCADA systems, DCS platforms, and tag servers such as Kepware and Prosys.

OPC UA has become the de-facto standard for the IT/OT boundary because it offers three things at once: a well-defined wire protocol, a rich type system for describing complex industrial assets, and a serious security model that has been independently reviewed (the German BSI assessment of 2017 remains a useful read). Industrie 4.0 architectures, MQTT-over-UA convergence (PubSub), and most modern asset administration shells all use it.

OPC Classic vs OPC UA

AspectOPC Classic (DA / HDA / A&E)OPC UA
TransportDCOMTCP (binary, port 4840) or HTTPS
PlatformsWindows onlyCross-platform
SecurityInherits DCOM/Windows ACLs (notoriously hard)X.509 certs, signing, encryption, user tokens
Information modelFlat tag listRich, typed, object-oriented address space
Through firewallsPainful (RPC ports)Single TCP port
DiscoveryOPC Enum (DCOM)Local Discovery Server (LDS)
Pub/Sub supportNonePubSub spec (UDP, MQTT, AMQP transports)

Information Model & Nodes

OPC UA models a system as a graph of nodes. Each node has a NodeId (its unique address), a NodeClass (Object, Variable, Method, ObjectType, ...), a BrowseName, and references to other nodes. This is what lets a client introspect a server without prior knowledge of its tags.

Common NodeClasses:

  • Object — a logical entity (a pump, a tank, a folder).
  • Variable — a value you can read or subscribe to (temperature, setpoint, status word).
  • Method — a callable function exposed by the server (e.g. ResetTrip()).
  • ObjectType / VariableType — type definitions; enable polymorphism.
  • ReferenceType — typed edges between nodes (HasComponent, HasProperty, Organizes).

A NodeId is typically written as ns=<namespace>;<id-type>=<value>:

  • ns=2;s=Channel1.Device1.Tag42  (string ID — Kepware convention)
  • ns=3;i=1015  (numeric ID — typical Siemens server)
  • ns=0;i=2253  (the standard Server object — always present)
  • ns=4;g=72962B91-FA75-4AE6-8D28-B404DC7DAF63  (GUID ID — sometimes seen on .NET-based servers)

The companion specifications (PLCopen for PLCs, OPC UA for Machinery, OPC UA for Pumps, etc.) standardise type hierarchies so that, say, every conformant pump exposes the same FlowRate property at a predictable place in the address space. Where a server implements a companion spec, integration time drops from days to hours because the client can rely on well-known browse paths.

Address Space

The address space is the root-rooted graph of nodes a server exposes. Every conformant OPC UA server has the same well-known root structure under namespace 0 (Root → Objects, Types, Views). Vendor data lives under Objects. You browse the address space using Browse requests — exactly what tools like UaExpert do when you connect.

Three useful built-in views once you connect:

  • Server object (ns=0;i=2253) — server status, capabilities, redundancy info, supported profiles.
  • Types folder — every type the server declares. Useful when you want to subscribe to instances of a particular type.
  • Vendor namespace under Objects — your real tags live here.
UaExpert. Install UaExpert first. It is the de-facto OPC UA debugging client. Before you write a single line of code, browse the server in UaExpert to confirm the NodeIds you intend to use.

Security Modes

OPC UA security is a combination of a SecurityMode (what is protected on the wire) and a SecurityPolicy (which crypto suite is used), plus a separate UserTokenType for the human or service identity.

SecurityModeWhat it protectsWhen to use
NoneNothing — cleartext on the wireClosed lab networks only. Never in production.
SignIntegrity & authenticity (no encryption)When the payload isn't confidential but tamper detection is required.
SignAndEncryptIntegrity, authenticity, confidentialityDefault for any deployment that traverses untrusted networks.

Recommended SecurityPolicy as of writing: Basic256Sha256 or, for newer servers, Aes256_Sha256_RsaPss. Avoid the deprecated Basic128Rsa15 and Basic256 — both have known weaknesses and are removed in current versions of the OPC UA stack.

SecurityPolicyStatusUse for
NoneInsecureLab only
Basic128Rsa15DeprecatedLegacy systems being decommissioned
Basic256DeprecatedLegacy systems being decommissioned
Basic256Sha256CurrentDefault production policy
Aes128_Sha256_RsaOaepCurrentNewer servers, modern crypto suite
Aes256_Sha256_RsaPssCurrentHighest-assurance deployments

Authentication

Independent of transport-layer security, the client identifies itself with a UserToken:

  • Anonymous — no identity. Allowed only when policy permits.
  • UserName — username + password, transmitted over the secure channel.
  • Certificate — X.509 user certificate, the most production-grade option.
  • IssuedToken — federated identity (JWT, Kerberos). Rare in industrial deployments.

The application instance certificate is separate again — it identifies the client software (not the user) and must be trusted by the server before any connection can succeed. First-connection trust is usually handled by manually moving the rejected client cert from the server's rejected/ folder into its trusted/ folder. UaExpert does this in its GUI; for headless clients you do it on the filesystem.

Three layers of identity are involved in every connection:

LayerWhat it identifiesCert/token
Server application instanceThe server software itselfServer X.509 cert
Client application instanceThe client software itselfClient X.509 cert
User sessionThe user or service account on whose behalf the client actsUserName/password or user X.509

Discovery (LDS)

A Local Discovery Server (LDS) is a tiny OPC UA server that runs on a host and advertises every other UA server registered with it. Clients query the LDS to discover endpoints without knowing port numbers ahead of time.

# Discover endpoints on a host running an LDS on the default port
opc.tcp://10.20.30.40:4840

# Discover endpoints on a directly addressed server
opc.tcp://plc-01.factory.lan:48010

In a small deployment you can skip the LDS and connect to each server's endpoint directly. In larger plants, the LDS-ME (Local Discovery Server – Multicast Extension) plus optional Global Discovery Server (GDS) automates certificate provisioning across a fleet — the GDS becomes the CA that issues and rotates application instance certs for every UA participant.

Sample Python client (opcua-asyncio)

This example connects to a Kepware or Prosys simulation server, browses the address space, reads two variables, and subscribes to changes on a third. It uses opcua-asyncio, the maintained async successor to python-opcua.

import asyncio
from asyncua import Client, ua

URL = "opc.tcp://kepware.factory.lan:49320"

class SubHandler:
    def datachange_notification(self, node, val, data):
        print(f"data change  {node}  ->  {val}")

async def main():
    async with Client(url=URL) as client:
        # Application instance cert / private key
        await client.set_security_string(
            "Basic256Sha256,SignAndEncrypt,"
            "/etc/sgt/opcua/client_cert.der,"
            "/etc/sgt/opcua/client_key.pem"
        )
        client.set_user("sgt-collector")
        client.set_password("REDACTED")

        # Browse the Objects folder
        objects = client.nodes.objects
        for child in await objects.get_children():
            print("child:", await child.read_browse_name())

        # Read two tags
        ns = 2
        flow  = client.get_node(ua.NodeId("Channel1.Device1.Flow",  ns))
        level = client.get_node(ua.NodeId("Channel1.Device1.Level", ns))
        print("flow  =", await flow.read_value())
        print("level =", await level.read_value())

        # Subscribe to a status word at 500 ms
        status = client.get_node(ua.NodeId("Channel1.Device1.Status", ns))
        sub = await client.create_subscription(500, SubHandler())
        await sub.subscribe_data_change(status)

        await asyncio.sleep(60)
        await sub.delete()

if __name__ == "__main__":
    asyncio.run(main())
First-connect trust. The first time the script above runs, the server will reject the client certificate. Open the server's certificate manager and move the cert from rejected/ to trusted/, then rerun. This is intentional — OPC UA never auto-trusts unknown peers.

Subscriptions and monitored items

OPC UA subscriptions are how you efficiently track values that change. A subscription has a publishing interval (how often the server checks for new data) and contains one or more monitored items, each with its own sampling interval, deadband, and queue size. The server only sends notifications when a monitored value actually changes by more than the deadband — this is dramatically more efficient than client-side polling, especially for fleets with thousands of tags.

# Monitor with a 1% absolute deadband
from asyncua.ua import (
    MonitoringParameters, DataChangeFilter,
    DataChangeTrigger, DeadbandType,
)
params = MonitoringParameters()
params.SamplingInterval = 250
params.QueueSize        = 10
params.DiscardOldest    = True
params.Filter = DataChangeFilter(
    Trigger      = DataChangeTrigger.StatusValue,
    DeadbandType = DeadbandType.Absolute.value,
    DeadbandValue= 0.5,
)

Mapping OPC UA tags to MQTT topics

For cloud relay, SGT Systems gateways typically subscribe to OPC UA variables and republish them as MQTT messages following the topic convention in the MQTT Broker Setup Guide.

OPC UA NodeIdMQTT topicPayload
ns=2;s=Channel1.Device1.Flowsgt/dhaka-plant/plc-01/flow_lpm{"ts":"...","v":42.7,"u":"L/min","q":"good"}
ns=2;s=Channel1.Device1.Levelsgt/dhaka-plant/plc-01/level_pct{"ts":"...","v":78.4,"u":"%","q":"good"}
ns=2;s=Channel1.Device1.Statussgt/dhaka-plant/plc-01/status{"ts":"...","v":1,"u":"enum","q":"good"}

Recommended mapping rules:

  • Always include the OPC UA quality code (good, uncertain, bad) in the MQTT payload. Cloud analytics must be able to discard bad-quality samples.
  • Preserve the server timestamp, not the gateway wall clock — clock skew on PLC networks is real.
  • Use subscriptions, not polling. OPC UA's data-change subscriptions are bandwidth-efficient and report only on deadband-crossing.
  • Throttle pathological tags (vibration signals, raw counters) at the gateway before relay.
  • Encode the source NodeId in a separate field if you need round-tripping; do not stuff it into the topic.

Performance and Operations

  • Tune publishing and sampling intervals. A 100 ms sampling interval on 10,000 monitored items is enormous load. Sample slow signals slowly.
  • Use a single session for many monitored items rather than many sessions for a few items — sessions are heavy.
  • Watch keep-alive and lifetime counts. If the server is busy and misses the publish window, the subscription times out and your gateway thinks the link died.
  • Renew certificates before they expire. Application instance certs default to one year. Add a calendar reminder; an expired cert is a hard outage.
  • Plan for cert revocation. Even with a CRL or OCSP responder, propagation can take minutes. For rapid revocation, also remove the cert from each server's trusted/ folder.

Need help?

OPC UA certificate management, server commissioning, and cloud relay design are SGT Systems specialities. Reach the team at support@sgtsystems.com or via our contact page.

v1.0 · Last updated May 24, 2026 · Published May 24, 2026
© 2026 Smart Global Tech Systems Limited
• Related documentation

More from Integration & API

Browse all →