Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

B&R OPC-UA Integration: Server Configuration, Address Mapping, Security, and Certificate Management

Overview

B&R Automation Runtime includes a built-in OPC-UA server that exposes PLC process variables to any OPC-UA compliant client. This is one of the most important diagnostic access points when working with undocumented B&R machines — OPC-UA allows reading and writing variables without needing the original Automation Studio project. This document covers how the OPC-UA server is configured, how address mapping works, namespace organization, security models, certificate management, and how to use OPC-UA for diagnostics on machines with no OEM documentation.

Architecture

The B&R OPC-UA server runs as a system task within Automation Runtime (priority 4–190 tier). It is integrated into the CPU firmware and requires no additional hardware. Key characteristics:

  • Default port: 4840 (standard OPC-UA port, configurable)
  • Runs on: Ethernet interface (IF2) — NOT on the POWERLINK interface (IF3)
  • Configuration file: OpcUa.Config.xml on the CF card
  • Address configuration: Under ServerConfiguration → BaseAddresses in the config file
  • Part of: mapp Technology framework (specifically mapp OPC-UA component)

Enabling the OPC-UA Server

Via Automation Studio (Normal Method)

  1. Open the project in Automation Studio
  2. Go to Physical View
  3. Right-click on the CPU (e.g., X20CP1584) → Configuration
  4. Expand OPC-UA System
  5. Set “Activate OPC-UA System” to On
  6. Configure server settings (port, endpoint, security policy)
  7. Add an OPC-UA Default View from the Toolbox to the Configuration View
  8. Enable specific variables as OPC-UA tags (right-click → Enable Tag)
  9. Set user role access rights for each tag (read, write, browse)
  10. Build & Transfer to the PLC

Critical: Variables Are NOT Automatically Exposed

Enabling the OPC-UA server does NOT automatically expose all process variables. Each variable must be explicitly enabled as an OPC-UA tag. This means:

  • Grayed-out variables in the Default View = NOT accessible via OPC-UA
  • Black/active variables = enabled and accessible
  • The OEM had to deliberately enable each variable for external access

This is a major consideration for undocumented machines — if the OEM didn’t enable OPC-UA tags, you cannot access them via OPC-UA regardless of whether the server is running.

Without Automation Studio

If you have no project but the OPC-UA server is running:

  1. Scan for the server using UaExpert or any OPC-UA discovery client
  2. Browse the namespace to see what variables are exposed
  3. Read/write through the client

Namespace and Address Structure

B&R OPC-UA Namespace Layout

When connected to a B&R OPC-UA server, the namespace follows this structure:

Objects
└── PLC
    ├── Modules
    │   ├── Default
    │   │   ├── <TaskName1>        (e.g., "Cyclic#1", "HMI_Inputs")
    │   │   │   ├── Variable1
    │   │   │   ├── Variable2
    │   │   │   └── StructName
    │   │   │       ├── Member1
    │   │   │       └── Member2
    │   │   └── <TaskName2>
    │   │       └── ...
    │   └── (additional modules)
    ├── System
    │   └── (system diagnostics, status)
    └── Server
        └── (server configuration, status)

Node IDs

B&R OPC-UA Node IDs typically follow the format:

  • ns=2;s=PLC.Modules.Default.<TaskName>.<VariableName> (string-based)
  • Numeric namespace indices: ns=0 (OPC-UA standard), ns=1 (B&R system), ns=2+ (user application)

Variables are organized by the task class they belong to. Only variables within tasks that have been configured in the OPC-UA Default View are visible.

Custom Namespaces

You can create custom namespaces using a nodeset file (.xml), which provides more flexibility. A nodeset file can:

  • Link OPC-UA nodes to specific PLC variables
  • Create custom data types and structures
  • Organize variables into logical groups (e.g., “Machine1”, “Conveyor”, “Press”)
  • Add metadata (engineering units, descriptions, limits)

Security Model

Authentication Methods

MethodDescriptionDefault Availability
AnonymousNo authentication requiredEnabled by default (role “Everyone”)
Username/PasswordB&R user managementConfigurable
Certificate-basedX.509 certificate validationConfigurable

Important: If the “Anonymous” user is deleted from the user-role system, OPC-UA clients cannot connect without credentials. This is a common issue when OEMs tighten security.

User Roles and Access Rights

B&R implements OPC-UA role-based access control:

  • Everyone — default role, typically browse + read
  • Operator — read + limited write
  • Engineer/Admin — full read/write access
  • Custom roles — can be defined per installation

Each OPC-UA tag can have individual access rights configured:

  • Visible — appears in browse
  • Browse — node info can be read
  • Read — current value can be read
  • Write — value can be modified
  • History — historical data can be accessed

Security Policies

B&R OPC-UA supports the standard OPC-UA security policies:

  • None — no encryption, no signing (common on legacy machines)
  • Basic128Rsa15 — basic encryption
  • Basic256 — stronger encryption
  • Basic256Sha256 — strongest commonly available

Certificate Management

Certificate Location

Certificates are stored on the CF card in the certificate store:

  • Path: Accessible via Automation Studio → Configuration → Access and Security → Certificate Store
  • Own certificates — the PLC’s server certificate
  • Communication partner certificates — trusted client certificates
  • CA certificates — certificate authority chains

Managed Certificate Store (AR 6.5+)

