Ab einem gewissen Komplexitätsgrad ist Spezialisierung der schnellste Weg zur Erledigung einer Aufgabe. Die Entstehung der OPC im Jahr 1996 folgte ebendieser Erkenntnis. Ein Entwicklerteam aus den fünf Unternehmen Rockwell, Opto 22, Fisher-Rosemount, Intellution und Intuitive Technologies entwickelte unter dem Namen OLE for Process Control ein herstellerübergreifendes Kommunikationsschema.

Ziel war die Schaffung eines Interface, über das SPS sowohl Live- als auch historische Informationen zur Verfügung stellen und Alarme auslösen können. Im Laufe der Zeit erwies sich die enge Bindung an Microsoft OLE (Object Linking and Embedding) als Hemmschuh, der die Nutzung des Standards abseits der Windows-Plattform unnötig erschwerte.

Zur Lösung des Problems setzte man auf eine neue Variante des Protokolls, gemäß dem damals relevanten Design-Paradigma der serviceorientierten Architektur  mit einer Aufteilung zwischen den Daten und Diensten, die die Daten zur Verfügung stellen.

Für wen lohnt sich OPC UA und was kostet es?

Vor der Beschäftigung mit den technischen Details sei hier auf die Rolle von OPC UA im Systemverbund als Ganzes eingegangen. Im Prinzip handelt es sich bei OPC UA um eine Abstraktionsschicht, die das Verbinden von Automatisierungskomponenten verschiedener Hersteller ermöglicht. Für Entwickler ist das System dabei in zweierlei Hinsicht relevant: einerseits als Programmierschnittstelle für die Interaktion mit fertigen Automatisierungskomponenten. Zweitens kann OPC UA auch für selbst entwickelte Automatisierungskomponenten interessant sein – wer die Technologie unterstützt, erfreut sich mit Sicherheit einer breiten Beliebtheit am Markt.

Als Nächstes stellt sich die Frage nach den Kosten. Reale OPC-UA-Systeme bestehen so gut wie immer aus zwei Komponenten – einerseits den von der OPC Foundation bereitgestellten Spezifikationen und andererseits dem allgemeinen Code. Im Allgemeinen gilt, dass die Spezifikationen <span> unter verschiedenen quelloffenen Lizenzen bereitstehen, sodass bei ihrer Nutzung keine Kosten entstehen. Wer allerdings Beispielcode der Foundation verwenden möchte, der die Spezifikation implementiert, muss der Foundation beitreten. Weitere Informationen hierzu finden sich unter. Insbesondere für Kleinunternehmen kann die jährliche Mitgliedschaft weniger als 1000 € kosten.

Kostenstelle Nummero zwei ist dann der Code, der als Basis der Implementierung dient. Aufgrund des immensen Umfangs ist es nicht realistisch, als Kleinunternehmen solchen Code selbst zu entwickeln, woraus folgt, dass der Anbieter des Stacks für seine Arbeit Geld sehen will. Die hier anfallenden Preise unterscheiden sich dann in Abhängigkeit von Geschicklichkeit beim Verhandeln, Zielplattform und Abnahmemenge. Darüber hinaus gibt es allerdings Test- und Demoversionen der verschiedenen Stacks sowie auch quelloffene Implementierungen eines OPC-UA-Servers und mehr (siehe unten).

Technologieübergreifendes System

Aufgrund der Erfahrungen mit der Nutzung von OLE in der ersten Variante von OPC baute man OPC UA so Technologie-agnostisch wie nur irgend möglich auf. Dies führt dazu, dass je nach Aufgabe unterschiedliche Standardprotokolle zum Einsatz kommen können. Hier ein kleiner Überblick der häufig verwendeten Technologien:

Aufgabe Protokoll
OPC-UA-Server-Client-Kommunikation TCP via IANA-registriertem Port 4840
Kommunikation mit Endgeräten TSN, 5G, diverse Feldbusse
Cloudbasierte Event-Verteilung AMQP, MQTT, etc.
Web-Interfaces REST, WebSockets


Grundbaustein jeder auf OPC UA basierenden Architektur ist das Uniform OPC UA Object, das sich - unwissenschaftlich und schematisch dargestellt - wie in Bild 1 präsentiert.

