ESPHome spricht MQTT über einen einzigen YAML-Block. Füge mqtt: mit einer Broker-Adresse hinzu, und jeder Sensor, Schalter und jede Leuchte auf dem Gerät veröffentlicht ihren Zustand und nimmt Befehle auf vorhersehbaren Topics an – ganz ohne C++. Das funktioniert mit Home Assistant über MQTT-Discovery und genauso gut ohne Home Assistant, etwa um Node-RED, Grafana oder dein eigenes Backend von einem beliebigen Broker aus zu versorgen.
Dieser Leitfaden behandelt eine vollständige Konfiguration mit einem externen Broker, das Topic-Layout von ESPHome, Discovery, Birth- und Will-Messages, TLS, eigene Subscriptions und wie du jeden Teil im Browser prüfst.
Eine minimale, funktionierende Konfiguration
esphome:
name: livingroom
esp32:
board: esp32dev
framework:
type: esp-idf
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
logger:
ota:
- platform: esphome
password: !secret ota_password
mqtt:
broker: broker.connectmq.com
port: 1883
username: !secret mqtt_user
password: !secret mqtt_password
client_id: esphome-livingroom
topic_prefix: testmqtt/esphome/livingroom
discovery: false
sensor:
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 30s
- platform: uptime
name: "Uptime"
switch:
- platform: gpio
pin: GPIO2
name: "Relay"
id: relaywifi_ssid: "your-ssid"
wifi_password: "your-wifi-password"
ota_password: "change-me"
mqtt_user: "username"
mqtt_password: "password"Flashe sie mit esphome run livingroom.yaml. Im Log solltest du Connecting to MQTT... und danach MQTT Connected! sehen.
Drei Einstellungen solltest du explizit setzen, statt dich auf die Standardwerte zu verlassen:
topic_prefixist standardmäßig der Node-Name (livingroom). Auf einem geteilten Broker kollidiert das mit den Wohnzimmern aller anderen. Ein eindeutiges Präfix wietestmqtt/esphome/livingroomhält deine Topics bei dir.client_idmuss pro Gerät eindeutig sein. Zwei Geräte mit derselben ID trennen sich gegenseitig in einer Schleife. Lässt du sie weg, erzeugt ESPHome eine aus Name und MAC – das ist in Ordnung; kopiere nur nie eine feste ID zwischen YAML-Dateien.discovery: false, solange du auf einem öffentlichen oder geteilten Broker testest, damit du keine Home-Assistant-Konfigurationsnachrichten in einen Namensraum schreibst, den andere mitlesen. Schalte es ein, sobald du deinen eigenen Broker nutzt.
Die Topics, die ESPHome erzeugt
Jede Entität bekommt ein State-Topic, steuerbare Entitäten zusätzlich ein Command-Topic. Die Object-ID ist der Entitätsname in Kleinbuchstaben, Leerzeichen werden zu Unterstrichen:
| Entität | Topic | Richtung |
|---|---|---|
| Verfügbarkeit | testmqtt/esphome/livingroom/status | Gerät → Broker (online / offline) |
| Sensor WiFi Signal | testmqtt/esphome/livingroom/sensor/wifi_signal/state | Gerät → Broker |
| Sensor Uptime | testmqtt/esphome/livingroom/sensor/uptime/state | Gerät → Broker |
| Zustand des Schalters Relay | testmqtt/esphome/livingroom/switch/relay/state | Gerät → Broker (ON / OFF) |
| Befehl für den Schalter Relay | testmqtt/esphome/livingroom/switch/relay/command | Broker → Gerät (ON / OFF / TOGGLE) |
| Logs | testmqtt/esphome/livingroom/debug | Gerät → Broker |
Mit state_topic: und command_topic: überschreibst du jedes davon pro Entität, wenn du in ein bestehendes Topic-Design passen musst. Die Option log_topic: steuert das Debug-Topic; setze sie auf null, um keine Logs mehr über MQTT zu senden – das spart Bandbreite auf vielbeschäftigten Geräten.
Birth-, Will- und Shutdown-Messages
ESPHome sendet nach dem Verbinden eine Birth-Message und registriert beim Broker ein Last Will. Standardmäßig landen beide retained auf <topic_prefix>/status, mit den Payloads online und offline. Genau das nutzt Home Assistant für die Verfügbarkeit der Entitäten. Du kannst sie anpassen:
mqtt:
# ...
birth_message:
topic: testmqtt/esphome/livingroom/availability
payload: "connected"
retain: true
will_message:
topic: testmqtt/esphome/livingroom/availability
payload: "lost"
retain: true
shutdown_message:
topic: testmqtt/esphome/livingroom/availability
payload: "shutdown"
retain: true
keepalive: 30sDas Will veröffentlicht der Broker, nicht das Gerät – etwa 1,5 × keepalive, nachdem das Gerät verstummt ist. Die Shutdown-Message sendet das Gerät selbst vor einem geplanten Neustart oder OTA-Update, sodass du „absichtlicher Neustart" von „Strom weg" unterscheiden kannst. Das Timing erklärt MQTT Last Will, das Retained-Flag Retained Messages.
Home-Assistant-Discovery
Mit discovery: true (Standard) veröffentlicht ESPHome pro Entität eine retained Konfigurationsnachricht unter <discovery_prefix>/<component>/<node>/<object_id>/config. Die MQTT-Integration von Home Assistant abonniert dieses Präfix und legt die Entitäten automatisch an.
mqtt:
broker: broker.connectmq.com
port: 1883
username: !secret mqtt_user
password: !secret mqtt_password
discovery: true
discovery_prefix: homeassistant
discovery_retain: trueGut zu wissen:
- Das Präfix muss übereinstimmen. Home Assistant hört auf
homeassistant, sofern du das in den Optionen der MQTT-Integration nicht geändert hast. Änderst du eine Seite, änderst du beide. - Discovery-Nachrichten sind retained. Benennst du eine Entität um oder löschst sie, bleibt die alte Konfiguration auf dem Broker. Entferne sie, indem du eine leere retained Nachricht auf das alte Config-Topic veröffentlichst.
- Ein Broker für beide. Home Assistant muss sich mit demselben Broker verbinden wie das Gerät. Für die Home-Assistant-Seite lies Home Assistant MQTT.
Aus YAML abonnieren und veröffentlichen
ESPHome kann auf beliebige Topics reagieren, nicht nur auf die eigenen Command-Topics, und beliebige Nachrichten veröffentlichen:
mqtt:
# ...
on_message:
- topic: testmqtt/esphome/livingroom/cmd/toggle
qos: 1
then:
- switch.toggle: relay
on_json_message:
topic: testmqtt/esphome/livingroom/cmd/json
then:
- if:
condition:
lambda: 'return x["relay"] == "on";'
then:
- switch.turn_on: relay
else:
- switch.turn_off: relay
interval:
- interval: 60s
then:
- mqtt.publish:
topic: testmqtt/esphome/livingroom/heartbeat
payload: "alive"
qos: 0
retain: falseon_json_message parst den Payload mit ArduinoJson und stellt ihn als x bereit. Halte Payloads klein: Sehr große Nachrichten können auf speicherarmen Boards den Puffer des Clients sprengen.
TLS mit einem externen Broker
Auf dem ESP32 fügst du das CA-Zertifikat des Brokers hinzu und wechselst auf Port 8883:
mqtt:
broker: broker.connectmq.com
port: 8883
username: !secret mqtt_user
password: !secret mqtt_password
certificate_authority: |
-----BEGIN CERTIFICATE-----
... root CA of your broker's certificate chain ...
-----END CERTIFICATE-----Nutze die Root-CA der Kette, die der Broker präsentiert, nicht das Serverzertifikat selbst. Für MQTT über TLS auf dem ESP32 ist das ESP-IDF-Framework die empfohlene Wahl. Die Unterstützung auf dem ESP8266 ist deutlich eingeschränkter (nur Fingerprints mit dem Arduino-Framework); nimm für Geräte, bei denen TLS wichtig ist, also einen ESP32 oder halte ESP8266-Geräte in einem vertrauenswürdigen lokalen Netz. Unser ESP32-TLS-Leitfaden zeigt, wie du das richtige Zertifikat mit openssl s_client ausliest.
Jeden Teil im Browser testen
- Öffne den Online-MQTT-Client, verbinde dich mit
broker.connectmq.comauf Port 8084 (Pfad/mqtt) und abonnieretestmqtt/esphome/livingroom/#. - Du solltest
status = online(retained) sowie alle 30 Sekunden die Zustände vonwifi_signalunduptimesehen. - Veröffentliche
ONauftestmqtt/esphome/livingroom/switch/relay/command. Das Relais schaltet, undswitch/relay/statemeldetON. - Veröffentliche irgendetwas auf
testmqtt/esphome/livingroom/cmd/toggle, umon_messagezu testen. - Schalte das Board aus. Nach etwa 1,5 × Keepalive setzt das Will
statusaufoffline. Startest du es stattdessen über das Dashboard neu, siehst du zuerst die Shutdown-Message.
Deinen ESPHome-Node im Online-Client beobachten
Taucht eine Entität nicht auf dem erwarteten Topic auf, gib Topic und Filter in den Topic Matcher ein, um einen Tippfehler im Präfix zu finden.
Kurzreferenz zur Fehlersuche
| Log-Meldung | Wahrscheinliche Ursache |
|---|---|
MQTT Disconnected: TCP disconnected. | Falscher Host oder Port, Firewall, TLS-Port ohne certificate_authority |
MQTT Disconnected: Not Authorized. | Falscher Benutzername oder falsches Passwort, oder eine ACL verweigert den Client |
MQTT Disconnected: Identifier Rejected. | Client-ID abgelehnt oder doppelt vergeben |
| Gerät startet nach 15 Minuten neu | reboot_timeout erreicht, weil der Broker nicht erreichbar ist |
Eine Schritt-für-Schritt-Diagnose findest du unter ESPHome MQTT verbindet sich nicht.
ESPHome für MQTT zu konfigurieren ist vor allem eine Frage der Benennung: ein eindeutiges Topic-Präfix und eine eindeutige Client-ID, Discovery nur dort eingeschaltet, wo Home Assistant lebt, und Verfügbarkeits-Topics, denen du trauen kannst. Stimmt das, prüfe Zustand, Befehle und Will im Online-Client – dann wandert dasselbe YAML vom Test-Broker in die Produktion, indem du einen Hostnamen und ein Secret änderst.
Häufig gestellte Fragen
Kann ich ESPHome gleichzeitig mit MQTT und der nativen API nutzen?
Ja. Die Komponenten api: und mqtt: sind unabhängig. Viele Setups behalten die native API für Home Assistant und ergänzen MQTT, damit andere Systeme (Node-RED, ein Datenlogger, ein zweiter Standort) dieselben Sensoren lesen können.
Warum startet mein ESPHome-Gerät alle 15 Minuten neu?
Die Komponente mqtt: hat reboot_timeout, standardmäßig 15 Minuten: Ist der Broker so lange nicht erreichbar, startet das Gerät neu. Behebe die Verbindung oder setze reboot_timeout: 0s, um das bei Geräten abzuschalten, die offline weiterlaufen müssen.
Auf welche Topics veröffentlicht ESPHome?
Standardmäßig auf <topic_prefix>/<component_type>/<object_id>/state, wobei topic_prefix der Node-Name und object_id der Entitätsname in Kleinbuchstaben mit Unterstrichen ist. Steuerbare Entitäten hören auf demselben Pfad mit der Endung /command.

