Grundlagen

Sparkplug B erklärt: MQTT für das Industrial IoT

Sparkplug B erklärt: der Topic-Namespace spBv1.0, NBIRTH/NDEATH- und DATA/CMD-Nachrichten, Protobuf-Payloads, bdSeq und seq sowie die Primary Host Application.

Aktualisiert · 8 Min. Lesezeit

Reines MQTT ist bewusst meinungsfrei: beliebiges Topic, beliebige Payload. Genau diese Flexibilität wird in Fabriken zum Problem, wo ein SCADA-System des einen Herstellers Daten von PLC-Gateways eines anderen verstehen muss. Sparkplug B schließt diese Lücke. Es ist eine offene Spezifikation, gepflegt von der Sparkplug Working Group der Eclipse Foundation, die festlegt, wie MQTT im Industrial IoT eingesetzt wird: eine feste Topic-Struktur, ein binäres Payload-Format und Regeln, mit denen du jederzeit weißt, ob jedes Gerät online ist. Version 3.0 der Spezifikation ist außerdem als internationaler Standard ISO/IEC 20237 veröffentlicht.

Wenn du neu im zugrunde liegenden Protokoll bist, fang mit Was ist MQTT? an.

Die Komponenten eines Sparkplug-Systems

  • MQTT-Server – ein beliebiger konformer MQTT-3.1.1- oder MQTT-5-Broker.
  • Edge Node – ein Gateway oder Gerät, das sich mit MQTT verbindet, zum Beispiel ein PLC-Gateway. Es publisht seine eigenen Daten und die Daten der dahinterliegenden Devices.
  • Device – ein Sensor, eine SPS oder eine Maschine, die an einem Edge Node hängt. Devices verbinden sich nicht selbst mit MQTT; der Edge Node spricht für sie.
  • Host Application – ein Consumer wie SCADA, MES oder ein Historian, der Daten abonniert und Befehle sendet. Eine davon kann als Primary Host Application festgelegt werden.

Der Sparkplug-Topic-Namespace

Jedes Sparkplug-B-Topic folgt derselben Struktur:

Topic-Struktur
spBv1.0/<group_id>/<message_type>/<edge_node_id>[/<device_id>]

# Examples
spBv1.0/Plant1/NBIRTH/Gateway-07
spBv1.0/Plant1/DDATA/Gateway-07/Press-3
spBv1.0/Plant1/DCMD/Gateway-07/Press-3
  • spBv1.0 – Namespace und Version der Payload-Definition.
  • group_id – eine logische Gruppierung von Edge Nodes, etwa ein Standort oder eine Produktionslinie.
  • message_type – einer der unten aufgeführten Nachrichtentypen.
  • edge_node_id und die optionale device_id – identifizieren den Publisher.

Weil die Struktur fest ist, können Consumer mit Wildcards wie spBv1.0/Plant1/+/# oder spBv1.0/+/DDATA/# abonnieren. Füge sie in den Topic-Matcher ein, um zu prüfen, was sie treffen, oder lies die Regeln in MQTT-Topics und Wildcards nach.

Nachrichtentypen

TypPublisht vonZweck
NBIRTHEdge NodeMeldet den Node als online; listet alle Node-Metriken mit Namen, Typen und aktuellen Werten
NDEATHEdge Node (per Last Will)Meldet den Node als offline
DBIRTHEdge NodeMeldet ein Device als online, mit seiner vollständigen Metrikliste
DDEATHEdge NodeMeldet ein Device als offline
NDATA / DDATAEdge NodeGeänderte Werte von Node- oder Device-Metriken (Report by Exception)
NCMD / DCMDHost ApplicationBefehle an einen Node oder ein Device, z. B. einen Sollwert schreiben oder ein Rebirth anfordern
STATEHost ApplicationMeldet, ob eine Host Application online ist

Sparkplug setzt auf Report by Exception: Nachdem die BIRTH-Nachricht alle Metriken festgelegt hat, enthalten DATA-Nachrichten nur noch geänderte Werte. Ein Consumer, der spät dazukommt oder den Überblick verliert, kann eine frische BIRTH anfordern, indem er ein NCMD sendet, das die Metrik Node Control/Rebirth auf true setzt.

Session-Zustand: NDEATH, bdSeq und seq

Das Killer-Feature von Sparkplug: Ein Host weiß immer, ob Daten aktuell sind. Das baut auf dem Last Will and Testament von MQTT auf:

  1. Beim Verbinden registriert der Edge Node eine NDEATH-Nachricht als seinen Will. Der Will enthält eine bdSeq-Metrik (Birth/Death-Sequenz).
  2. Direkt nach dem Verbinden publisht er NBIRTH mit derselben bdSeq, gefolgt von einem DBIRTH für jedes Device.
  3. Fällt der Node weg, publisht der Broker den NDEATH-Will. Der Host gleicht dessen bdSeq mit dem letzten NBIRTH ab und markiert alle Metriken dieses Nodes und seiner Devices als veraltet.

bdSeq wird mit jeder neuen MQTT-Session hochgezählt (mit Überlauf bei 255), damit ein verspätet eintreffendes NDEATH aus einer alten Verbindung nicht für den Tod der aktuellen gehalten wird.