Ein OPC-UA-Objekt kann über seine Variablen Eigenschaften und Prozessdaten exponieren, wobei es sich nicht nur um aktuelle, sondern explizit auch um historische Informationen handeln kann. Über Methoden können Aufrufer Handlungen im OPC-UA-Objekt auslösen, während Ereignisse (Events) im Allgemeinen das tun, was man als Kenner von MQTT und Co. von ihnen erwarten würde.

Figure 1: The Uniform object exposes a wide variety of interfaces.
Bild 1. Das Uniform-Objekt exponiert verschiedenste Interfaces.

Für die Kommunikation beziehungsweise Interaktion mit den diversen im OPC-UA-Objekt lebenden Parametern und Attributen kennt die Spezifikation zwei grundlegende Vorgehensweisen. Einerseits gibt es ein auf dem SOA-Prinzip <span> basierendes Client/Server-Modell. Hierbei kann zum Beispiel eine SPS, die Messdaten vorhält, die Rolle des Servers übernehmen. Clients wie eine Tablet-App, ein Dashboard auf dem PC oder auch ein Analysetool können die Daten dann abrufen. Solch eine Client/Server-Struktur kennt man auch von anderen verteilten Informationssystemen. Wichtig ist hier unter anderem, dass das Abrufen der Messdaten vom Server per Polling erfolgt.

Mit Pub(lish)/Sub(cribe) steht ein alternatives Kommunikationsschema zur Verfügung, das sich an der eventbasierten Programmierung orientiert und prinzipiell vergleichbar mit den in MQTT implementierten Eventsystemen funktioniert. Hervorzuheben ist, dass in MQTT-Brokern eingehende Informationen auch in Richtung OPC UA weitergereicht werden können.

Zur Nomenklatur von OPC UA empfehle ich einen detaillierten Artikel, der die Konzepte von OPC UA ausführlich vorstellt.

Ein OPC-UA-Serververbund agiert außerdem als vereinheitlichendes System, wobei der Hintergedanke ist, dass insbesondere in komplizierten Industrie-Automatisierungsprojekten Informationen in einer Vielzahl von Systemen vorgehalten werden.

In den Spezifikationen für ein „globales Namespace-Modell“ hebt die OPC-Foundation mehrfach hervor, dass die unterschiedlichen Adressierungssysteme - man vergleiche Feldbus und TCP/IP - durch den OPC-UA-Verbund normalisiert werden. Wichtig ist außerdem, dass das Modell nicht nur die eigentlichen Instanzen, sondern auch Instanz-Typen umfasst, die im jeweiligen Automatisierungssystem anzutreffen sind.

Inbetriebnahme eines OPC-UA-Servers

Trotz der immensen Marktbreite gibt es kaum leicht zugängliche Beispiel-Implementierungen von OPC-UA-Servern. In den folgenden Schritten wollen wir auf ein containerbasiertes System mit Microsoft Azure setzen.

Trotz der weiter oben ausgeführten Unabhängigkeiten gilt, dass .NET-Technologien in der Welt von OPC UA eine besondere Rolle einnehmen. So gibt es beispielsweise das .NET-Repositorium des Standardisierungsgremiums, das unter <span> bereitsteht und Referenzimplementierungen des Standards in .NET-Technologien anbietet.

Spezifischerweise wollen wir in den folgenden Schritten den unter bereitstehenden Demo-Server verwenden, weil er eine Gruppe von mehr oder weniger schlüsselfertigen Phänomenen zur Analyse bereitstellt. Angemerkt sei, dass die Eclipse-Foundation mit Milo ein ähnliches Produkt anbietet: Der Milo-eigene Demonstrationscontainer findet sich unter.
 

In den folgenden Schritten wird der Autor seine mit Ubuntu 24.04 laufende Achtkern-Workstation als Testsystem verwenden. Die dort befindliche Docker-Version präsentiert sich folgendermaßen:

tamhan@TAMHAN18:~$ docker --version

Docker version 28.4.0, build d8eb465

