IoT industriel

Concevoir des topics MQTT basés sur l'ISA-95

Comment encoder la hiérarchie des équipements ISA-95 dans des topics MQTT : ordre des niveaux, conception des feuilles, planification des wildcards, choix de payload et pièges courants, ainsi que la republication des données Sparkplug B dans la même arborescence.

Diagramme de topics MQTT ISA-95 associant les niveaux entreprise, site, zone, ligne et machine à un chemin de topic
Essayez-le sur votre propre broker MQTTObtenez un broker MQTT privé et managé avec l’offre Free et partez d’exemples de code prêts à l’emploi.
Essayer gratuitement Exemples de code Aucune carte bancaire requise

Les topics MQTT ISA-95 placent la hiérarchie des équipements de l'usine directement dans le chemin du topic, si bien que acme/dallas/packaging/line-02/filler/telemetry indique à chaque abonné exactement d'où vient une valeur. Dans ce guide, vous verrez comment encoder chaque niveau ISA-95, comment concevoir la feuille du topic, comment planifier les abonnements avec wildcards avant d'en avoir besoin et quels pièges provoquent le plus de reprises une fois un namespace en production.

Pourquoi encoder l'ISA-95 dans les topics MQTT

Les topics MQTT sont des chaînes libres séparées par des slashs, et le broker MQTT ne leur attribue aucun sens au-delà de la correspondance avec les abonnements. Cette liberté est dangereuse à l'échelle d'une usine. Si chaque intégrateur invente sa propre structure, les consommateurs finissent avec une table de correspondance par source.

La hiérarchie des équipements ISA-95 résout ce problème en fournissant une structure qui existe déjà dans la documentation de l'usine, le MES et le système de maintenance. L'encoder dans les topics vous apporte trois propriétés gratuitement :

  • La découvrabilité. Quiconque connaît l'usine peut trouver une valeur en parcourant l'arborescence.
  • Le contexte. Le topic porte l'adresse de l'actif, les payloads n'ont donc pas besoin de la répéter.
  • L'abonnement sélectif. Les wildcards correspondent naturellement à des périmètres organisationnels : un site, une zone, toutes les remplisseuses.

Si vous avez besoin d'un rappel sur les niveaux eux-mêmes, lisez d'abord l'article sur la hiérarchie des équipements ISA-95.

Le modèle de base

Le modèle canonique place les niveaux du plus large au plus étroit, suivis d'un espace de noms qui indique le type de données contenu dans le message :

<enterprise>/<site>/<area>/<work center>/<work unit>/<namespace>[/<detail>]

acme/dallas/packaging/line-02/filler/telemetry
acme/dallas/packaging/line-02/filler/state
acme/dallas/packaging/line-02/filler/alarms
acme/dallas/packaging/line-02/filler/events/batch-complete
acme/dallas/packaging/line-02/filler/cmd/stop

Règles pour chaque niveau

Niveau Règle Exemple
Entreprise Un nom court et stable ; à omettre seulement si le broker ne sert qu'une seule société acme
Site Un code d'emplacement qui survit aux réorganisations dallas, izmir
Zone Zone fonctionnelle ou produit packaging, utilities
Centre de travail Ligne, cellule, cellule de process, unité ou zone de stockage line-02, cell-03
Unité de travail Machine ou unité, idéalement par numéro d'actif filler, cnc-01
Espace de noms Vocabulaire fixe telemetry, state, alarms, events, cmd

Gardez une profondeur fixe pour les topics d'équipement. Lorsque chaque unité de travail se trouve au niveau cinq, +/+/+/+/+/state renvoie l'état de toutes les machines de l'entreprise, et la position de chaque niveau dans le chemin est garantie.

Concevoir la feuille

L'espace de noms et tout ce qui le suit concentrent l'essentiel des débats de conception. Il existe deux grandes options pour la télémétrie.

Un objet par équipement. Toutes les valeurs courantes d'une machine vont dans un seul document JSON sur .../filler/telemetry. C'est compact, les valeurs liées restent cohérentes dans le temps, et il ne faut qu'un seul retained message par machine.

{ "ts": "2026-10-16T08:15:02Z", "speed_bpm": 118.4, "temp_c": 41.2, "good_count": 18342, "v": 1 }

Un topic par mesure. Chaque valeur a son propre topic, comme .../filler/telemetry/speed_bpm, avec un payload scalaire ou un petit JSON. Cela correspond naturellement aux outils orientés tags comme les systèmes SCADA, et les consommateurs peuvent s'abonner exactement aux signaux dont ils ont besoin.

