UNS(Unified Namespace)コネクタ
**UNS(Unified Namespace)**コネクタは、コネクタ設定と受信ペイロードからISA-95に準拠したトピック階層を構築し、注入された_uns_topicキーを持つJSONペイロード、またはメトリクス配列内でデータをラップするSparkplugBスタイルのエンベロープを発行するプロセッサです。Walker ReynoldsとISA-95標準によって普及したUnified Namespaceにプラントデータを整理するための正準的な構成要素です。
コネクタタイプ:
UNS- ISA-95トピックでペイロードを装飾し、出力をJSONまたはSparkplugBとして再構築するステートレスプロセッサ
- ✅ ISA-95階層:エンタープライズ / サイト / エリア / ライン / セル
- ✅ オプションのペイロード駆動の動的トピックレベル(マッピング)
- ✅ 2つの出力形式:
json(パススルー +_uns_topic)とsparkplugb(メトリクス配列を持つエンベロープ) - ✅ 空の階層レベルを優雅にスキップ
- ✅ SparkplugB出力上のメッセージごとのタイムスタンプ(Unixミリ秒)
JSON出力を持つ静的ISA-95階層
Section titled “JSON出力を持つ静的ISA-95階層”{ "type": "UNS", "config": { "enterprise": "Acme", "site": "Milan", "area": "Assembly", "line": "Line1", "cell": "Station3", "outputFormat": "json" }}ペイロードからの動的トピックレベル
Section titled “ペイロードからの動的トピックレベル”{ "type": "UNS", "config": { "enterprise": "Acme", "site": "Milan", "area": "Assembly", "mappings": [ { "inputKey": "machine_id", "topicLevel": "machine" }, { "inputKey": "shift_id", "topicLevel": "shift" } ], "outputFormat": "json" }}SparkplugBエンベロープ出力
Section titled “SparkplugBエンベロープ出力”{ "type": "UNS", "config": { "enterprise": "Acme", "site": "Milan", "area": "Packaging", "line": "Line2", "outputFormat": "sparkplugb" }}設定パラメータ
Section titled “設定パラメータ”Enterprise
Section titled “Enterprise”必須。トップレベルのISA-95エンタープライズ(会社/部門名)。
{ "enterprise": "Acme" }必須。物理的なサイト(プラント、工場、建物)。
{ "site": "Milan" }オプション。サイト内の機能エリア。
{ "area": "Assembly" }オプション。エリア内の生産ライン。
{ "line": "Line1" }オプション。ライン内の特定のセルまたはワークステーション。
{ "cell": "Station3" }Mappings
Section titled “Mappings”オプション。ペイロードからトピックレベルへのマッピングの配列。各マッピングについて、コネクタはdata[inputKey]を検索し、<topicLevel>/<value>をトピックに追加します。
{ "mappings": [ { "inputKey": "machine_id", "topicLevel": "machine" }, { "inputKey": "shift_id", "topicLevel": "shift" } ]}動作:
- 各エントリには
inputKeyとtopicLevelの両方が必須 - 欠落した入力キーはエラーチャネル経由で報告され、トピックレベルは省略されます
- 非文字列の入力値は
fmt.Sprintf("%v", ...)で強制変換されます
Output Format
Section titled “Output Format”必須。以下のいずれかである必要があります:
json-_uns_topicが注入された元のペイロードのパススルーsparkplugb- メトリクスが{ name, value }ペアのリストである{ topic, timestamp, metrics }エンベロープ
{ "outputFormat": "sparkplugb" }トピック構築
Section titled “トピック構築”トピックレベルは/で結合されます。空のオプションレベル(エリア、ライン、セル)はスキップされます。マッピングは宣言された順序で表示されます。
例:
設定:
{ "enterprise": "Acme", "site": "Milan", "area": "Assembly", "line": "Line1", "mappings": [ { "inputKey": "machine_id", "topicLevel": "machine" } ]}受信ペイロード:
{ "machine_id": "M-007", "temperature": 24.5 }結果のトピック:
Acme/Milan/Assembly/Line1/machine/M-007出力ペイロードの例
Section titled “出力ペイロードの例”JSON出力
Section titled “JSON出力”入力:
{ "machine_id": "M-007", "temperature": 24.5, "pressure": 5.2}設定:
{ "enterprise": "Acme", "site": "Milan", "area": "Assembly", "line": "Line1", "mappings": [ { "inputKey": "machine_id", "topicLevel": "machine" } ], "outputFormat": "json"}出力:
{ "machine_id": "M-007", "temperature": 24.5, "pressure": 5.2, "_uns_topic": "Acme/Milan/Assembly/Line1/machine/M-007"}SparkplugBエンベロープ出力
Section titled “SparkplugBエンベロープ出力”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 } ]}timestampは処理時のUnixミリ秒です。metricsエントリの順序は保証されません(Goマップ反復は順不同)。
データフロー
Section titled “データフロー”DataPayload → UNS → DataPayload + _uns_topic(json) OR { topic, timestamp, metrics }(sparkplugb)一般的なユースケース
Section titled “一般的なユースケース”1. ISA-95トピックでPLCデータをMQTTにブリッジ
Section titled “1. ISA-95トピックでPLCデータをMQTTにブリッジ”生のPLCペイロードをUNS準拠のMQTTトピックに再構築:
{ "type": "UNS", "config": { "enterprise": "Acme", "site": "Detroit", "area": "Stamping", "line": "PressLine1", "outputFormat": "json" }}ダウンストリームのMqttV5Writerは、_uns_topicをMQTTトピックにマップするReshapeステップを介して_uns_topicをパブリッシュトピックとして使用します。
2. IgnitionまたはHiveMQのためのSparkplugBパブリッシュ
Section titled “2. IgnitionまたはHiveMQのためのSparkplugBパブリッシュ”多くのSCADAプラットフォーム(Ignition、HiveMQなど)はSparkplugBエンベロープを期待します。一致するようにsparkplugb出力を使用します:
{ "type": "UNS", "config": { "enterprise": "Acme", "site": "Milan", "area": "Bottling", "line": "Filler1", "outputFormat": "sparkplugb" }}3. 顧客によるマルチテナントトピックルーティング
Section titled “3. 顧客によるマルチテナントトピックルーティング”動的マッピングを使用してトピックに顧客識別子を埋め込む:
{ "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" }}{tenant_id: "T-1", site_id: "S-99", device_id: "D-42"}の結果のトピック:
ConnectCo/Cloud/tenant/T-1/customer-site/S-99/device/D-42トラブルシューティング
Section titled “トラブルシューティング”出力に_uns_topicが欠落
Section titled “出力に_uns_topicが欠落”問題: ダウンストリームコンシューマが_uns_topicキーを見ない
解決策:
outputFormat: jsonが設定されていることを確認(SparkplugBエンベロープはペイロード全体を置き換えます。_uns_topicの代わりにトップレベルにtopicがあります)- UNSコネクタが実際にパイプラインにあることを確認 — 中間ペイロードをダンプするために
Logライターを使用
input key %q not found in payloadエラー
Section titled “input key %q not found in payloadエラー”問題: 設定されたマッピングが、ペイロードに存在しないキーを参照している
解決策:
- 入力キーが上流のペイロードと正確に一致することを確認(大文字小文字を区別)
- 必要なキーが存在することを保証するために上流に
ReshapeまたはTransformを使用 - キーが時々欠落する場合、代わりに静的
area/line/cellの一部にすることを検討
SparkplugB出力に空のmetrics配列
Section titled “SparkplugB出力に空のmetrics配列”問題: 出力エンベロープが{ topic, timestamp, metrics: [] }
解決策:
- メトリクス配列は入力ペイロードのキーから構築されます。空の入力 → 空のメトリクス
- 上流コネクタが非空のペイロードを配信していることを確認
トピックに予期しないスラッシュまたは空のセグメント
Section titled “トピックに予期しないスラッシュまたは空のセグメント”問題: トピックに//または末尾のスラッシュが含まれている
解決策:
enterprise、siteなどにスラッシュを含めないでください — コネクタがそれらを挿入します。埋め込まれたスラッシュは不正な形式のパスを生成します- オプションレベルの空文字列を避けてください —
""を渡すのではなく、フィールドを未設定のままにします
SparkplugBメトリクスのソートに関する懸念
Section titled “SparkplugBメトリクスのソートに関する懸念”問題: メトリクスの順序が実行間で一貫していない
解決策:
- Goマップ反復は意図的に順不同です。ダウンストリームコンシューマが順序を気にする場合、このコネクタに到達する前にメトリクスを明示的なリストに変換する
Reshapeを介して上流でソートします - または、コンシューマに受信時に
nameでソートさせます
ベストプラクティス
Section titled “ベストプラクティス”1. UNSトピックを契約として扱う
Section titled “1. UNSトピックを契約として扱う”トピック階層はダッシュボード、ヒストリアン、その他のMeddleパイプラインによって消費されます。一度パブリッシュされると、安定したインターフェイスとして扱ってください — 事後にareaやlineをリネームすることはダウンストリームコンシューマを壊します。
2. 安定した階層には静的レベルを使用
Section titled “2. 安定した階層には静的レベルを使用”階層がペイロードに依存しない場合は、マッピングよりも静的enterprise/site/area/line/cellを優先します。マッピングは強力ですが、ペイロード形状への依存を追加します。
3. グリーンフィールドにはJSON、SCADAブリッジングにはSparkplugBを優先
Section titled “3. グリーンフィールドにはJSON、SCADAブリッジングにはSparkplugBを優先”jsonはよりシンプルで、任意のダウンストリームコンシューマで動作します。既存のSparkplugBエコシステム(Ignition、HiveMQ Edgeなど)と相互運用する必要がある場合のみsparkplugbを使用します。
4. MQTTの前にReshapeと組み合わせる
Section titled “4. MQTTの前にReshapeと組み合わせる”ほとんどのMQTTライターは、トピックを明示的に設定する必要があります。UNSコネクタの後、_uns_topicをパブリッシュトピックフィールドに昇格させるReshapeステップを使用します:
... → UNS → Reshape(_uns_topic → topicに移動) → MqttV5Writer5. 組織レベルでUNSをドキュメント化
Section titled “5. 組織レベルでUNSをドキュメント化”組織全体のためにISA-95スキーマを一度選び、すべてのサイトとラインにわたって一貫して適用します。Meddleデプロイメント間でのスキーマドリフトは、互換性のないトピックツリーを作成します。
ワークフロー例
Section titled “ワークフロー例”PLC → UNS → MQTT(クラウドブローカー)
Section titled “PLC → UNS → MQTT(クラウドブローカー)”ModbusReader → Reshape → UNS → Reshape → MqttV5Writer- ModbusReader: PLCから生のレジスタデータを取得
- Reshape: 生のアドレスを人間が読みやすいキーにリネーム
- UNS:
_uns_topicで装飾 - Reshape:
_uns_topicをMQTTtopicフィールドに昇格 - MqttV5Writer: UNSの下で整理されたクラウドブローカーにパブリッシュ
SparkplugBエッジゲートウェイ
Section titled “SparkplugBエッジゲートウェイ”OpcuaReader → Predictive → UNS(sparkplugb) → MqttV5Writer- OpcuaReader: 複数のOPC UAエンドポイントから集約
- Predictive: トレンド/RUL/ヘルススコアを追加
- UNS: 拡充されたペイロードをSparkplugBエンベロープでラップ
- MqttV5Writer: SparkplugB対応ブローカー(例:HiveMQ Edge → Ignition)にパブリッシュ
マルチサイト集約
Section titled “マルチサイト集約”[サイトAパイプライン] ─┐[サイトBパイプライン] ─┼─→ UNS → InfluxDb2Writer[サイトCパイプライン] ─┘各サイトパイプラインは独自のUNS設定でデータをラベル付けし、ダウンストリームコンシューマがトピックだけで曖昧さを解消できるようにします。
関連コネクタ
Section titled “関連コネクタ”- MQTT v5 - UNS装飾ペイロードをブローカーにパブリッシュ
- MQTT v3 - レガシーMQTTパブリッシング
- Reshape -
_uns_topicをライターのトピックフィールドに昇格 - Filter -
_uns_topicパターンでフィルタリング - Router - UNS階層に基づくブランチルーティング
追加リソース
Section titled “追加リソース”- ISA-95標準 - エンタープライズ制御システム統合
- Unified Namespace概念(Walker Reynolds) - 業界入門
- SparkplugB仕様(Eclipse Tahu) - 公式仕様PDF
- HiveMQ Sparkplugリソース - リファレンスブローカーとツール
- Ignition Sparkplugモジュール - SCADA統合の例