Starting with AR 6.5, B&R introduced the ManagedCertificateStore with the ArMcsRecreateCert function block for programmatic certificate recreation. In AR 6.5, the ManagedCertificateStore is extended to cover ANSL, FTP, HTTP, and SMTP libraries (not just OPC-UA). Additionally, the ArCert library now supports creating, exporting, viewing, and deleting certificate signing requests (CSRs), and the AsHttp httpsClient supports Server Name Indication (SNI). These features are not available on AR 4.x (CP1584 maximum), but are relevant for migration planning to newer B&R hardware.

Creating and Managing Certificates

  1. In Automation Studio: Configuration → Access & Security → Certificate Store → Own certificates
  2. Double-click New OPC UA certificate
  3. Configure: subject, validity, key size
  4. Transfer to PLC

Certificate-Only Access

For secure installations, certificate-based access can be configured:

  1. Create SSL configuration referencing the certificate
  2. Apply to OPC-UA server
  3. Add trusted client certificates to the communication partner store
  4. Disable anonymous access

Replacing Certificates Without Automation Studio

If you need to change certificates on a running PLC without the project:

  1. Access the CF card via FTP (user partition)
  2. The certificate store is typically at F:\System\Certificates\ or similar
  3. Replace the server certificate file
  4. Cold restart the PLC to apply

Caution: Incorrect certificate replacement can lock you out of OPC-UA entirely.

Certificate Management Deep Dive

Certificate Creation Step-by-Step

When creating an OPC-UA certificate for a B&R PLC, the subject fields must be configured correctly for the PLC to accept and serve the certificate properly.

Recommended subject fields:

FieldValueExample
CN (Common Name)PLC hostname or descriptive nameBR-PLC-001 or Line3-Controller
O (Organization)Company or plant nameACME Manufacturing
L (Locality)City or site locationDetroit
S (State)State or provinceMichigan
C (Country)Two-letter country codeUS

Key size: Minimum 2048-bit RSA. 4096-bit is supported on newer firmware but increases handshake latency.

Validity period: Typical production use is 1-3 years. Longer periods reduce renewal overhead but weaken the security boundary if the private key is compromised.

Certificate Renewal Workflow

  1. Generate a new certificate with the same subject fields and new validity period
  2. Replace the server certificate on the CF card (System/Certificates/Own/)
  3. Warm restart — the OPC-UA server reloads the certificate
  4. All connected clients receive BadCertificateUntrusted and must re-accept the new certificate
  5. Update any client certificate stores that pinned the old certificate

SHA1 Deprecation Issue

Older Automation Studio versions generated OPC-UA certificates using SHA1 signatures. Modern clients (UaExpert 1.5+, .NET OPC-UA stack, Python asyncua) reject SHA1 at the security layer.

Symptoms: BadCertificateUntrusted on any sign/encrypt policy; works with security None. Verify: openssl x509 -in cert.der -inform DER -text -noout | grep "Signature Algorithm".

Resolution: Regenerate the certificate with SHA256 via Automation Studio → Certificate Store. Ensure mapp version is 5.x+ (SHA256 native support). On firmware older than AR 4.30, use security None as a workaround.

Self-Signed vs CA-Signed Certificates

AspectSelf-SignedCA-Signed
Trust modelManual trust per clientChain trust via CA root
DeploymentSimple, no external dependencyRequires CA infrastructure
RevocationNot possibleCRL/OCSP supported
ScalabilityPoor for many devicesGood for fleet management
Recommended forSingle-machine setups, developmentProduction lines, multi-PLC systems

For production environments with multiple PLCs, use an internal CA (e.g., Smallstep CA, HashiCorp Vault PKI, or B&R’s own Automation Studio CA feature). This eliminates the need to manually trust each PLC’s certificate on every client.

Certificate Trust Chain Management

The B&R certificate store on the CF card maintains three categories under System/Certificates/:

  • Own/ — server certificate + private key (DER format)
  • Trusted/ — accepted client certificates from connecting clients
  • CA/ — CA root and intermediate certificates

Trust validation order: check Trusted/ folder for direct match, then check CA/ for chain validation (intermediate to root), then verify validity period.

Adding a trusted CA: Export CA root cert in DER format, upload to System/Certificates/CA/ via FTP, warm restart. All certificates signed by that CA are automatically trusted.

SSL Configuration in Automation Studio

To bind a certificate to the OPC-UA server in Automation Studio:

  1. Configuration → Access & Security → SSL Configuration — create a new SSL Configuration object
  2. Set the Certificate Reference to the OPC-UA certificate in the Certificate Store
  3. Under OPC-UA System → Server Configuration, set the SSL Configuration reference
  4. Build and transfer

The SSL Configuration also controls TLS versions (TLS 1.2 minimum recommended), cipher suites, and whether the server requests client certificates.

mappView OPC-UA Client Certificate Configuration

When mappView acts as an OPC-UA client (connecting to another PLC or external server), it needs its own client certificate:

  1. In the mappView configuration, open mapp OPC-UA Client
  2. Set the Certificate reference to a client certificate from the Certificate Store
  3. The target server must trust this certificate (either directly or via CA chain)
  4. Configure the security policy to match what the server offers

Failure to configure the client certificate results in BadSecurityChecksFailed on the server side.

Certificate Backup and Restore Procedure

