Introduction to OPC UA Events

POST IS WORK IN PROGRESS

Events are one of three ways to provide data from an OPC UA server. Important to note, it is a completely different mechanism than reading or subscribing to OPC UA variables.

When to use OPC UA Events?

  • It is one possible way to provide several consistent values in one transaction.
  • Events allow certain kind of flexibility. Events can be extended with additional values in a compatible way via a new inherited type. And the client can choose which values it wants to get. This is done with a so called event filter.
  • Events are a good way to model and transport other information than raw data values. Events should be used to indicate that certain things “happen.” For example state changes like a process has started or a process is completed.
  • Events can be used to inform about changes in the OPC UA address space. For example there is the BaseModelChangeEvent.
  • Finally Events are the foundation for the alarms and conditions system.

How to subscribe to Events?

  • Event instances are not visible in the address space, but the EventType definitions are. The EventType defines the content of an event like a template.
  • An object node and an event filter is needed to subscribe to events. Using the event filter, the subscription can be limited to certain EventTypes and certain attributes.
  • Every OPC UA server has to provide all it’s events via the predefined Server-Object node. Additionally it can provide the possibility to register for events on other object nodes.
  • An object node can be used for event subscription, when the attribute “EventNotifier” (https://reference.opcfoundation.org/v104/Core/docs/Part3/5.5.1/) is set to 1. That attribute is defined in the object node class, so it is an attribute of every object.

Example event hierarchy:

Code example with Python:

In python there is a great high level api, which allows to program OPC UA stuff with very few lines of code. In python adding a filter is optional. If no filter is passed, it is auto created. The example uses the sampling interval 0 and the PubSubStatusEventType.

sub = await client.create_subscription(0, callback)
h = await sub.subscribe_events(client.nodes.server, pubSubStatusEventType)

Code example with .NET:

The .NET library from OPCFoundation is more low level and needs more code. In the examples a helper class “FilterDeclaration” is used to auto create the event filter.

// the filter to use.
m_filter = new FilterDeclaration(pubSubStatusEventType, null);
 
// create a monitored item based on the current filter settings.            
m_monitoredItem = new MonitoredItem();
m_monitoredItem.StartNodeId = Opc.Ua.ObjectIds.Server;
m_monitoredItem.AttributeId = Attributes.EventNotifier;
m_monitoredItem.SamplingInterval = 0;
m_monitoredItem.QueueSize = 1000;
m_monitoredItem.DiscardOldest = true;
m_monitoredItem.Filter = m_filter.GetFilter();
 
m_subscription.AddItem(m_monitoredItem);

How is the filter auto created?

Use UaExport to view Events

Custom Event Filter

Two ways to implement the ContenFilter for EvenTypes:

For ConditionEvents a special entry is necessary in the SelectClause to get the ConditionId (NodeId). See bottom of ConditionType Model.

OPC UA Fundamentals – 2

Modeling with Objects and Variables

Just to recap, Variables ore one of the possibilities to deliver the values, Objects are used for structure and semantics. This post will further explain Objects and Variables and how they are used in an example. For a general overview about the OPC UA Node Classes and the node tree, please refer to OPC UA Fundamentals – 1.

Objects

Each Object has an ObjectType. The different ObjectTypes are organized in a type hierarchy, inheriting from each other. On top of the pyramid there is the BaseObjectType being the root of all ObjectTypes. An Object node itself has no data value, just a name. The OPC UA standard predefines a lot of ObjectTypes.

Practically Objects are used in two manners. First there are simple Objects that define just the Object node themself. They can be used like folders in a file system, helping to organize all the files and make it more easy to explore. In that case, just the BaseObjectType can be used. Secondly Objects can define a whole structure of nodes. The corresponding ObjectType defines the template. This is useful if those structures appear several times in the node tree, for modeling purposes, for defining standards and to make these structures easily discoverable for Clients.

Simple ObjectBaseObjectType
Object with node structurederived types like StateMachineType

Variables

Variable nodes are one way to provide the precious data. They have a Value attribute with a defined data type. For beginners, one of the most confusing concepts of OCP UA is the introduction of the VariableType. It is not to be confused with the DataType. The DataType defines the structure and type of the value. However the VariableType enables further possibilities through defining additional subvariables or limitations to attributes. Usage of a VariableType will be shown later in the concrete example. The OPC UA standard predefines a lot of VariableTypes

Like the ObjectTypes, the VariableTypes are organized in a type hierarchy. On top of the pyramid there is the BaseVariableType. A simple Variable node which just provides a value (also called “Property”), can be of BaseVariableType or PropertyType. The PropertyType is the same as the BaseVariableType, just with another name exactly for that purpose.

Simple VariableBaseVariableType or PropertyType
Variable with subvariablesderived types like AnalogItemType

Modeling a coffee machine

Let’s suppose we are creating an OPC UA server for a coffee machine. The first thoughts go into which values we want to provide (e.g. via Variables) and which commands for remote control shall be possible (e.g. via Methods). Let’s make a table to collect the ideas.

SelectorDataType: IntegerDefines the kind of coffee, like Espresso.
CounterDataType: IntegerCounts the served cups.
TempDataType: IntegerCurrent temperature of the brewing group.
CupDetectedDataType: BoolIs a cup detected.
IsDetectedDataType: BoolIs the water tank inserted.
FillingLevelDataType: DoubleFilling level of the water tank.
StartMethodStart producing a cup of coffee.
StopMethodStop or interrupt producing a cup.

Now it would be possible to provide all those values as a flat list of nodes. But there are many advantages in creating more structure and semantics. One possible first iteration of a node tree is shown in the next diagram. It introduces Objects for the control unit, the brewing group and the water tank. The simplest way is to just use the BaseObjectType for all Objects and the PropertyType for all Variables.

To really leverage the advantages of the ObjectType system, like in defining a standard for coffee machine manufacturers, we introduce further types. We create a new type “ControlType” which defines the whole node structure of the ControlUnit. Also we want to deliver the filling level of the water tank including a unit and the allowed value range. Therefore we can use the OPC UA predefined VariableType “AnalogItemType“.

Finally we could define an ObjectType “CoffeeMachineType” for the entire coffee machine. So each coffee machine instance object would need to have exactly that predefined node structure. Most of the, time when creating such new ObjectTypes, they derive from BaseObjectType.

Further exploration of Objects and Variables

A great way to further explore predefined types, custom made types and node trees is to use a generic OPC UA client like the UaExpert of UnifiedAutomation. Just connect to a sample OPC UA server and have a look at the node tree and the type hierarchies. Since each OPC UA server includes all the predefined types, that can be a more interesting way. Reading just the documentation can be boring. After creating an account, UaExpert can be downloaded from the website of UnifiedAutomation. The next Screenshots show the experience. Within the folder “Types” you can explore the complete OPC UA type space.

Another important source of information are the official OPC UA specifications and the Companion Specifications. There is a html version and a pdf version on the site of the OPCFoundation. Create a free account and get the pdf documents.

OPC UA specification Part5: Information Model contains all the predefined ObjectTypes and VariableTypes.

The newer companion specifications also contain a introduction to OPC UA, focusing on Objects and Variables.

Finally you can find all standardized and predefined types in the UA-Nodeset Github Repository of the OPCFoundation. That is for programmatic usage.

OPC UA Fundamentals – 1

That first post explains some fundamentals and focus on the very basic building blocks of an OPC UA server.

Possibilities to provide data in OPC UA

One of the main use cases of an OPC UA server is to provide data in a structured and semantic way. There are 3 different ways to provide data in a server to be consumed by the clients. Each way has its advantages and disadvantages and reasons for its existence.

  1. Variable nodes
    It is possible to read a variable, write to a variable or subscribe to variable to be informed of value changes.
  2. Methods
    Methods can be called including input parameters and can deliver a result. So methods can be used to retrieve data or to execute commands.
  3. Events
    It is possible to subscribe to events, which is a different mechanism than subscribing to a variable. Events can also transport data.

As listed, there are more possibilities than just the variable nodes. Another post will focus on the pros and cons and will give advice when to use what.

Everything is a node

An OPC UA Server can be compared to just a bag full of nodes. Everything you can think of is represented as a node. With the only exception of OPC UA Events. There are nodes of all flavors, for example instance nodes, type nodes and reference nodes. Even a data type, like an integer, is a node.

All nodes live happily in the address space and can have relations to each other. As the name suggests, each node can be addressed via its so called NodeId. The NodeId is unique for each node in the address space and consists of two parts, the NamespaceIndex (ns) and the Identifier. All predefined nodes of the OPC UA standard live in the predefined namespace “http://opcfoundation.org/UA/” with Index 0 and have standardized identifiers. For example the NodeId of the string data type node is [ns=0, i=12], which is the same in each OPC UA server.

Node Classes

The different flavors of nodes in an OPC UA server are called node classes. All 8 node classes are briefly introduced.

An Object Type defines a template for a structure of nodes or just a single node. The structure can contain Variables, Methods and Objects.

Objects are instances of an ObjectType. They are structuring elements needed to create the node tree, like folders in the file system and can contain defined node substructures, as defined in the corresponding ObjectType.

The VariableType exists, to not be limited to simple variables. A VariableType can define a variable with subvariables. It is not to be confused with the DataType and is the most unfamiliar concept for the ordinary mortal developer.

A variable contains a value which has a DataType. Depending of its VariableType it can have subvariables. It is one of the three ways to get the valuable data.

A DataType is a data type ;-). There are predefined simple data types like Boolean, String or DateTime and complex data types called structures – like a struct in a programming language. New data types can be defined. The value of a variable has a data types.

A method node represents, as the name implies, a method. A method can have input and output parameters with certain data types. It is one of the three ways to get the valuable data.

ReferenceTypes define different types of relations between nodes. A ReferenceType can be attached to a node and references another node. Using ReferenceTypes the node trees are defined. For example with the “HasChild” ReferenceType.

With views different masks can be put on the address space to provide different views and to not show everything at the same time. Not needed 😉

The OPC UA instance node tree

An OPC UA server exposes its objects, methods and variables via a node tree. It defines the relations between the nodes and can be used by a client to browse (explore) the address space in a structured and meaningful way. The following diagram shows an exemplary tree in two levels of detail. On the left side also the corresponding ObjectTypes (OT) and VariableTypes (VT) are insinuated as well as the yellow dot for the ReferenceType. The right side shows a simplified version.

The next post will focus more on explaining Objects and Variables and will show concrete examples.