Skip to Content
Communication protocolsOPC UA

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.

  1. Ensure the OPC UA server is running and accessible via network connection from the NOVA instance.
  2. 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.

  1. Provide the node ID as a string to the read_node method in the correct server format.

    Node identifier follow the OPC UA specification format, e.g., ns=2;s=Machine.Temperature.

    The method returns the current value of the specified node.
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.

  1. 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.

  1. Provide the parent node ID and the method node ID.
  2. 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.

  1. Define a condition function that returns True when the subscription should stop.
  2. 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 UA node_id where the function is defined, e.g. ns=2;s=my_node.
  • function_id represents the string notation of the OPC UA node_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

  1. subscribe to a data exchange  and
  2. monitor data exchanges 

Available config parameters

Available config parameters and their default values are:

ConfigDefault
requested_publishing_interval1000
requested_lifetime_count10000
max_notifications_per_publish1000
priority0
queue_size1
sampling_interval0.0
request_timeout_seconds4
security_config (read more)-

Config can be set completely, partially, or not at all. If not set, default values are used.

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.

Server 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.
    openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
    A self-signed certificate will be generated at the location of the command execution. The generated files key.pem and cert.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:

  1. security_policy specifies the algorithms to use during secure communication.
    Supported algorithms are:
    • Basic128Rsa15
    • Basic256
    • Basic256Sha256
  2. message_security_mode indicates the level of security applied to the messages
    • Sign
    • SignAndEncrypt
  3. client_certificate_path indicates the path to the client certificate file.
  4. client_private_key_path indicates the path to the client private key file.
Last updated on