Unabhängig davon trägt jede Nachricht eines Edge Nodes eine seq-Nummer von 0 bis 255. NBIRTH beginnt bei 0, jede folgende Nachricht zählt hoch, und nach 255 geht es wieder bei 0 los. Sieht ein Host eine Lücke, weiß er, dass eine Nachricht verloren ging, und kann ein Rebirth anfordern.

Die Primary Host Application und STATE

Daten sind nur nützlich, wenn jemand sie aufzeichnet. Eine Primary Host Application publisht eine Retained STATE-Nachricht (und registriert ein Offline-STATE als ihren Will). Edge Nodes, die mit einem Primary Host konfiguriert sind, warten, bis dieser online ist, bevor sie ihre Births publishen. Geht er offline, trennen sie sich und können Daten lokal speichern oder auf einen anderen MQTT-Server ausweichen, bis er zurück ist. In Sparkplug 3.0 lautet das Topic spBv1.0/STATE/<host_id> mit einer kleinen JSON-Payload:

spBv1.0/STATE/scada-main
{ "online": true, "timestamp": 1760140800000 }

Ältere 2.x-Deployments nutzten das Topic STATE/<host_id> mit einem einfachen ONLINE/OFFLINE-String.

Protobuf-Payloads

Sparkplug-B-Payloads werden mit Google Protocol Buffers kodiert. Eine Payload hat einen Zeitstempel, eine seq und eine Liste von Metriken. Jede Metrik hat einen Namen, einen Datentyp, einen Wert, einen optionalen Zeitstempel und einen optionalen numerischen Alias. Aliase werden im BIRTH deklariert; DATA-Nachrichten können dann den Alias statt des vollen Namens senden, was Nachrichten kompakt hält.

Eine dekodierte DDATA-Payload
timestamp: 1760140800123
seq: 17
metrics {
  alias: 4            # "Press-3/Hydraulic/Pressure" in DBIRTH
  timestamp: 1760140800120
  datatype: Float
  float_value: 182.4
}

Die binäre Kodierung macht Payloads klein, was auf schmalbandigen Verbindungen zählt; Paketgrößen kannst du mit dem MQTT-Paketgrößen-Rechner abschätzen. Der Nachteil: Ein generischer Client zeigt nur rohe Bytes. Trotzdem kannst du damit prüfen, ob Births und Deaths auf den richtigen Topics ankommen:

Einen Sparkplug-Namespace im Online-Client beobachten

Welche MQTT-Einstellungen Sparkplug nutzt

  • QoS 0 für NBIRTH/DBIRTH-, DATA- und CMD-Nachrichten; QoS 1 für den NDEATH-Will und STATE.
  • Retain false für alles außer STATE, das retained wird.
  • Clean Sessions für Edge Nodes (Clean Session true in 3.1.1 bzw. Clean Start true mit einer Session Expiry von 0 in MQTT 5). Sparkplug verwaltet den Zustand selbst über Births und Rebirths und ist daher nicht auf persistente Sessions angewiesen.

Einstieg mit Eclipse Tahu

Eclipse Tahu ist die Referenzimplementierung von Sparkplug, mit der Protobuf-Definition und Client-Bibliotheken für Java, C, Python und JavaScript. Es kümmert sich um Kodierung, Aliase und Sequenznummern, sodass du dich auf deine Metriken konzentrieren kannst. Die Sparkplug Working Group veröffentlicht außerdem ein Technology Compatibility Kit (TCK), mit dem sich prüfen lässt, ob Implementierungen der Spezifikation folgen.

Sicherheitsaspekte

Da Sparkplug-Befehle Sollwerte auf echten Maschinen schreiben können, behandle den Zugriff auf NCMD- und DCMD-Topics als sicherheitskritisch. Nutze TLS, eindeutige Zugangsdaten pro Edge Node und ACLs, die jeden Node nur unterhalb seiner eigenen edge_node_id publishen lassen. Unsere Best Practices zur MQTT-Sicherheit behandeln die Details.

Häufig gestellte Fragen

Was ist der Unterschied zwischen MQTT und Sparkplug B?

MQTT ist ein Transportprotokoll, das Bytes über Topics transportiert, ohne festzulegen, was Topics oder Payloads bedeuten. Sparkplug B ist eine Spezifikation auf Basis von MQTT, die einen festen Topic-Namespace, ein Protobuf-Payload-Format und ein Session-State-Management definiert, damit Industriegeräte und SCADA-Systeme verschiedener Hersteller zusammenarbeiten können.

Braucht Sparkplug B einen speziellen MQTT-Broker?

Nein. Sparkplug B funktioniert mit jedem MQTT-3.1.1- oder MQTT-5-konformen Broker, der QoS, Retained Messages und Last Will unterstützt. Manche Broker bieten optionale Sparkplug-spezifische Features, für den Grundbetrieb sind diese aber nicht nötig.

Warum sind Sparkplug-B-Nachrichten in meinem MQTT-Client unlesbar?

Sparkplug-B-Payloads sind binäre Google Protocol Buffers, kein JSON oder Text. Ein generischer MQTT-Client zeigt sie als rohe Bytes an. Du brauchst ein Sparkplug-fähiges Tool oder eine Bibliothek wie Eclipse Tahu, um sie in Metriken zu dekodieren.