DESIGN-Praxis / embedded-HMI Qt OPC UA – Ein Tutorial

Verwendung von Qt OPC UA

Das nachfolgende Tutorial nutzt einen Server auf der Basis von open62541 als Platzhalter für eine echte Maschine. Dieser Server ist Bestandteil der von Qt OPC UA mitgelieferten Beispiele [3]. Dort findet sich auch der vollständige Quellcode des im Tutorial entwickelten HMI. Zum Nachvollziehen des Tutorials empfiehlt es sich, Qt OPC UA herunterzuladen beziehungsweise die Dokumentation als Referenz greifbar zu halten.

Der Server simuliert eine Maschine, die aus zwei Tanks, einer Pumpe und einem Ventil besteht. Die Pumpe bewegt Wasser aus dem ersten in den zweiten Tank. Das Ventil befindet sich am zweiten Tank und dient dazu, Wasser abzulassen. Pumpe und Ventil können durch OPC-UA-Methodenaufrufe gesteuert werden. Der Zielwert für das Pumpen und Ablassen ist durch eine Variable im OPC-UA-Server konfigurierbar. Die Bezeichnung der Maschine, die Füllstände der beiden Tanks, der Status des Ventils und der aktuelle Zustand der Maschine stehen ebenfalls als Variablen zur Verfügung. Es empfiehlt sich, mit Hilfe eines generischen OPC-UA-Browsers wie UaExpert [4] den Adressraum des Servers zu erforschen, um die NodeIds der einzelnen Knoten herauszufinden (Bild 1).

Im Rahmen des Tutorials soll zur Steuerung dieser Maschine ein HMI auf der Basis von Qt Quick implementiert werden. Qt Quick ist eines von zwei HMI-Frameworks in Qt und wird typischerweise für moderne embedded-Anwendungen genutzt. Die Architektur von Qt Quick trennt eine Anwendung in ein in C++ geschriebenes Backend und ein in QML implementiertes UI.
QML als Sprache erlaubt die rein deklarative Beschreibung eines UI. Die Interaktion zwischen Backend und UI findet über das Meta-Object-System von Qt statt. Dieses stellt unter anderem Signals, Slots und Properties zur Verfügung. Signale dienen zur losen Kopplung von Komponenten und werden emittiert, um zum Beispiel eine Wert-Änderung zu übermitteln. Slots werden mit Signalen verbunden und dienen ihrer Behandlung. Slots können darüber hinaus direkt aus QML heraus aufgerufen werden. Properties enthalten Werte. Diese können in QML für Property-Bindings genutzt werden - ändert sich der Wert eines Properties im Backend, aktualisiert sich das UI automatisch.

Qt OPC UA stellt eine Reihe von C++-Klassen zur Verfügung. Der QOpcUaProvider erlaubt die Instanziierung eines spezifischen OPC UA-Plugins. Über den Provider erhält man einen QOpcUaClient. Über den Client wiederum können Verbindungen zu einem Server verwaltet werden.
Der Client erzeugt darüber hinaus auf Anfrage Instanzen von QOpcUaNodes. Diese repräsentieren 1:1 einen Knoten im Adressraum des Servers und werden zum Beispiel benötigt um Werte zu lesen, zu schreiben oder zu überwachen. Für eine Qt-Quick-Anwendung werden diese Klassen in einem in C++ geschriebenen Backend genutzt. Dieses Backend behandelt die Kommunikation mit dem OPC-UA-Server und stellt dem HMI eine Abstraktion der Daten und Operationen auf diesem zur Verfügung.
Die Werte der serverseitigen Variablen werden als Read-only-Properties abgebildet, wozu für jede Variable eine Member-Variable im Backend samt dazugehöriger Getter-Methode und Changed-Signal angelegt werden muss. Das Aufrufen von Methoden und das Schreiben von Variablen auf dem OPC UA-Server wird durch Slots implementiert und ist so direkt in QML aufrufbar.