MQTT-Grundlagen

MQTT-Geräte-Online-Status mit LWT und Retained Messages zuverlässig erkennen

Ein schrittweises Präsenzmuster für MQTT-Geräteflotten: retained Birth Messages, ein retained Last Will, Offline-Meldungen beim geordneten Herunterfahren und ein Monitor, der den Zustand jedes Geräts in Echtzeit verfolgt.

Flotten-Dashboard mit grünen und grauen Anzeigen, die den MQTT Online-Status jedes Geräts darstellen
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

Welche Geräte sind gerade verbunden? Das ist die erste Frage, die jeder Betreiber stellt, ob in der Leitwarte eines Werks oder im Service eines Maschinenbauers, und beim MQTT Online-Status von Geräten lässt sich erstaunlich viel falsch machen. Das zuverlässige Muster kombiniert drei Bausteine: eine retained Birth Message, ein retained Last Will und eine explizite Offline-Meldung beim Herunterfahren. In diesem Leitfaden bauen Sie dieses Muster Schritt für Schritt auf, ergänzen einen Flotten-Monitor in Python und lernen, wie Sie die Sonderfälle vermeiden, durch die Dashboards falsche Zustände anzeigen.

Die Bausteine

Jeder Baustein löst einen Teil des Problems:

Baustein Wer veröffentlicht Wann Deckt ab
Birth Message (online, retained) Gerät Direkt nach jedem erfolgreichen Verbindungsaufbau Gerät ist aktiv, auch nach Reconnects
Last Will (offline, retained) Broker, im Namen des Geräts Verbindungsverlust ohne DISCONNECT Abstürze, Stromausfall, Netzwerkfehler
Shutdown-Meldung (offline, retained) Gerät Vor einem sauberen Disconnect Geplante Neustarts und Abschaltungen
Retain-Flag bei allen dreien Alle Immer Später geöffnete Dashboards sehen trotzdem den aktuellen Zustand

Lassen Sie einen davon weg, entsteht ein blinder Fleck. Ohne Birth Message bleibt ein wiederhergestelltes Gerät „offline“. Ohne Will bleiben Abstürze unbemerkt. Ohne Shutdown-Meldung bleibt ein geplant abgeschaltetes Gerät für immer „online“, denn ein sauberes DISCONNECT weist den Broker an, den Will zu verwerfen. Falls der Will-Mechanismus neu für Sie ist, lesen Sie zuerst MQTT Last Will and Testament.

Das Status-Topic entwerfen

Geben Sie jedem Gerät genau ein Status-Topic an einer vorhersehbaren Stelle:

connectmq/demo/<prefix>/<site>/<device-id>/status

Eine Wildcard wie connectmq/demo/<prefix>/+/+/status liefert dann den Status der gesamten Flotte mit einem einzigen Abonnement. Da alle Statusmeldungen retained sind, erhält ein startender Monitor sofort den letzten bekannten Zustand jedes Geräts. Wie das Speichern funktioniert, erklärt der Artikel zu MQTT Retained Messages.

In einer Fabrik mit Unified Namespace (UNS) gehört das Status-Topic direkt unter den ISA-95-Pfad der Maschine, also unter Enterprise, Site, Area, Line und Cell, etwa acme/werk-stuttgart/montage/linie-1/zelle-3/status. Mit acme/werk-stuttgart/+/+/+/status sieht die Leitwarte eines Werks dann alle Maschinen dieses Standorts, mit acme/+/montage/# die Montagebereiche aller Werke. Sparkplug B setzt dasselbe Prinzip mit eigenen Birth- und Death-Nachrichten um; mehr dazu in Sparkplug B und Unified Namespace.

Als Payload genügt für viele Tools ein einfacher String online oder offline. JSON liefert zusätzlichen Kontext, der im Betrieb hilft:

{"state":"online","ts":1760600000,"fw":"2.4.1","ip":"10.0.4.17","reason":"boot"}

