Tutorials

ESPHome-MQTT-Konfiguration: Discovery, Birth/Will und externe Broker

Die ESPHome-Komponente mqtt: einrichten: Broker und Zugangsdaten, topic_prefix, Home-Assistant-Discovery, Birth- und Will-Messages, TLS, on_message und Tests.

Aktualisiert · 9 Min. Lesezeit

ESPHome-MQTT-Konfiguration: Discovery, Birth/Will und externe Broker

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

livingroom.yaml
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: relay
secrets.yaml
wifi_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_prefix ist standardmäßig der Node-Name (livingroom). Auf einem geteilten Broker kollidiert das mit den Wohnzimmern aller anderen. Ein eindeutiges Präfix wie testmqtt/esphome/livingroom hält deine Topics bei dir.
  • client_id muss 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ätTopicRichtung
Verfügbarkeittestmqtt/esphome/livingroom/statusGerät → Broker (online / offline)
Sensor WiFi Signaltestmqtt/esphome/livingroom/sensor/wifi_signal/stateGerät → Broker
Sensor Uptimetestmqtt/esphome/livingroom/sensor/uptime/stateGerät → Broker
Zustand des Schalters Relaytestmqtt/esphome/livingroom/switch/relay/stateGerät → Broker (ON / OFF)
Befehl für den Schalter Relaytestmqtt/esphome/livingroom/switch/relay/commandBroker → Gerät (ON / OFF / TOGGLE)
Logstestmqtt/esphome/livingroom/debugGerä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:

Custom availability
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: 30s

Das 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.

Discovery on your own broker
mqtt:
  broker: broker.connectmq.com
  port: 1883
  username: !secret mqtt_user
  password: !secret mqtt_password
  discovery: true
  discovery_prefix: homeassistant
  discovery_retain: true

Gut 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:

Custom subscriptions and publishes
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: false

on_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:

TLS on ESP32
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

  1. Öffne den Online-MQTT-Client, verbinde dich mit broker.connectmq.com auf Port 8084 (Pfad /mqtt) und abonniere testmqtt/esphome/livingroom/#.
  2. Du solltest status = online (retained) sowie alle 30 Sekunden die Zustände von wifi_signal und uptime sehen.
  3. Veröffentliche ON auf testmqtt/esphome/livingroom/switch/relay/command. Das Relais schaltet, und switch/relay/state meldet ON.
  4. Veröffentliche irgendetwas auf testmqtt/esphome/livingroom/cmd/toggle, um on_message zu testen.
  5. Schalte das Board aus. Nach etwa 1,5 × Keepalive setzt das Will status auf offline. 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-MeldungWahrscheinliche 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 neureboot_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.