Notions de base

Sparkplug B expliqué : MQTT pour l’IoT industriel

Sparkplug B expliqué : l’espace de noms spBv1.0, les messages NBIRTH/NDEATH et DATA/CMD, les payloads Protobuf, bdSeq et seq, et la Primary Host Application.

Mis à jour · 8 min de lecture

MQTT est volontairement neutre : n’importe quel topic, n’importe quel payload. Cette souplesse pose problème en usine, où un SCADA d’un fournisseur doit comprendre les données de passerelles d’automates conçues par un autre. Sparkplug B comble ce manque. C’est une spécification ouverte, maintenue par le Sparkplug Working Group de la fondation Eclipse, qui définit comment utiliser MQTT pour l’IoT industriel : une structure de topics fixe, un format de payload binaire et des règles permettant de savoir si chaque appareil est en ligne. La version 3.0 de la spécification est également publiée en tant que norme internationale ISO/IEC 20237.

Si vous découvrez le protocole sous-jacent, commencez par qu’est-ce que MQTT.

Les composants d’un système Sparkplug

  • Serveur MQTT — n’importe quel broker conforme MQTT 3.1.1 ou 5.
  • Edge Node — une passerelle ou un appareil qui se connecte à MQTT, par exemple une passerelle d’automate. Il publie ses propres données et celles des appareils situés derrière lui.
  • Device — un capteur, un automate ou une machine rattaché à un Edge Node. Les devices ne se connectent pas eux-mêmes à MQTT ; l’Edge Node parle en leur nom.
  • Host Application — un consommateur comme un SCADA, un MES ou un historian qui s’abonne aux données et envoie des commandes. L’une d’elles peut être désignée comme Primary Host Application.

L’espace de noms des topics Sparkplug

Chaque topic Sparkplug B suit la même structure :

Structure des topics
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 — l’espace de noms et la version de la définition du payload.
  • group_id — un regroupement logique d’Edge Nodes, comme un site ou une ligne de production.
  • message_type — l’un des types de messages ci-dessous.
  • edge_node_id et le device_id facultatif — identifient l’éditeur.

La structure étant fixe, les consommateurs peuvent s’abonner avec des jokers (wildcards) comme spBv1.0/Plant1/+/# ou spBv1.0/+/DDATA/#. Collez-les dans le testeur de topics pour vérifier ce qu’ils ciblent, ou lisez topics et jokers MQTT pour les règles.

Types de messages

TypePublié parRôle
NBIRTHEdge NodeAnnonce que le nœud est en ligne ; liste toutes ses métriques avec noms, types et valeurs courantes
NDEATHEdge Node (via Last Will)Annonce que le nœud est hors ligne
DBIRTHEdge NodeAnnonce qu’un device est en ligne, avec la liste complète de ses métriques
DDEATHEdge NodeAnnonce qu’un device est hors ligne
NDATA / DDATAEdge NodeValeurs modifiées des métriques du nœud ou du device (report by exception)
NCMD / DCMDHost ApplicationCommandes vers un nœud ou un device, par ex. écrire une consigne ou demander un rebirth
STATEHost ApplicationAnnonce si une Host Application est en ligne

Sparkplug repose sur le report by exception (remontée sur changement) : une fois que le message BIRTH a établi toutes les métriques, les messages DATA ne transportent que les valeurs qui ont changé. Un consommateur qui arrive en retard, ou qui perd le fil, peut demander un nouveau BIRTH en envoyant un NCMD qui positionne la métrique Node Control/Rebirth à true.

État de session : NDEATH, bdSeq et seq

L’atout majeur de Sparkplug, c’est qu’un host sait toujours si les données sont à jour. Il s’appuie sur le Last Will and Testament de MQTT :

  1. Lorsque l’Edge Node se connecte, il enregistre un message NDEATH comme will. Ce will transporte une métrique bdSeq (séquence birth/death).
  2. Juste après la connexion, il publie un NBIRTH avec le même bdSeq, suivi d’un DBIRTH pour chaque device.
  3. Si le nœud décroche, le broker publie le will NDEATH. Le host compare son bdSeq à celui du dernier NBIRTH et marque comme périmées toutes les métriques de ce nœud et de ses devices.

bdSeq s’incrémente à chaque nouvelle session MQTT (en revenant à 0 après 255), de sorte qu’un NDEATH tardif provenant d’une ancienne connexion ne soit pas pris pour la mort de la connexion actuelle.

Par ailleurs, chaque message publié par un Edge Node porte un numéro seq de 0 à 255. NBIRTH commence à 0 et chaque message suivant l’incrémente, en revenant à 0 après 255. Si un host constate un trou, il sait qu’un message a été perdu et peut demander un rebirth.

