MQTT: Wie das Protokoll hinter AGV-Kommunikation funktioniert
Wie MQTT funktioniert: Publish/Subscribe, Broker, Topics und Wildcards, QoS-Stufen, Retained Messages und Last Will. Mit Einordnung gegenüber OPC UA und REST.
Warum MQTT in jedem AGV-Projekt auftaucht
Sobald ein AGV-Projekt technisch wird, fällt der Begriff MQTT. VDA 5050 setzt darauf auf, praktisch jeder Flottenmanager bringt einen MQTT-Broker mit, und die IT bekommt eine Anforderungsliste mit Ports, Zertifikaten und Topic-Namen auf den Tisch. Was MQTT eigentlich ist und wie es funktioniert, steht dabei selten dabei.
Dieser Artikel erklärt das Protokoll von Grund auf: wie Publish/Subscribe funktioniert, was ein Broker tut, wie Topics aufgebaut sind, was die QoS-Stufen tatsächlich garantieren und welche Mechanismen dafür sorgen, dass ein Flottenmanager binnen Sekunden merkt, wenn ein Fahrzeug offline geht.
Weiterführend: VDA 5050 beschreibt, welche Daten zwischen Flottenmanager und Fahrzeug ausgetauscht werden. Der VDA-5050-Nachrichtenfluss zeigt die konkreten Topics und Payloads. Flottenmanager als SaaS behandelt, wo der Broker steht. Dieser Artikel erklärt das Protokoll selbst, unabhängig von VDA 5050.
Was MQTT ist
MQTT ist ein schlankes Nachrichtenprotokoll nach dem Publish/Subscribe-Muster, das auf TCP aufsetzt. Entwickelt wurde es 1999 von Andy Stanford-Clark (IBM) und Arlen Nipper (damals Arcom), um Messwerte von Ölpipelines über teure und unzuverlässige Satellitenverbindungen zu übertragen.
Genau aus dieser Herkunft stammen die Eigenschaften, die MQTT heute für Fahrzeugflotten attraktiv machen:
- Minimaler Overhead. Der feste Header einer MQTT-Nachricht ist zwei Byte groß. Zum Vergleich: allein die Header eines HTTP-Requests umfassen typischerweise einige hundert Byte.
- Toleranz gegenüber instabilen Verbindungen. Sitzungsverwaltung, Wiederzustellung und ein definierter Offline-Mechanismus sind Teil des Protokolls, nicht der Anwendung.
- Keine gleichzeitige Erreichbarkeit nötig. Sender und Empfänger müssen nie zur selben Zeit online sein und kennen einander nicht einmal.
MQTT 3.1.1 ist seit 2014 OASIS-Standard und seit 2016 zusätzlich als ISO/IEC 20922 normiert. MQTT 5.0 kam 2019 dazu. Beide Versionen sind heute im Feld anzutreffen.
Publish/Subscribe statt Request/Response
Der entscheidende Unterschied zu einer klassischen Schnittstelle liegt in der Richtung der Initiative. Bei Request/Response fragt ein Client aktiv nach und wartet auf Antwort. Wer den Zustand von 30 Fahrzeugen kennen will, fragt 30-mal, immer wieder, und erfährt Änderungen frühestens beim nächsten Durchlauf.
Bei Publish/Subscribe meldet stattdessen jeder Teilnehmer beim Broker an, woran er interessiert ist. Wer etwas zu sagen hat, schickt es einmal an den Broker, und der verteilt es an alle passenden Empfänger, in dem Moment, in dem es entsteht.
Daraus ergeben sich drei Entkopplungen, die in der Praxis den Ausschlag geben:
Räumlich
Publisher und Subscriber kennen weder Adresse noch Anzahl der Gegenstelle. Ein neues Fahrzeug kommt hinzu, ohne dass am Flottenmanager etwas konfiguriert wird.
Zeitlich
Beide Seiten müssen nicht gleichzeitig verbunden sein. Der Broker überbrückt kurze Ausfälle, sofern Sitzung und QoS entsprechend gewählt sind.
Ablauftechnisch
Niemand blockiert auf eine Antwort. Senden und Empfangen laufen unabhängig voneinander, was bei hunderten Nachrichten pro Sekunde entscheidend ist.
Die drei Bausteine
Broker
Die einzige Serverkomponente. Nimmt Verbindungen an, verwaltet Abonnements und leitet jede Nachricht an alle passenden Subscriber weiter. Den Inhalt interpretiert er nicht.
Client
Alles, was sich verbindet: Flottenmanager, jedes AGV, ein Dashboard, ein Gateway. Ein Client kann publizieren, abonnieren oder beides. Eine Sonderrolle gibt es nicht.
Topic
Die Adresse einer Nachricht. Eine frei wählbare, mit Schrägstrichen gegliederte Zeichenkette. Es gibt keine Registrierung: Ein Topic existiert, sobald jemand darauf publiziert.
Topics und Wildcards
Ein Topic ist eine UTF-8-Zeichenkette, hierarchisch durch / gegliedert. Struktur und Benennung legt die Anwendung fest, nicht das Protokoll:
werk1/halle2/agv/AGV-0017/position
werk1/halle2/foerderer/FT-003/status
Subscriber können mit zwei Platzhaltern arbeiten:
| Wildcard | Bedeutung | Beispiel | Trifft |
|---|---|---|---|
+ |
genau eine Ebene | werk1/+/agv/+/position |
Positionen aller AGVs in allen Hallen von Werk 1 |
# |
alle verbleibenden Ebenen | werk1/halle2/# |
Alles unterhalb von Halle 2, beliebig tief verschachtelt |
Das # darf ausschließlich am Ende eines Filters stehen. Platzhalter gelten nur beim Abonnieren: Publiziert wird immer auf ein konkretes, vollständig ausgeschriebenes Topic.
Zwei Konventionen haben sich in Projekten bewährt. Topics beginnen nicht mit / und enthalten keine Leerzeichen, und die Hierarchie geht vom Allgemeinen zum Speziellen, damit Wildcard-Abos sinnvolle Schnitte ergeben. Topics, die mit $ beginnen (etwa $SYS/), sind brokerinternen Statistiken vorbehalten.
Genau dieses Prinzip nutzt VDA 5050 mit seiner festen Hierarchie interfaceName/majorVersion/manufacturer/serialNumber/topic. Der Flottenmanager abonniert alle Fahrzeugzustände mit einem einzigen Filter, während jedes AGV nur auf Topics mit seiner eigenen Seriennummer hört.
Ein Verbindungsaufbau Schritt für Schritt
MQTT kennt eine überschaubare Zahl von Pakettypen. Wer sie kennt, kann einen Mitschnitt lesen und Verbindungsprobleme selbst eingrenzen:
| Paket | Richtung | Bedeutung |
|---|---|---|
CONNECT |
Client → Broker | Verbindungswunsch mit Client-ID, Zugangsdaten, Keep-Alive, Sitzungsverhalten und optionalem Last Will |
CONNACK |
Broker → Client | Annahme oder Ablehnung, dazu die Information, ob eine bestehende Sitzung fortgesetzt wird |
SUBSCRIBE |
Client → Broker | Liste von Topic-Filtern mit gewünschter QoS-Stufe |
SUBACK |
Broker → Client | Bestätigung je Filter, inklusive der tatsächlich gewährten QoS |
PUBLISH |
beide Richtungen | Die eigentliche Nachricht: Topic, Flags und Payload |
PUBACK, PUBREC, PUBREL, PUBCOMP |
beide Richtungen | Quittungen für QoS 1 und QoS 2 |
PINGREQ, PINGRESP |
Client ↔ Broker | Lebenszeichen innerhalb des Keep-Alive-Intervalls |
DISCONNECT |
Client → Broker (in 5.0 auch umgekehrt) | Sauberes Verbindungsende. Der Last Will wird in diesem Fall nicht gesendet |
Ein typischer Ablauf beim Start eines Fahrzeugs: CONNECT mit Last Will auf dem eigenen Status-Topic, CONNACK, SUBSCRIBE auf das eigene Auftrags-Topic, SUBACK, danach fortlaufend PUBLISH des eigenen Zustands, unterbrochen von PINGREQ, wenn gerade nichts zu senden ist.
Die QoS-Stufen
Quality of Service legt fest, wie viel Aufwand Sender und Broker treiben, damit eine Nachricht ankommt. Die Stufe wird pro Nachricht beim Publizieren und pro Filter beim Abonnieren gewählt:
| Stufe | Garantie | Handshake | Typischer Einsatz |
|---|---|---|---|
| QoS 0 | höchstens einmal | PUBLISH |
Hochfrequente Positions- und Sensordaten, bei denen die nächste Nachricht ohnehin in Millisekunden folgt |
| QoS 1 | mindestens einmal | PUBLISH → PUBACK |
Aufträge, Alarme, Verbindungsstatus. Alles, was ankommen muss und wo ein Duplikat verkraftbar ist |
| QoS 2 | genau einmal | PUBLISH → PUBREC → PUBREL → PUBCOMP |
Nicht idempotente oder abrechnungsrelevante Kommandos. Im AGV-Umfeld selten nötig |
Höhere Stufen kosten Round-Trips und Zustandshaltung auf beiden Seiten. VDA 5050 nutzt deshalb bewusst QoS 0 für order, state und visualization und hebt nur beim connection-Topic auf QoS 1 an, weil ein verlorener Offline-Hinweis nicht durch die nächste Nachricht geheilt wird.
Retained Messages
Normalerweise sieht ein Subscriber nur, was nach seinem Abonnement publiziert wird. Wer sich um 10:00 Uhr verbindet, erfährt nichts über die Nachricht von 09:59 Uhr.
Das Retained-Flag ändert das: Der Broker speichert pro Topic die zuletzt mit diesem Flag publizierte Nachricht und liefert sie jedem neuen Subscriber sofort aus. Das eignet sich für Zustände, die dauerhaft gelten, etwa Konfigurationswerte oder den Online-Status eines Fahrzeugs. Für Ereignisse eignet es sich nicht.
Last Will und Keep-Alive
Diese beiden Mechanismen beantworten gemeinsam die Frage, die in der Praxis am häufigsten gestellt wird: Woher weiß der Flottenmanager, dass ein AGV weg ist?
Der Last Will wird bereits beim CONNECT hinterlegt, also lange bevor er gebraucht wird. Der Client übergibt Topic, Payload, QoS und Retained-Flag einer Nachricht, die der Broker veröffentlichen soll, falls die Verbindung nicht sauber beendet wird. Ein Stromausfall am Fahrzeug, ein abgerissener WLAN-Link oder ein abgestürzter Prozess lösen sie aus, ein reguläres DISCONNECT dagegen nicht.
Das Keep-Alive ist die Zusage des Clients, mindestens alle N Sekunden irgendetwas zu senden, notfalls ein PINGREQ. Hört der Broker eineinhalb Keep-Alive-Intervalle lang nichts, gilt der Client als tot und der Last Will wird ausgelöst.
Daraus folgt eine Auslegungsentscheidung, die bewusst getroffen werden sollte:
| Keep-Alive | Ausfall erkannt nach | Einordnung |
|---|---|---|
| 10 s | 15 s | Reaktionsschnell, etwas mehr Grundlast im Netz |
| 30 s | 45 s | Üblicher Kompromiss für AGV-Flotten |
| 60 s | 90 s | Sparsam, aber eine Minute Unklarheit über ein stehendes Fahrzeug |
| 300 s | 7,5 min | Für mobile Fahrzeuge praktisch unbrauchbar |
MQTT 5.0 ergänzt ein Will Delay Interval: Der Last Will wird erst nach einer Wartezeit veröffentlicht. Verbindet sich der Client vorher erneut, entfällt er. Das entschärft kurze Funklöcher beim WLAN-Roaming, die sonst jedes Mal als Fahrzeugausfall gemeldet würden.
Sitzungen: was der Broker sich merkt
Beim Verbindungsaufbau entscheidet der Client, ob er eine frische Sitzung will oder an eine bestehende anknüpft. In MQTT 3.1.1 geschieht das über das Flag Clean Session:
Clean Session = true: Der Broker verwirft alles Vorherige. Abonnements müssen neu gesetzt werden, zwischengespeicherte Nachrichten sind verloren.Clean Session = false: Der Broker behält Abonnements und gepufferte QoS-1- und QoS-2-Nachrichten für diese Client-ID. Nach einem Reconnect läuft die Zustellung weiter.
MQTT 5.0 trennt das sauberer in Clean Start (beginne mit einer frischen Sitzung) und Session Expiry Interval (wie lange die Sitzung nach dem Trennen aufgehoben wird).
Der Anker dieser Sitzung ist die Client-ID. Sie muss pro Broker eindeutig sein. Verbinden sich zwei Clients mit derselben ID, trennt der Broker die ältere Verbindung. Baut diese sofort wieder auf, entsteht eine Schleife, in der sich beide gegenseitig hinauswerfen. Das Fehlerbild sind Fahrzeuge, die im Sekundentakt zwischen online und offline wechseln.
MQTT 3.1.1 oder MQTT 5.0
3.1.1 ist nach wie vor die am weitesten verbreitete Version und für ein AGV-Projekt vollkommen ausreichend. 5.0 ist im Konzept rückwärtskompatibel, aber nicht auf Protokollebene: Client und Broker müssen sich auf dieselbe Version einigen.
| Neuerung in 5.0 | Nutzen |
|---|---|
| Reason Codes | Ablehnungen und Fehler sind maschinenlesbar begründet, statt nur als abgebrochene Verbindung sichtbar |
| User Properties | Freie Schlüssel-Wert-Paare im Header, etwa für Korrelations-IDs oder Tracing |
| Topic Aliases | Lange Topic-Namen werden je Verbindung auf eine Zahl abgebildet, was Bandbreite spart |
| Shared Subscriptions | Mehrere Instanzen teilen sich einen Abo-Strom über $share/gruppe/topic, Basis für Lastverteilung |
| Message Expiry | Nachrichten verfallen nach einer definierten Zeit, statt veraltet zugestellt zu werden |
| Session Expiry | Explizite Lebensdauer einer Sitzung statt des binären Clean-Session-Flags |
| Will Delay | Der Last Will feuert erst nach einer Wartezeit und überspringt so kurze Funklöcher |
| Request/Response | Response Topic und Correlation Data sind standardisiert, statt in jedem Projekt neu erfunden zu werden |
In der Praxis gibt der Fuhrpark den Ausschlag: Die Version muss von jedem Fahrzeug unterstützt werden, das an den Broker soll. Sie gehört deshalb ins Lastenheft und nicht erst in die Inbetriebnahme.
Sicherheit
MQTT bringt selbst keine Verschlüsselung mit. Sicherheit entsteht aus der Kombination von TLS, Authentifizierung und Autorisierung am Broker:
Transportverschlüsselung
MQTT über TLS (MQTTS) auf Port 8883. Der unverschlüsselte Port 1883 gehört im Produktivbetrieb geschlossen. Für MQTT über WebSockets gibt es keinen reservierten Port, üblich sind 8083, 8084 oder 443.
Authentifizierung
Benutzername und Passwort oder, robuster, Client-Zertifikate mit gegenseitiger TLS-Authentifizierung. Jeder Client bekommt eigene Zugangsdaten, keine gemeinsam genutzten.
Autorisierung
ACLs am Broker legen fest, wer auf welchem Topic publizieren und abonnieren darf. Ein Fahrzeug bekommt Rechte ausschließlich auf seinem eigenen Namensraum, nie auf dem der anderen.
Client-IDs
Eine dokumentierte Namenskonvention verhindert Kollisionen und macht Logs lesbar. Sinnvoll ist die Kopplung an Seriennummer oder Anlagenkennzeichen.
Der Payload selbst bleibt dabei unangetastet. Wer Vertraulichkeit über den Broker hinaus braucht, muss die Nutzdaten zusätzlich auf Anwendungsebene verschlüsseln.
Broker-Auswahl und Dimensionierung
| Broker | Charakter |
|---|---|
| Eclipse Mosquitto | Sehr leichtgewichtig, in C geschrieben, Einzelknoten. Der Klassiker für einen Standort |
| HiveMQ | Java, clusterfähig, Enterprise-Funktionen und kommerzieller Support |
| EMQX | Erlang, clusterfähig, ausgelegt auf sehr große Clientzahlen |
| VerneMQ | Erlang, clusterfähig, Open Source |
| NanoMQ | Besonders kleiner Footprint, gedacht für Edge-Geräte und Gateways |
| Managed Cloud | Betrieb ausgelagert, dafür Abhängigkeit von der Internetverbindung |
Zur Dimensionierung: Ein AGV erzeugt über alle Topics hinweg grob eine bis fünf Nachrichten pro Sekunde, dominiert von hochfrequenten Positionsdaten. Eine Flotte von 50 Fahrzeugen liegt damit bei einigen hundert Nachrichten pro Sekunde, was für jeden der genannten Broker unkritisch ist. Der Engpass in AGV-Projekten ist praktisch nie der Broker, sondern die WLAN-Abdeckung.
Zwei Punkte gehören trotzdem in die Auswahl: ob der Broker die benötigte MQTT-Version und QoS-Stufe unterstützt (nicht jeder Managed-Broker bietet QoS 2 an), und ob er sich für Hochverfügbarkeit clustern lässt. Wo der Broker dann betrieben wird, behandelt Flottenmanager als SaaS.
MQTT, OPC UA oder REST?
In einem Werk existieren diese Protokolle nebeneinander. Die Frage ist nicht, welches gewinnt, sondern welches für welche Strecke passt:
| Kriterium | MQTT | OPC UA | REST über HTTP |
|---|---|---|---|
| Kommunikationsmuster | Publish/Subscribe über Broker | Client/Server, zusätzlich eine PubSub-Variante | Request/Response |
| Datenmodell | Keines, reine Bytes im Payload | Reichhaltiges, typisiertes Informationsmodell | Keines, meist JSON nach eigener Konvention |
| Overhead | Sehr gering | Hoch | Mittel bis hoch |
| Ereignisgetrieben | Ja, nativ | Ja, über Subscriptions | Nein, erfordert Polling oder Webhooks |
| Entkopplung der Teilnehmer | Hoch | Mittel | Gering |
| Typische Rolle im Werk | Fahrzeug- und Gerätekommunikation, VDA 5050 | Maschinen- und Anlagenintegration mit Semantik | ERP-, WMS- und Web-Schnittstellen |
- MQTT, wenn viele Teilnehmer ereignisgetrieben Zustände austauschen und die Verbindung nicht garantiert stabil ist. Genau das ist der AGV-Fall.
- OPC UA, wenn Maschinendaten mit Bedeutung transportiert werden und ein gemeinsames Informationsmodell wichtiger ist als geringer Overhead.
- REST, wenn ein System ein anderes gezielt abfragt oder anstößt, etwa beim Quittieren eines Transportauftrags gegenüber dem Lagerverwaltungssystem.
Ein typischer Aufbau kombiniert alle drei: Das ERP oder WMS spricht per REST mit dem Flottenmanager, der Flottenmanager spricht per MQTT und VDA 5050 mit den Fahrzeugen, und die Anlagentechnik hängt per OPC UA daneben. Wie die obere Ebene davon aussieht, beschreibt SAP-Anbindung an das FTS.
Typische Stolpersteine in AGV-Projekten
- Doppelte Client-IDs. Zwei Clients mit derselben ID werfen sich gegenseitig aus der Verbindung. Symptom sind Fahrzeuge, die im Sekundentakt zwischen online und offline springen.
- QoS als Ende-zu-Ende-Garantie verstanden. Die Stufe wird je Abschnitt ausgehandelt, und für die zweite Strecke zählt das Minimum aus Publish- und Abo-QoS.
- Abonnement auf
#. Ein Analysewerkzeug oder Dashboard, das alles abonniert, zieht den gesamten Traffic auf sich. In Produktivsystemen gehört das per ACL unterbunden. - Veraltete Retained Messages. Nach Umbauten oder ausgemusterten Fahrzeugen bleiben alte Zustände stehen, und ein neuer Subscriber hält sie für aktuell.
- Keep-Alive zu großzügig gewählt. Der Wert bestimmt direkt, wie lange ein ausgefallenes Fahrzeug unbemerkt bleibt. Er ist eine Projektentscheidung, kein Vorgabewert.
- WLAN-Roaming nicht betrachtet. Jeder Wechsel zwischen Access Points kann die TCP-Verbindung abreißen lassen. Ohne schnelles Roaming (802.11r, k, v) und persistente Sitzungen entstehen Lücken in den Daten.
- Kein Monitoring. Nachrichtenrate, Verbindungsabbrüche und Broker-Last gehören auf ein Dashboard. Sonst fällt ein schleichendes Problem erst auf, wenn die Flotte steht.
Checkliste für die Inbetriebnahme
- [ ] Broker-Produkt und Betriebsort festgelegt
- [ ] MQTT-Version (3.1.1 oder 5.0) mit allen Lieferanten abgestimmt
- [ ] Client-ID-Konvention dokumentiert und projektweit eindeutig
- [ ] TLS auf Port 8883 aktiv, Port 1883 im Produktivbetrieb geschlossen
- [ ] Eigene Zugangsdaten oder Zertifikate je Client, keine gemeinsam genutzten
- [ ] ACLs schränken jeden Client auf seinen Topic-Namensraum ein
- [ ] Keep-Alive festgelegt und die daraus folgende Ausfallerkennungszeit akzeptiert
- [ ] Last Will auf einem Status-Topic definiert, Retained-Verhalten geklärt
- [ ] Löschstrategie für Retained Messages dokumentiert
- [ ] Monitoring für Nachrichtenrate, Verbindungen und Broker-Last eingerichtet
- [ ] WLAN-Abdeckung und Roaming auf allen Fahrwegen geprüft
Kernaussagen
- MQTT entkoppelt die Teilnehmer: Publisher und Subscriber kennen einander nicht, der Broker ist die einzige Serverkomponente und damit der einzige Integrationspunkt, den die IT absichern muss.
- Topics sind frei gestaltbare Hierarchien. Die Wildcards
+und#machen daraus flexible Abonnements, gehören aber per ACL eingegrenzt. - QoS wirkt pro Verbindungsabschnitt, nicht Ende zu Ende. Für die effektive Stufe zählt das Minimum aus Publish- und Abo-QoS.
- Last Will und Keep-Alive bestimmen, wie schnell ein Fahrzeugausfall auffällt. Das ist eine bewusste Auslegung, kein Vorgabewert.
- MQTT transportiert Bytes ohne Bedeutung. Die Semantik kommt aus der Ebene darüber, in der Intralogistik meist aus VDA 5050.
Wer diese Mechanismen kennt, liest eine Lieferantenspezifikation deutlich anders: Topics, QoS-Stufen und Keep-Alive-Werte sind dann keine Formalien mehr, sondern Angaben mit direkten Folgen für Reaktionszeit und Diagnosefähigkeit der Anlage.
Die Spezifikationen beider Versionen sind frei verfügbar unter mqtt.org.
AGVHub