OPC UA
Open Platform Communications Unified Architecture is a standardized open-source communication protocol that enables seamless and secure data exchange between robot controllers and other systems within a robotic cell. It ensures interoperability across different devices and manufacturers, simplifying the integration, monitoring, and coordination of automation setups in production environments.
In robotic programs, OPC UA is commonly used to perform I/O operations during program execution. This is accomplished by using an OPC UA client that connects to an OPC UA server, which must be network-accessible from NOVA. Both Python and Wandelscript provide functionalities to integrate OPC UA operations into their workflows.
Python client
To use Wandelbots NOVA Python SDK in conjunction with an OPC UA server, you need a Python OPC UA client library.
Install asyncua
library
The NOVA Python SDK is built upon asyncua
, so the structure and methods will be familiar and easier to adapt to.
asyncua
is a big Python library for OPC UA and thus offers a lot of functionality.
Its structure also matches the recommended way of writing Python programs with NOVA.
The NOVA Python SDK offers a convenience wrapper around asyncua
to connect to an OPC UA server, reading and writing data,
invoking methods, and subscribing to node changes.
Of course, you can also use any other Python OPC UA library if it better suits your requirements.
Connect to OPC UA server
Create a connection to your OPC UA server using the OPCUAClient
context manager.
- Ensure the OPC UA server is running and accessible via network connection from the NOVA instance.
- Provide the server URL, e.g.,
opc.tcp://192.168.0.100:4840
.
The context manager establishes a connection and automatically handles cleanup.
from nova.extentions.opcua.client import OPCUAClient
async def connect_example():
url = "opc.tcp://192.168.0.100:4840" # Replace with your server URL
async with OPCUAClient(url) as client:
print("Connected to OPC UA server")
Read values from nodes
Read data from specific OPC UA nodes using their node identifiers.
- Provide the node ID as a string to the
read_node
method in the correct server format.The method returns the current value of the specified node.Node identifier follow the OPC UA specification format, e.g.,
ns=2;s=Machine.Temperature
.
from nova.extentions.opcua.client import OPCUAClient
async def read_example(url: str):
async with OPCUAClient(url) as client:
temperature = await client.read_node("ns=2;s=Machine.Temperature") # Replace with OPC UA server node ID
print("Current temperature:", temperature)
Write values to nodes
Send data to OPC UA nodes to control devices or update server values.
- Provide the target node ID and the value to write.
Ensure the value type matches what the server expects, Use appropriate data types, e.g., bool, int, float, string.
from nova.extentions.opcua.client import OPCUAClient
async def write_example(url: str):
async with OPCUAClient(url) as client:
await client.write_node("ns=2;s=Machine.StartButton", True) # Replace with OPC UA server node ID
print("Machine start signal sent")
Call server methods
Execute functions or methods defined on the OPC UA server.
- Provide the parent node ID and the method node ID.
- Pass any required parameters as additional arguments.
The method returns the result from the server function.
from nova.extentions.opcua.client import OPCUAClient
async def call_method_example(url: str):
parent_node = "ns=2;s=Machine.Controller" # Node containing the method, replace with OPC UA server node ID
method_node = "ns=2;s=Machine.Controller.Reset" # Method to call, replace with OPC UA server method node ID
async with OPCUAClient(url) as client:
result = await client.call_node(parent_node, method_node, "param1", 42)
print("Method result:", result)
Subscribe to node changes
Monitor nodes for value changes and react when specific conditions are met.
- Define a condition function that returns
True
when the subscription should stop. - Use
SubscriptionConfig
to customize subscription behavior, e.g., printing received messages.
The subscription stops once the condition is met.
from nova.extentions.opcua.client import OPCUAClient, SubscriptionConfig
def condition(value):
return value == 100 # Stop when value reaches 100
async def subscribe_example(url: str):
config = SubscriptionConfig(print_received_messages=True)
async with OPCUAClient(url) as client:
await client.watch_node_until_condition(
key="ns=2;s=Machine.Counter", # Replace with OPC UA server node ID
condition=condition,
config=config,
)
print("Condition met, subscription stopped")
Wandelscript client
Wandelscript supports request-response interaction as client functionality, including:
- Reading data
- Writing data
- Calling methods
- Waiting for OPC UA signals
Read value
Read a device value with opcua_read(host, node_id, config)
function.
-
host
is the address of the OPC UA server, e.g.opc.tcp://0.0.0.0:4840
. -
node_id
represents the string notation of the OPC UA node id, e.g.ns=2;s=my_node
. Read more about the OPC UA node id here . -
config
is an optional parameter you can provide to configure the OPC UA client. It must be passed as the last argument. Currently supported config parameters are:request_timeout_seconds
: The time in seconds to wait for the response from the server.
host = "opc.tcp://0.0.0.0:4840"
node_id = "ns=2;s=my_node"
config = {
request_timeout_seconds: 10
}
result = opcua_read(host, node_id, config)
print(result) // prints the value
Write value
Write a value to the OPC UA node with opcua_write(host, node_id, value, config)
.
host
is the address of the OPC UA server, e.g.opc.tcp://0.0.0.0:4840
.node_id
represents the string notation of the OPC UA node id, e.g.ns=2;s=my_node
. Read more about the OPC UA node id here .value
is any primitive data type supported by Wandelscript.config
is an optional parameter you can provide to configure the OPC UA client. It must be passed as the last argument. Currently supported config parameters are:request_timeout_seconds
: The time in seconds to wait for the response from the server.
host = "opc.tcp://0.0.0.0:4840"
node_id = "ns=2;s=my_node"
config = {
request_timeout_seconds: 10
}
opcua_write(host, node_id, True, config)
Call method
Call a function defined on the OPC UA server using opcua_call(host, object_id, function_id, argument1, argument2, ..., config)
.
Pass any number of arguments. It returns the function’s return value from the OPC UA server.
host
is the address of the OPC UA server, e.g.opc.tcp://0.0.0.0:4840
.object_id
represents the string notation of the OPC UAnode_id
where the function is defined, e.g.ns=2;s=my_node
.function_id
represents the string notation of the OPC UAnode_id
, e.g.ns=2;s=my_node
.- Arguments can be parameters (0, 1, or more) of primitive data types to pass to the OPC UA function. The values are sent in the order they are defined.
config
is an optional parameter you can provide to configure the OPC UA client. It must be passed as the last argument. Currently supported config parameters are:request_timeout_seconds
: The time in seconds to wait for the response from the server.
host = "opc.tcp://0.0.0.0:4840"
object_id = "ns=2;s=my_object"
function_id = "ns=2;s=my_function"
config = {
request_timeout_seconds: 10
}
opcua_call(host, object_id, function_id, True, config)
Get the value returned by the OPC UA function with result
. The value returned will be assigned to result
.
host = "opc.tcp://0.0.0.0:4840"
object_id = "ns=2;s=my_object"
function_id = "ns=2;s=my_function"
config = {
request_timeout_seconds: 10
}
result = opcua_call(host, object_id, function_id, True, config)
print(result)
Wait for OPC UA signal
Wait until a node has the desired value using wait_for_opcua_value(host, node_id, value, config)
.
The function will check for equality between the provided value and the node value until both values match.
Equality checks are executed whenever the OPC UA server sends a data change notification.
This is the default behavior:
host
is the address of the OPC UA server, e.g.opc.tcp://0.0.0.0:4840
.node_id
represents the string notation of the OPC UA node id, e.g.ns=2;s=my_node
. Read more about the OPC UA node id here .value
is any primitive data type supported by Wandelscript.
This script will wait until the node specified by node_id
has the value True
:
host = "opc.tcp://0.0.0.0:4840"
node_id = "ns=2;s=my_node"
result = wait_for_opcua_value(host, node_id, True)
print(result) // prints the value
Configure data exchange with config
parameter
Wandelscript provides several config parameters to set up the data exchange between the server and client. These parameters are applied via an OPC UA subscription. When subscribing to a data exchange, the server informs the client about all data changes happening for the respective node. The provided information can be monitored and received by the client.
Use the official OPC UA documentation to
Available config parameters
Available config parameters and their default values are:
Config | Default |
---|---|
requested_publishing_interval | 1000 |
requested_lifetime_count | 10000 |
max_notifications_per_publish | 1000 |
priority | 0 |
queue_size | 1 |
sampling_interval | 0.0 |
request_timeout_seconds | 4 |
security_config (read more) | - |
Config can be set completely, partially, or not at all. If not set, default values are used.
Complete
config = {
requested_publishing_interval: 1000
requested_lifetime_count: 10000
max_notifications_per_publish: 1000
priority: 0
queue_size: 1
sampling_interval: 0.0
request_timeout_seconds: 4
}
wait_for_opcua_value(host, node_id, node_value, config)
Server responses
Servers can respond to the requested config with their own settings if certain restrictions are in place. In this case, the subscription will be created with the modified configuration, and you’ll be notified in the logs.
Your desired configuration might request a publishing interval of 1000 ms:
config = {
requested_publishing_interval: 1000
sampling_interval: 0.0
}
wait_for_opcua_value(host, node_id, node_value, config)
The server configuration might set the publishing interval to 200 ms and thus override the requested configuration.
To minimize the risk of such a scenario, we recommend configuring your subscription settings on the OPC UA server side as closely as possible to your desired values.
If this is not possible due to restrictions, set the requested config values as close as possible to the server’s configuration.