La Primary Host Application et STATE

Les données n’ont de valeur que si quelqu’un les enregistre. Une Primary Host Application publie un message STATE retenu (et enregistre un STATE hors ligne comme will). Les Edge Nodes configurés avec un primary host attendent qu’il soit en ligne avant de publier leurs births ; s’il passe hors ligne, ils se déconnectent et peuvent stocker les données localement ou basculer vers un autre serveur MQTT jusqu’à son retour. Dans Sparkplug 3.0, le topic est spBv1.0/STATE/<host_id> avec un petit payload JSON :

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

Les anciens déploiements 2.x utilisaient le topic STATE/<host_id> avec une simple chaîne ONLINE/OFFLINE.

Payloads Protobuf

Les payloads Sparkplug B sont encodés avec Google Protocol Buffers. Un payload comporte un horodatage, un seq et une liste de métriques. Chaque métrique possède un nom, un type de données, une valeur, un horodatage facultatif et un alias numérique facultatif. Les alias sont déclarés dans le BIRTH ; les messages DATA peuvent ensuite envoyer l’alias au lieu du nom complet, ce qui garde les messages compacts.

Un payload DDATA décodé
timestamp: 1760140800123
seq: 17
metrics {
  alias: 4            # "Press-3/Hydraulic/Pressure" in DBIRTH
  timestamp: 1760140800120
  datatype: Float
  float_value: 182.4
}

L’encodage binaire produit des payloads compacts, ce qui compte sur les liaisons contraintes ; vous pouvez estimer la taille des paquets avec le calculateur de taille de paquet MQTT. L’inconvénient : un client générique affiche des octets bruts. Vous pouvez néanmoins en utiliser un pour vérifier que les births et deaths arrivent sur les bons topics :

Observer un espace de noms Sparkplug dans le client en ligne

Les paramètres MQTT utilisés par Sparkplug

  • QoS 0 pour les messages NBIRTH/DBIRTH, DATA et CMD ; QoS 1 pour le will NDEATH et STATE.
  • Retain à false pour tout, sauf STATE, qui est retenu.
  • Sessions propres pour les Edge Nodes (Clean Session à true en 3.1.1, ou Clean Start à true avec une expiration de session à 0 en MQTT 5). Sparkplug gère lui-même l’état via les births et rebirths : il ne s’appuie donc pas sur les sessions persistantes.

Démarrer avec Eclipse Tahu

Eclipse Tahu est l’implémentation de référence de Sparkplug, avec la définition Protobuf et des bibliothèques clientes pour Java, C, Python et JavaScript. Elle gère l’encodage, les alias et les numéros de séquence pour que vous puissiez vous concentrer sur vos métriques. Le Sparkplug Working Group publie aussi un Technology Compatibility Kit (TCK) pour tester la conformité des implémentations à la spécification.

Considérations de sécurité

Comme les commandes Sparkplug peuvent écrire des consignes sur de vraies machines, traitez l’accès aux topics NCMD et DCMD comme critique pour la sécurité. Utilisez TLS, des identifiants uniques par Edge Node et des ACL qui n’autorisent chaque nœud à publier que sous son propre edge_node_id. Nos bonnes pratiques de sécurité MQTT détaillent ces points.

Questions fréquentes

Quelle est la différence entre MQTT et Sparkplug B ?

MQTT est un protocole de transport qui achemine des octets sur des topics sans définir la signification des topics ni des payloads. Sparkplug B est une spécification au-dessus de MQTT qui définit un espace de noms de topics fixe, un format de payload Protobuf et une gestion de l’état des sessions, afin que des appareils industriels et des systèmes SCADA de fournisseurs différents puissent interopérer.

Sparkplug B nécessite-t-il un broker MQTT spécial ?

Non. Sparkplug B fonctionne avec tout broker conforme MQTT 3.1.1 ou MQTT 5 qui prend en charge la QoS, les messages retenus et le Last Will. Certains brokers proposent des fonctionnalités optionnelles dédiées à Sparkplug, mais elles ne sont pas nécessaires au fonctionnement de base.

Pourquoi les messages Sparkplug B sont-ils illisibles dans mon client MQTT ?

Les payloads Sparkplug B sont des Google Protocol Buffers binaires, pas du JSON ni du texte. Un client MQTT générique les affiche comme des octets bruts. Il vous faut un outil compatible Sparkplug ou une bibliothèque comme Eclipse Tahu pour les décoder en métriques.