Beim Will kann das Gerät den Zeitstempel eines künftigen Ausfalls nicht kennen, halten Sie ihn also einfach: {"state":"offline","reason":"lwt"}. Der Monitor protokolliert, wann er ihn empfangen hat.

Schritt 1: Das Gerät

Dieses paho-mqtt-2.x-Skript verhält sich wie ein gut konzipiertes Gerät. Es setzt vor dem Verbinden einen retained Will, veröffentlicht in on_connect eine retained Birth Message, damit sie sich nach jedem Reconnect wiederholt, und sendet beim geordneten Herunterfahren eine retained Offline-Meldung. Es verbindet sich mit dem öffentlichen MQTT-Broker unter broker.connectmq.com, der für Tests und Prototypen gedacht ist:

import json
import signal
import sys
import time
import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
DEVICE_ID = sys.argv[1] if len(sys.argv) > 1 else "pump-07"
STATUS = f"connectmq/demo/z8b2/plant1/{DEVICE_ID}/status"

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=f"z8b2-{DEVICE_ID}")
client.will_set(STATUS, json.dumps({"state": "offline", "reason": "lwt"}),
                qos=1, retain=True)
client.reconnect_delay_set(min_delay=1, max_delay=30)

def on_connect(client, userdata, flags, reason_code, properties):
    if reason_code.is_failure:
        print("connect failed:", reason_code)
        return
    birth = {"state": "online", "ts": int(time.time()), "reason": "connect"}
    client.publish(STATUS, json.dumps(birth), qos=1, retain=True)
    print("online")

def shutdown(signum, frame):
    bye = {"state": "offline", "ts": int(time.time()), "reason": "shutdown"}
    client.publish(STATUS, json.dumps(bye), qos=1, retain=True).wait_for_publish(timeout=5)
    client.disconnect()
    client.loop_stop()
    sys.exit(0)

client.on_connect = on_connect
signal.signal(signal.SIGINT, shutdown)
signal.signal(signal.SIGTERM, shutdown)

client.connect(BROKER, 1883, keepalive=20)
client.loop_start()
while True:
    time.sleep(1)  # hier würde echte Telemetrie veröffentlicht

Starten Sie es mit python device.py pump-07 und in einem zweiten Terminal mit python device.py fan-02.

Schritt 2: Der Flotten-Monitor

Der Monitor abonniert alle Status-Topics und führt eine Gerätetabelle. Da die Statusmeldungen retained sind, kennt er den vollständigen Flottenzustand wenige Sekunden nach dem Start:

import json
import time
import uuid
import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
FILTER = "connectmq/demo/z8b2/+/+/status"
fleet = {}

def on_connect(client, userdata, flags, reason_code, properties):
    client.subscribe(FILTER, qos=1)

def on_message(client, userdata, msg):
    device = msg.topic.split("/")[-2]
    if not msg.payload:  # leerer retained Payload = Gerät entfernt
        fleet.pop(device, None)
        return
    try:
        state = json.loads(msg.payload).get("state", "unknown")
    except ValueError:
        state = msg.payload.decode(errors="replace")
    previous = fleet.get(device, {}).get("state")
    fleet[device] = {"state": state, "since": time.strftime("%H:%M:%S")}
    tag = "retained" if msg.retain else "live"
    if previous != state:
        print(f"[{tag}] {device}: {previous} -> {state}")

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2,
                     client_id=f"monitor-{uuid.uuid4().hex[:8]}")
client.on_connect = on_connect
client.on_message = on_message
client.connect(BROKER, 1883, keepalive=30)
client.loop_forever()

Schritt 3: Jeden Fehlerfall testen