Backup: FTP to PLC, download the entire System/Certificates/ directory. Optionally convert to PEM: openssl x509 -in cert.der -inform DER -out cert.pem -outform PEM

Restore: Upload backup System/Certificates/ via FTP, cold restart to reload. Verify by connecting with UaExpert and checking the server certificate fingerprint. Always back up before firmware upgrades — upgrades may invalidate certificate bindings.

Connecting with OPC-UA Clients

Using UaExpert (Free OPC-UA Client)

  1. Install UaExpert (Unified Automation)
  2. Server → Add
  3. Enter the PLC IP address
  4. The Discovery URL will be: opc.tcp://<PLC_IP>:4840
  5. Click Connect
  6. A certificate approval dialog appears — check “Trust Server Certificate”
  7. Browse: Objects → PLC → Modules → Default to find variables
  8. Set Authentication to Anonymous if no credentials configured

Python Client (asyncua)

import asyncio
from asyncua import Client

async def read_br_variables():
    url = "opc.tcp://192.168.1.100:4840"
    async with Client(url=url) as client:
        # Browse available variables
        root = client.nodes.root
        objects = await root.get_child(["Objects", "PLC", "Modules", "Default"])
        children = await objects.get_children()
        for child in children:
            name = await child.get_browse_name()
            value = await child.get_value()
            print(f"{name}: {value}")

        # Read a specific variable by node ID
        var = client.get_node("ns=2;s=PLC.Modules.Default.Cyclic#1.MyVariable")
        value = await var.get_value()
        print(f"MyVariable = {value}")

        # Write a variable
        await var.write_value(42.0)

asyncio.run(read_br_variables())

Node-RED Integration

Use the OPCUA-IIoT node in Node-RED:

  1. Configure OPC-UA server endpoint: opc.tcp://<PLC_IP>:4840
  2. Security mode: None (for legacy machines)
  3. Browse to find variable node IDs
  4. Use Read/Write nodes for data exchange

Practical Client Examples

Python Subscription Example (asyncua)

Subscriptions are preferred over polled reads — the server pushes updates only when values change.

import asyncio
from asyncua import Client, ua

url = "opc.tcp://192.168.1.100:4840"

async def data_change_callback(node, val, data):
    name = await node.get_browse_name()
    print(f"[CHANGE] {name.Name} = {val}")

async def subscription_example():
    async with Client(url=url) as client:
        sub = await client.create_subscription(500, data_change_callback)

        nodes = [
            "ns=2;s=PLC.Modules.Default.Cyclic#1.Temperature",
            "ns=2;s=PLC.Modules.Default.Cyclic#1.Pressure",
            "ns=2;s=PLC.Modules.Default.Cyclic#1.Status",
        ]
        for nid in nodes:
            node = client.get_node(nid)
            params = ua.MonitoringParameters(
                ClientHandle=len(sub.monitored_items),
                SamplingInterval=250,
                QueueSize=10,
                DiscardOldest=True
            )
            await sub.subscribe_data_change(node, params)

        print("Subscribed. Press Ctrl+C to exit.")
        try:
            while True:
                await asyncio.sleep(1)
        except KeyboardInterrupt:
            await sub.delete()

asyncio.run(subscription_example())

Python Write Example — B&R Gotcha

When writing to B&R OPC-UA variables, write_value() works for scalars. For complex structures with engineering unit scaling, you may need write_params or write individual members.

import asyncio
from asyncua import Client, ua

url = "opc.tcp://192.168.1.100:4840"

async def write_example():
    async with Client(url=url) as client:
        scalar = client.get_node("ns=2;s=PLC.Modules.Default.Cyclic#1.Setpoint")
        await scalar.write_value(75.5)
        print("Setpoint written: 75.5")

        struct_node = client.get_node("ns=2;s=PLC.Modules.Default.Cyclic#1.RecipeData")
        variant = ua.Variant(
            {"Param1": 100, "Param2": 3.14, "Enable": True},
            ua.VariantType.ExtensionObject
        )
        try:
            await struct_node.write_value(variant)
        except ua.UaError:
            print("Structure write failed — writing individual members:")
            await client.get_node(
                "ns=2;s=PLC.Modules.Default.Cyclic#1.RecipeData.Param1"
            ).write_value(100)
            await client.get_node(
                "ns=2;s=PLC.Modules.Default.Cyclic#1.RecipeData.Param2"
            ).write_value(3.14)
            await client.get_node(
                "ns=2;s=PLC.Modules.Default.Cyclic#1.RecipeData.Enable"
            ).write_value(True)

asyncio.run(write_example())

UaExpert Workflow for Undocumented PLCs

  1. Launch UaExpert, add server: Server → Add → enter PLC IP
  2. Discovery: UaExpert queries opc.tcp://<IP>:4840. If discovery fails, manually enter the endpoint URL
  3. Certificate dialog: Check “Trust server certificate” on first connect
  4. Authentication: Start with Anonymous. If rejected, try common B&R credentials (admin/admin, operator/operator)
  5. Browse: Expand Objects → PLC → Modules → Default. Subfolders = task classes, contents = PLC variables
  6. Export: Right-click “Default” → Create Address Space Snapshot → saves CSV of all nodes
  7. Test: Drag a variable to Data Access View. Double-click value to attempt write
  8. System nodes: Objects → PLC → System shows CPU utilization, memory, task cycle times

