Skip to content

de Architecture

SEB103 edited this page Sep 21, 2026 · 1 revision

English · Deutsch · Français · Italiano · Русский · Українська

Architektur

Dieses Kapitel vermittelt einem neuen Entwickler schnell ein mentales Modell des Programms: die wichtigsten Module, wie die Oberfläche das Backend erreicht, die Thread- und Prozessgrenzen und wie Daten und Befehle fließen. Jede genannte Klasse verweist auf ihre Seite in der OpcUaManager API Reference.

Build-Ziele

Die Anwendung wird aus drei statischen Bibliotheken, zwei ausführbaren Dateien und zwei QML-Modulen gebaut (siehe Projektstruktur):

  • OpcUaCore — der OPC-UA-Client-Kern, die Item-Modelle, die Persistenz und die Client-Projektschicht. Bindet Qt Core, Network, OpcUa und Sql ein.
  • ServerProjectCore — das Server-Projekt-Domänenmodell (.uaserver), Serializer, Validator und NodeSet2-Ein-/Ausgabe. Bindet nur Qt Core ein, sodass die eigenständige Laufzeit es ohne den Client-Stack wiederverwenden kann.
  • OpcUaQmlApi — die QML-zugewandten Fassaden. Hängt von OpcUaCore und ServerProjectCore ab.
  • appOpcUaManager — die GUI-Anwendung (app/).
  • OpcUaServerRuntime — die eigenständige open62541-Server-Anwendung (runtime/).
  • QML-Module OpcUaManager (Bildschirme) und Base (wiederverwendbare Steuerelemente).

Die Grenze zwischen QML und C++

Das C++-Backend wird QML über Kontext-Eigenschaften bereitgestellt, nicht über registrierte QML-Typen. Die Anwendungs-Engine setzt diese auf den Wurzelkontext:

  • cppManagerOpcUa → OpcUaManager (Client-Operationen und Modelle)
  • cppServerStudio → ServerStudio (Server-Entwurf und Laufzeitsteuerung)
  • cppProjectManager → die Client-Projekt-Fassade
  • cppAppEngine → AppEngine (Anwendungsdienste)
  • cppAppInfo → AppInfo, cppLocale → LocaleController, cppLicenseModel → LicenseModel, cppUpdate → UpdateController

Da Kontext-Eigenschaften keinen Import benötigen, bleiben die wiederverwendbaren Base-Komponenten frei von jedem C++-Import; nur die Anwendungsschicht bindet sie an die Fassaden. Es gibt bewusst keine Cpp.*-QML-Module in diesem Code.

OPC-UA-Client: GUI-Thread gegenüber Worker-Thread

Der Client ist über zwei Threads verteilt, um die Oberfläche reaktionsfähig zu halten:

  • OpcUaManager läuft im GUI-Thread. Er besitzt die Modelle (OpcUaModel, DataAccessModel, AttributesModel, TrendModel) und ist das einzige Objekt, mit dem QML spricht.
  • OpcUaService läuft in einem eigenen Worker-Thread, den AppEngine erzeugt. Er besitzt den QOpcUaClient und führt Discovery, Verbinden/Trennen, Durchsuchen, Lesen, Schreiben und Abonnements aus.

Beide kommunizieren über in die Warteschlange gestellte Signale, sodass die netz- und PKI-nahe Arbeit das Rendern nie blockiert. Das Dekodieren strukturierter (CODESYS-artiger) Werte übernimmt ein Helfer, der den Instanz-Teilbaum durchsucht.

OPC-UA-Server: zwei Prozesse

Der entworfene Server läuft als separater Prozess, nicht innerhalb der GUI:

  • ServerStudio (GUI) besitzt das im Speicher gehaltene Server-Projekt und die Bearbeitungsmodelle und steuert die Laufzeit.
  • ServerRuntimeController besitzt einen QProcess, der OpcUaServerRuntime ausführt. Die Laufzeit bettet open62541 ein, baut den Adressraum aus dem Projekt, wendet Sicherheit an, simuliert Werte und führt Verhaltensregeln aus.
  • Beide kommunizieren über einen einfachen Vertrag: Die Laufzeit gibt eine READY-Zeile mit ihrem Endpunkt auf stdout aus und akzeptiert STOP auf stdin. Ein separater QLocalSocket-Diagnose-Seitenkanal streamt Live-JSON zu Sitzung und Betriebszeit.

Open in Client verbindet den integrierten Client mit dem laufenden lokalen Server, indem dessen Discovery-URL an OpcUaManager übergeben wird.

Daten- und Befehlsfluss (Client-Lesen)

  1. QML ruft eine Methode auf cppManagerOpcUa (OpcUaManager) auf.
  2. OpcUaManager leitet die Anfrage über ein in die Warteschlange gestelltes Signal an OpcUaService weiter.
  3. OpcUaService führt den OPC-UA-Aufruf im Worker-Thread aus.
  4. Das Ergebnis kehrt als in die Warteschlange gestelltes Signal zurück; OpcUaManager aktualisiert das betreffende Modell (OpcUaModel / DataAccessModel), an das QML gebunden ist.

Konfiguration und Speicherung

  • AppPaths entscheidet über installierte gegenüber portablen Speicherorten und befüllt beim ersten Start den beschreibbaren Speicher.
  • Einstellungen liegen in einem INI-Speicher; Client-Projekte (.uaproj) und Server-Projekte (.uaserver) sind JSON und werden von ihren Serializern atomar geschrieben.
  • Überwachte Knoten werden in einer SQLite-Datenbank persistiert (NodeDatabase).
  • LocaleController installiert und wechselt live die Oberflächensprache.
English
Deutsch
Français
Italiano
Русский
Українська

Clone this wiki locally