Die MES-MQTT-Integration ersetzt das Geflecht aus individuellen Schnittstellen zwischen einem Manufacturing Execution System und dem Shopfloor durch einen einzigen ereignisgesteuerten Namespace. Dieser Leitfaden zeigt, wie Sie Topics für Fertigungsaufträge, Stückzahlen und Prüfergebnisse strukturieren, was die Payloads enthalten sollten und wie Sie einen kleinen Adapter schreiben, der ein MES mit einem MQTT-Broker verbindet.
Warum die MES-Integration meist der schwierigste Teil ist
Ein Manufacturing Execution System erfasst, was produziert wird, auf welcher Anlage, von wem und mit welchem Ergebnis. Dafür braucht es Daten von den Maschinen und muss Anweisungen zurückschicken. Traditionell geschieht das über Punkt-zu-Punkt-Verbindungen: hier eine OPC-Verbindung, dort eine Datenbanktabelle, die minütlich abgefragt wird, anderswo eine CSV-Datei, die eine Linien-SPS auf einem Netzlaufwerk ablegt.
Jede dieser Verbindungen funktioniert für sich, doch zusammen erzeugen sie Probleme, die jeder Anlageningenieur kennt:
- Ein zweiter Abnehmer (ein OEE-Dashboard, ein Instandhaltungssystem) bedeutet eine weitere Schnittstelle zur selben Maschine.
- Polling erzeugt Verzögerung und Last; eine Stückzahl ist nur so aktuell wie die letzte Abfrage.
- Wird das MES aktualisiert oder ersetzt, brechen alle Schnittstellen gleichzeitig.
- Niemand hat einen zentralen Ort, an dem sichtbar ist, welche Daten tatsächlich fließen.
Ein ereignisgesteuerter Ansatz kehrt das um. Maschinen und Gateways publizieren, was passiert, in dem Moment, in dem es passiert. Das MES abonniert die Ereignisse, die es braucht, und publiziert seine eigenen Entscheidungen, etwa einen freigegebenen Fertigungsauftrag. Andere Systeme abonnieren dieselben Ereignisse, ohne das MES anzufassen. Wenn Sie unsicher sind, wo das MES im Verhältnis zu ERP und SCADA steht, lesen Sie zuerst MES vs. ERP vs. SCADA.
So funktioniert die MES-MQTT-Integration
Das zentrale Element ist ein MQTT-Broker, mit dem sich alle Teilnehmer als Client verbinden. Niemand verbindet sich direkt mit jemand anderem. Drei Flüsse decken die meisten MES-Anforderungen ab:
| Fluss | Richtung | Beispiel-Topic | Typische QoS |
|---|---|---|---|
| Auftragsfreigabe | MES zur Linie | acme/plant1/assembly/line2/mes/order/current |
1, retained |
| Stückzahlen | Maschine zum MES | acme/plant1/assembly/line2/cell3/count |
1 |
| Maschinenzustand | Maschine zum MES | acme/plant1/assembly/line2/cell3/state |
1, retained |
| Prüfergebnisse | Prüfstation zum MES | acme/plant1/assembly/line2/qc1/result |
1 |
| Auftragsbestätigung | Linie zum MES | acme/plant1/assembly/line2/mes/order/ack |
1 |
Der Topic-Pfad folgt der ISA-95-Anlagenhierarchie (Enterprise, Site, Area, Line, Cell), dem Rückgrat eines Unified Namespace (UNS). Jede ISA-95-Ebene wird zu einer Ebene im Topic-Baum des UNS auf dem Broker, in einem deutschen Werk etwa acme/werk-stuttgart/montage/linie-2/zelle-3/count. Die Details dieser Benennung behandelt der Beitrag Unified Namespace aufbauen.
Zwei MQTT-Funktionen sind für MES-Verkehr besonders wichtig:
- Retained Messages. Der aktuelle Fertigungsauftrag und der aktuelle Maschinenzustand werden als retained message gespeichert, sodass ein HMI nach einem Neustart sofort weiß, was zu fertigen ist, ohne das MES zu fragen.
- QoS 1. Stückzahlen und Prüfergebnisse dürfen nicht verloren gehen und werden daher mit At-least-once-Zustellung publiziert. Das MES muss folglich mit Duplikaten umgehen, üblicherweise über eine Sequenznummer pro Publisher.
Payload-Verträge, die Änderungen überstehen
Topics sagen Ihnen, woher ein Ereignis kommt; Payloads sagen Ihnen, was passiert ist. Vereinbaren Sie pro Ereignistyp einen Vertrag und versionieren Sie ihn. Ein Stückzahl-Ereignis, dem ein MES vertrauen kann, sieht so aus:
{
"schema": "count/v1",
"ts": "2026-10-16T08:42:13.512Z",
"seq": 18233,
"orderId": "WO-2026-04417",
"material": "HSG-220-B",
"good": 1,
"scrap": 0,
"source": "cell3-plc"
}
Einige Regeln machen diese Verträge robust:
- Inkremente oder Summen senden, nicht beides. Inkremente mit Sequenznummer lassen sich leicht deduplizieren; Summen lassen sich nach einer Lücke leicht wiederherstellen. Wählen Sie pro Signal eine Variante und dokumentieren Sie sie.
- Die Auftrags-ID mitführen. Die Linie kennt den aktiven Auftrag bereits aus dem retained Auftrags-Topic. Wird sie in jedes Ereignis gestempelt, spart sich das MES eine Abfrage, und beim Auftragswechsel werden keine Stückzahlen falsch zugeordnet.
- An der Quelle zeitstempeln, in UTC mit Millisekunden.
- Ein Schema-Feld mitsenden, damit Abnehmer
count/v2verarbeiten können, ohne zu brechen.
Ein funktionierender MES-Adapter in Python
Die meisten MES-Produkte bieten eine REST-API oder eine Datenbankschnittstelle statt MQTT. Ein kleiner Adapter verbindet beides: Er abonniert Shopfloor-Ereignisse, ruft das MES auf und publiziert MES-Entscheidungen zurück in den Namespace. Das folgende Beispiel nutzt paho-mqtt 2.x und eine Platzhalterfunktion post_to_mes, die Sie durch Ihren MES-API-Aufruf ersetzen.
import json
import uuid
import paho.mqtt.client as mqtt
LINE = "connectmq/demo/mes-5c21/line2" # in Produktion den vollständigen ISA-95-Pfad verwenden
last_seq = {}
def post_to_mes(kind, event):
# Durch einen Aufruf Ihrer MES-API ersetzen, z. B. requests.post(...)
print(f"MES <- {kind}: {event}")
def release_order(client, order_id, material, quantity):
order = {"schema": "order/v1", "orderId": order_id,
"material": material, "quantity": quantity, "status": "RELEASED"}
client.publish(f"{LINE}/mes/order/current", json.dumps(order), qos=1, retain=True)
def on_connect(client, userdata, flags, reason_code, properties):
print("Connected:", reason_code)
client.subscribe(f"{LINE}/+/count", qos=1)
client.subscribe(f"{LINE}/+/state", qos=1)
client.subscribe(f"{LINE}/+/result", qos=1)
client.subscribe(f"{LINE}/mes/order/ack", qos=1)
release_order(client, "WO-2026-04417", "HSG-220-B", 500)
def on_message(client, userdata, msg):
event = json.loads(msg.payload)
kind = msg.topic.rsplit("/", 1)[-1]
source = msg.topic.split("/")[-2]
seq = event.get("seq")
if seq is not None:
key = (source, kind)
if seq <= last_seq.get(key, -1):
return # Duplikat aus einer QoS-1-Neuzustellung
last_seq[key] = seq
post_to_mes(kind, {"source": source, **event})
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
client_id=f"mes-adapter-{uuid.uuid4().hex[:8]}")
client.on_connect = on_connect
client.on_message = on_message
client.connect("broker.connectmq.com", 1883, keepalive=30)
client.loop_forever()
Testen Sie ihn gegen den Öffentlichen MQTT-Broker, indem Sie eine Stückzahl über die Kommandozeile publizieren:
mosquitto_pub -h broker.connectmq.com -p 1883 -i cell3-test-5c21 -q 1 \
-t "connectmq/demo/mes-5c21/line2/cell3/count" \
-m '{"schema":"count/v1","seq":1,"orderId":"WO-2026-04417","good":1,"scrap":0}'
Publizieren Sie dieselbe Nachricht zweimal, leitet der Adapter sie nur einmal weiter. Denken Sie daran, dass der öffentliche MQTT-Broker für alle lesbar ist und nur für Tests und Prototypen gedacht ist; verwenden Sie daher nur erfundene Auftragsnummern.
In Produktion sollten Sie den Deduplizierungszustand (last_seq) dauerhaft speichern, den Adapter mit einer persistenten Session betreiben, damit er Ereignisse erhält, die während eines Neustarts in der Warteschlange lagen, und ihm eigene Zugangsdaten geben.
Integrationsmuster und Stolperfallen
Befehle brauchen Bestätigungen. Gibt das MES einen Auftrag frei, sollte die Linie eine Bestätigung mit Auftrags-ID und Status publizieren (angenommen, abgelehnt, gestartet). Ohne sie kann das MES nicht erkennen, ob der Auftrag angekommen ist. MQTT 5 Request/Response mit Response-Topic und Correlation Data formalisiert dieses Muster.
Das MES aus dem Maschinenregelkreis heraushalten. Verriegelungen und Sicherheitslogik bleiben in der SPS. MQTT transportiert Ereignisse und Anweisungen, keine harte Echtzeitsteuerung.
Das MES nicht zum Namespace werden lassen. Wenn jeder Abnehmer Daten über das MES liest, sind Sie wieder bei der Punkt-zu-Punkt-Integration. Publizieren Sie Rohereignisse an den Broker und lassen Sie das MES einen Abonnenten unter vielen sein, neben Werkzeugen für die Betriebsdatenerfassung, OEE-Dashboards und Historians.
Auftragswechsel einplanen. Die meisten Fehlzuordnungen von Stückzahlen passieren in den Sekunden rund um einen Auftragswechsel. Lassen Sie die Linie die Auftrags-ID auf jede Stückzahl stempeln, und lassen Sie das MES einen Auftrag erst schließen, wenn es ein explizites Ende-Ereignis erhalten hat.
| Stolperfalle | Auswirkung | Vorbeugung |
|---|---|---|
| Keine Sequenznummern | Doppelte Zählung nach Reconnects | seq pro Publisher, Deduplizierung im Adapter |
| Auftrag nicht retained | HMI zeigt nach Neustart nichts an | Aktuellen Auftrag mit Retain publizieren |
| Geteilte Client-IDs | Adapter werfen sich gegenseitig raus | Eindeutige ID pro Instanz |
| Broker auf einem einzelnen Werks-PC | Integration stoppt, wenn der PC stoppt | Einen verwalteten MQTT-Broker nutzen |
Den Namespace auf einem verwalteten MQTT-Broker betreiben
Sobald MES, Gateways und Dashboards vom Broker abhängen, werden seine Verfügbarkeit und Sicherheit zur Verfügbarkeit und Sicherheit Ihrer Integration. Ein vollständig verwalteter MQTT-Broker nimmt Ihnen Patches, Zertifikate und Überwachung eines eigenen Brokers ab. ConnectMQ bietet MQTT 3.1.1 und 5.0 über TLS (8883) und sicheres WebSocket (8084), an Client-IDs gebundene Zugangsdaten sowie ein Portal mit Live-Topic-Explorer und einer nach ISA-95-Ebenen geordneten Geräteansicht. So lässt sich leicht prüfen, ob Stückzahlen und Zustände unter der richtigen Linie und Zelle im UNS ankommen.
Sprechen Ihre Maschinen Sparkplug B, kann ConnectMQ die Daten dekodieren und in lesbare ISA-95-Topics republizieren, sodass der MES-Adapter einfache JSON-Pfade statt Protobuf abonniert. Mehr dazu, wie Sparkplug B und der UNS zusammenspielen, lesen Sie unter Sparkplug B und Unified Namespace. Für das größere Architekturbild siehe den Leitfaden zu Smart Manufacturing und die Übersicht, was ein Cloud-MQTT-Broker bietet.
Verbinden Sie Ihr MES mit ConnectMQ
Registrieren Sie sich unter app.connectmq.com, erstellen Sie ohne Kreditkarte einen Broker im kostenlosen Serverless-Plan und richten Sie den obigen Adapter mit YOUR_USERNAME, YOUR_PASSWORD und YOUR_CLIENT_ID aus dem Portal darauf aus.
Häufig gestellte Fragen
Braucht mein MES native MQTT-Unterstützung?
Nein. Viele Integrationen nutzen einen kleinen Adapter, der auf der einen Seite MQTT und auf der anderen die MES-API oder -Datenbank spricht. Native Unterstützung macht lediglich den Adapter überflüssig.
Sollte das MES Fertigungsaufträge als retained messages publizieren?
Ja. Der aktuelle Auftrag pro Linie ist ein Zustand, kein Ereignis. Wird er retained, weiß jeder später verbundene Client, was gerade läuft. Die Auftragshistorie gehört in die MES-Datenbank.
Wie vermeide ich doppelte Zählungen mit QoS 1?
Versehen Sie jedes Stückzahl-Ereignis mit einer Sequenznummer pro Publisher und verwerfen Sie jede Sequenz, die der Adapter bereits verarbeitet hat. Alternativ publizieren Sie laufende Summen und berechnen die Differenzen auf MES-Seite.
Ist MQTT sicher genug für MES-Verkehr?
Mit TLS, eindeutigen Zugangsdaten pro Client und einem Broker, der die Bindung an Client-IDs durchsetzt, eignet sich MQTT für MES-Verkehr zwischen Werk und Cloud. Sicherheits- und Verriegelungslogik bleibt in der SPS.