Wireshark OPC-UA Capture and Decode

  1. Start Wireshark, set capture filter: port 4840
  2. Connect with the OPC-UA client, then stop capture
  3. Install the OPC-UA dissector (Edit → Preferences → Protocols → OPC UA) if not present
  4. For encrypted traffic, set security to None for debugging — Wireshark cannot decrypt without session keys
  5. Key frames to inspect: Hello/ACK (TCP+OPC-UA handshake), CreateSession, Browse/Read/Write (node IDs visible in plaintext with security None), PublishResponse (subscription data)

C#/.NET OPC-UA Client Example

using Opc.Ua;
using Opc.Ua.Client;

var endpointUrl = "opc.tcp://192.168.1.100:4840";

var config = new ApplicationConfiguration()
{
    ApplicationName = "B&R OPC-UA Client",
    ApplicationUri = new Uri("urn:BROpcUaClient"),
    ApplicationType = ApplicationType.Client,
    SecurityConfiguration = new SecurityConfiguration
    {
        AutoAcceptUntrustedCertificates = true,
        MinimumCertificateKeySize = 1024
    }
};

config.CertificateValidator.CertificateValidation += (s, e) =>
{
    if (e.Error.StatusCode == StatusCodes.BadCertificateUntrusted)
        e.Accept = true;
};

var endpoint = CoreClientUtils.SelectEndpoint(endpointUrl, useSecurity: false);
using var session = Session.Create(config, endpoint, updateBeforeConnect: true,
    "BROpcUaClient", 60000, null, null).Result;

var readNode = new NodeId("PLC.Modules.Default.Cyclic#1.Temperature", 2);
Console.WriteLine($"Temperature: {session.ReadValue(readNode).Value}");

session.WriteValue(
    new NodeId("PLC.Modules.Default.Cyclic#1.Setpoint", 2),
    new DataValue(72.5));

var subscription = new Subscription(session.DefaultSubscription)
{
    PublishingInterval = 500, PublishingEnabled = true,
    LifetimeCount = 1000, KeepAliveCount = 10
};
session.AddSubscription(subscription);

var item = new MonitoredItem(subscription.DefaultItem)
{
    DisplayName = "Pressure",
    StartNodeId = new NodeId("PLC.Modules.Default.Cyclic#1.Pressure", 2),
    SamplingInterval = 250, QueueSize = 10, DiscardOldest = true
};
item.Notification += (_, e) =>
{
    foreach (var c in e.NotificationList)
        Console.WriteLine($"Pressure: {c.Value}");
};
subscription.AddItem(item);
subscription.Create();
Console.WriteLine("Subscribed. Press Enter to exit.");
Console.ReadLine();
session.Close();

Package: OPCFoundation.NetStandard.Opc.Ua (NuGet). Requires .NET Standard 2.0+ or .NET 6+.

Finding an Unknown OPC-UA Server

For machines with no documentation:

Step 1: Find the PLC IP Address

  • Check the SDM (System Diagnostics Manager): http://<IP>/sdm
  • Use Wireshark to capture B&R ANSL discovery packets
  • Check network switch/router ARP table for B&R MAC OUI prefixes
  • Try common B&R default IP ranges (192.168.100.x, 192.168.1.x)

Step 2: Check if OPC-UA is Active

## Scan for OPC-UA port 4840
nmap -p 4840 <PLC_IP>

## Or try connecting with openssl
openssl s_client -connect <PLC_IP>:4840

Step 3: Determine the OPC-UA Configuration

You cannot determine the OPC-UA configuration from the PLC alone without:

  • The original project
  • A system dump analyzed in Automation Studio
  • The ability to browse the server

Key unknowns:

  • Is OPC-UA activated at all?
  • What port is it on? (default 4840, but configurable)
  • What variables are enabled?
  • What authentication is required?
  • What encryption policy is used?

Step 4: Try Connection

Use UaExpert to attempt connection at the default port. If anonymous access is enabled and variables were configured, you’ll see them in the namespace. If not, you need to explore alternative access methods (PVI, FTP, direct I/O monitoring).

Performance Considerations

  • OPC-UA runs as a system task (lower priority than cyclic tasks)
  • Sampling interval is typically 100 ms minimum for standard OPC-UA subscriptions
  • If the task idle time is too low, OPC-UA responses will time out
  • The OPC-UA server can be a significant CPU load if many subscriptions are active
  • For high-speed data collection, POWERLINK or direct I/O access is faster

Configuration File Deep Dive

OpcUa.Config.xml Structure

The OPC-UA server behavior is controlled by OpcUa.Config.xml on the CF card, generated by Automation Studio but editable via FTP.

OpcUa.Config.xml
├── ServerConfiguration
│   ├── ApplicationUri / ApplicationName / ProductUri / ServerName
│   ├── BaseAddresses (list of endpoint URLs)
│   ├── SecurityPolicies (uri + certificate per policy)
│   ├── MaxSessions / MaxSubscriptionsPerSession
│   ├── MaxMonitoredItemsPerSubscription
│   ├── RequestTimeout / ServiceLevel / AuditingEnabled
│   └── MaxResponseMessageSize
├── EndpointConfiguration
│   ├── TransportProfileUri / SecurityMode
│   ├── SecurityPolicyUri / SecurityLevel
├── UserTokenPolicies (anonymous, username, certificate)
├── CertificateConfiguration
│   ├── CertificateStorePath / IssuedCertificatesPath
│   └── TrustedCertificatesPath
└── NodeManager → BaseAddress

