UNS (Unified Namespace)-Konnektor
Übersicht
Abschnitt betitelt „Übersicht“Der UNS (Unified Namespace)-Konnektor ist ein Prozessor, der eine ISA-95-konforme Topic-Hierarchie aus der Konnektor-Konfiguration und der eingehenden Payload aufbaut und dann entweder eine JSON-Payload mit injiziertem _uns_topic-Schlüssel oder einen SparkplugB-artigen Umschlag ausgibt, der die Daten in einem Metrics-Array umhüllt. Es ist der kanonische Baustein für die Organisation von Anlagendaten in einem Unified Namespace, wie er von Walker Reynolds und dem ISA-95-Standard popularisiert wurde.
Konnektor-Typen:
UNS- Zustandsloser Prozessor, der Payloads mit einem ISA-95-Topic dekoriert und die Ausgabe als JSON oder SparkplugB umformt
Funktionen
Abschnitt betitelt „Funktionen“- ✅ ISA-95-Hierarchie: Enterprise / Site / Area / Line / Cell
- ✅ Optionale payload-gesteuerte dynamische Topic-Ebenen (Mappings)
- ✅ Zwei Ausgabeformate:
json(Passthrough +_uns_topic) undsparkplugb(Umschlag mit Metrics-Array) - ✅ Überspringt leere Hierarchieebenen elegant
- ✅ Pro-Nachricht-Zeitstempel (Unix-Millisekunden) bei SparkplugB-Ausgabe
Grundkonfiguration
Abschnitt betitelt „Grundkonfiguration“Statische ISA-95-Hierarchie mit JSON-Ausgabe
Abschnitt betitelt „Statische ISA-95-Hierarchie mit JSON-Ausgabe“{ "type": "UNS", "config": { "enterprise": "Acme", "site": "Milan", "area": "Assembly", "line": "Line1", "cell": "Station3", "outputFormat": "json" }}Dynamische Topic-Ebenen aus Payload
Abschnitt betitelt „Dynamische Topic-Ebenen aus Payload“{ "type": "UNS", "config": { "enterprise": "Acme", "site": "Milan", "area": "Assembly", "mappings": [ { "inputKey": "machine_id", "topicLevel": "machine" }, { "inputKey": "shift_id", "topicLevel": "shift" } ], "outputFormat": "json" }}SparkplugB-Umschlag-Ausgabe
Abschnitt betitelt „SparkplugB-Umschlag-Ausgabe“{ "type": "UNS", "config": { "enterprise": "Acme", "site": "Milan", "area": "Packaging", "line": "Line2", "outputFormat": "sparkplugb" }}Konfigurationsparameter
Abschnitt betitelt „Konfigurationsparameter“Enterprise
Abschnitt betitelt „Enterprise“Erforderlich. Das ISA-95-Top-Level-Unternehmen (Firmen-/Divisionsname).
{ "enterprise": "Acme" }Erforderlich. Der physische Standort (Anlage, Werk, Gebäude).
{ "site": "Milan" }Optional. Ein funktionaler Bereich innerhalb des Standorts.
{ "area": "Assembly" }Optional. Eine Produktionslinie innerhalb des Bereichs.
{ "line": "Line1" }Optional. Eine spezifische Zelle oder Arbeitsstation innerhalb der Linie.
{ "cell": "Station3" }Mappings
Abschnitt betitelt „Mappings“Optional. Ein Array von Payload-zu-Topic-Ebenen-Mappings. Für jedes Mapping sucht der Konnektor data[inputKey] und hängt <topicLevel>/<value> an das Topic an.
{ "mappings": [ { "inputKey": "machine_id", "topicLevel": "machine" }, { "inputKey": "shift_id", "topicLevel": "shift" } ]}Verhalten:
- Sowohl
inputKeyals auchtopicLevelsind für jeden Eintrag erforderlich - Fehlende Eingabeschlüssel werden über den Fehlerkanal gemeldet; die Topic-Ebene wird weggelassen
- Nicht-String-Eingabewerte werden mit
fmt.Sprintf("%v", ...)konvertiert
Output Format
Abschnitt betitelt „Output Format“Erforderlich. Muss einer der folgenden sein:
json- Passthrough der ursprünglichen Payload mit eingefügtem_uns_topicsparkplugb- Umschlag{ topic, timestamp, metrics }, wobei metrics eine Liste von{ name, value }-Paaren ist
{ "outputFormat": "sparkplugb" }Topic-Konstruktion
Abschnitt betitelt „Topic-Konstruktion“Topic-Ebenen werden mit / verbunden. Leere optionale Ebenen (Area, Line, Cell) werden übersprungen. Mappings erscheinen in der Reihenfolge, in der sie deklariert sind.
Beispiel:
Konfiguration:
{ "enterprise": "Acme", "site": "Milan", "area": "Assembly", "line": "Line1", "mappings": [ { "inputKey": "machine_id", "topicLevel": "machine" } ]}Eingehende Payload:
{ "machine_id": "M-007", "temperature": 24.5 }Resultierendes Topic:
Acme/Milan/Assembly/Line1/machine/M-007Beispiele für Ausgabe-Payloads
Abschnitt betitelt „Beispiele für Ausgabe-Payloads“JSON-Ausgabe
Abschnitt betitelt „JSON-Ausgabe“Eingabe:
{ "machine_id": "M-007", "temperature": 24.5, "pressure": 5.2}Konfiguration:
{ "enterprise": "Acme", "site": "Milan", "area": "Assembly", "line": "Line1", "mappings": [ { "inputKey": "machine_id", "topicLevel": "machine" } ], "outputFormat": "json"}Ausgabe:
{ "machine_id": "M-007", "temperature": 24.5, "pressure": 5.2, "_uns_topic": "Acme/Milan/Assembly/Line1/machine/M-007"}SparkplugB-Umschlag-Ausgabe
Abschnitt betitelt „SparkplugB-Umschlag-Ausgabe“Gleiche Eingabe und Basiskonfiguration mit outputFormat: sparkplugb:
{ "topic": "Acme/Milan/Assembly/Line1/machine/M-007", "timestamp": 1747740875123, "metrics": [ { "name": "machine_id", "value": "M-007" }, { "name": "temperature", "value": 24.5 }, { "name": "pressure", "value": 5.2 } ]}Der timestamp ist Unix-Millisekunden zum Verarbeitungszeitpunkt. Beachten Sie, dass die Reihenfolge der metrics-Einträge nicht garantiert ist (Go-Map-Iteration ist ungeordnet).
Datenfluss
Abschnitt betitelt „Datenfluss“DataPayload → UNS → DataPayload + _uns_topic (json) ODER { topic, timestamp, metrics } (sparkplugb)Häufige Anwendungsfälle
Abschnitt betitelt „Häufige Anwendungsfälle“1. Überbrückung von SPS-Daten zu MQTT mit ISA-95-Topic
Abschnitt betitelt „1. Überbrückung von SPS-Daten zu MQTT mit ISA-95-Topic“Rohe SPS-Payloads in ein UNS-konformes MQTT-Topic umformen:
{ "type": "UNS", "config": { "enterprise": "Acme", "site": "Detroit", "area": "Stamping", "line": "PressLine1", "outputFormat": "json" }}Ein nachgelagerter MqttV5Writer verwendet dann _uns_topic als Publish-Topic über einen Reshape-Schritt, der _uns_topic → MQTT-Topic abbildet.
2. SparkplugB-Veröffentlichung für Ignition oder HiveMQ
Abschnitt betitelt „2. SparkplugB-Veröffentlichung für Ignition oder HiveMQ“Viele SCADA-Plattformen (Ignition, HiveMQ usw.) erwarten SparkplugB-Umschläge. Verwenden Sie die sparkplugb-Ausgabe zur Übereinstimmung:
{ "type": "UNS", "config": { "enterprise": "Acme", "site": "Milan", "area": "Bottling", "line": "Filler1", "outputFormat": "sparkplugb" }}3. Mandantenübergreifendes Topic-Routing nach Kunde
Abschnitt betitelt „3. Mandantenübergreifendes Topic-Routing nach Kunde“Dynamische Mappings verwenden, um die Kundenkennung in das Topic einzubetten:
{ "type": "UNS", "config": { "enterprise": "ConnectCo", "site": "Cloud", "mappings": [ { "inputKey": "tenant_id", "topicLevel": "tenant" }, { "inputKey": "site_id", "topicLevel": "customer-site" }, { "inputKey": "device_id", "topicLevel": "device" } ], "outputFormat": "json" }}Resultierendes Topic für {tenant_id: "T-1", site_id: "S-99", device_id: "D-42"}:
ConnectCo/Cloud/tenant/T-1/customer-site/S-99/device/D-42Fehlerbehebung
Abschnitt betitelt „Fehlerbehebung“Fehlendes _uns_topic in der Ausgabe
Abschnitt betitelt „Fehlendes _uns_topic in der Ausgabe“Problem: Der nachgelagerte Verbraucher sieht den _uns_topic-Schlüssel nicht
Lösungen:
- Bestätigen, dass
outputFormat: jsongesetzt ist (der SparkplugB-Umschlag ersetzt die Payload vollständig; er hattopicauf der obersten Ebene anstelle von_uns_topic) - Überprüfen, dass der UNS-Konnektor tatsächlich in der Pipeline ist — einen
Log-Writer verwenden, um Zwischen-Payloads auszugeben
input key %q not found in payload-Fehler
Abschnitt betitelt „input key %q not found in payload-Fehler“Problem: Ein konfiguriertes Mapping referenziert einen Schlüssel, der nicht in der Payload vorhanden ist
Lösungen:
- Überprüfen, ob der Eingabeschlüssel exakt mit der vorgelagerten Payload übereinstimmt (Groß-/Kleinschreibung beachten)
- Einen
ReshapeoderTransformvorgelagert verwenden, um sicherzustellen, dass erforderliche Schlüssel existieren - Wenn der Schlüssel manchmal fehlt, erwägen Sie, ihn als Teil des statischen
area/line/cellzu machen
SparkplugB-Ausgabe hat leeres metrics-Array
Abschnitt betitelt „SparkplugB-Ausgabe hat leeres metrics-Array“Problem: Ausgabeumschlag ist { topic, timestamp, metrics: [] }
Lösungen:
- Das Metrics-Array wird aus den Schlüsseln der Eingabe-Payload erstellt. Eine leere Eingabe → leeres Metrics
- Überprüfen, dass der vorgelagerte Konnektor nicht-leere Payloads liefert
Topic hat unerwartete Schrägstriche oder leere Segmente
Abschnitt betitelt „Topic hat unerwartete Schrägstriche oder leere Segmente“Problem: Topic enthält // oder Trailing-Slashes
Lösungen:
- Schließen Sie keine Schrägstriche in
enterprise,siteusw. ein — der Konnektor fügt sie ein. Eingebettete Schrägstriche erzeugen fehlerhafte Pfade - Vermeiden Sie leere Strings für optionale Ebenen — lassen Sie das Feld ungesetzt, anstatt
""zu übergeben
Sortierungsbedenken bei SparkplugB-Metrics
Abschnitt betitelt „Sortierungsbedenken bei SparkplugB-Metrics“Problem: Metrics-Reihenfolge ist zwischen Läufen inkonsistent
Lösungen:
- Go-Map-Iteration ist absichtlich ungeordnet. Wenn nachgelagerten Verbrauchern die Reihenfolge wichtig ist, vorgelagert über einen
Reshapesortieren, der die Metrics in eine explizite Liste konvertiert, bevor sie diesen Konnektor erreichen - Oder lassen Sie den Verbraucher beim Empfang nach
namesortieren
Best Practices
Abschnitt betitelt „Best Practices“1. Das UNS-Topic als Vertrag behandeln
Abschnitt betitelt „1. Das UNS-Topic als Vertrag behandeln“Die Topic-Hierarchie wird von Dashboards, Historien und anderen Meddle-Pipelines konsumiert. Sobald veröffentlicht, behandeln Sie sie als stabile Schnittstelle — das nachträgliche Umbenennen von area oder line bricht nachgelagerte Verbraucher.
2. Statische Ebenen für stabile Hierarchien verwenden
Abschnitt betitelt „2. Statische Ebenen für stabile Hierarchien verwenden“Bevorzugen Sie statische enterprise/site/area/line/cell gegenüber Mappings, wann immer die Hierarchie nicht von der Payload abhängt. Mappings sind mächtig, fügen aber eine Abhängigkeit von der Payload-Form hinzu.
3. JSON für Greenfield, SparkplugB für SCADA-Bridging bevorzugen
Abschnitt betitelt „3. JSON für Greenfield, SparkplugB für SCADA-Bridging bevorzugen“json ist einfacher und funktioniert mit jedem nachgelagerten Verbraucher. Verwenden Sie sparkplugb nur, wenn Sie mit einem bestehenden SparkplugB-Ökosystem (Ignition, HiveMQ Edge usw.) interoperieren müssen.
4. Mit einem Reshape vor MQTT kombinieren
Abschnitt betitelt „4. Mit einem Reshape vor MQTT kombinieren“Die meisten MQTT-Writer erfordern, dass das Topic explizit gesetzt wird. Nach dem UNS-Konnektor einen Reshape-Schritt verwenden, der _uns_topic in das Publish-Topic-Feld befördert:
... → UNS → Reshape (verschiebe _uns_topic → topic) → MqttV5Writer5. UNS auf Organisationsebene dokumentieren
Abschnitt betitelt „5. UNS auf Organisationsebene dokumentieren“Wählen Sie einmal ein ISA-95-Schema für die gesamte Organisation und wenden Sie es konsistent über alle Standorte und Linien an. Schema-Drift über Meddle-Bereitstellungen erzeugt inkompatible Topic-Bäume.
Beispiel-Workflows
Abschnitt betitelt „Beispiel-Workflows“SPS → UNS → MQTT (Cloud-Broker)
Abschnitt betitelt „SPS → UNS → MQTT (Cloud-Broker)“ModbusReader → Reshape → UNS → Reshape → MqttV5Writer- ModbusReader: Holt rohe Registerdaten von einer SPS
- Reshape: Benennt Roh-Adressen in menschenlesbare Schlüssel um
- UNS: Dekoriert mit
_uns_topic - Reshape: Befördert
_uns_topicin das MQTT-topic-Feld - MqttV5Writer: Veröffentlicht in einem Cloud-Broker, organisiert unter dem UNS
SparkplugB-Edge-Gateway
Abschnitt betitelt „SparkplugB-Edge-Gateway“OpcuaReader → Predictive → UNS (sparkplugb) → MqttV5Writer- OpcuaReader: Aggregiert von mehreren OPC UA-Endpunkten
- Predictive: Fügt Trend/RUL/Gesundheitsscore hinzu
- UNS: Umhüllt die angereicherte Payload in einem SparkplugB-Umschlag
- MqttV5Writer: Veröffentlicht in einem SparkplugB-fähigen Broker (z.B. HiveMQ Edge → Ignition)
Multi-Standort-Aggregation
Abschnitt betitelt „Multi-Standort-Aggregation“[Standort A Pipeline] ─┐[Standort B Pipeline] ─┼─→ UNS → InfluxDb2Writer[Standort C Pipeline] ─┘Jede Standort-Pipeline kennzeichnet ihre Daten mit ihrer eigenen UNS-Konfiguration, sodass nachgelagerte Verbraucher allein anhand des Topics unterscheiden können.
Verwandte Konnektoren
Abschnitt betitelt „Verwandte Konnektoren“- MQTT v5 - UNS-dekorierte Payloads an einen Broker veröffentlichen
- MQTT v3 - Legacy-MQTT-Veröffentlichung
- Reshape -
_uns_topicin das Topic-Feld des Writers befördern - Filter - Nach
_uns_topic-Mustern filtern - Router - Verzweigung basierend auf der UNS-Hierarchie
Zusätzliche Ressourcen
Abschnitt betitelt „Zusätzliche Ressourcen“- ISA-95-Standard - Enterprise-Control System Integration
- Unified Namespace-Konzept (Walker Reynolds) - Branchenprimer
- SparkplugB-Spezifikation (Eclipse Tahu) - Offizielles Spec-PDF
- HiveMQ Sparkplug-Ressourcen - Referenz-Broker und Tools
- Ignition Sparkplug-Modul - SCADA-Integrationsbeispiel