Sparkplug Templates sind der Weg von Sparkplug B, wiederverwendbare Anlagentypen zu definieren, das MQTT-Gegenstück zu einem benutzerdefinierten Datentyp (UDT) in einer SPS oder einem SCADA-System, vergleichbar mit einem PLC-Datentyp in TIA Portal oder einem Objekttyp in OPC UA. In diesem Leitfaden erfahren Sie, wie Template-Definitionen und -Instanzen funktionieren, wie Parameter, Verschachtelung und Versionen hineinpassen, wie Sie ein Pumpen-Template in Python bauen und wie Sie dasselbe Modell über viele Edge Nodes hinweg konsistent halten.
Warum es Templates gibt
Ohne Templates ist eine Pumpe nur eine Menge lose zusammenhängender Metriken: Pump1/Speed, Pump1/Running, Pump1/Pressure. Eine zweite Pumpe wiederholt dieselben Namen mit anderem Präfix, und nichts teilt der Host-Anwendung mit, dass beides Pumpen sind. Nennt ein Edge Node die Metrik Speed und ein anderer RPM, muss jeder Konsument diesen Unterschied kennen.
Templates lösen das, indem sie den Typ von der Instanz trennen. Sie definieren eine Pump einmal mit ihren Member-Metriken, Datentypen und Standardwerten. Jede physische Pumpe ist dann eine Instanz, die auf die Definition verweist. Eine Host-Anwendung, die Templates versteht, kann automatisch passende Objekte anlegen, auf jede Pumpe dieselben Anzeigen und Alarme anwenden und erkennen, wenn eine Instanz nicht zu ihrem Typ passt.
Definitionen und Instanzen
Sowohl Definitionen als auch Instanzen sind Metriken mit dem Datentyp 19 (Template), deren Wert eine Template-Nachricht ist:
| Template-Feld | Zweck | In einer Definition | In einer Instanz |
|---|---|---|---|
| version | Optionaler Versions-String | Empfohlen | Optional |
| metrics | Member-Metriken | Member mit Datentypen und Standardwerten | Member mit aktuellen Werten |
| parameters | Benannte, typisierte Konstanten | Mit Standardwerten deklariert | Pro Instanz überschrieben |
| template_ref | Name der verwendeten Definition | Nicht gesetzt | Pflicht, verweist auf die Definition |
| is_definition | Kennzeichnet eine Definition | true | false |
Wo Definitionen stehen
Template-Definitionen werden im NBIRTH veröffentlicht, vor jeder Instanz, die sie nutzt. In Datennachrichten werden sie nicht wiederholt. Manche Plattformen stellen Definitionsnamen einen Ordner wie _types_/ voran, um Typen von Live-Tags zu trennen. Das ist eine Plattformkonvention, keine Vorgabe; richten Sie sich also danach, was Ihre Host-Anwendung erwartet.
Wo Instanzen stehen
Instanzen können im NBIRTH (Anlagen auf Node-Ebene) oder in einem DBIRTH (Anlagen hinter einem Device) erscheinen. Jede Instanz enthält im Birth den vollständigen Satz an Member-Metriken mit aktuellen Werten. Datennachrichten übertragen danach die Änderungen.
Ein dekodiertes Beispiel
So sieht eine Pumpendefinition in einem NBIRTH nach dem Dekodieren aus:
{
"name": "_types_/Pump",
"datatype": 19,
"templateValue": {
"version": "1.2",
"isDefinition": true,
"parameters": [
{ "name": "RatedSpeed", "type": 9, "floatValue": 1500.0 }
],
"metrics": [
{ "name": "Running", "datatype": 11, "booleanValue": false },
{ "name": "Speed", "datatype": 9, "floatValue": 0.0 },
{ "name": "DischargePressure", "datatype": 9, "floatValue": 0.0 },
{ "name": "StartCount", "datatype": 8, "longValue": "0" }
]
}
}
Und eine Instanz davon in einem DBIRTH:
{
"name": "CoolingPump1",
"alias": 20,
"datatype": 19,
"templateValue": {
"templateRef": "_types_/Pump",
"version": "1.2",
"isDefinition": false,
"parameters": [
{ "name": "RatedSpeed", "type": 9, "floatValue": 2900.0 }
],
"metrics": [
{ "name": "Running", "datatype": 11, "booleanValue": true },
{ "name": "Speed", "datatype": 9, "floatValue": 2875.5 },
{ "name": "DischargePressure", "datatype": 9, "floatValue": 3.4 },
{ "name": "StartCount", "datatype": 8, "longValue": "1287" }
]
}
}
Die Instanz überschreibt den Parameter RatedSpeed, weil diese Pumpe einen anderen Motor hat. Parameter eignen sich ideal für Typenschilddaten und Grenzwerte, die sich je Anlage unterscheiden, sich zur Laufzeit aber nicht ändern.
Ein Template in Python bauen
Dieses Snippet erstellt die Definition und eine Instanz mit Klassen, die aus der Datei sparkplug_b.proto von Eclipse Tahu generiert wurden. Den einmaligen Schritt der Codegenerierung zeigt unser Tutorial zum Dekodieren von Sparkplug B in Python.
import time
import sparkplug_b_pb2 as spb
BOOLEAN, FLOAT, UINT64, TEMPLATE = 11, 9, 8, 19
MEMBERS = [("Running", BOOLEAN), ("Speed", FLOAT),
("DischargePressure", FLOAT), ("StartCount", UINT64)]
def set_value(metric, datatype, value):
metric.datatype = datatype
if datatype == BOOLEAN:
metric.boolean_value = value
elif datatype == FLOAT:
metric.float_value = value
elif datatype == UINT64:
metric.long_value = value
def add_pump_definition(payload):
m = payload.metrics.add()
m.name = "_types_/Pump"
m.datatype = TEMPLATE
t = m.template_value
t.version = "1.2"
t.is_definition = True
p = t.parameters.add()
p.name, p.type, p.float_value = "RatedSpeed", FLOAT, 1500.0
for name, dtype in MEMBERS:
member = t.metrics.add()
member.name = name
set_value(member, dtype, False if dtype == BOOLEAN else 0)
def add_pump_instance(payload, name, alias, rated_speed, values):
m = payload.metrics.add()
m.name = name
m.alias = alias
m.timestamp = int(time.time() * 1000)
m.datatype = TEMPLATE
t = m.template_value
t.template_ref = "_types_/Pump"
t.version = "1.2"
t.is_definition = False
p = t.parameters.add()
p.name, p.type, p.float_value = "RatedSpeed", FLOAT, rated_speed
for name, dtype in MEMBERS:
member = t.metrics.add()
member.name = name
set_value(member, dtype, values[name])
nbirth = spb.Payload(timestamp=int(time.time() * 1000), seq=0)
add_pump_definition(nbirth)
dbirth = spb.Payload(timestamp=int(time.time() * 1000), seq=1)
add_pump_instance(dbirth, "CoolingPump1", 20, 2900.0,
{"Running": True, "Speed": 2875.5,
"DischargePressure": 3.4, "StartCount": 1287})
print(len(nbirth.SerializeToString()), "byte NBIRTH,",
len(dbirth.SerializeToString()), "byte DBIRTH")
In einem echten Edge Node enthält das NBIRTH außerdem bdSeq und Node Control/Rebirth, wie in Sparkplug Birth- und Death-Zertifikate gezeigt. Veröffentlichen Sie diese Payloads auf spBv1.0/{group}/NBIRTH/{node} und spBv1.0/{group}/DBIRTH/{node}/{device}.
Template-Werte zur Laufzeit aktualisieren
Births enthalten vollständige Instanzen, Datennachrichten sollten aber klein bleiben. Plattformen unterscheiden sich darin, wie sie Änderungen an einem Template-Member melden. Manche senden die Instanz-Metrik in NDATA oder DDATA erneut und nehmen nur die geänderten Member auf. Andere stellen jeden Member nach dem Birth als eigene Metrik mit Alias bereit, sodass eine Drehzahländerung als einzelner Skalarwert übertragen wird. Beide Ansätze verlassen sich darauf, dass das Birth Namen, Datentypen und Aliase festlegt. Deshalb kann ein Host, der das Birth verpasst, auch Template-Aktualisierungen nicht interpretieren.
Bevor Sie sich auf ein Design festlegen, veröffentlichen Sie ein Birth und einige Datennachrichten von Ihrer Edge-Plattform und sehen sich das dekodierte Ergebnis an. Prüfen Sie, ob Ihre Host-Anwendung den richtigen Instanz-Member aktualisiert, ob unveränderte Member ihre Werte behalten und ob ein Rebirth die vollständige Instanz wiederherstellt. Mit zwei oder drei Pumpen in einer Testgruppe dauert das Minuten und erspart Ihnen, eine Abweichung erst nach der Konfiguration Hunderter Anlagen zu entdecken.
Verschachtelung und Komposition
Eine Member-Metrik eines Templates kann selbst ein Template sein. Ein Skid-Template könnte zwei Pump-Instanzen, eine Tank-Instanz und einige skalare Metriken enthalten. Komposition hält Modelle lesbar und erlaubt es, kleine, gut getestete Typen wiederzuverwenden.
Halten Sie die Verschachtelung flach. Jeder Host muss jede Ebene auflösen, und tiefe Hierarchien machen Births groß. Große Births zählen auf geteilter Infrastruktur: Der öffentliche MQTT-Broker akzeptiert Nachrichten bis 64 KB, und jeder Plan hat ein eigenes Größenlimit für Nachrichten. Modelliert ein Node Hunderte von Anlagen, prüfen Sie die Birth-Größe frühzeitig.
Templates über Edge Nodes hinweg konsistent halten
Templates zahlen sich nur aus, wenn jeder Edge Node dieselbe Definition verwendet. In der Praxis schleichen sich Abweichungen ein, wenn Nodes von verschiedenen Personen konfiguriert oder zu unterschiedlichen Zeiten aktualisiert werden. Diese Gewohnheiten verhindern das:
- Führen Sie eine zentrale Bibliothek von Definitionen unter Versionskontrolle und generieren Sie daraus die Edge-Node-Konfiguration.
- Setzen Sie das Feld
versionund erhöhen Sie es bei jeder Änderung an Membern, Datentypen oder Parametern. - Ändern Sie nie den Datentyp eines Members an Ort und Stelle; fügen Sie einen neuen Member oder eine neue Version hinzu.
- Verwenden Sie überall denselben Definitionsnamen, einschließlich Groß- und Kleinschreibung.
- Bilden Sie Unterschiede zwischen Anlagen über Parameter ab, nicht über zusätzliche Member.
- Vergleichen Sie nach dem Deployment die dekodierten NBIRTH-Definitionen jedes Nodes mit der Bibliothek.
- Rollen Sie neue Versionen Node für Node aus und bestätigen Sie, dass der Host während des Übergangs beide akzeptiert.
Bei Schritt 6 hilft eine dekodierte Ansicht. ConnectMQ dekodiert Sparkplug B im Topic-Explorer des Portals, sodass Sie das NBIRTH jedes Nodes öffnen und Definitionen vergleichen können, ohne ein Skript zu schreiben. Beachten Sie, dass Births angezeigt werden, wenn sie veröffentlicht werden; ist ein Node bereits online, fordern Sie ein Rebirth an, um sie zu sehen.
Häufige Probleme
| Symptom | Wahrscheinliche Ursache | Lösung |
|---|---|---|
| Host zeigt Instanz-Member als unbekannt an | Definition fehlt im NBIRTH | Definitionen im NBIRTH vor den Instanzen veröffentlichen |
| Instanz abgelehnt oder nur teilweise angezeigt | template_ref passt nicht zum Definitionsnamen | Exakter Name, Groß-/Kleinschreibung beachten |
| Derselbe Typ verhält sich je Node anders | Definitionen sind zwischen Nodes auseinandergedriftet | Zentrale Bibliothek und Versionsprüfungen |
| Births zu groß | Viele tief verschachtelte Instanzen | Abflachen, Devices aufteilen oder Plan-Limits prüfen |
| Manche Konsumenten ignorieren Templates | Werkzeug unterstützt Datentyp 19 nicht | Einen Host mit Template-Unterstützung nutzen oder für diesen Konsumenten abflachen |
Templates, ISA-95 und der Unified Namespace (UNS)
Templates modellieren, was eine Anlage ist; ISA-95 modelliert, wo sie steht. Beides ergänzt sich: ein Pump-Typ, instanziiert unter Standort, Bereich und Linie. Der Ort, an dem beides zusammenkommt, ist der UNS: Die ISA-95-Equipment-Hierarchie (Enterprise → Site → Area → Line → Cell) wird zur Topic-Struktur auf dem MQTT-Broker, etwa acme/werk-ludwigshafen/kuehlung/linie-1/kuehlpumpe-1/drehzahl, und jede Pumpe im Baum trägt dieselben Member, weil sie aus derselben Template-Definition stammt. So finden MES, Instandhaltung und Predictive-Maintenance-Modelle jede Pumpe am erwarteten Ort und im erwarteten Format. ConnectMQ kann Sparkplug-Daten in ISA-95-Topics wie connectmq/factory1/production/line1/cnc1/telemetry erneut veröffentlichen und gibt Konsumenten ohne Sparkplug-Unterstützung so eine lesbare, standortbasierte Sicht. Mehr zur Strukturierung von Anlagendaten finden Sie in MQTT, Sparkplug B und der Unified Namespace, in der Referenz zu den Sparkplug B Datentypen und im Grundlagenleitfaden zu Industrial IoT mit MQTT.
Starten Sie mit ConnectMQ
Betreiben Sie Ihre Template-basierten Edge Nodes auf einem verwalteten MQTT-Broker, ohne die Infrastruktur selbst zu betreiben, oder bauen Sie zuerst einen Prototyp auf dem öffentlichen MQTT-Broker mit einer zufälligen Group ID; er ist für Tests gedacht, nicht für echte Produktionsdaten. Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker, ganz ohne Kreditkarte, und prüfen Sie Ihre Template-Definitionen und -Instanzen dekodiert im Portal.
Häufig gestellte Fragen
Sind Sparkplug Templates dasselbe wie SPS-UDTs?
Sie erfüllen denselben Zweck: ein wiederverwendbarer Typ mit benannten, typisierten Membern. Viele Edge-Plattformen bilden UDTs aus SPS oder SCADA direkt auf Sparkplug Templates ab.
Wo müssen Template-Definitionen veröffentlicht werden?
Im NBIRTH, vor jeder Instanz, die auf sie verweist. Instanzen können dann im NBIRTH oder in DBIRTH-Nachrichten erscheinen.
Wofür werden Template-Parameter verwendet?
Parameter enthalten Konstanten pro Instanz wie Nenndrehzahl, Grenzwerte oder Typenschilddaten. Die Definition liefert Standardwerte, und jede Instanz kann sie überschreiben.
Unterstützen alle Sparkplug-Host-Anwendungen Templates?
Nein. Die Unterstützung variiert, prüfen Sie Ihren Host also, bevor Sie alles als Templates modellieren. Für Konsumenten ohne Unterstützung flachen Sie Member zu regulären Metriken ab oder nutzen eine lesbare, per ISA-95 erneut veröffentlichte Ansicht.



