Wemos-D1 mit ESPHome in Home Assistant

Unsere I2C-Module lassen sich hervorragend über ESPHome in Home Assistant einbinden.

Wenn Sie planen, digitale Eingangs- oder Ausgangskarten in Ihrer Unterverteilung zu verbauen und diese komfortabel steuern möchten, ist der Wemos D1 als I2C-Master die ideale Wahl.

In diesem Beitrag zeige ich, wie ein Wemos D1 (ESP8266) mit ESPHome in Home Assistant eingebunden wird und wie darüber eigene I2C-Module genutzt werden können.
Der Fokus liegt dabei nicht auf der Installation von ESPHome selbst, sondern auf dem schrittweisen Aufbau und Verständnis der YAML-Konfiguration.

Anhand eines konkreten Beispiels werden:

  • der I2C-Bus eingerichtet,
  • digitale und analoge Ein- und Ausgänge eingebunden,
  • sowie Sensoren und steuerbare Werte (Slider) in Home Assistant sichtbar gemacht.

Am Ende des Beitrags steht eine vollständige YAML-Datei zum Download sowie ein Beispiel, wie die Ein- und Ausgänge in Home Assistant dargestellt werden.

Hardware I2C-Master mit Wemos D1 ESP8266

Wemos-D1 I2C-Master für die Hutschiene
Wemos-D1 I2C-Master für die Hutschiene

Der Bausatz I2C-WLAN-Modul für den WEMOS-D1 hat den Pegelwandler PCA9517 on Board, der die I2C-Signale vom Wemos-D1 von 3,3 auf 5V anhebt. An drei Status-LEDs kann man die Pegel der I2C-SIgnale SDA, SCL und INT beobachten.

Über unsere Busverbindern lassen sich die neueren E/A-Module im Handumdrehen mit dem Master verbinden.
Die „älteren“ SPS-Baugruppen können wie gewohnt über den Stecker verkabelt werden.

Aufbau der Peripherie

Hardware-Aufbau für I2WD1-Testboard

In diesem Blogbeitrag zeige ich wie diese vier Grundmodule angesprochen werden können.

  • Digitale Eingangskarte 8 Bit, mit PCF8574A z.B. I2HE oder I2EOK
  • Digitale Ausgangskarte 8 Bit, mit PCF8574 z.B. I2HA, I2AOK, I2AT ….
  • Analoge Eingangskarte 5 Kanal 0-10V I2HAE
  • Analoge Ausgangskarte 4 Kanal 0-10V I2HAA

ESPHome in Home Assistant

Voraussetzung für die Funktion ist, dass ESPHome in Home Assistant installiert und gestartet ist.
Eine Anleitung gibt es hier: Getting Started with ESPHome and Home Assistant

Zusätzlich habe ich den File editor installiert. Mit ihm kann man Konfigurations-Dateien wie z.B. die Datei secrets.yaml anlegen und editieren.

Neuen Wemos D1 in ESPHome anlegen

Um einen neuen Wemos D1 (oder D1 mini) in ESPHome für Home Assistant einzurichten, gehst du folgendermaßen vor:

  • ESPHome Dashboard öffnen:
    In Home Assistant öffnest du das ESPHome‑Add‑on (oben in der Seitenleiste). Dort siehst du eine Übersicht deiner ESP‑Boards.
  • Neues Gerät erstellen:
    Klicke auf „+ New Device“ oder „Gerät hinzufügen“.
    Du wirst durch einen kleinen Assistenten geführt:
    – Gib einen Gerätenamen ein (z. B. i2wd1-testboard).
    – Wähle den Board‑Typ aus – für Wemos D1 mini ist das z. B. esp8266 → d1_mini.
    – Trage dein WLAN SSID und Passwort ein oder verwende die Datei secrets.yaml für alle Passwörter
  • Erste Konfiguration speichern:
    Nach Abschluss erstellt ESPHome für dich eine Basis‑YAML‑Datei – du kannst sie im Editor öffnen und nach deinen Bedürfnissen erweitern.
  • Firmware installieren:
    Verbinde den Wemos per USB am Besten mit dem Gerät, auf dem Home Assistant läuft. Das funktioniert am einfachsten.
    Klicke im Dashboard auf „Install“ → „Plug into the computer running ESPHome Device Builder“ und folge den Anweisungen.
    ESPHome kompiliert die Firmware und spielt sie auf den Wemos.
  • Verbinden mit Home Assistant:
    Sobald der Wemos gestartet ist und sich mit deinem WLAN verbunden hat, sollte Home Assistant das Gerät automatisch erkennen.
    Alternativ kannst du es manuell über Einstellungen → Geräte & Dienste → Integration hinzufügen → ESPHome eintragen.