Editing the Config File via FTP

When you have no Automation Studio project and need to modify OPC-UA server settings:

  1. Connect to the PLC via FTP (default credentials: user/user or admin/admin depending on configuration)
  2. Navigate to the user partition (typically F:\ or the volume labeled “User”)
  3. Locate OpcUa.Config.xml — it may be at the root or under a project-specific directory
  4. Download the file to your local machine
  5. Edit with a text editor (XML-aware editor recommended — notepad++ with XML plugin, VS Code)
  6. Backup the original file first (OpcUa.Config.xml.bak)
  7. Upload the modified file
  8. Perform a warm restart of the PLC to reload the configuration

Caution: Invalid XML will prevent the OPC-UA server from starting. Validate the XML before uploading. The server does not provide detailed parse error logs — it simply fails to start.

Key Configuration Parameters

ParameterDefaultDescription
MaxSessions100Maximum concurrent OPC-UA sessions (client connections)
MaxSubscriptionsPerSession100Maximum subscriptions per session
MaxMonitoredItemsPerSubscription1000Maximum monitored items (variables) per subscription
MaxBrowseContinuationPoints50Parallel browse operations
MaxHistoryContinuationPoints50Parallel history read operations
RequestTimeout10000 msServer-side request timeout
ServiceLevel100-255Server service level (100 = minimum)
MaxResponseMessageSize0 (unlimited)Maximum response message size in bytes

Endpoint Configuration

Endpoints define how clients connect. Each endpoint specifies:

  • Transport Profile URI: opc.tcp for binary TCP transport (standard), http for SOAP/HTTP (legacy, rarely used)
  • Security Mode: None, Sign, SignAndEncrypt
  • Security Policy URI: Maps to the actual encryption algorithm:
    • http://opcfoundation.org/UA/SecurityPolicy#None
    • http://opcfoundation.org/UA/SecurityPolicy#Basic128Rsa15
    • http://opcfoundation.org/UA/SecurityPolicy#Basic256
    • http://opcfoundation.org/UA/SecurityPolicy#Basic256Sha256

Changing the OPC-UA Port Without Automation Studio

  1. FTP to the PLC, download OpcUa.Config.xml
  2. Locate <BaseAddresses> and change the port in the endpoint URI:
    <BaseAddresses>
      <EndpointUri>opc.tcp://192.168.1.100:4841</EndpointUri>
    </BaseAddresses>
    
  3. Backup the original, upload the modified file, warm restart
  4. After changing the port, clients must use the new endpoint URL directly — auto-discovery will not find the server at the old port

Namespace and Variable Discovery Without Project

Recursive Python Namespace Browser

When working with an undocumented B&R PLC, the first task is discovering what variables are exposed. This script recursively browses the entire OPC-UA namespace and prints a tree of all nodes with their data types and current values.

import asyncio
from asyncua import Client

url = "opc.tcp://192.168.1.100:4840"

async def browse_recursive(client, node, indent=0):
    name = await node.get_browse_name()
    node_class = await node.read_node_class()
    display_name = await node.get_display_name()

    prefix = "  " * indent
    info = f"{prefix}[{node_class.name}] {display_name.Text}"

    try:
        value = await node.get_value()
        data_type = await node.read_data_type()
        info += f" = {value} ({data_type.Identifier})"
    except Exception:
        pass

    try:
        desc = await node.read_description()
        if desc and desc.Text:
            info += f"  -- {desc.Text}"
    except Exception:
        pass

    print(info)

    try:
        children = await node.get_children()
        for child in children:
            await browse_recursive(client, child, indent + 1)
    except Exception:
        pass

async def discover_namespace():
    async with Client(url=url) as client:
        print(f"=== OPC-UA Namespace Discovery: {url} ===")
        root = client.nodes.root
        objects = client.nodes.objects
        await browse_recursive(client, objects, indent=0)

asyncio.run(discover_namespace())

Usage notes:

  • On large namespaces, this can take several minutes — the B&R OPC-UA server has a default browse limit and may require continuation point handling
  • Redirect output to a file: python discover.py > namespace_dump.txt
  • The output can be cross-referenced with any partial documentation or PLC I/O lists

Mapping Discovered Variables to IO Points

After discovering the namespace, map variables back to physical I/O:

  • Task class names in OPC-UA correspond to Automation Studio task classes: Cyclic#1/Cyclic#2 (I/O processing), HMI_Inputs/HMI_Outputs (HMI interface), Alarm/Recipe/DataLogger (mapp components), IO_.../DI_.../DO_.../AI_.../AO_... (digital/analog I/O)
  • Variable naming patterns: gMachine_State (global state), stAxis_<Name> (axis structure), rSensor_<Location> (sensor reading), bSwitch_<Function> (boolean input)
  • Struct members map directly to Automation Studio variable names (bEnable, rActualValue, rSetpoint)

Reconstructing IO Mapping via OPC-UA Browse

For a completely undocumented machine:

  1. Start with System node: CPU diagnostics, firmware version, task cycle times
  2. Browse Modules → Default → <task classes>: application variables by task
  3. Look for variables with engineering units metadata — often correspond to physical sensors
  4. Look for structures named after hardware: Axis_Drive1, IoModule_Terminal1
  5. Compare with physical I/O module count on the hardware to validate coverage

