The UAF is a framework (or "toolkit") that helps you to create advanced OPC UA applications with
minimal effort. Essentially, it takes care of some technical aspects (such as Session and
Subscription management, server discovery, address resolution, ...) so that you can concentrate on
the functional aspects of your software application.
Some very concise and easy to understand examples can be found here:
The following example (a single example, split up into several pieces) shows you some advantages
of the UAF, in Python. In C++, the equivalent code would be a bit more verbose, but the C++ API
is essentially the same as the Python API.
Intuitive API:
All code from the Software Developers Kit is wrapped into some convenient namespaces and
classes (many more than can be seen below of course).
import pyuaf
from pyuaf.util import Node, NodeId, QualifiedName
from pyuaf.util import RelativePathElement, LocalizedText
from pyuaf.util.primitives import UInt16
from pyuaf.client import Client
from pyuaf.client.settings import ClientSettings
Automatic discovery:
Just provide one or more Discovery URL(s), and the UAF will then automatically and periodically
perform the discovery for you.
settings = ClientSettings()
settings.applicationName = "myClient"
settings.discoveryUrls.append("opc.tcp://localhost:4841")
# create the client with the given settings
myClient = Client(settings)
Easy node addressing
You can address nodes
The UAF will resolve the addresses of the nodes, regardless on what server the nodes are hosted.
# first define some URIs (Uniform Resource Identifiers):
ns = "MyOrganization" # the "namespace URI" of the organization or company
plc12 = "PLC/12/Server/URI" # the "server URI" of the OPC UA server running on some PLC
# now define some absolute addresses:
tank5 = Address( NodeId("Tank5" , ns), plc12) )
tank5_name = Address( NodeId("Tank5Name", ns), plc12) )
# now define some relative addresses (Tank5/Sensor3 and Tank5/Sensor3/Status):
tank5_sensor3 = Address( tank5, [ RelativePathElement(QualifiedName("Sensor3", ns)) ] )
tank5_sensor3_status = Address( tank5, [ RelativePathElement(QualifiedName("Sensor3", ns)),
RelativePathElement(QualifiedName("Status" , ns)) ] )
# the UAF accepts even relative addresses to relative addresses! So you could also do:
tank5_sensor3_status = Address( tank5_sensor3, [ RelativePathElement(QualifiedName("Status", ns)) ] )
Automatic address resolution
You can now read/write/monitor/... the Value (or any other attribute) of the nodes that we
addressed above. Even if these nodes are hosted by multiple servers, the UAF will automatically:
This can be seen in the following lines: reading or writing just takes a single line of code!
# let's read
# - the tank name (a LocalizedText, which may be exposed by an OPC UA-enabled PLC)
# - and the sensor status (an UInt16, which may be exposed by some OPC UA-enabled smart sensor)
result = myClient.read([tank5_name, tank5_sensor3_status])
if isinstance(result.targets[0].data, LocalizedText):
name = result.targets[0].data.text()
if isinstance(result.targets[1].data, UInt16):
status = result.targets[1].data.value
# we can also write a new name
result = myClient.write( [tank5_name], [LocalizedText("Oil tank", "EN")] )
if result.targets[0].status.isGood():
print("OK, the new name was written successfully!")
Persistent monitored items
You can create monitored items once, and then forget about them...
def myCallback(notification):
print("New sensor status received: %d" %notification.data.value)
myClient.createMonitoredData([tank5_sensor3_status], notificationCallbacks = [myCallback])
More stuff
For instance, UAF clients have also a generic processRequest
method that can process fully
configurable ReadRequest
s, WriteRequest
s, MethodCallRequest
s, ...
Dive into the documentation or the examples to find out more!
The UAF is based on the commercial C++ OPC UA Software Developers Kit from Unified Automation. A demo
version of this SDK can be downloaded from their website for free: http://www.unified-automation.com
More info about the dependencies: see dependencies.rst.txt
The Python documentation is online here.
The C++ documentation you can easily generate yourself by using Doxygen.
Use the Doxyfile in the src directory.
Linux installation guide: see install_linux.rst.txt
Windows installation guide: see install_windows.rst.txt
Author: Wim Pessemier
Contact: W**.P********@ster.kuleuven.be
(replace the asterisks)
Organization: Institute of Astronomy, KU Leuven (Belgium)
Project website: http://github.com/uaf
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see http://www.gnu.org/licenses/.