Nach dem ersten Flashen kannst du weitere Änderungen drahtlos Over‑The‑Air (OTA) aktualisieren – das erspart erneutes USB‑Anschließen.

YAML-Datei anpassen

In der automatisch von ESPHome angelegten Konfigurationsdatei müssen jetzt einige Eintragungen vorgenommen werden.

# ================= I2C Bus =================
i2c:
  id: i2c_bus
  sda: 4
  scl: 5
  scan: true
  frequency: 70000
 
# ========= Hier werden alle PCF8574 und PCF8574A eingetragen ========= #
pcf8574:
  - id: 'I2HE_56'                 # 112 (8-Bit) = 56 (7-Bit) = 0x38 hex
    address: 0x38
    pcf8575: False
 
  - id: 'I2HA_32'                # 64 (8-Bit) = 32 (7-bit) = 0x20 hex
    address: 0x20
    pcf8575: False
 
# ========= Hier die Adressen der analogen Karten eintragen ========= #
substitutions:
  adr_I2HAE_08: "0x08"
  adr_I2HAA_58: "0x58"

# Globales Array für analoge Eingangskarte I2HAE
globals:
  - id: input_data
    type: uint8_t[11]

I2C:
Hier wird der I2C-Bus des ESP8266 eingerichtet.

  • id: i2c_bus ist ein interner Name, damit andere Komponenten später auf denselben Bus zugreifen können.
  • sda und scl geben die GPIO-Pins an, die für die Datenleitung (SDA) und Taktleitung (SCL) verwendet werden.
  • scan: true sorgt dafür, dass ESPHome beim Start alle angeschlossenen I2C-Geräte automatisch erkennt.
  • frequency: 70000 legt die Übertragungsrate fest (hier 70 kHz).
    Für die Analogen Karten hat sich diese Einstellung bewährt

PCF8574:

PCF8574/PCF8574A sind I2C‑Expander: Sie erweitern die digitalen Ein- und Ausgänge des Boards.

  • id: Interner Name für das jeweilige Modul.
  • address: Die I2C-Adresse des Moduls. Geräte mit unterschiedlichen Adressen können am gleichen Bus hängen.
  • pcf8575: False: Gibt an, dass es ein 8-Bit-Modul (PCF8574) ist. PCF8575 wäre ein 16-Bit-Modul.

Substitutions:
Das ist eine Art Variablenliste für die YAML-Datei. Du legst hier die I2C-Adressen deiner analogen Karten einmal fest.
Später im Code kannst du z. B. ${adr_I2HAE_08} verwenden, statt die Adresse überall neu zu tippen.
Vorteil: Wenn sich die Adresse mal ändert, musst du sie nur an einer Stelle anpassen.

globals:
Hier wird eine globale Variable definiert, auf die mehrere Sensoren im YAML zugreifen können.

  • input_data ist ein Byte-Array mit 11 Elementen, das als Zwischenspeicher für die Rohdaten der analogen Eingangskarte dient.

Die analoge I2C-Karte liefert mehrere Messwerte in einem Datenblock, der zuerst vollständig in dieses Array eingelesen wird. Anschließend greifen die einzelnen analogen Sensoren auf die jeweiligen Bytes zu und berechnen daraus die Spannungswerte.


Im nächsten Schritt werden die digitalen Eingänge eines PCF8574-I2C-Moduls in Home Assistant eingebunden.

# ========= Hier werden die digitalen Eingänge der Module konfiguriert ========= #
binary_sensor:
### I2C-INPUT Adresse 56 ###
  - platform: gpio
    name: "E56.0"
    device_class: opening
    pin:
      pcf8574: I2HE_56
      number: 0
      mode: INPUT
      inverted: False
    filters:
      - delayed_on: 25ms
      - delayed_off: 25ms
     
  - platform: gpio
    name: "E56.1"
    device_class: opening
    pin:
      pcf8574: I2HE_56
      number: 1
      mode: INPUT
      inverted: False
    filters:
      - delayed_on: 25ms
      - delayed_off: 25ms

