Industrial IoT

MQTT SCADA: Telemetrie mit Report by Exception modernisieren

Wie MQTT die SCADA-Telemetrie verändert: Report by Exception statt Polling, ein Broker als Drehscheibe zwischen RTUs und SCADA-Hosts, Zustandserkennung mit Last Will und Sparkplug B sowie ein schrittweiser Migrationspfad.

Entfernte RTUs, die Telemetrie an einen zentralen Broker senden, der SCADA-Server und Dashboards versorgt, als Darstellung einer MQTT-SCADA-Architektur
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

MQTT-SCADA-Architekturen ersetzen das klassische Modell, in dem der Master jede RTU pollt, durch Geräte, die per Report by Exception an einen zentralen Broker melden, und SCADA-Hosts, die abonnieren, was sie brauchen, ob in der Wasserversorgung von Stadtwerken, in Energienetzen oder über mehrere Produktionsstandorte hinweg. Strukturiert nach ISA-95, wird der Broker dabei zum Unified Namespace (UNS) der Anlage. Dieser Leitfaden erklärt, warum dieser Wechsel Bandbreite spart und die Integration vereinfacht, wie die Zustandserkennung funktioniert, wenn nichts gepollt wird, und wie Sie ein bestehendes System Schritt für Schritt migrieren. Außerdem bauen Sie einen kleinen Python-Host, der Offline- und veraltete RTUs erkennt, die Kernkompetenz hinter jedem MQTT-basierten SCADA.

So funktioniert klassische SCADA-Telemetrie

In einem klassischen SCADA-System führt die Masterstation das Gespräch. Sie pollt jede RTU oder SPS der Reihe nach über Modbus, DNP3 oder ein Herstellerprotokoll und fragt in jedem Zyklus dieselben Register ab, ob sich etwas geändert hat oder nicht. Das Modell hat echte Stärken: Der Master weiß immer, ob ein Gerät geantwortet hat, und das Timing ist vorhersehbar.

Es hat aber auch bekannte Kosten:

  • Bandbreite für unveränderte Daten. Ein Tankfüllstand, der sich zweimal pro Stunde ändert, wird trotzdem alle paar Sekunden gelesen.
  • Die Scanzeit wächst mit dem Netz. Auf Funk- oder Satellitenstrecken verlängert jede zusätzliche RTU den Polling-Zyklus für alle.
  • Enge Kopplung. Jeder neue Konsument, ein Historian, ein Analysewerkzeug, eine zweite Leitwarte, pollt die Geräte entweder erneut oder hängt von den Schnittstellen des SCADA-Servers ab.
  • Geräteadressen überall. Registertabellen und Protokolldetails sickern in jedes System, das die Daten benötigt.

Was sich mit MQTT SCADA ändert

Mit MQTT öffnet die RTU oder das Edge-Gateway eine ausgehende Verbindung zu einem Broker und veröffentlicht Werte, wenn sie sich relevant ändern. SCADA-Hosts, Historians und Dashboards sind Abonnenten. Der Broker sitzt in der Mitte und verteilt die Nachrichten.

Aspekt Polling-SCADA MQTT SCADA
Wer initiiert Master pollt jedes Gerät Gerät veröffentlicht, Hosts abonnieren
Verkehr Jeder Datenpunkt in jedem Scan Nur Änderungen plus Heartbeats
Konsument hinzufügen Neue Polls oder SCADA-Schnittstelle Neues Abonnement, Geräte unberührt
Verbindungsrichtung Master zum Gerät (eingehend ins Feld) Gerät zum Broker (ausgehend aus dem Feld)
Gerätezustand Implizit: keine Antwort bedeutet Problem Explizit: Last Will, Birth/Death-Nachrichten
Datenkontext Registeradressen Benannte Topics, oft ISA-95 oder Sparkplug
Effizienz auf der Strecke Schlecht bei hoher Latenz Gut: persistente Sitzung, kleine Pakete

Der größte konzeptionelle Wechsel ist Report by Exception (RBE). Statt zu fragen, meldet das Feld. Ein Totband für jeden Analogwert und die sofortige Veröffentlichung jeder digitalen Zustandsänderung halten die Daten mit einem Bruchteil des Verkehrs aktuell. Der Leitfaden zu Report by Exception behandelt die Bemessung von Totbändern im Detail.

