OPC UA Client
Learn how to connect to an OPC UA server using the Heisenware OPC UA integration.
The OpcuaClient
class provides a high-level interface for communicating with OPC UA servers. It simplifies complex operations like establishing secure connections, browse the server's address space, reading and writing variables, calling methods, monitoring data for changes, and handling file transfers.
An instance of the client must be created to manage the connection state and session with a server. For secure connections, certificates must be generated first using the createCertificates
function.
Video tutorial
Watch the video to learn how to connect to an OPC UA Server and read, record and visualize OPC UA data from that server within Heisenware.
Getting Started: Security & Certificates
For secure OPC UA communication (Sign
or SignAndEncrypt
), a Public Key Infrastructure (PKI) is essential. This is a system of folders and files that manages digital certificates to establish trust between the client and server.
When is Security Needed?
You only need to manage a PKI store if you intend to connect to a server using a securityMode
of Sign
or SignAndEncrypt
. For unsecured connections (securityMode: 'None'
), you can ignore the certificate management functions.
Certificate Generation: Self-Signed vs. CA-Signed
The createCertificates
static method prepares your client for secure connections. It can operate in two modes:
Self-Signed (Default): This is the simplest method. The client creates its own unique certificate that is not signed by a higher authority. This is the recommended approach for most scenarios as it's easier to manage.
CA-Signed (Optional): The client first creates its own mini Certificate Authority (CA) and then uses that CA to sign its application and user certificates. This is useful for scenarios where a server is configured to trust a single CA instead of many individual client certificates.
Establishing Trust
OPC UA security is built on a two-way trust model:
The Server Must Trust Your Client: A server administrator must configure the server to accept your client's public certificate.
Your Client Must Trust the Server: To prevent man-in-the-middle attacks, your client must have the server's public certificate in its own trust list.
The createCertificates
and addServerCertificate
functions are designed to manage this process from the client's side.
The Client's PKI Folder Structure
Running createCertificates
generates a standard folder structure named pki
. The key folders are:
pki/own/certs/
: Contains your client's public certificates (e.g.,heisenware_opcua_client.pem
). This is the file you give to the server administrator.pki/own/private/
: Contains your client's private keys. Keep these secret! The code automatically sets their file permissions to be readable only by the owner.pki/trusted/certs/
: This is the client's trust list. You must place the public certificates of any OPC UA servers you want to connect to securely in this folder. TheaddServerCertificate
function automates this.pki/issuers/certs/
: In CA-mode, this contains the public certificate of the CA that can issue certificates.
A Guide to Certificate-Based Connections: Pitfalls & Troubleshooting
Establishing a secure certificate-based connection is the most common point of failure in OPC UA. An error almost always means there is a broken link in the chain of trust. This guide covers the most common pitfalls.
Pitfall 1: Server Rejects the Client Certificate
This happens when your client attempts to connect, and the server immediately closes the connection. The error message is often generic, like "The connection has been disconnected by third party"
. This means the server does not trust your client's application certificate.
How to Fix (Prosys Example):
Attempt to connect your client to the Prosys server. This will fail, but it makes Prosys aware of your client's certificate.
In the Prosys Simulation Server UI, go to the Certificates tab.
Your client's certificate (
HeisenwareOPCUAClient
) will appear in the Rejected Certificates list.Right-click on your certificate and select Trust. This moves it to the Trusted Certificates list.
Try connecting your client again. It should now succeed.
If using CA-mode: Instead of trusting the client certificate directly, you would place your CA's public certificate (
heisenware_ca_cert.pem
) into the Prosys PKI folder atpki/CA/issuers/certs/
.
Pitfall 2: Client Rejects the Server Certificate
This is the reverse problem. Your client does not trust the server it's connecting to. You will receive a very clear error message: "server Certificate verification failed"
.
This happens because, for security, the client will only connect to servers it knows.
How to Fix:
You must add the server's public certificate to your client's trust store.
Obtain the server's public certificate file (e.g., by exporting it from the Prosys Certificates tab).
Use the
addServerCertificate
static method to add it to your client'spki/trusted/certs
folder.
CRITICAL: Never set automaticallyAcceptUnknownCertificate: true
in a production environment. This disables server validation and exposes you to man-in-the-middle attacks.
Pitfall 3: The SAN Mismatch
This is a very common reason for a "server Certificate verification failed"
error, even when trust has been established.
What it is: A certificate's Subject Alternative Name (SAN) field lists all the hostnames and IP addresses for which it is valid.
The Problem: When you connect, the client strictly checks if the hostname in your endpoint URL (e.g.,
opc.tcp://lenovo:4840
) is present in the server certificate's SAN list. If it's not, the connection is rejected.
How to Fix (Prosys Example):
Diagnose: You try to connect to
opc.tcp://localhost:53530
, but it fails. You check the Prosys certificate's SAN field usingopenssl
and see it only listsDNS:lenovo
.The Fix: Change your endpoint URL to match what's in the certificate:
await client.connect("opc.tcp://lenovo:53530/OPCUA/SimulationServer")
. The connection will now succeed.
Pitfall 4: Certificate Revocation List (CRL) Failures
This is an advanced and subtle issue. A certificate may contain a URL pointing to a Certificate Revocation List (CRL). A secure client will try to download this list to ensure the server's certificate hasn't been revoked. If the client is in an isolated network without internet access, it cannot download the CRL, and the validation fails.
How to Fix:
The proper solution is to manually download the CRL file and place it in the client's pki/issuers/crl
or pki/trusted/crl
folder. If you created the server's certificate with your own CA, you can generate an empty CRL file to satisfy the check.
Pitfall 5: Application vs. User Authentication
It's crucial to understand the two different types of certificates used:
Application Certificate (
heisenware_opcua_client.pem
): Identifies your application. It is used to create the secure, encrypted channel between the client and server. This is mandatory for a secure connection.User Certificate (
heisenware_opcua_user.pem
): Identifies a human user. It is used to log in and acquire permissions after the secure channel is already established. This is optional.
The Pitfall: Setting up user certificate authentication requires extra configuration on the server. For Prosys, this feature is only available in the Professional Edition. The server administrator must create a user and explicitly map that user account to the user's public certificate.
Setup & Certificate Management
These static functions are used for the one-time setup of a secure connection.
createCertificates
Initializes the entire local PKI store. It creates a new Certificate Authority (CA) and uses it to issue a client certificate (for the application) and a user certificate (for user authentication). This only needs to be run once.
Output
Returns true on successful creation of the PKI structure and certificates.
addServerCertificate
Adds a server's public certificate to your client's trust list, allowing your client to establish a secure connection with it.
Parameters
certificateInput
: The server's public certificate, provided either as a file path or as the PEM content string itself.certificateName
: An optional filename for the certificate. This is required if you provide the certificate content as a string.
Example 1: Adding a certificate from a file
# certificateInput
'/path/to/downloaded/server_cert.pem'
Example 2: Adding a certificate from a string variable
# certificateInput
'-----BEGIN CERTIFICATE-----\nMIIC...etc...\n-----END CERTIFICATE-----'
# certificateName
'my_trusted_server.pem'
Output
Returns true if the certificate was saved successfully.
Client Instantiation and Connection
create
Constructs an OPC UA client instance. The security settings you provide here determine how the client will attempt to connect.
Parameters
options
: An object for configuring the connection's security.securityMode
: Can beNone
,Sign
, orSignAndEncrypt
. Defaults toNone
.securityPolicy
: The encryption algorithm to use (e.g.,Basic256Sha256
). Defaults toNone
.automaticallyAcceptUnknownCertificate:
Turns of server trust checking. Defaults tofalse
.
Example: Create a client for an unsecured connection
# (No arguments needed)
Example: Create a client for a secure connection
# options
securityMode: SignAndEncrypt
securityPolicy: Basic256Sha256
connect
Connects to an OPC UA server using the security settings defined in create
and the user identity provided here.
Parameters
endpointUrl
: The full URL of the server endpoint.userIdentity
: An optional object specifying how to authenticate as a user.username
&password
: For username/password authentication.useDefaultUserCertificate
: Set totrue
to authenticate with the user certificate created bycreateCertificates
.
Connection and Authentication Examples
Here are examples for various connection scenarios.
Example 1: Unsecured, Anonymous Connection
This requires no PKI setup and no user identity.
# (In create function)
# (No arguments)
# (In connect function)
# endpointUrl
opc.tcp://my-server.com:4840
Example 2: Secure, Anonymous Connection
This requires the PKI setup (createCertificates and addServerCertificate) but no user identity.
# (In create function)
# options
securityMode: SignAndEncrypt
securityPolicy: Basic256Sha256
# (In connect function)
# endpointUrl
opc.tcp://my-secure-server.com:4840
Example 3: Secure Connection with Username/Password
This requires the PKI setup for a secure channel, plus username/password credentials for user authentication.
# (In create function)
# options
securityMode: SignAndEncrypt
securityPolicy: Basic256Sha256
# (In connect function)
# endpointUrl
opc.tcp://my-secure-server.com:4840
# userIdentity
username: myuser
password: mysecretpassword
Example 4: Secure Connection with a User Certificate
This is the most secure method, using certificates for both channel security and user authentication.
# (In create function)
# options
securityMode: SignAndEncrypt
securityPolicy: Basic256Sha256
# (In connect function)
# endpointUrl
opc.tcp://my-secure-server.com:4840
# userIdentity
useDefaultUserCertificate: true
Standard Operations
Once connected, you can use these functions to interact with the server.
disconnect
Closes the active session and disconnects from the OPC UA server.
Parameters
None.
Output
Returns true
on a successful disconnection.
isConnected
Checks if the client has a valid and active channel with the server.
Parameters
None.
Output
Returns true
if the client is connected, otherwise false
.
browse
This is the generic, non-recursive browse function. It can start from any node address on the server. The more specific functions like browseObjects
are convenience wrappers around this one.
Parameters
address: The
nodeId
or a full browse path (e.g.,/0:Objects/2:Demo
) from which to start Browse.
Example
# address
/0:Objects/2:Demo
Output
An array of objects, where each object represents a found node and contains its browseName
, nodeId
, and nodeClass
.
browseObjects
Performs a non-recursive browse of the server's Objects
folder. You can specify a deeper path to start from.
Parameters
path: The browse path, starting from within the
Objects
folder. Path items are separated by/
, and each item usesnamespaceIndex:BrowseName
format (e.g.,2:Demo/2:Dynamic
).
Example
# path
2:Demo/2:Dynamic/2:Scalar
Output
An array of objects, where each object represents a found node and contains its browseName
, nodeId
, and nodeClass
.
browseTypes
Performs a non-recursive browse of the server's Types
folder. This is useful for exploring the server's data type hierarchy.
Parameters
path: An optional browse path to start from within the
Types
folder. If omitted, it browses from the root of theTypes
folder.
Example
# path
0:BaseObjectType/0:FolderType
Output
An array of objects, where each object represents a found data type node.
browseViews
Performs a non-recursive browse of the server's Views
folder. Views are predefined, filtered collections of nodes.
Parameters
path: An optional browse path to start from within the
Views
folder. If omitted, it browses from the root of theViews
folder.
Example
# path
0:Server
Output
An array of objects, where each object represents a found node within the specified view.
readNode
Reads all attributes of a specific OPC UA node, returning a detailed data structure. This is more comprehensive than readVariable
, which only fetches the node's value.
Parameters
address: The
nodeId
or a valid browse path of the node to read.
Example: Read using nodeId
# address
ns=2;s=Demo.Dynamic.Int32
Example: Read using Browse Path
# address
/0:Objects/2:Demo/2:Dynamic/2:Int32
Output
A JSON object representing the node's DataValue
. This includes the value, status code, and server/source timestamps. For example:
{
"value": {
"dataType": "Int32",
"value": 12345
},
"statusCode": {
"name": "Good",
"value": 0
},
"serverTimestamp": "2025-07-11T08:52:34.000Z",
"sourceTimestamp": "2025-07-11T08:52:34.000Z"
}
readVariable
Reads the value of a single variable from the server. This is a convenience function that extracts just the value from the node's data.
Parameters
address: The address of the variable, which can be its
nodeId
(recommended) or a full browse path.
Example: Read using nodeId
# address
ns=2;s=Demo.Dynamic.Int32
Example: Read using Browse Path
# address
/0:Objects/2:Demo/2:Dynamic/2:Int32
Output
The raw value of the variable (e.g., a number, a string, a boolean, or an array).
writeVariable
Writes a new value to a variable on the server. The function automatically handles the conversion from a standard JavaScript type to the required OPC UA data type.
Parameters
address: The
nodeId
or browse path of the variable to write to.value: The new value to set.
Example
# address
ns=2;s=Demo.Dynamic.Int32
# value
42
Output
The function returns null
on a successful write or throws an error on failure.
callMethod
Invokes a method on an OPC UA object on the server. Input arguments are automatically converted to the correct data types as defined by the method on the server.
Parameters
methodAddress: The
nodeId
or browse path of the method to call.inputValues: An array of values to pass as input arguments to the method.
Example
This example calls a method that takes two input arguments.
# methodAddress
ns=2;s=Demo.Methods.Multiply
# inputValues
[ 5, 10 ]
Output
An array containing the output arguments returned by the method call.
monitorNode
Subscribes to changes for an entire OPC UA node. The provided callback function is triggered with the full node data object (including value, status, and timestamps) whenever a change is detected by the server.
Parameters
address: The
nodeId
or browse path of the node to monitor.listener: The callback function that will receive the full data object on change.
options: An object to configure the subscription.
samplingInterval: How often (in milliseconds) the server should check for changes. Default is
1000
.
Example
# address
ns=2;s=Demo.Dynamic.UInt16
# listener
<callback>
# options
samplingInterval: 5000
Output
Returns a unique nodeId
string that acts as an identifier for this monitored item, which is needed for stopMonitor
.
monitorVariable
Subscribes to value changes for a specific variable. A callback function is triggered every time the server reports a new value.
Parameters
address: The
nodeId
or browse path of the variable to monitor.listener: The callback function that will receive the new value.
options: An object to configure the subscription.
samplingInterval: How often (in milliseconds) the server should check the variable for changes. Default is
1000
.
Example
# address
ns=2;s=Demo.Dynamic.UInt16
# listener
<callback>
# options
samplingInterval: 5000
Output
Returns a unique nodeId
string that acts as an identifier for this monitored item. This ID is used to stop the monitoring later.
stopMonitor
Terminates an active subscription for a monitored item.
Parameters
nodeId: The identifier string that was returned by a previous call to
monitorNode
ormonitorVariable
.
Example
# nodeId
ns=2;s=Demo.Dynamic.UInt16
Output
Returns true
if the subscription was terminated successfully.
browseDirectory
Recursively browses a file-system-like directory structure exposed by an OPC UA server.
Parameters
address: The
nodeId
or browse path of the starting directory node.
Output
A nested array of objects representing the directory structure.
readFile
Reads the entire content of a file exposed by the OPC UA server's file transfer feature.
Parameters
address: The
nodeId
or browse path of the file node on the server.
Example
# address
ns=2;s=Demo.Files.TextFile
Output
The complete content of the file, encoded as a base64 string.
writeFile
Creates a new file in a specified folder on the server and uploads content to it.
Parameters
folderAddress: The
nodeId
or browse path of the folder where the file will be created.newFileName: The name for the new file.
pathOrBase64: The content to upload, either as a base64 string or a local file system path.
Example
# folderAddress
ns=2;s=Demo.Files
# newFileName
report.txt
# pathOrBase64
SGVsbG8sIFdvcmxkIQ==
Output
The nodeId
of the newly created file on the server.
deleteFile
Deletes a file from a folder on the OPC UA server.
Parameters
folderAddress: The
nodeId
or browse path of the folder containing the file.fileName: The name of the file to delete.
Example
# folderAddress
ns=2;s=Demo.Files
# fileName
report.txt
Output
Returns true
if the file was deleted successfully.
listenToEvents
Registers a callback function to receive important lifecycle events from the client, such as Connected
, Connection Lost
, Session Closed
, etc. This is useful for monitoring the health of the connection.
Parameters
listener: The callback function to receive event strings.
Output
Returns true
.
Last updated