Use NOVA authentication with OPC UA
The Wandelbots NOVA OPC UA client supports username and password–based authentication.
Provide the username and password together with host
:
host = "opc.tcp://username:password@0.0.0.0:4840"
Example: Communicate with a camera
This example shows the process of communicating with a Cognex camera that is set up to detect a pattern.
# - - - - - Load a job onto the camera: - - - - -
host = "your server host"
job_name = "07_pattern_detection.job"
object_id = "ns=2;s=VisionSystem"
function_id = "ns=2;s=LoadJob"
opcua_call(host, object_id, function_id, job_name)
# - - - - - Write a value to the camera: - - - - -
host="your server host"
node_id = "ns=2;s=Pattern_1.Tool_Enabled"
value = 1
opcua_write(host, node_id, value)
# - - - - - Trigger an image acquisition: - - - - -
opcua_call(host, "ns=2;s=VisionSystem", "ns=2;s=TriggerManualAcquisition")
# - - - - - Read values from the camera: - - - - -
opc_tags = ["ns=2;s=Pattern_1.Tool_Enabled", "ns=2;s=Pattern_1.Fixture.X", "ns=2;s=Pattern_1.Fixture.Y", "ns=2;s=Pattern_1.Fixture.Angle"]
for i = 0..<len(opc_tags):
opc_tag = opc_tags[i]
result = opcua_read(host, opc_tag)
print(opc_tag)
print(result)
SSL certificates
When an OPC UA client communicates with an OPC UA server, it’s crucial to follow the security best practices outlined by the OPC UA specification. One of the key measures is using secure communication channels that encrypt and verify all data. SSL certificates make this possible: They encrypt the connection and help verify the identities of both client and server.
In this section, we will see how you can use Wandelscript functions with SSL certificates.
Obtain a certificate
There are two ways you can obtain a certificate:
- CA-signed certificate: You can obtain a certificate from a Certificate Authority (CA). Contact the CA of your choice to get certified.
- Self-signed certificate: You can create a self-signed certificate using the
openssl
command in your terminal.A self-signed certificate will be generated at the location of the command execution. The generated filesopenssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
key.pem
andcert.pem
will be used in the next steps.
Upload certificate
Wandelbots NOVA provides a storage service where you can store data.
You will upload the key.pem
and cert.pem
files to a folder in the storage service and later use them in Wandelscript.
Upload the cert.pem file
curl --request PUT \
--url http://$(YOUR_NOVA_INSTANCE)/api/v1/cells/$(CELL_NAME)/store/objects/certs/cert.pem \
--form "AnyValue=@cert.pem"
Upload the key.pem file
curl --request PUT \
--url http://$(YOUR_NOVA_INSTANCE)/api/v1/cells/$(CELL_NAME)/store/objects/certs/key.pem \
--form "AnyValue=@key.pem"
The folder name in the storage service is specified via the URL path, in this case certs
.
If you want a different folder name or structure, adjust the URL path accordingly and make sure to include the file extension .pem
.
Pass certificate
Wandelscript functions will use the certificate to establish a secure connection with the OPC UA server.
Use the config parameter security_config
to provide the certificate in any of the Wandelscript OPC UA communication functions mentioned above.
host = "opc.tcp://0.0.0.0:4840"
node_id = "ns=2;s=my_node"
config = {
request_timeout_seconds: 10,
security_config: {
security_policy: "Basic256Sha256",
message_security_mode: "SignAndEncrypt",
client_certificate_path: "certs/cert.pem",
client_private_key_path: "certs/key.pem"
}
}
opcua_write(host, node_id, True, config)
The security configuration allows for four parameters:
security_policy
specifies the algorithms to use during secure communication.
Supported algorithms are:- Basic128Rsa15
- Basic256
- Basic256Sha256
message_security_mode
indicates the level of security applied to the messages- Sign
- SignAndEncrypt
client_certificate_path
indicates the path to the client certificate file.client_private_key_path
indicates the path to the client private key file.