Der Broker als SCADA-Drehscheibe

In einem MQTT-SCADA-Design wird der Broker zum zentralen Nervensystem. Feldgeräte wissen nicht und kümmert es nicht, wie viele Hosts ihre Daten nutzen, und Hosts müssen keine Geräteadressen kennen. Diese Entkopplung ermöglicht Muster, die mit Polling umständlich sind:

  • Redundante SCADA-Hosts abonnieren dieselben Topics, ohne den Feldverkehr zu verdoppeln.
  • IT-Konsumenten wie Historians und Analysen abonnieren parallel, ohne das Leitsystem zu berühren.
  • Schrittweise Migrationen können altes und neues SCADA nebeneinander mit denselben Live-Daten betreiben.

Zu verstehen, was ein MQTT-Broker macht, ist hier die Grundlage: Er leitet Nachrichten weiter, hält Retained-Werte und Sitzungszustände und setzt durch, wer sich verbinden darf.

Vom SCADA-Broker zum Unified Namespace

Seine volle Wirkung entfaltet die Drehscheibe, wenn die Topics nicht nach Registeradressen, sondern nach der ISA-95-Anlagenhierarchie (IEC 62264) benannt sind: Enterprise → Site → Area → Line → Cell. Aus rtu07/ai3 wird dann zum Beispiel acme/werk-stuttgart/montage/linie-1/zelle-3/temperatur. Diese Struktur ist der Unified Namespace: eine gemeinsame, aktuelle Sicht auf alle Anlagendaten, in die SCADA, MES, ERP, Historian und Analysen gleichermaßen publizieren und aus der sie abonnieren. Der SCADA-Host ist darin ein Konsument unter mehreren statt der einzige Zugang zu den Felddaten. Wie Sparkplug B und UNS zusammenpassen, beschreibt der Artikel Sparkplug B und Unified Namespace.

Zustandserkennung ohne Polling

Der häufigste Einwand gegen MQTT SCADA lautet: „Wenn ich nicht mehr polle, woher weiß ich, dass eine RTU lebt?“ MQTT beantwortet das auf zwei Ebenen.

Keep Alive und Last Will. Jeder Client deklariert ein Keep-Alive-Intervall. Hört der Broker das 1,5-Fache dieses Intervalls nichts, schließt er die Sitzung und veröffentlicht die Last-Will-Nachricht des Clients, zum Beispiel ein Retained-offline auf dem Status-Topic der RTU. Verbindet sich die RTU wieder, veröffentlicht sie ein Retained-online. Jeder Abonnent, auch einer, der später startet, sieht den aktuellen Zustand.

Sparkplug B. Die Sparkplug-Spezifikation formalisiert das für SCADA: Edge Nodes veröffentlichen beim Verbinden NBIRTH- und DBIRTH-Nachrichten mit allen Metriken, NDEATH als Last Will, und eine Primary Host Application veröffentlicht ihren eigenen STATE, damit Edge Nodes wissen, ob ein SCADA-Host zuhört. Hosts können ein Rebirth anfordern, wenn sie eine Lücke erkennen. Ignition und viele Edge-Gateways implementieren das nativ; die Host-Seite beschreibt der Artikel zu Sparkplug Primary Host Applications.

Auch mit reinen JSON-Topics sollten Sie veraltete Daten erkennen: ein Gerät, das verbunden ist, dessen Werte sich aber nicht mehr aktualisieren, etwa weil seine Feld-I/O ausgefallen ist.

Beispiel: Ein minimaler MQTT-SCADA-Host in Python

Dieser Host abonniert Status und Telemetrie der RTUs, verfolgt den Online-Zustand anhand von Retained-Last-Will-Nachrichten und markiert jede RTU, deren Daten sich nicht innerhalb des erwarteten Heartbeats geändert oder aktualisiert haben. Führen Sie ihn mit einem Simulator gegen den öffentlichen MQTT-Broker aus, der nur für Tests gedacht ist, und richten Sie ihn dann auf Ihren eigenen Broker.

import json
import time
import uuid
import threading

import paho.mqtt.client as mqtt