Les deux sont valables. Choisissez par espace de noms et documentez-le. Un hybride courant consiste en un objet pour la télémétrie et des valeurs retenues par topic pour state et quelques KPI clés.

Planifier vos abonnements avec wildcards

Avant de figer la structure, notez les abonnements dont vos consommateurs auront besoin et vérifiez que chacun tient en un seul filtre avec wildcards :

Consommateur Besoin Abonnement
Tableau de bord de site Tout un site acme/dallas/#
Superviseur du conditionnement Tous les états d'une zone acme/dallas/packaging/+/+/state
Analytique de parc Toutes les remplisseuses, partout acme/+/+/+/filler/telemetry
Service d'alarmes Toutes les alarmes acme/+/+/+/+/alarms
Historian Toute la télémétrie acme/+/+/+/+/telemetry

Si un périmètre nécessaire exige plusieurs abonnements ou un filtrage côté client, la structure travaille contre vous. Cela signifie généralement qu'un niveau manque, que l'ordre est incohérent ou que le vocabulaire des feuilles est trop lâche.

Publier des topics ISA-95 depuis le code

Générer les topics en un seul endroit évite que des fautes de frappe créent des branches parasites. Ce helper Python construit et valide le chemin, puis publie l'état et la télémétrie retenus. Installez le client avec pip install "paho-mqtt>=2.0". Il utilise le serveur MQTT public gratuit avec un préfixe de démo ; sur un broker privé, définissez PREFIX avec le nom de votre entreprise.

import json
import re
import threading
from dataclasses import dataclass
from datetime import datetime, timezone

import paho.mqtt.client as mqtt

PREFIX = "connectmq/demo/r8t5"      # sur votre propre broker : "acme"
SAFE = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)*$")
NAMESPACES = {"telemetry", "state", "alarms", "events", "cmd"}

@dataclass(frozen=True)
class Asset:
    site: str
    area: str
    work_center: str
    work_unit: str

    def topic(self, namespace: str) -> str:
        for level in (self.site, self.area, self.work_center, self.work_unit):
            if not SAFE.match(level):
                raise ValueError(f"invalid level: {level!r}")
        if namespace not in NAMESPACES:
            raise ValueError(f"unknown namespace: {namespace!r}")
        return f"{PREFIX}/{self.site}/{self.area}/{self.work_center}/{self.work_unit}/{namespace}"

filler = Asset("dallas", "packaging", "line-02", "filler")

connected = threading.Event()

def on_connect(client, userdata, flags, reason_code, properties):
    print("connected:", reason_code)
    connected.set()

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="isa95-pub-r8t5")
client.on_connect = on_connect
client.connect("broker.connectmq.com", 1883, keepalive=60)
client.loop_start()
connected.wait(timeout=10)

client.publish(filler.topic("state"), "running", qos=1, retain=True).wait_for_publish()
telemetry = {"ts": datetime.now(timezone.utc).isoformat(), "speed_bpm": 118.4, "temp_c": 41.2, "v": 1}
client.publish(filler.topic("telemetry"), json.dumps(telemetry), qos=1, retain=True).wait_for_publish()
print("published to", filler.topic("telemetry"))

client.loop_stop()
client.disconnect()

Vérifiez avec un wildcard correspondant au tableau ci-dessus :

mosquitto_sub -h broker.connectmq.com -p 1883 -i isa95-sub-r8t5 -t "connectmq/demo/r8t5/+/packaging/+/+/state" -v

Le serveur MQTT public gratuit est lisible par tous et autorise 8 niveaux de topic, c'est pourquoi le préfixe de démo remplace ici le niveau entreprise. Réservez les vrais noms d'actifs et les vraies valeurs à un broker privé.

Intégrer Sparkplug B dans l'arborescence ISA-95

Les topics Sparkplug B suivent un format fixe, spBv1.0/<group>/<type>/<edge node>/<device>, avec des payloads Protobuf. Ils ne suivent pas l'ISA-95, et les consommateurs qui ne connaissent pas Sparkplug ne peuvent pas les lire. Plutôt que d'abandonner Sparkplug à l'edge, republiez ses données dans votre arborescence ISA-95.

ConnectMQ le fait automatiquement : il décode les payloads Sparkplug B, Protobuf ou JSON, et les republie dans des topics ISA-95. Par exemple, spBv1.0/factory1/DDATA/line1/cnc1 est republié sous connectmq/factory1/production/line1/cnc1/telemetry. Choisissez des identifiants de groupe et d'edge node Sparkplug qui portent des noms d'usine parlants, afin que les chemins ISA-95 obtenus soient lisibles. Les compromis entre les deux approches sont abordés dans MQTT, Sparkplug B et le Unified Namespace.