Limitations: What You Cannot Discover via OPC-UA

  • Internal program logic: You cannot see ladder logic, ST code, or function block implementations
  • Communication parameters: POWERLINK node assignments, MODBUS register mappings, or serial port configurations are not exposed
  • Disabled variables: Any variable the OEM did not explicitly enable as an OPC-UA tag is invisible
  • Array dimensions: B&R OPC-UA may expose arrays but with limited dimension metadata
  • User-defined types: Complex user-defined data types may appear as generic structures without meaningful member descriptions
  • Timing information: Task cycle times are visible, but internal timing (delays, timer configurations) is not
  • Hardware configuration: The physical I/O topology (which terminal is in which slot) is not directly exposed — only the logical variable names
  • Alarm/event history: Unless mapp AlarmX was configured to publish through OPC-UA, alarm data is not available via standard variable browsing

OPC-UA Troubleshooting

Common Connection Failures

SymptomLikely CauseResolution
Connection refused (TCP RST)OPC-UA server not runningCheck if OPC-UA is activated in the PLC configuration. Warm restart. Verify port via nmap
Connection timeoutNetwork firewall blocking port 4840Check firewall rules. Open TCP 4840 inbound on the PLC network segment
Certificate rejectionServer cert untrusted by clientTrust the server certificate in the client. In UaExpert: check “Trust Server Certificate” on first connect
BadCertificateUntrustedSHA1-signed certificateRegenerate certificate with SHA256. See Certificate Management Deep Dive
BadSecurityChecksFailedSecurity policy mismatchClient and server must share at least one common security policy. Check server endpoints
BadSessionClosedSession timeoutIncrease client keep-alive interval. Check PLC CPU load — high load causes OPC-UA timeouts
BadUserAccessDeniedInsufficient permissionsVerify user role assignment. Check if anonymous access was disabled
BadNodeIdUnknownVariable node does not existVerify the node ID against a fresh namespace browse. Variable names are case-sensitive
No endpoints discoveredDiscovery service not respondingTry direct connection with the endpoint URL opc.tcp://<IP>:4840
Connection drops intermittentlyNetwork instability or CPU overloadCheck network cabling, switch port errors, and PLC task idle time

Certificate Trust Issues

Scenario: Client connects successfully with security=None but fails with any signing or encryption policy.

  1. Verify the server certificate is not expired: openssl x509 -in cert.der -inform DER -dates -noout
  2. Verify the signature algorithm: openssl x509 -in cert.der -inform DER -text -noout | grep "Signature Algorithm"
  3. Check if the client certificate is in the PLC’s trusted store:
    • FTP to PLC → browse System/Certificates/Trusted/
    • If the client certificate is missing, upload it
  4. For CA-signed certificates, ensure the CA root is in System/Certificates/CA/

Authentication Failures

  • Anonymous rejected: The OEM removed the “Everyone” role. You must authenticate with a configured username/password. Check the B&R User Management for valid accounts.
  • Username/password rejected: Verify credentials against the B&R user management (accessible via Automation Studio or the SDM web interface). Passwords are case-sensitive.
  • Certificate authentication rejected: The client certificate is not in the trusted store, or the SSL Configuration on the PLC requires a specific certificate that was not presented by the client.

Timeout Issues

OPC-UA timeouts on B&R systems are almost always caused by insufficient task idle time:

  • Check CPU utilization: PLC.System.CPU.Utilization and per-task cycle times via OPC-UA System nodes
  • If task idle time is below 10%, the OPC-UA system task cannot respond within the request timeout
  • Reduce active subscriptions, increase sampling intervals, or optimize cyclic task code
  • Increase client-side timeout (UaExpert: Tools → Options → Advanced → Operation Timeout)

Variable Not Found / Namespace Issues

  • Node IDs in B&R OPC-UA are case-sensitive: PLC.Modules.Default.Cyclic#1 is not the same as plc.modules.default.cyclic#1
  • The namespace index (ns=X) can change between firmware upgrades or configuration rebuilds — always verify with a fresh browse
  • If variables disappear after a PLC update, the OEM may have modified the OPC-UA Default View configuration
  • Empty namespaces under Objects → PLC → Modules → Default mean no variables were enabled for that task class

Port Conflicts

  • Another service on the PLC may be using port 4840 (unlikely but possible with custom configurations)
  • A firewall between the client and PLC may be blocking the port
  • If the OPC-UA port was changed from the default, the discovery URL will not match — always try direct endpoint connection
  • Multiple OPC-UA servers on the same network segment with the same ApplicationUri can cause client confusion

Security Policy Mismatch

If the client and server have no overlapping security policies:

  1. Use UaExpert to connect and check the server’s offered endpoints (shown in the connection dialog before connecting)
  2. Ensure the client supports at least one of the server’s offered security policies
  3. If the server only offers Basic256Sha256 and the client only supports None, upgrade the client or reconfigure the server’s security policies in OpcUa.Config.xml
  4. For legacy B&R firmware, the server may only offer None and Basic128Rsa15 — modern clients that reject SHA1 may only have None as an option

OPC-UA Performance Tuning

Subscription vs Polled Reads

