Python OPC UA
OPC UA server stores data and clients read and write data for real-time monitoring and control applications. OPC (Object Linking and Embedding (OLE) for Process Control) is commonly used with a Distributed Control Systems (DCS), Programmable Logic Controllers (PLCs), Human Machine Interfaces (HMIs), and other data transfer applications. It is a newer standard than the older Modbus protocol. OPC UA is platform independent version while OPC DA or OPC HDA (older version) relies on the Microsoft DCOM communication that has inadequate security controls and is not cross-platform. OPC UA support access to current data as well as historical events, multiple hierarchies, and provides commands (methods and programs).
Install opcua
The opcua Python package is a full-featured set of methods that include an OPC UA server and OPC UA client. Install the opcua, opcua-client, and opcua-webclient packages with pip from PyPI repositories.
pip install opcua-client
pip install opcua-webclient
There are several example applications in the opcua documentation to help build server and client applications. OPC UA includes a server that stores the values and clients that read and write to the server. There may be multiple clients that read and write values to the server. The client and server may also be on the same computer.
OPC UA Python Server (Run First)
This example code is an OPC UA server that creates MyObject with MyVariable value that increments by 0.1 every second. The code runs the server on localhost (IP Address: 127.0.0.1) with port 502. Run the OPC UA server before running the client or webclient because they need an OPC server to read or write values.
sys.path.insert(0, "..")
import time
from opcua import ua, Server
if __name__ == "__main__":
# setup our server
server = Server()
server.set_endpoint("opc.tcp://0.0.0.0:4840/freeopcua/server/")
# setup our own namespace, not really necessary but should as spec
uri = "http://examples.freeopcua.github.io"
idx = server.register_namespace(uri)
# get Objects node, this is where we should put our nodes
objects = server.get_objects_node()
# populating our address space
myobj = objects.add_object(idx, "MyObject")
myvar = myobj.add_variable(idx, "MyVariable", 6.7)
myvar.set_writable() # Set MyVariable to be writable by clients
# starting!
server.start()
try:
count = 0
while True:
time.sleep(1)
count += 0.1
myvar.set_value(count)
finally:
#close connection, remove subscriptions, etc
server.stop()
OPC UA Python Client
With the OPC UA server running, test a simple client that reads or writes.
sys.path.insert(0, "..")
from opcua import Client
if __name__ == "__main__":
client = Client("opc.tcp://localhost:4840/freeopcua/server/")
#connect using a user
# client = Client("opc.tcp://admin@localhost:4840/freeopcua/server/")
try:
client.connect()
# Client has a few methods to get proxy to UA nodes that
# should always be in address space such as Root or Objects
root = client.get_root_node()
print("Objects node is: ", root)
# Node objects have methods to read and write node attributes
# as well as browse or populate address space
print("Children of root are: ", root.get_children())
# get a specific node knowing its node id
#var = client.get_node(ua.NodeId(1002, 2))
#var = client.get_node("ns=3;i=2002")
#print(var)
#var.get_data_value() # get value of node as a DataValue object
#var.get_value() # get value of node as a python builtin
#var.set_value(3.9) # set node value using implicit data type
# Now getting a variable node using its browse path
myvar = root.get_child(["0:Objects", "2:MyObject", "2:MyVariable"])
obj = root.get_child(["0:Objects", "2:MyObject"])
print("myvar is: ", myvar)
print("myobj is: ", obj)
print(myvar.get_value())
finally:
client.disconnect()
OPC UA Web Client
Run the opcua-webclient by running the command to start on 127.0.0.1 (localhost) on port 8080. Optionally include python3 -m at the beginning to specify the python version to run the web client.
With the web client running, open a new browser window with the address http://127.0.0.1:8080 or click on the link. The OPC UA Web Client is a basic interface to browse the OPC UA server Root, Objects, Types, and Views.
OPC UA Client
A more full-featured viewer is the OPC UA Client that runs with pyQT as a GUI application. This client allows subscription to data changes and events, writing of variable values, attributes, and references, and the ability to call methods. There is a contextual menu with a tree architecture to view object hierarchies and create simple real-time trends of data. Run opcua-client from the terminal or command prompt.
✅ Knowledge Check
1. What is the primary purpose of an OPC UA server in Python?
- Incorrect. An OPC UA server's primary function is not to create website-based applications. Instead, it's more about serving data for real-time monitoring and control applications in automation systems.
- Incorrect. While OPC UA does have GUI applications, like the OPC UA Client, the primary function of the server is to store values for monitoring and control.
- Correct. The OPC UA server stores values for real-time monitoring and control, and clients can read and write to those values.
- Incorrect. The OPC UA server doesn't serve to install Python packages. It's more related to real-time monitoring and control in automation systems.
2. Which of the following best describes OPC UA compared to the older Modbus protocol?
- Incorrect. It's the older OPC DA or OPC HDA that relies on Microsoft DCOM communication, not OPC UA. OPC UA is platform-independent.
- Incorrect. Modbus is an older protocol compared to OPC UA.
- Correct. OPC UA offers these features, which makes it versatile and suitable for modern automation systems.
- Incorrect. OPC UA is platform-independent and doesn't rely on any specific operating system like Windows.