Starten Sie den Monitor und beide Geräte, arbeiten Sie dann diese Checkliste ab und prüfen Sie jedes Mal, ob der Monitor korrekt reagiert:

  1. Monitor-Neustart. Stoppen und starten Sie den Monitor. Beide Geräte erscheinen sofort als online, markiert mit retained.
  2. Geordnetes Herunterfahren. Drücken Sie Strg+C bei fan-02. Der Monitor zeigt sofort offline mit dem Grund shutdown.
  3. Absturz. Beenden Sie pump-07 mit kill -9. Das Betriebssystem schließt den Socket, der Broker veröffentlicht den Will und der Monitor zeigt offline.
  4. Stiller Netzwerkverlust. Trennen Sie das Netzwerk des Geräts, ohne den Prozess zu beenden. Nach etwa dem 1,5-Fachen des Keepalive von 20 Sekunden greift der Will.
  5. Wiederherstellung. Stellen Sie das Netzwerk wieder her. paho verbindet sich neu, on_connect läuft, und die Birth Message setzt das Gerät wieder auf online.
  6. Außerbetriebnahme. Veröffentlichen Sie eine leere retained Message auf dem Status-Topic. Der Monitor entfernt das Gerät.

Dieselben Topics können Sie auch live im Browser beobachten: Der browserbasierte Client und der Topic-Explorer im ConnectMQ-Portal zeigen Statuswechsel in Echtzeit, sobald Ihre Geräte mit Ihrem eigenen Broker verbunden sind.

Sonderfälle, durch die Dashboards falsche Zustände zeigen

Doppelte Client IDs. Zwei Geräte mit derselben ID werfen sich gegenseitig hinaus. Jede Übernahme kann einen Will und eine Birth Message auslösen, sodass der Status ständig flattert. Eindeutige IDs sind Pflicht; siehe den Leitfaden zur MQTT Client ID.

Birth Message nur einmal beim Booten. Wenn Sie online außerhalb des Connect-Callbacks veröffentlichen, bleibt ein Gerät, das sich nach einem kurzen Netzwerkaussetzer neu verbindet, für immer offline. Veröffentlichen Sie sie bei jedem Verbindungsaufbau.

Will nicht retained. Ein Dashboard, das nach dem Ausfall geöffnet wird, erfährt nie davon.

Flackern durch schnelle Reconnects. Ein Gerät, das sich innerhalb von Sekunden neu verbindet, erzeugt trotzdem ein Offline/Online-Paar. In MQTT 5 unterdrückt ein Will Delay Interval den Will, wenn die Session rechtzeitig wieder aufgenommen wird.

Langer Keepalive. Bei einem Keepalive von 300 Sekunden wirkt ein ausgefallenes Gerät über sieben Minuten lang online. Wählen Sie einen Keepalive, der dazu passt, wie schnell Sie Bescheid wissen müssen.

„Verbunden“ heißt nicht „gesund“. Ein Gerät kann seine MQTT-Verbindung halten, während sein Sensor ausgefallen ist. Veröffentlichen Sie ein separates Health- oder Heartbeat-Feld, wenn Sie Lebendigkeit auf Anwendungsebene brauchen.

Präsenz oder Heartbeat: Was brauchen Sie?

Verbindungsbasierte Präsenz und Anwendungs-Heartbeats beantworten unterschiedliche Fragen, und viele Flotten benötigen beides.

Signal Beantwortet Erkennungszeit Aufwand
Birth + LWT auf dem Status-Topic Ist das Gerät mit dem Broker verbunden? Sofort bis 1,5 x Keepalive Nahezu keiner; nur Keepalive-Pings
Periodische Heartbeat-Nachricht Läuft die Anwendungsschleife noch? Ein bis zwei Heartbeat-Intervalle Ein kleines Publish pro Intervall
Prüfung der Telemetrie-Aktualität Liefert der Sensor noch Daten? Abhängig von der erwarteten Publish-Rate Keiner auf dem Gerät; Logik im Consumer

Ein Gerät, dessen Hauptschleife hängt, kann weiterhin Keepalive-Pings beantworten, wenn der MQTT-Client in einem eigenen Thread läuft; der Verbindungsstatus bleibt dann online. Ein aus der Hauptschleife veröffentlichter Heartbeat oder ein Consumer, der Geräte mit veralteter Telemetrie markiert, erkennt diesen Fall. Senden Sie Heartbeats nicht retained und in maßvoller Frequenz; einmal pro Minute reicht für die meisten Überwachungszwecke.