Die Inbetriebnahme erfolgt idealerweise mit dem folgenden Kommando, das einige Voreinstellungen für die im Container lebende SPS-Implementierung anliefert:

tamhan@TAMHAN18:~$ docker run --rm -it -p 50000:50000 -p 8080:8080 --name opcplc mcr.microsoft.com/iotedge/opc-plc:latest --pn=50000 --autoaccept --sph --sn=5 --sr=10 --st=uint --fn=5 --fr=1 --ft=uint --gn=5 --aa --ut

Im Rahmen des ersten Startprozesses lädt docker die benötigten Komponenten aus dem Repository herunter, woraufhin nach erfolgreichem Anlassen die Meldung PLC simulation started, press Ctrl+C to exit …  im Kommandozeilenfenster erscheint. Lassen Sie das Fenster offen, um die SPS (englisch PLC) aktiv und überwachbar zu halten. Während der Arbeit wird der Container dort immer wieder Statusinformationen auswerfen.

Wichtig sind außerdem die Parameter --aa --ut, die die normalerweise strikte und zertifikatsbasierte Authentifizierung von Clients deaktiviert. OPC UA unterscheidet sich von der auch als OPC DA bezeichneten Vorgängerversion unter anderem durch stringentere Sicherheitsfunktionen, die bei unseren Laborexperimenten allerdings hinderlich sind (siehe hierzu <span>).

Test-Verbindungsaufbau mit Nutzung eines generischen Clients

Entwickler kennen es: Wer beispielsweise ein Bluetooth-LE-System online bringen möchte, ist gut beraten, einen Server zuerst mit einem Bluetooth-LE-Scanner zu analysieren. Aus der formellen Struktur von OPC UA folgt, dass OPC UA ebenfalls mehr oder weniger generische Scanner zur Verfügung stellt.

Spezifischerweise wollen wir in den folgenden Schritten auf den unter bereitstehenden UA Expert setzen. Es handelt sich dabei um eine „Werbeofferte“ der Unified Automation: Das Unternehmen bietet SDKs an, die Entwicklern die Erzeugung von mit OPC UA interagierenden Programmen in verschiedensten Programmiersprachen ermöglichen. UA Expert ist allerdings nur ein Beispiel im breiten Markt von OPC UA. Unter findet sich eine regelmäßig aktualisierte Liste mit weiteren Komponenten.

Vor dem Herunterladen des für Windows und Linux gleichermaßen zur Verfügung stehenden Scanners ist eine Anmeldung bei Unified Automation erforderlich. Für Linux erhält man ein .tar-gz-Archiv, das extrahiert und danach nach folgendem Schema zur Ausführung bereitgemacht beziehungsweise ausgeführt wird:

tamhan@TAMHAN18:~/Downloads/UaExpert-2.0.1-x86_64-linux$ chmod +x UaExpert-2.0.1-x86_64.AppImage

tamhan@TAMHAN18:~/Downloads/UaExpert-2.0.1-x86_64-linux$ ./UaExpert-2.0.1-x86_64.AppImage

Im Rahmen des ersten Starts fordert das System zur Erzeugung einer kryptografischen Identität auf. Bild 2 zeigt die Beispieleinstellungen des Autors.
 

Figure 2: These settings complete the initialization.
Bild 2. Mit diesen Einstellungen lässt sich die Initialisierung abschließen.

Danach muss man den Servers-Ordner rechts anklicken und eine neue Serverkonfiguration anlegen. Weil unser Beispielserver seine Dienste nicht unter dem Standard-Port 4840 exponiert, wechseln wir in das Feld Advanced. Unter Server Information -> Endpoint Url wird danach der String opc.tcp://localhost:50000 eingegeben.

Nach dem erfolgreichen Verbindungsaufbau - das Übergeben der weiter oben erwähnten Parameter --aa und --ut erlaubt wie gesagt die Auswahl einer ungesicherten Verbindung - wird der weiter unten eingeblendete Namespace-Fensterbereich wie in Bild 3 gezeigt mit den diversen Objekten bevölkert.

Figure 3: The attributes offered by the example server appear in the reference client.
Bild 3. Die vom Beispielserver angeboten Attribute
erscheinen im Reference-Client.