...

Binary Sensor:
Jeder Eingang muss als „binary_sensor“ angelegt werden. Er erscheint später als Schalter bzw. Statusanzeige in Home Assistant.

  • platform: gpio
    Der Eingang verhält sich für ESPHome wie ein normaler GPIO-Pin, kommt aber vom I2C-Expander.
  • name:
    Dieser Text wird im Dashboard dann neben dem Sensor angezeigt
  • device_class: opening
    Sorgt für eine passende Darstellung in Home Assistant (z. B. als Kontakt).
  • pin:
    • pcf8574: I2HE_56
      Verknüpft den Eingang mit dem zuvor definierten PCF8574-Modul an Adresse 56.
    • number: 0-7
      Gibt an, welcher Pin des PCF8574 verwendet wird.
    • mode: INPUT
      Der Pin wird als Eingang konfiguriert.
    • inverted: False
      Eingang nicht invertieren. (Passt so für unsere Eingenagskarten)
  • filters: delayed_on / delayed_off
    Entprellung des Eingangs, um kurze Störungen oder Prellen von Kontakten zu unterdrücken.

Im nächsten Schritt werden die digitalen Ausgänge eines PCF8574-I2C-Moduls in Home Assistant eingebunden.

# ========= Hier werden die digitalen Ausgänge der Module konfiguriert ========= # 
switch:
### I2C-OUTPUT Adresse 32 ###
  - platform: gpio
    name: "A32.0"
    pin:
      pcf8574: I2HA_32
      number: 0
      mode:
        output: true
    inverted: true

  - platform: gpio
    name: "A32.1"
    pin:
      pcf8574: I2HA_32
      number: 1
      mode:
        output: true
    inverted: true

...

Switch:
Jeder Ausgang wird in Home Assistant als Schalter (switch) angelegt.
So lassen sich die Ausgänge direkt in der Oberfläche ein- und ausschalten oder in Automationen verwenden.

  • platform: gpio
    Der Ausgang verhält sich für ESPHome wie ein normaler GPIO-Pin, steuert aber den I2C-Expander.
  • name:
    Dieser Text wird im Dashboard dann neben dem Schalter angezeigt
  • pin:
    • pcf8574: I2HA_32
      Verknüpft den Ausgang mit dem zuvor definierten PCF8574-Modul an Adresse 32.
    • number: 0-7
      Gibt an, welcher Pin des PCF8574 verwendet wird.
    • mode: OUTPUT
      Der Pin wird als Ausgang konfiguriert.
    • inverted: True
      Ausgang invertieren. (Passt so für unsere Ausgangskarten)

Jetzt wird es interessant, denn für die analogen I2C-Karten gibt es in ESPHome keine fertigen Komponenten. Deshalb müssen die Messwerte direkt per I2C über einen lambda-Code ausgelesen werden.

Dabei passiert Folgendes:

  • Über den I2C-Bus wird zuerst ein Kommando an die analoge Karte gesendet, um den internen Datenzeiger zurückzusetzen.
  • Anschließend liest der ESP 11 Bytes am Stück aus der Karte aus.
    Diese Rohdaten werden in dem oben definierten globalen Array gespeichert.
  • Aus jeweils zwei Bytes wird dann der eigentliche Messwert berechnet und auf einen Spannungswert skaliert.
  • Der berechnete Wert wird von ESPHome als normaler Sensor an Home Assistant übergeben.

Auf diese Weise lassen sich auch eigene oder spezielle I2C-Module sauber in ESPHome integrieren, obwohl es dafür keine Standard-Treiber gibt.

Der Sensor verhält sich in Home Assistant anschließend genauso wie jeder andere native ESPHome-Sensor.