Status-Topics in anderen Tools nutzen

Da das Muster nur aus retained MQTT-Nachrichten besteht, kann jedes MQTT-fähige Tool es ohne spezielle Integration verarbeiten. In Node-RED speist ein mqtt in-Node, der die Status-Wildcard abonniert, ein Dashboard oder einen Benachrichtigungs-Flow. Die MQTT-Integration von Home Assistant kann ein Status-Topic mit den Payloads online und offline einer Availability-Einstellung zuordnen. Der MQTT-Consumer-Input von Telegraf kann Zustandswechsel für Verfügbarkeitsberichte in eine Zeitreihendatenbank schreiben. Jedes dieser Tools verbindet sich als gewöhnlicher MQTT-Client mit dem Broker; Voraussetzung ist nur, dass Sie sich auf Topic-Namen und Payload-Werte einigen. Einfache Strings online und offline sind am portabelsten, wenn Sie Standard-Tools einsetzen wollen; JSON liefert reicheren Kontext für Ihren eigenen Code.

Broker-seitiger Status bei ConnectMQ

Das obige Muster funktioniert mit jedem Broker. Zusätzlich veröffentlicht ConnectMQ den Verbindungsstatus unter $SYS/broker/connection/{clientId}/state. Ein Monitor kann dies als unabhängige Quelle abonnieren, die nicht davon abhängt, dass die Geräte-Firmware ihren Will korrekt konfiguriert. Die Geräteansicht im Portal ordnet Ihre Geräte nach ISA-95-Ebenen und passt damit zu einem UNS-Topic-Baum, und Alarmregeln mit Schwellenwerten können Sie benachrichtigen, wenn Werte Grenzen überschreiten. Nutzen Sie in der Produktion TLS auf Port 8883 mit YOUR_USERNAME, YOUR_PASSWORD und YOUR_CLIENT_ID aus dem Portal. Ein verwalteter MQTT-Broker hält die Präsenz-Infrastruktur für Sie am Laufen; die Grundlagen dahinter finden Sie im MQTT-Tutorial.

Starten Sie mit ConnectMQ

Erstellen Sie unter app.connectmq.com einen kostenlosen Broker im Serverless-Plan, ganz ohne Kreditkarte. Setzen Sie die Geräte- und Monitor-Skripte mit Ihren Zugangsdaten ein, und Sie haben in wenigen Minuten eine zuverlässige Präsenzerkennung für Ihre Flotte auf einem Cloud-MQTT-Broker.

Häufig gestellte Fragen

Warum wird mein Gerät nach dem Herunterfahren noch als online angezeigt?

Ein sauberes DISCONNECT verwirft den Last Will. Veröffentlichen Sie vor dem Trennen selbst eine retained Offline-Meldung.

Warum bleibt mein Gerät nach dem Reconnect offline?

Vermutlich wird die Birth Message nur einmal beim Start veröffentlicht. Senden Sie sie im On-Connect-Callback, damit jeder Reconnect den Status aktualisiert.

Wie schnell wird ein Offline-Gerät erkannt?

Sofort, wenn die TCP-Verbindung geschlossen wird. Verschwindet das Gerät still, nach etwa dem 1,5-Fachen des Keepalive-Intervalls.

Sollten Statusmeldungen retained sein?

Ja. Wenn Birth-, Will- und Shutdown-Meldungen retained sind, erhält jeder später abonnierende Client sofort den aktuellen Zustand.

Verwandte Artikel

Wer hat MQTT erfunden? Die Geschichte von Ölpipelines bis zum IoT

MQTT wurde 1999 von Andy Stanford-Clark (IBM) und Arlen Nipper (Arcom) erfunden, um Ölpipelines per Satellit zu überwachen. Verfolgen Sie den Weg zu Open Source, OASIS, ISO und den heutigen verwalteten MQTT-Brokern in der Cloud.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.