UA Expert zeigt alle von den diversen Servern zur Verfügung gestellten Attribute in dieser Inbox an - in diesem Beispiel verwenden wir natürlich nur einen Server.

Figure 4: Numerous methods are available in the OPC PLC.
Bild 4. In der OPC PLC stehen etliche Methoden zur Verfügung.

Besonders interessant ist das OPC-PLC-Objekt (das die SPS darstellt); in Bild 4 sehen wir dessen Methodenbaum. Klickt man die Funktionen rechts an, öffnet dies einen Aufruf-Dialog. Bild 5 zeigt, wie UA Expert einen erfolgreichen Aufruf der Methode quittiert.

Figure 5: The boiler is activated through an OPC UA method call.
Bild 5. Die Aktivierung des Boilers erfolgt durch einen OPC-UA-Methodenaufruf.

Profile und Facetten

Einer der innovativsten Aspekte von Bluetooth LE war das Profil-System, weil es eine flexible und trotzdem generische Realisierung von Systemen ermöglichte. Idee dabei ist, dass ein „System X“ zumindest einige Attribute implementiert, die die grundlegenden Funktionen auf eine generische Art und Weise exponieren. Herstellerspezifische Sondereigenschaften lassen sich über weitere Attribute realisieren, die für eine damit nicht vertraute Gegenstelle „transparent“ erscheinen.

In OPC UA findet sich ein bis zu einem gewissen Grad ähnliches System. Grundlegend sind dabei die OPC-UA-Datentypen: Variablenarten, die analog zu fix typisierten Programmiersprachen Datenformate auf system- und architekturübergreifende Art beschreiben. Im Allgemeinen finden sich hier bekannte Typen wie Integer, Boolean und Co. - unter  wird die Thematik zusammengefasst.

Im nächsten Schritt bekommen wir es mit Facetten, englisch Facets, zu tun. Dabei handelt es sich um Interfaces, die eine bestimmte Funktion spezifizieren. Hintergedanke ist, dass ein System, das eine bestimmte Facette implementiert, von einem Konsumenten, der diese ebenfalls erwartet, bearbeitet werden kann. Ähnlichkeiten zu Bluetooth-LE-Profilen beziehungsweise den aus der objektorientierten Programmierung bekannten Interfaces sind nicht zufällig.

Eine Ebene darüber finden sich die Profiles, die im Fall von OPC UA eine Gruppe von verpflichtenden und optionalen Facetten zusammenfassen. Unter  findet sich eine Liste allgemeiner Profile. Industriespezifische Standards sind beispielsweise das unter beschriebene OPC for Woodworking, das sich auf die Bedürfnisse der holzverarbeitenden Industrie konzentriert.

Beim Entwickeln von OPC-UA-zertifizierten Systemen bekommt man es auch mit dem Begriff der Conformance Unit zu tun. Unter findet sich eine gute Zusammenfassung des Themas.

open62541 – OPC-UA-Server in quelloffener Version

Wer OPC UA in einem kommerziellen Projekt einsetzen möchte, wird von verschiedenen Unternehmen mit mehr oder weniger zum Kompilieren bereiten SDKs unterstützt.

Obwohl bei so gut wie allen Stacks Testversionen zur Verfügung stehen, verdient das komplett quelloffene open62541 <span> in diesem Artikel eine besondere Erwähnung. Es handelt sich dabei um einen mehr oder weniger komplett in klassischem C gehaltenen OPC-UA-Stack. Unter <span> gibt es eine (ältere) Variante, die die Portierung auf die Entwicklungsumgebung ESP-IDF von Espressif illustriert.

Obwohl eine vollständige Besprechung der Programmierung des Stacks in diesem Artikel aus Platzgründen unmöglich ist, wollen wir doch die Kernkonzepte vorstellen. Technisch beziehungsweise von den Paradigmen her orientiert sich open62541 an einer Mischung aus ESP-IDF und Palm OS. Ein grundlegender OPC-UA-Server lässt sich durch folgenden Code ins Leben rufen:

#include <open62541/server.h>

 

int main(void) {

  UA_Server *server = UA_Server_new();

  UA_Server_runUntilInterrupt(server);

  UA_Server_delete(server);

  return 0;

}

