Getting Started with OPC UA: A Beginner's Guide with Python Example
OPC UA (Open Platform Communications Unified Architecture) is a powerful protocol that facilitates seamless data exchange between devices and systems across industries. Getting started with OPC UA is essential for leveraging its enhanced security, scalability, and interoperability. As industries embrace Industry 4.0 and the Industrial Internet of Things (IIoT), OPC UA serves as the backbone of connected systems, enabling machines, sensors, and software to communicate efficiently and securely.
Whether you are creating smart factories, modernizing legacy equipment, or supporting real-time data exchange, OPC UA is your ideal solution. In this article, we explain how OPC UA works, explore its architecture, and guide you through setting up an OPC UA server and client using Python. This makes it simple to start working with this crucial technology.
OPC UA Architecture Overview
The OPC UA architecture is designed for flexibility, scalability, and interoperability in industrial applications. It follows a layered structure, where each layer performs a specific function. These range from managing communication protocols to handling data and information models.
Use Case Specific Protocol Mappings
This layer ensures OPC UA can interact with various protocols that it does not natively support. For instance, if you have a device that uses a different communication protocol, it requires mapping to translate its data into OPC UA format. This mapping bridges the gap, enabling seamless integration.
Client-Server and Pub/Sub Models
OPC UA supports two main communication paradigms: Client-Server and Pub/Sub (Publish-Subscribe).
Client-Server Communication:
- Clients send requests to the server, such as retrieving data or controlling devices.
- Servers respond with requested information or execute the specified actions.
Pub/Sub (Publish-Subscribe):
- Publishers send data to one or more subscribers.
- This model is ideal for real-time data transmission and event notifications. For example, a device can broadcast status updates to all subscribed clients.
Information Model Access
The Information Model Access layer ensures OPC UA clients and servers can interact with data efficiently. It includes several key services for browsing, reading, and writing data. Here’s an overview of the services:
- Browsing Data: The Browse service helps clients discover available data and its structure. For example, a client might locate a device (object) with a temperature variable (node).
- Accessing Data:
- Read: Retrieve the current value of a variable, such as the temperature of a sensor.
- Write: Update the value of a variable, like adjusting a target temperature or turning a device on or off.
- Executing Methods: Clients can invoke server methods for actions like starting a motor or updating device parameters.
- Subscriptions and Notifications:
- Data Subscriptions: Receive updates when variables, such as temperature, change.
- Event Notifications: Get alerts for events like alarms or errors
Information Model Building Blocks
The Information Model Building Blocks layer forms the foundation of OPC UA’s data structure. It defines how information is represented, organized, and accessed across networks, ensuring consistency and extensibility.
Core Concept: Address Space
At the heart of OPC UA is the Address Space, which organizes data hierarchically. The address space contains nodes, with each node belonging to a specific node class that determines its role. Key node types include:
- Objects: Represent physical or logical entities, such as machines or sensors.
- Variables: Contain measurable data, such as a sensor’s temperature or pressure readings.
- Methods: Represent executable functions, like starting a motor or configuring a parameter.
- Events: Capture notifications or alerts, such as warnings or errors.
The address space uses a tree-like structure to connect objects and variables. This layout simplifies data navigation and ensures interoperability between devices. For example, a temperature sensor might be an object within the address space, with variables representing its current temperature or battery status.
Modeling Rules: Consistency and Extensibility
Modeling rules define the structure and behavior of data models, ensuring they are flexible yet standardized. These rules govern how data is inherited, extended, and accessed:
- Inheritance: Objects can inherit properties from parent objects, streamlining model development.
- Extensibility: Models can evolve by adding new data points without disrupting existing systems.
- Access Control: Specify permissions for data interaction, such as reading, writing, or subscribing.
For example, a factory’s control system might extend a standard device model to include additional attributes unique to its equipment, all while remaining compatible with OPC UA standards.
Extensions for Specific Use Cases
Above the core structure, OPC UA provides additional layers for specialized applications:
- Core Information Models: Define universal data structures applicable across industries.
- Companion Information Models: Tailored for specific sectors, like automation or energy.
- Vendor-Specific Extensions: Allow manufacturers to create custom models for their devices.
These extensions ensure flexibility for various industrial applications while maintaining compliance with OPC UA standards.
Programming Example in Python
In this example, we will create an OPC UA Server and an OPC UA Client in Python using the opcua
library. We will set up a server that provides a simple temperature variable and a client that retrieves and periodically updates this variable.
To install python-opcua
, open your command prompt or terminal and run the following command:
pip install opcua
OPC UA Server
First, we will create a simple OPC UA Server that provides a temperature variable. The server will run on localhost and be accessible via the standard port 4840.
Steps to Create a Server:
- Create an instance of the server and set the endpoint (
opc.tcp://localhost:4840/freeopcua/server/
). - Register a namespace (to access the address space) for the model.
- Add an object named
MyDevice
(e.g., a device or sensor) to the server’s address space. - Assign a variable named “Temperature” to this object and mark it as writable.
- Run the server and increase the temperature every 2 seconds.
from opcua import Server
import time
# Create server instance
server = Server()
# Set the endpoint URL
server.set_endpoint("opc.tcp://localhost:4840/freeopcua/server/")
# Set the server name
server.set_server_name("My OPC UA Server")
# Create server object and node
uri = "http://mynamespace"
idx = server.register_namespace(uri)
# Create an object in the address space
objects = server.nodes.objects
my_object = objects.add_object(idx, "MyDevice")
# Add a variable to the object
temperature = my_object.add_variable(idx, "Temperature", 22.5)
temperature.set_writable() # Set the variable as writable
# Start the server
server.start()
print("OPC UA Server is running...")
try:
# Server is running and updating the temperature every 2 seconds
while True:
temperature.set_value(temperature.get_value() + 0.1) # Increase the temperature
time.sleep(2) # Update every 2 seconds
finally:
server.stop()
OPC UA Client
Now, let’s create an OPC UA Client that communicates with the server we just created, retrieves the temperature variable, and displays it regularly. The client will connect to the server, query the temperature, and output the result.
Steps to create a client:
- The client connects to the server by specifying the server’s endpoint.
- The client browses the address space and accesses the temperature variable.
- The client reads the temperature variable and displays its current value.
from opcua import Client
import time
# OPC UA Server URL (same as the server endpoint)
url = "opc.tcp://localhost:4840/freeopcua/server/"
# Establish connection to the OPC UA Server
client = Client(url)
try:
# Connect to the server
client.connect()
print("Connected to the server")
# Access the temperature variable in the address space
temperature_node = client.get_node("ns=2;i=2")
# Read the temperature every 2 seconds
while True:
temperature = temperature_node.get_value() # Get the temperature value
print(f"Current temperature: {temperature} °C")
time.sleep(2)
finally:
# Disconnect from the server
client.disconnect()
print("Disconnected from the server")
This example demonstrated how to connect to an OPC UA server, access a temperature variable, and continuously monitor its value. With OPC UA’s powerful capabilities, this approach can be extended to more complex industrial applications, enabling real-time data exchange across a variety of systems.
Conclusion
In this article, we’ve explored the fundamentals of OPC UA and how it enables seamless, secure communication across industrial systems. With its ability to support both Client-Server and Pub/Sub communication models, OPC UA is the ideal protocol for integrating devices, sensors, and machines in the era of Industry 4.0.
We walked you through the architecture of OPC UA and provided a practical guide to setting up an OPC UA server and client using Python. Whether you’re just starting or looking to implement OPC UA in your system, this guide gives you the tools to connect and communicate with your devices securely and efficiently. OPC UA is more than just a protocol—it’s the backbone of modern, interconnected industrial systems, driving innovation and efficiency.