Mit Raspberry Pi GPIO MQTT schalten Sie ein Relais, eine LED oder einen Summer von überall und sehen den Zustand von Tastern und Kontakten in Echtzeit – ohne einen einzigen Port in Ihrem Netzwerk zu öffnen. In diesem Tutorial nutzen Sie gpiozero und paho-mqtt, um einen Ausgang per MQTT-Befehl ein- und auszuschalten, Änderungen an Eingängen sofort zu veröffentlichen und alles als Retained-Zustand zu melden. Sie testen mit broker.connectmq.com und einem Kommandozeilen-Client und stellen dann auf private Zugangsdaten um.
Wie die Teile zusammenspielen
Der Pi baut eine ausgehende Verbindung zu einem MQTT-Broker auf und abonniert ein Command-Topic. Alles, was MQTT veröffentlichen kann (eine Smartphone-App, Node-RED, ein Web-Dashboard, ein Skript), sendet ON oder OFF an dieses Topic, und der Pi schaltet den Pin. Ändert sich der Pin oder wird ein Taster gedrückt, veröffentlicht der Pi den neuen Zustand auf einem separaten State-Topic.
Diese Trennung zwischen Command- und State-Topics ist die wichtigste Designentscheidung in diesem Tutorial:
| Topic | Richtung | Retained | Beispiel-Payload |
|---|---|---|---|
.../gpio/led/set |
Steuerung an den Pi | Nein | ON |
.../gpio/led/state |
Pi an alle | Ja | ON |
.../gpio/button/state |
Pi an alle | Ja | PRESSED |
.../status |
Pi an alle | Ja (Last Will) | online / offline |
Befehle sind nicht retained, damit ein veraltetes „ON“ beim Neustart des Pi nie erneut ausgelöst wird. Zustände sind retained, damit jedes später verbundene Dashboard sofort die aktuellen Werte sieht. Ein Dashboard sollte das State-Topic anzeigen und nicht wiedergeben, was es selbst gesendet hat, denn das State-Topic spiegelt wider, was tatsächlich an der Hardware passiert ist.
Verdrahtung
Sie benötigen eine LED mit einem 330-Ohm-Widerstand (oder ein Relaismodul) und einen Taster.
- LED-Anode (langes Bein) über den Widerstand an GPIO 17 (physischer Pin 11), Kathode an Masse.
- Taster zwischen GPIO 27 (physischer Pin 13) und Masse. gpiozero aktiviert den internen Pull-up, daher ist kein Widerstand nötig.
GPIO-Pins arbeiten mit 3,3 V und liefern nur wenige Milliampere. Steuern Sie Relais, Motoren und alles mit Netzspannung über eine geeignete Treiberplatine oder ein Relaismodul an, niemals direkt. Das Tutorial Raspberry Pi Relais per MQTT zeigt, wie das sicher geht.
Die Bibliotheken installieren
gpiozero ist auf Raspberry Pi OS vorinstalliert und nutzt das lgpio-Backend, das auf jedem Modell funktioniert – auch auf dem Raspberry Pi 5 mit seinem I/O-Chip RP1. Legen Sie eine virtuelle Umgebung an, die die Systempakete sieht, und fügen Sie paho-mqtt hinzu:
sudo apt install -y python3-gpiozero python3-lgpio
python3 -m venv --system-site-packages ~/gpio-mqtt/.venv
source ~/gpio-mqtt/.venv/bin/activate
pip install "paho-mqtt>=2.0"
python -c "import gpiozero, paho.mqtt; print('ok')"
Mit --system-site-packages vermeiden Sie, GPIO-Bibliotheken per pip zu kompilieren – die häufigste Ursache für Installationsfehler auf neueren Pi-Modellen. Ihr Benutzer muss Mitglied der Gruppe gpio sein, was beim Standardbenutzer bereits der Fall ist.
Das Raspberry Pi GPIO MQTT Skript
import os
import signal
import uuid
import paho.mqtt.client as mqtt
from gpiozero import LED, Button
BROKER = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "1883"))
USERNAME = os.getenv("MQTT_USERNAME")
PASSWORD = os.getenv("MQTT_PASSWORD")
CLIENT_ID = os.getenv("MQTT_CLIENT_ID", f"pi-gpio-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("TOPIC_PREFIX", "connectmq/demo/g3p6v2/pi1")
led = LED(17)
button = Button(27, bounce_time=0.05)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
if USERNAME:
client.username_pw_set(USERNAME, PASSWORD)
if PORT == 8883:
client.tls_set()
client.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(1, 30)
def publish_led_state():
client.publish(f"{PREFIX}/gpio/led/state", "ON" if led.is_lit else "OFF", qos=1, retain=True)
def publish_button_state():
state = "PRESSED" if button.is_pressed else "RELEASED"
client.publish(f"{PREFIX}/gpio/button/state", state, qos=1, retain=True)
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
print("connect failed:", reason_code)
return
print("connected")
client.subscribe(f"{PREFIX}/gpio/+/set", qos=1)
client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)
publish_led_state()
publish_button_state()
def on_message(client, userdata, msg):
target = msg.topic.split("/")[-2]
command = msg.payload.decode(errors="ignore").strip().upper()
if target != "led":
return
if command == "ON":
led.on()
elif command == "OFF":
led.off()
elif command == "TOGGLE":
led.toggle()
else:
print("ignored command:", command)
return
publish_led_state()
button.when_pressed = publish_button_state
button.when_released = publish_button_state
client.on_connect = on_connect
client.on_message = on_message
client.connect_async(BROKER, PORT, keepalive=30)
client.loop_start()
try:
signal.pause()
except KeyboardInterrupt:
pass
finally:
client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True).wait_for_publish(2)
client.loop_stop()
client.disconnect()
led.off()
Einige Details verdienen Beachtung. gpiozero führt when_pressed-Callbacks in einem eigenen Thread aus, und publish() von paho ist threadsicher, daher ist der Aufruf aus dem Callback unproblematisch. bounce_time filtert das mechanische Prellen des Tasters, das sonst Salven von Drück- und Loslass-Events erzeugt. on_connect abonniert nach jedem Reconnect erneut und veröffentlicht die Zustände neu, sodass der Broker stets den aktuellen Stand hält. Unbekannte Befehle werden ignoriert, statt sie zu erraten.
Von einem anderen Rechner testen
Starten Sie das Skript auf dem Pi und öffnen Sie dann auf Ihrem Laptop ein Terminal zum Mitlesen und ein weiteres zum Senden von Befehlen:
# Terminal 1: alle Topics dieses Pi mitlesen
mosquitto_sub -h broker.connectmq.com -p 1883 -i gpio-watch-g3p6v2 -t "connectmq/demo/g3p6v2/pi1/#" -v
# Terminal 2: Befehle senden
mosquitto_pub -h broker.connectmq.com -p 1883 -i gpio-cmd-g3p6v2 -t "connectmq/demo/g3p6v2/pi1/gpio/led/set" -m ON
mosquitto_pub -h broker.connectmq.com -p 1883 -i gpio-cmd-g3p6v2 -t "connectmq/demo/g3p6v2/pi1/gpio/led/set" -m TOGGLE
Die LED schaltet, und Terminal 1 zeigt den neuen led/state. Drücken Sie den Taster, und button/state wechselt zwischen PRESSED und RELEASED. Beenden Sie das Skript mit Strg+C, und der Status wechselt auf offline; ziehen Sie stattdessen den Stecker, veröffentlicht der Broker nach Ablauf des Keepalive den Last Will.
Der kostenlose öffentliche MQTT-Broker ist ideal für diesen Test, aber denken Sie daran, dass jeder auf seinen öffentlichen Topics lesen und veröffentlichen kann. Lassen Sie dort kein echtes Relais steuerbar.
Auf weitere Pins erweitern
Um mehrere Ausgänge zu steuern, halten Sie ein Dictionary benannter Geräte vor und schlagen sie anhand des Topics nach:
from gpiozero import OutputDevice
outputs = {"led": LED(17), "fan": OutputDevice(22), "pump": OutputDevice(23, active_high=False)}
Ersetzen Sie in on_message die einzelne LED durch outputs.get(target) und veröffentlichen Sie den Zustand für den passenden Namen. Verwenden Sie in Topics Namen statt Pin-Nummern: Ein Dashboard sollte nicht kaputtgehen, wenn Sie das Board neu verdrahten. Für Eingänge wie Temperatursensoren veröffentlichen Sie zeitgesteuert statt bei Änderung; das DHT22-MQTT-Tutorial zeigt dieses Muster.
Ausfallsicheres Verhalten für Ausgänge
Legen Sie im Voraus fest, was ein Ausgang tun soll, wenn etwas schiefgeht, denn das Netzwerk wird irgendwann ausfallen. Bei einer Lampe ist es in Ordnung, den letzten Zustand zu halten. Bei einer Pumpe, Heizung oder einem Ventil ist es meist sicherer abzuschalten, wenn eine Weile kein Befehl oder Heartbeat eingetroffen ist. Ein einfaches Muster ist ein Zeitstempel, der in on_message aktualisiert wird, und eine Prüfung in der Hauptschleife, die den Ausgang nach beispielsweise zehn Minuten Funkstille abschaltet und den neuen Zustand veröffentlicht, sobald die Verbindung zurück ist.
Denken Sie auch an den Start. gpiozero setzt Ausgänge beim Anlegen des Objekts auf aus, sodass nach einem Neustart jeder Ausgang in einem bekannten sicheren Zustand startet, bis ein neuer Befehl eintrifft. Belassen Sie es dabei, statt den vorherigen Zustand aus einer Datei wiederherzustellen – es sei denn, der Prozess erfordert es wirklich. Ist das der Fall, dokumentieren Sie das Verhalten am Gerät und im Dashboard, damit niemand überrascht wird.
Fehlerbehebung
GPIO busyoderlgpio.error: Ein anderer Prozess hält den Pin. Beenden Sie andere Skripte oder Dienste, die ihn nutzen, und prüfen Sie, dass nicht zwei Instanzen laufen.- No module named lgpio: Die venv wurde ohne
--system-site-packagesangelegt. Legen Sie sie neu an oder installieren Siepython3-lgpio. - Befehle bewirken nichts: Prüfen Sie das exakte Topic und ob der Pi „connected“ ausgegeben hat. Abonnieren Sie
#unter Ihrem Präfix, um zu sehen, was tatsächlich veröffentlicht wird. - LED schaltet sich nach jedem Neustart ein: Jemand hat eine Retained Message auf das
set-Topic veröffentlicht. Löschen Sie sie, indem Sie mitmosquitto_pub -r -neine leere Retained Message auf dieses Topic senden. - Zufällige Taster-Events: Erhöhen Sie
bounce_timeoder verkürzen Sie die Verdrahtung; lange, ungeschirmte Kabel fangen Störungen ein.
Einrichtung für den Produktivbetrieb
Für alles jenseits einer Demo erstellen Sie einen privaten Broker bei ConnectMQ und starten das Skript mit MQTT_PORT=8883, MQTT_USERNAME=YOUR_USERNAME, MQTT_PASSWORD=YOUR_PASSWORD und MQTT_CLIENT_ID=YOUR_CLIENT_ID aus dem Portal. TLS verhindert, dass Befehle unterwegs mitgelesen oder gefälscht werden, und Zugangsdaten pro Gerät sorgen dafür, dass nur Ihre Clients auf Ihre Topics veröffentlichen können. Betreiben Sie es als Dienst mit den Schritten aus Python-MQTT-Skript beim Booten starten, damit die Ausgänge nach einem Stromausfall wieder unter Kontrolle sind. Mit einem verwalteten MQTT-Broker gibt es auf dem Pi außer Ihrem Skript nichts zu installieren oder zu warten.
Wenn Sie gerade erst anfangen, behandelt das Raspberry Pi MQTT Tutorial Installation und Grundlagen, und die gpiozero-Dokumentation listet jede unterstützte Geräteklasse auf.
Steuern Sie Ihren Pi von überall mit ConnectMQ
Erstellen Sie unter app.connectmq.com einen kostenlosen Serverless-Broker ohne Kreditkarte. Mit dem MQTT-Client im Browser von ConnectMQ senden Sie ON- und OFF-Befehle und verfolgen die State-Topics, ohne etwas zu installieren – so steuern Sie Ihren Pi wenige Minuten nach der Registrierung von Smartphone oder Laptop aus.
Häufig gestellte Fragen
Kann ich RPi.GPIO statt gpiozero verwenden?
RPi.GPIO unterstützt den Raspberry Pi 5 nicht. gpiozero mit dem lgpio-Backend funktioniert auf allen aktuellen Modellen und übernimmt Entprellung und Threading für Sie.
Warum Retained Messages für Zustände, aber nicht für Befehle?
Ein Retained-Zustand lässt neue Abonnenten den aktuellen Wert sofort sehen. Ein Retained-Befehl würde bei jedem Reconnect des Pi erneut abgespielt und Ausgänge unerwartet schalten.
Ist es sicher, Netzspannungsgeräte auf diese Weise zu steuern?
Nur über ein passend dimensioniertes Relaismodul oder Schütz, das von einer Fachkraft installiert wurde, und mit TLS sowie privaten Zugangsdaten am Broker. Schalten Sie Netzspannung nie direkt über GPIO-Pins.
Wie schnell erreichen Befehle den Pi?
Bei einer stabilen Verbindung kommen MQTT-Befehle typischerweise in deutlich unter einer Sekunde an – mehr als genug für Lampen, Relais und die meisten Automatisierungsaufgaben.