Besonders wichtig ist hier das Objekt UA_Server. Es repräsentiert einen OPC-UA-Server in seiner Gesamtheit. Im vorliegenden Codebeispiel wollen wir davon ausgehen, dass die Host-Plattform multithreading-fähig ist. Der Aufruf runUntilInterrupt erzeugt einen Thread, der danach den OPC-UA-Server so lange zur Verfügung stellt, bis er durch ein CTRL+C beendet wird.

Möchte man eine Variable zum Server hinzufügen, so muss im ersten Schritt eine Instanz der Klasse UA_VariableAttributes erzeugt werden. Sie nimmt danach die diversen Attribute auf, die einem OPC-UA-Client gegenüber exponiert werden sollen:

static void

addVariable(UA_Server *server) {

  UA_VariableAttributes attr =

       UA_VariableAttributes_default;

  UA_Int32 myInteger = 42;

  UA_Variant_setScalar(&attr.value,

      &myInteger, &UA_TYPES[UA_TYPES_INT32]);

  attr.description =

      UA_LOCALIZEDTEXT("en-US","the answer");

  attr.displayName =

      UA_LOCALIZEDTEXT("en-US","the answer");

  attr.dataType =

      UA_TYPES[UA_TYPES_INT32].typeId;

  attr.accessLevel = UA_ACCESSLEVELMASK_READ |

                     UA_ACCESSLEVELMASK_WRITE;

Im nächsten Schritt entsteht eine Containerstruktur, die die Position der Variable im Namespace abbildet. Zu guter Letzt wird die Methode addVariableNode mit einem Verweis auf das Server-Objekt aufgerufen, um das Einpflegen der Variable in den Speicher des Servers erfolgreich abzuschließen:

  UA_NodeId myIntegerNodeId =

        UA_NODEID_STRING(1, "the.answer");

  UA_QualifiedName myIntegerName =

        UA_QUALIFIEDNAME(1, "the answer");

  UA_NodeId parentNodeId =

        UA_NS0ID(OBJECTSFOLDER);

  UA_NodeId parentReferenceNodeId =

        UA_NS0ID(ORGANIZES);

  UA_Server_addVariableNode(server,

          myIntegerNodeId, parentNodeId,

          parentReferenceNodeId, myIntegerName,

          UA_NS0ID(BASEDATAVARIABLETYPE),

          attr, NULL, NULL);

}

Natürlich lassen sich in Variablen abgelegte Werte später aktualisieren. Hierzu sei auf das unter <span> bereitstehende Tutorial verwiesen, das die diversen Vorgehensweisen detailliert durchspielt.

Zur Implementierung der weiter oben vorgeführten Methoden setzt der vorliegende Stack auf Funktionspointer. Auch hier gilt, dass die verlinkte Dokumentation weitere Informationen zu den Programmier-Paradigmen liefert.

Zusammenfassung

OPC UA kann als Inspiration für das in Bluetooth LE implementierte Datenhaltungsschema angesehen werden. Wer sich das Protokoll als „Bluetooth LE für Automatisierung“ vorstellt, mag damit zwar etwas simplifizieren, liegt am Ende aber nicht allzu falsch. Allgemein gilt, dass die Interaktion mit OPC-UA-Technologie wesentlich einfacher von der Hand geht, als es der immense Umfang der Standarddokumente erwarten lassen lässt.

Autor und Redaktion hoffen, dass die Überlegungen Anstoß für die Leserschaft sind, sich mit industrieller Automatisierung zu beschäftigen. Dabei handelt es sich um ein immenses Wachstumsfeld, in dem hohe Stundensätze abzugreifen sind.


Fragen oder Kommentare?

 

Haben Sie technische Fragen oder Anmerkungen zu diesem Artikel? Wenden Sie sich bitte per Mail an den Autor unter tamhan@tamoggemon.com oder die Elektor-Redaktion redaktion@elektor.de.


Anmerkung der Redaktion: Dieser Artikel (250864-01) erscheint in Elektor Juli/August 2026.

Elektor Green Memebrship 4-2026 (1)