ApproachNetwork TrafficServer LoadData FreshnessRecommended Use
SubscriptionLow (push on change)LowerNear real-timeContinuous monitoring, alarming, dashboards
Polled ReadHigh (periodic request)HigherPeriodic (poll interval)One-time reads, data logging, batch processing
Batched ReadMediumMediumPeriodicReading many variables at once

Recommendation: Always prefer subscriptions over polled reads. A single subscription with 100 monitored items generates significantly less network traffic than polling 100 variables every 250 ms.

Dead Band Settings for Analog Values

Dead bands prevent unnecessary notifications for insignificant analog value changes. Set the absolute dead band to match sensor resolution — a temperature sensor with 0.1C resolution does not need notifications for 0.001C changes. Dead bands are not applicable to integers and booleans.

Queue Size and Sampling Rate Optimization

  • QueueSize=1: Only the latest value is kept. Intermediate values are lost. Use for dashboards where only the current value matters.
  • QueueSize=10+: Multiple intermediate values are queued. Use for data logging or trend analysis. Client receives all intermediate values on each publish cycle.
  • SamplingInterval: The minimum practical interval on B&R OPC-UA is typically 50-100 ms. Intervals below 50 ms may be rounded up by the server.
  • PublishingInterval: The server sends queued notifications at this interval. Set to 500-1000 ms for normal operation. Lower values increase CPU and network load.

Impact on Cyclic Task Performance

The OPC-UA server runs as a system task at a priority between 4 and 190. If cyclic tasks are consuming most of the CPU cycle, the OPC-UA server task gets starved:

  1. Monitor task idle time: Via OPC-UA, read PLC.System.Tasks.<TaskName>.IdleTime. If below 10%, expect OPC-UA response degradation
  2. Correlation: When cyclic task cycle time spikes (e.g., from 5 ms to 15 ms), OPC-UA publish intervals will stretch proportionally
  3. Mitigation: Reduce the number of monitored items, increase sampling intervals, or optimize the cyclic task code
  4. Diagnostic: If you notice OPC-UA latency increasing during machine operation, check which cyclic task is consuming CPU and when

Monitoring Task Idle Time with OPC-UA Active

When OPC-UA is active, monitor task idle time to detect performance impact. Key node IDs:

  • PLC.System.Cyclic#1.IdleTime — idle time in microseconds
  • PLC.System.Cyclic#1.CycleTime — total cycle time in microseconds

Health thresholds:

  • Idle > 20% of cycle time: healthy, OPC-UA is not starving
  • Idle 10-20%: warning, reduce subscriptions or increase sampling intervals
  • Idle < 10%: critical, OPC-UA responses will timeout; optimize cyclic tasks first

If idle time drops when OPC-UA subscriptions are active, the OPC-UA system task is competing for CPU time. Reduce the number of monitored items or increase sampling intervals to relieve pressure.

OPC-UA History (Historical Access)

Historical Data Access

If the B&R OEM configured mapp DataLogger or mapp History with OPC-UA historical access enabled, you can read historical variable values from the OPC-UA server:

  1. The historical data is exposed through the OPC-UA Historical Data Access (HDA) service
  2. Not all B&R OPC-UA configurations include HDA — it must be explicitly configured in Automation Studio
  3. Available historical nodes appear in the namespace with the AccessLevelHistoryRead flag set

Reading Historical Data with Python

import asyncio
from asyncua import Client, ua

url = "opc.tcp://192.168.1.100:4840"

async def read_history():
    async with Client(url=url) as client:
        node = client.get_node("ns=2;s=PLC.Modules.Default.DataLogger.Temperature")
        start = ua.DateTime.utcfromisoformat("2025-12-01T00:00:00Z")
        end = ua.DateTime.utcfromisoformat("2025-12-31T23:59:59Z")
        details = ua.ReadRawModifiedDetails(
            IsReadModified=False, StartTime=start, EndTime=end,
            NumValuesPerNode=0, ReturnBounds=True
        )
        result = await node.read_history(
            history_read_details=details,
            timestamps_to_return=ua.TimestampsToReturn.Both
        )
        if result.StatusCode.is_good():
            for item in result.HistoryData.Values:
                print(f"{item.SourceTimestamp}: {item.Value.Value} [{item.Status}]")
        else:
            print(f"Failed: {result.StatusCode}")

asyncio.run(read_history())

Reading Historical Alarms via OPC-UA

If mapp AlarmX is configured to publish through OPC-UA, alarms appear as condition nodes with properties: EnabledState, AckedState, ActiveState, Severity. Query historical alarm events using the Event History service.

import asyncio
from asyncua import Client, ua

url = "opc.tcp://192.168.1.100:4840"

async def read_alarm_history():
    async with Client(url=url) as client:
        alarms = client.get_node("ns=2;s=PLC.Modules.Default.AlarmX")
        start = ua.DateTime.utcfromisoformat("2025-12-01T00:00:00Z")
        end = ua.DateTime.utcfromisoformat("2025-12-31T23:59:59Z")
        event_filter = await alarms.get_event_filter(
            evtype=client.get_node(ua.ObjectIds.AlarmConditionType)
        )
        details = ua.ReadEventDetails(
            StartTime=start, EndTime=end,
            MaxValuesPerNode=1000, Filter=event_filter
        )
        result = await alarms.read_event_history(details)
        if result and result.Events:
            for ev in result.Events:
                msg = ev.Message.Text if ev.Message else "No message"
                sev = ev.Severity if hasattr(ev, "Severity") else "N/A"
                print(f"{ev.Time}: [{sev}] {msg}")
        else:
            print("No alarm history or HDA not configured")