Pièges à éviter

  1. Slash initial. /acme/dallas crée un premier niveau vide et scinde les abonnements.
  2. Casse mixte. Les topics sont sensibles à la casse ; Line-02 et line-02 sont des branches différentes.
  3. Noms de protocole ou de fournisseur dans le chemin. acme/dallas/opcua/... lie les consommateurs à la technologie d'intégration du moment.
  4. Profondeur variable. Sauter un niveau pour une machine casse les wildcards positionnels. Utilisez plutôt un centre de travail de substitution.
  5. Horodatages ou identifiants dans les topics. Des topics comme .../telemetry/20261016 créent des branches sans limite et encombrent les retained messages.
  6. Retenir des événements. Retenez l'état, pas les flux d'événements ; un nouvel abonné ne doit pas recevoir un « batch complete » périmé.
  7. Des commandes sans requête ni réponse. Utilisez les response topics et les correlation data de MQTT 5 pour cmd, afin que le demandeur sache si la commande a réussi.
  8. Des chemins profonds sur des liaisons contraintes. Les topics longs ajoutent des octets à chaque message. Les topic aliases de MQTT 5 réduisent ce surcoût sans changer la conception.

Documenter la norme avant le déploiement

Une norme de topics qui n'existe que dans la tête d'un ingénieur sera enfreinte dès le deuxième intégrateur. Avant la mise en service de la première passerelle, rédigez une norme d'une page qui couvre :

  • L'ordre des niveaux et les caractères autorisés pour chacun.
  • La liste des espaces de noms et ce que chacun peut contenir, avec un exemple de payload.
  • Les topics retenus et ceux qui ne le sont pas.
  • Le format d'horodatage, le fuseau horaire et la convention d'unités.
  • Qui approuve les nouveaux sites, zones et centres de travail, et comment les demandes sont faites.

Remettez cette page à chaque intégrateur et à chaque fournisseur de passerelles, avec le helper de topics ci-dessus ou son équivalent dans leur langage. Lorsque la norme et le code concordent, la plupart des erreurs sont détectées avant même d'atteindre le broker.

La sécurité mérite une remarque à part : délivrez un identifiant par passerelle et par application pour que chaque publicateur soit identifiable et révocable, et utilisez TLS sur le port 8883 partout en dehors du labo. Nos bonnes pratiques de sécurité MQTT couvrent le reste.

Pour des arborescences complètes prêtes à copier, consultez la structure des topics UNS. Pour l'architecture qui les entoure, le guide MQTT pour l'IoT industriel est le point de départ.

Exploitez des topics MQTT ISA-95 sur ConnectMQ

ConnectMQ est un broker MQTT managé qui comprend les structures de topics industrielles : il détecte les topics ISA-95 et Unified Namespace, affiche les appareils par niveau ISA-95 dans le portail et republie Sparkplug B dans votre arborescence. Créez un broker avec l'offre gratuite Serverless sur app.connectmq.com, sans carte bancaire, et publiez votre première branche ISA-95 dès aujourd'hui.

Questions fréquentes

Le nom de l'entreprise doit-il être le premier niveau du topic ?

Oui, si le broker est susceptible de servir un jour plus d'une société ou d'une business unit. Pour un broker mono-société, vous pouvez l'omettre, mais l'ajouter plus tard implique de renommer tous les topics.

Comment gérer les machines qui n'appartiennent à aucune ligne ?

Attribuez-leur un centre de travail de substitution comme standalone ou shared pour qu'elles se trouvent à la même profondeur que tout le reste.

Peut-on utiliser des espaces ou des majuscules dans les topics MQTT ISA-95 ?

MQTT les autorise, mais ils provoquent des bugs subtils. Utilisez uniquement des lettres minuscules, des chiffres et des tirets.

Les topics ISA-95 fonctionnent-ils avec MQTT 3.1.1 ?

Oui. La conception des topics est indépendante de la version. MQTT 5 ajoute des compléments utiles comme les topic aliases et les response topics pour les commandes.

Articles liés

Tous les articles →

Votre broker MQTT privé, à quelques clics

Créez un compte, récupérez les identifiants de votre broker et connectez votre premier appareil — aucun serveur à installer, mettre à jour ou dimensionner.