BROKER, PORT = "broker.connectmq.com", 1883
PREFIX = "connectmq/demo/scada-7h2k"          # zufälliges Präfix: öffentliche Daten sind für alle lesbar
STALE_AFTER = 120                             # Sekunden; Heartbeat ist 60 s

rtus = {}   # rtu_id -> {"online": bool, "last_seen": float, "values": dict}
lock = threading.Lock()


def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    client.subscribe(f"{PREFIX}/+/status", qos=1)
    client.subscribe(f"{PREFIX}/+/telemetry/#", qos=1)


def on_message(client, userdata, msg):
    parts = msg.topic.split("/")
    rtu_id = parts[3]
    with lock:
        rtu = rtus.setdefault(rtu_id, {"online": False, "last_seen": 0.0, "values": {}})
        if parts[4] == "status":
            rtu["online"] = msg.payload.decode() == "online"
            print(f"[STATE] {rtu_id} is {'ONLINE' if rtu['online'] else 'OFFLINE'}")
        else:
            point = "/".join(parts[5:])
            rtu["values"][point] = json.loads(msg.payload)
            rtu["last_seen"] = time.time()


def watchdog():
    while True:
        time.sleep(10)
        now = time.time()
        with lock:
            for rtu_id, rtu in rtus.items():
                if rtu["online"] and now - rtu["last_seen"] > STALE_AFTER:
                    print(f"[STALE] {rtu_id}: no data for {int(now - rtu['last_seen'])} s")


client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=f"scada-host-{uuid.uuid4().hex[:6]}")
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, PORT, keepalive=30)
threading.Thread(target=watchdog, daemon=True).start()
client.loop_forever()

Simulieren Sie in einem anderen Terminal eine RTU, indem Sie einen Retained-Status und einen Telemetriewert veröffentlichen:

mosquitto_pub -h broker.connectmq.com -p 1883 -i rtu-sim-7h2k \
  -t 'connectmq/demo/scada-7h2k/rtu07/status' -m online -r -q 1
mosquitto_pub -h broker.connectmq.com -p 1883 -i rtu-sim2-7h2k \
  -t 'connectmq/demo/scada-7h2k/rtu07/telemetry/tank1/level' -m '{"value":3.42,"unit":"m"}' -q 1

Für einen dauerhaft laufenden Simulator mit echtem Last Will verwenden Sie mosquitto_sub oder ein Skript mit --will-topic connectmq/demo/scada-7h2k/rtu07/status --will-payload offline --will-retain und beenden es, um die Reaktion des Hosts zu beobachten. Nutzen Sie den kostenlosen öffentlichen MQTT-Broker nur für simulierte Werte wie diese.

Ein bestehendes SCADA-System migrieren

Ein Austausch in einem Schritt ist selten nötig. Ein schrittweiser Pfad hält den Betrieb sicher:

  1. Zuerst spiegeln. Ergänzen Sie neben dem bestehenden Master einen MQTT-Publisher, entweder ein SCADA-Modul, das Tags weiterleitet, oder ein Edge-Gateway, das dieselben RTUs im reinen Mithörmodus liest. An der Steuerung ändert sich nichts.
  2. Den Unified Namespace definieren. Einigen Sie sich auf Topic-Struktur (ISA-95-Pfade oder Sparkplug-Group- und Node-IDs) und Payload-Format, bevor es viele Quellen gibt. Legen Sie fest, wie Werk, Bereich, Linie und Zelle benannt werden, damit jeder neue Standort sich ohne Umbau in den UNS einfügt.
  3. Rein lesende Konsumenten anbinden. Historians, Dashboards und Analysen wechseln zum Broker. Validieren Sie die Werte gegen die SCADA-Bilder.
  4. Standorte auf RBE umstellen. Ersetzen Sie das Polling jeweils für einen Standort oder Streckentyp durch RBE-fähige RTUs oder Edge-Gateways. Vergleichen Sie Bandbreite und Datenaktualität.
  5. Steuerung vorsichtig verlagern. Befehle über MQTT benötigen Bestätigungsmuster, Timeouts und Verriegelungen. Die Command-Nachrichten von Sparkplug oder Request/Response mit Response-Topics in MQTT 5 helfen, das zu strukturieren.
  6. Altes Polling abschalten, erst wenn jeder Konsument umgezogen und das Alarmverhalten überprüft ist.