# ========= Hier werden die analogen Eingänge konfiguriert ========= # 
sensor:
  - platform: template
    name: "Analog-IN1"
    unit_of_measurement: "V"
    update_interval: 1s
    accuracy_decimals: 2
    lambda: |-
      // Zeiger auf 0 stellen
      uint8_t cmd[1] = {0x00}; 
      id(i2c_bus).write(${adr_I2HAE_08}, cmd, 1);
      delay(5); 
      // 11 Bytes lesen und ablegen
      if (id(i2c_bus).read(${adr_I2HAE_08}, id(input_data), 11) == esphome::i2c::ERROR_OK) {
        return (float)(id(input_data)[2]*256 + id(input_data)[1]) / 100.0f;
      } else {
        return NAN;
      }

  - platform: template
    name: "Analog-IN2"
    unit_of_measurement: "V"
    update_interval: 1s
    accuracy_decimals: 2
    lambda: |-
      return (float)(id(input_data)[4]*256 + id(input_data)[3]) / 100.0f;

  - platform: template
    name: "Analog-IN3"
    unit_of_measurement: "V"
    update_interval: 1s
    accuracy_decimals: 2
    lambda: |-
      return (float)(id(input_data)[6]*256 + id(input_data)[5]) / 100.0f;

...

Sensor:
Ein Sensor ist einfach ein Gerät oder eine Komponente, die Messwerte liefert.

  • platform: template
    Der Sensor wird über eigenen Code (lambda) berechnet, statt über fertige ESPHome-Komponenten.
  • name: „Analog-IN 1 .. 5“
    Name des Sensors in Home Assistant.
  • unit_of_measurement: „V“
    Anzeige in Volt.
  • update_interval: 1s
    Wie oft der Sensor den Wert aktualisiert (hier jede Sekunde).
  • accuracy_decimals
    Anzeige auf 2 Nachkommastellen.
  • lambda: return (float)(id(input_data)[4]*256 + id(input_data)[3]) / 100.0f;

    Was macht der lambda-Code?

    • Nimmt zwei Bytes aus dem globalen Array input_data (hier [4] und [3]).
    • Verknüpft sie zu einem 16-Bit-Wert (high*256 + low).
    • Teilt durch 100.0, um den Wert auf Volt zu skalieren.
    • Gibt das Ergebnis als Sensorwert an Home Assistant zurück.

Zum Schluss noch die Ansteuerung der analogen Ausgänge. Auch hier müssen wir den Weg über einen lambda-Code gehen, da es für die analoge Ausgangskarte keine fertige ESPHome Komponente gibt.

# ========= Hier werden die analogen Ausgänge konfiguriert ========= # 
number:
  - platform: template
    name: "Analog-OUT1"
    min_value: 0
    max_value: 100
    step: 1
    initial_value: 0
    optimistic: true
    mode: slider
    unit_of_measurement: "%" # Optional: zeigt % im Slider an
    set_action:
      lambda: |-
        // Wert von 0-100 auf 0-1000 skalieren
        int aw_val = (int)(x * 10.0f); 
        
        uint8_t hby = aw_val / 256;
        uint8_t lby = aw_val - hby * 256;
        
        uint8_t data[3];
        data[0] = 0;    // Kanal 0
        data[1] = lby;  
        data[2] = hby;  
        
        id(i2c_bus).write(${adr_I2HAA_58}, data, 3);
        delay(5);

  - platform: template
    name: "Analog-OUT2"
    min_value: 0
    max_value: 100
    step: 1
    initial_value: 0
    optimistic: true
    mode: slider
    unit_of_measurement: "%"
    set_action:
      lambda: |-
        int aw_val = (int)(x * 10.0f);
        uint8_t hby = aw_val / 256;
        uint8_t lby = aw_val - hby * 256;
        
        uint8_t data[3];
        data[0] = 1;    // Kanal 1
        data[1] = lby;
        data[2] = hby;
        
        id(i2c_bus).write(${adr_I2HAA_58}, data, 3);
        delay(5);

...