asyncio.run(read_alarm_history())

Time-Based Data Retrieval Constraints

  • Time zone: B&R OPC-UA uses UTC. If the PLC clock is not NTP-synchronized, timestamps may be inaccurate (see time-sync.md)
  • Resolution: Depends on mapp DataLogger config — typically 100 ms to 60 seconds
  • Retention: Stored on CF card or SRAM; old data is overwritten when the buffer fills
  • Aggregate functions: If supported, use ReadProcessedDetails for server-side aggregates (average, min, max, count, stddev) — more efficient than reading all raw values

Security Considerations for OPC-UA on B&R Systems

Known OPC-UA Vulnerabilities

CVEAdvisoryProductCVSSImpactMitigation
CVE-2025-11482SA25P006 (2026-05-26)PPT30 OS < 1.8.0v4.0 8.7 / v3.1 7.5Permanent DoS on OPC-UA server via resource exhaustion from concurrent connectionsUpdate PPT30 OS to 1.8.0; firewall port 4840 if OPC-UA not needed
CVE-2025-11044SA25P005 (2026-01-19)AR < 6.5 / R4.93v4.0 8.9ANSL flooding DoS (impacts OPC-UA indirectly by exhausting AR resources)Patched in R4.93; rate-limit at firewall
CVE-2026-0936SA26P001 (2026-01-29)PVI clientN/APVI logs credentials in plaintext (affects OPC-UA connections made via PVI)Update PVI to 6.5; see pvi-api.md

OPC-UA Hardening Checklist

  1. Disable anonymous access if possible — require username/password or certificate authentication
  2. Use security policy Basic256Sha256 or higher — never run production with security None
  3. Firewall port 4840 to allow only known OPC-UA clients and HMIs
  4. Monitor OPC-UA connection attempts — unexpected clients may indicate scanning
  5. Regenerate self-signed certificates with SHA256 and set reasonable validity (1-3 years)
  6. Replace self-signed certs with CA-signed when possible — see SA25P001 guidance in cybersecurity-hardening.md
  7. PPT30 HMI panels: If OPC-UA is enabled on a PPT30, verify OS version >= 1.8.0 (SA25P006)

CVE-2025-11482: PPT30 OPC-UA Server DoS

The PPT30 OPC-UA server has a resource exhaustion vulnerability (CWE-770). An unauthenticated network attacker can send messages that cause the OPC-UA server to become permanently unresponsive. A reboot is required to restore service. The vulnerability is scored CVSS v4.0 8.7 because:

  • No authentication required
  • Network-based exploitation
  • Permanent availability impact (reboot needed)
  • Affects safety-related HMI interactions when PPT30 is used as the operator interface

If your CP1584 system uses a PPT30 panel with OPC-UA:

  1. Check PPT30 OS version: Settings → System Information → OS Version
  2. Update to PPT30 OS 1.8.0 via B&R Update Tool
  3. If update is not immediately possible, restrict OPC-UA access to trusted IP addresses via firewall
  4. OPC-UA is not enabled by default on PPT30 — if you never explicitly enabled it, you are not affected

Cross-References

Key Findings

  • OPC-UA server is built into AR firmware but must be explicitly activated and variables individually enabled
  • Not all variables are automatically exposed — each must be enabled as an OPC-UA tag by the developer
  • Default port is 4840 on the standard Ethernet interface
  • Namespace structure: Objects → PLC → Modules → Default → <TaskName> → <Variables>
  • Three authentication methods: anonymous (default), username/password, certificate
  • Certificates stored on CF card in the certificate store
  • For undocumented machines: OPC-UA is the best diagnostic access point if it was configured, but useless if the OEM never enabled it
  • The OpcUa.Config.xml file on the CF card contains server configuration
  • OPC-UA runs as a lower-priority system task — it can be starved by long-running cyclic tasks

Community OPC-UA Tools for B&R

ToolURLPurpose
OpcUaSamplesgithub.com/br-automation-community/OpcUaSamples-sample-ASComprehensive OPC-UA configuration and coding samples in Ansi-C and ST, spanning AS4.1 through the newest AS version, with detailed explanations
easyuaclient-as-projectgithub.com/br-automation-community/easyuaclient-as-project-devEasyUaClnt — a simplicity wrapper library based on AsOpcUac for a clear OPC-UA client interface
demo-br-asyncuagithub.com/hilch/demo-br-asyncuaMinimal Python example accessing a B&R PLC via asyncua (asyncio-based OPC-UA stack). Alternative to the Python OPC-UA client examples in python-diagnostics.md
mappRemoteShellgithub.com/br-automation-community/mappRemoteShellSample project executing shell commands on a remote PC via OPC-UA + Python — demonstrates bidirectional OPC-UA communication for remote diagnostics
mappPanelgithub.com/br-automation-community/mappPanelSample for PLC to T-Panel communication over OPC-UA — useful for understanding panel integration patterns

Document updated: July 2026 (added security considerations section §13 with CVE-2025-11482/PPT30 OPC-UA DoS, OPC-UA hardening checklist; added community OPC-UA tools section)