Fallstricke beim Design

  • Kein Heartbeat. Reines RBE ohne periodische Aktualisierung macht einen eingefrorenen Wert ununterscheidbar von einem ruhigen.
  • Zeitstempel von Geräteuhren ohne Synchronisation. Die Analyse von Ereignisfolgen bricht, wenn RTU-Uhren driften. Verwenden Sie NTP- oder GPS-Zeit an der Quelle.
  • Überall QoS 2. Das fügt auf langsamen Strecken zusätzliche Round-Trips hinzu. QoS 1 mit idempotenten Konsumenten ist die übliche Wahl für Telemetrie.
  • Alles retainen. Retainen Sie Status und letzte Werte, keine hochfrequenten Datenströme.
  • Flache Topics. rtu07/ai3 skaliert nicht; benennen Sie nach Standort und Anlage entlang der ISA-95-Ebenen, wie oben für den Unified Namespace beschrieben.

Wo ConnectMQ ins Spiel kommt

Ein Broker als SCADA-Drehscheibe braucht TLS, Zugangsdaten pro Gerät und Schutz vor sich fehlverhaltenden Clients. ConnectMQ bietet MQTT 3.1.1 und 5.0 mit TLS, bindet jede Client-ID an ihre ausgegebenen Zugangsdaten und wendet Flood-Schutz sowie IP-Sperren nach wiederholten Fehlanmeldungen an. Das Portal dekodiert Sparkplug-B-Payloads, kann Sparkplug-Daten in lesbare ISA-95-Topics zurückveröffentlichen und bietet Schwellwert-Alarmregeln mit Alarmprotokoll, praktisch für eine schnelle Betriebsübersicht neben Ihrem SCADA-Host. SCADA-Software, Historians und Skripte verbinden sich als gewöhnliche MQTT-Clients. Wenn Sie nicht in jeder Leitwarte Broker-Infrastruktur betreiben möchten, lohnt sich ein Blick auf einen verwalteten MQTT-Broker; Implementierungsdetails mit einem konkreten SCADA-Paket finden Sie unter Ignition mit MQTT, den größeren Kontext im Leitfaden zu Industrial IoT mit MQTT.

Modernisieren Sie Ihre SCADA-Telemetrie mit ConnectMQ

Beginnen Sie mit einem Standort oder einem RTU-Typ. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker, ganz ohne Kreditkarte, verbinden Sie ein Gateway und Ihren SCADA-Host und vergleichen Sie die Daten direkt mit Ihrem bestehenden Polling.

Häufig gestellte Fragen

Kann MQTT DNP3 oder Modbus im SCADA ersetzen?

MQTT ersetzt häufig den Transport zwischen Außenstationen und Leitwarte, während Modbus oder DNP3 lokal zwischen einem Edge-Gateway und den Feldgeräten weiterhin genutzt werden können.

Woher weiß ein MQTT-SCADA-Host, dass ein Gerät offline ist?

Über die Last-Will-Nachricht des Geräts, die der Broker veröffentlicht, wenn das Keep Alive abläuft, oder über Sparkplug-NDEATH-Nachrichten. Ergänzen Sie eine Erkennung veralteter Daten für Geräte, die verbunden bleiben, aber keine Aktualisierungen mehr senden.

Ist Sparkplug B für MQTT SCADA erforderlich?

Nein, aber es standardisiert Birth- und Death-Nachrichten, Metrikdefinitionen und den Host-Zustand, was die Interoperabilität zwischen SCADA-Hosts und Edge-Geräten deutlich erleichtert.

Welche QoS sollte SCADA-Telemetrie verwenden?

QoS 1 ist die übliche Wahl, kombiniert mit Retained-Status-Topics. QoS 0 eignet sich für hochfrequente Daten, bei denen der nächste Messwert einen verlorenen ersetzt.

Verwandte Artikel

Industrial DataOps: Werksdaten kontextualisieren und steuern

Was Industrial DataOps in der Praxis bedeutet: Kontextualisierung, Normalisierung, Qualitätsprüfungen und Governance von OT-Daten und wie Sie diese Schicht auf einem MQTT-Namespace betreiben.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.