Number:
Ein number ist eine steuerbare Größe, die Home Assistant an ein Gerät oder Modul sendet – also das Gegenstück zum Sensor:

  • number: template
    Definiert einen „analogen Ausgang“ als steuerbaren Wert in Home Assistant.
  • name: „Analog-OUT1 .. 4“
    Name des Aktors in Home Assistant.
  • Slider in Home Assistant
    mode: slider, min_value/max_value und step bestimmen, wie der Nutzer den Wert einstellen kann.
  • optimistic: true
    Home Assistant geht davon aus, dass der Wert erfolgreich gesetzt wurde, auch wenn die Rückmeldung vom Gerät fehlt.
  • lambda-Code
    übersetzt den vom Slider gewählten Wert in das Format, das die analoge I2C-Karte versteht:
  • Was macht der lambda-Code?
    • Wert von 0–100 wird auf 0–1000 skaliert (x * 10)
    • In zwei Bytes aufgeteilt (high byte + low byte).
    • Kanalnummer davor setzen
    • Mit i2c_bus.write an die Karte schicken
    • Kurze Pause delay(5) für stabile Übertragung.

Praxis-Tipp: I2C-Bus Fehlersuche mit der Scan-Funktion

Einer der größten Vorteile von ESPHome ist der integrierte I2C-Scanner. Wenn ein Modul nicht wie gewünscht reagiert, liegt das oft an einer falschen Adresse oder einer fehlerhaften Verkabelung.

Da wir in der Konfiguration scan: true gesetzt haben, prüft der Wemos D1 bei jedem Systemstart den kompletten Adressbereich des Busses.

So nutzt du die Funktion zur Fehlersuche:

  • Öffne im ESPHome-Dashboard die Logs deines Geräts.
  • Starte den Wemos neu (entweder per Reset-Knopf oder über das Log-Fenster).
  • Achte auf die gelben Textzeilen. Dort erscheint eine Auflistung aller gefundenen Geräte: [I2C] [01:23:45] Found i2c device at address 0x20 [I2C] [01:23:45] Found i2c device at address 0x38

Was tun, wenn nichts gefunden wird?

  • Verkabelung prüfen: Sind SDA (D2) und SCL (D1) vertauscht?
  • Stromversorgung: Liegen die 5V am Horter-Modul an? (Die Status-LEDs am Master-Bausatz sollten leuchten).
  • Adresskonflikt: Haben zwei Module versehentlich die gleiche Jumper-Einstellung?

Der Scanner ist dein wichtigstes Werkzeug, um sicherzustellen, dass die Hardware-Basis steht, bevor du dich auf die Software-Konfiguration konzentrierst.

Ansicht im Home Assistant Dashboard

I2WD1-HomeAssistant Dashboard

Komplette YAML-Datei zum Download

Hier kann die komplette YAML-Datei für das I2WD1-Testboard heruntergeladen werden.
YAML-Datei I2WD1-Testboard (82 Downloads )

Ich würde die nicht in ESPHome direkt importieren sondern besser in einem Editor wie Notepad++ öffnen und in die vorbereitete Konfigurationsdatei rein kopieren ..um die bestehende substitutions und wifi Struktur deiner eigenen Installation nicht zu überschreiben.

Achtung:
Wie bereits oben besprochen, sind in der YAML-Datei meine sicherheitsrelevanten Daten nicht mit enthalten. Ich habe die in meinem ESPHome in einer separaten Datei secrets.yaml abgespeichert.

# Sensible Daten sind in der Datei "secrets.yaml" abgelegt
# ========================================================
# Enable Home Assistant API
api:
  encryption:
    key: !secret i2wd1_api_key

ota:
  - platform: esphome
    password: !secret i2wd1_ota_password

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

Die secrets.yaml muss im gleichen Ordner liegen wie die Konfigurationsdatei vom ESP!

/config/
└── esphome/
    ├── I2WD1-Testboard.yaml  <-- Deine Hauptdatei
    └── secrets.yaml          <-- Hier müssen die Zugangsdaten reinCode-Sprache: PHP (php)

Fazit

Mit ESPHome lassen sich auch eigene oder spezielle I2C-Module sehr flexibel in Home Assistant integrieren – selbst dann, wenn es dafür keine fertigen Komponenten gibt.
Durch den Einsatz von template-Sensoren, number-Slidern und etwas lambda-Code können analoge und digitale Signale sauber abgebildet und gesteuert werden.

Die hier gezeigte YAML-Struktur dient als Grundlage, die sich leicht auf weitere Module, Kanäle oder Projekte erweitern lässt.
So entsteht eine transparente, wartbare Lösung, bei der Hardware-Funktion und Home-Assistant-Darstellung klar miteinander verknüpft sind.

Speichere in deinen Favoriten diesen permalink.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert