ESP32 und Schwimmschalter: Wasserstand in Home Assistant überwachen

Für die Umsetzung dieses Setups wird ein funktionsfähiges Home-Assistant-System mit installiertem ESPHome-Add-on benötigt. Die Schritte zur Ersteinrichtung des Mikrocontrollers sind im Beitrag ESP32 NodeMCU mit ESPHome in Home Assistant einrichten detailliert beschrieben.

Die Überwachung definierter Wasserstandsgrenzen ist ein klassischer Anwendungsfall im Smart Home, beispielsweise für Zisternen, Aquarien oder als Überlaufschutz. In diesem Beitrag erfährst du, wie du mechanische Schwimmschalter (Pegelschalter) an einen ESP32 anschließt. Wir starten mit einem einfachen Sensor und erweitern das Setup anschließend um einen zweiten Schalter, um einen minimalen und maximalen Füllstand zu erfassen.

Die Kernkomponenten für den Aufbau

Transparenz-Check Damit ich diesen Blog werbefrei halten kann, verwende ich Affiliate-Links (mit * markiert). Wenn du darüber etwas kaufst, erhalte ich eine kleine Provision von Amazon – für dich ändert sich am Preis rein gar nichts. Danke für deinen Support meiner Projekte!

Für dieses Projekt benötigen wir neben dem Mikrocontroller die eigentlichen Sensoren und eine Lösung, um deren lose Kabelenden sauber anzuschließen.

ESP32 NodeMCU Development Board

Nahaufnahme eines physischen ESP32 NodeMCU Development Boards mit modernem USB-C Anschluss auf hellem Untergrund
ESP32 NodeMCU Board mit integrierter USB-C-Schnittstelle

Dieses ESP32 NodeMCU Development Board* (Werbung) bildet die Basis des Projekts. Es verarbeitet die Signale der Schalter und sendet die Zustandsänderungen per WLAN an Home Assistant.

Für diesen Beitrag wird die weit verbreitete 30-Pin-Variante mit ESP32-Chip verwendet. Die Programmierung und Stromversorgung erfolgt unkompliziert über die integrierte USB-C-Schnittstelle.

Schwimmschalter (Pegelschalter)

Ein typischer Schwimmschalter aus Kunststoff mit losen Kabelenden
Mechanischer Schwimmschalter mit losen Anschlusskabeln

Ein Schwimmschalter* (Werbung) ist ein mechanischer Schalter. Im Inneren des beweglichen Schwimmers befindet sich ein Magnet, der bei steigendem oder fallendem Wasserstand einen Reed-Kontakt im Schaft schließt oder öffnet.

Da es sich um einen reinen Kontakt handelt, spielt die Polarität der beiden Anschlusskabel keine Rolle. Die Sensoren werden meist mit losen Kabelenden (Litzen) ausgeliefert.

ESP32 Breakout Board (Expansion Board)

ESP32 Expansion Board mit Schraubklemmen für die GPIO-Pins
ESP32 Expansion Board mit praktischen Schraubklemmen

Um die losen Kabelenden des Schwimmschalters sicher mit dem ESP32 zu verbinden, ohne direkt zum Lötkolben greifen zu müssen, bietet sich ein ESP32 Breakout-Board mit Schraubklemmen* (Werbung) an.

Der ESP32 wird auf das Board gesteckt. Die GPIO-Pins werden dadurch nach außen auf Schraubklemmen geführt, in die sich Litzen direkt und sicher einklemmen lassen.

Einsatzzweck des Breakout-Boards Das Breakout-Board eignet sich gut für einen Versuchsaufbau und kann bei fachgerechter Montage auch dauerhaft verwendet werden. Für einen zuverlässigen Betrieb sollten Litzen mit passenden Aderendhülsen versehen, gegen Zug gesichert und alle Verbindungen vor Feuchtigkeit geschützt werden. Je nach Einbauort kommen alternativ verlötete und isolierte Verbindungen oder geeignete wassergeschützte Steckverbinder infrage.

Basis-Setup: Einen einzelnen Schwimmschalter anschließen

Für einen kurzen, störungsarmen Versuchsaufbau kann der interne Pull-up-Widerstand des ESP32 verwendet werden, sodass kein zusätzlicher Widerstand erforderlich ist. Bei längeren Leitungen oder elektrisch störungsreichen Umgebungen kann ein externer Pull-up-Widerstand beziehungsweise eine zusätzliche Schutzbeschaltung sinnvoll sein.

Verbinde die beiden Adern des Schwimmschalters wie folgt mit den Schraubklemmen des Breakout Boards. Die Reihenfolge der beiden Kabel des Schalters ist irrelevant. Auf dem Breakout-Board entspricht die Beschriftung D4 dem Pin GPIO 04 des ESP32.

Schwimmschalter (Kabel) ESP32 Pin Funktion
Kabel 1 GND Masseverbindung
Kabel 2 GPIO 04 (D4) Signaleingang (digital)
Nahaufnahme der Verkabelung eines Schwimmschalters am ESP32 Breakout-Board an den Klemmen D4 und GND
Physischer Anschluss am Breakout-Board: Ein Kabel an GND, das andere an GPIO 04

ESPHome Code-Konfiguration für einen Sensor

Damit der ESP32 den Zustand des Pins ausliest, nutzen wir in ESPHome die Komponente binary_sensor. Ob der Kontakt bei hohem oder niedrigem Wasserstand geschlossen ist, hängt vom jeweiligen Schalter und seiner Einbaulage ab. Prüfe die beiden Zustände daher vor der Montage mit einem Multimeter oder im ESPHome-Log.

Ein wichtiges Detail bei der Überwachung von Flüssigkeiten ist die Unruhe der Wasseroberfläche. Würden wir den Sensor ungefiltert auslesen, würde jede kleine Welle oder Erschütterung (z. B. beim Einlaufen von Wasser) ein schnelles Hin- und Herschalten auslösen. Das führt zu unruhigen Daten und unnötigen Automatisierungs-Triggern in Home Assistant.

Zusätzlich zum Entprellen des mechanischen Kontakts verwenden wir eine Verzögerung von 5 Sekunden, um kurze Zustandswechsel durch Wellen oder Erschütterungen auszublenden. Eine Änderung wird erst an Home Assistant übertragen, wenn der neue Zustand mindestens 5 Sekunden lang bestehen bleibt.

name: esp32-schwimmschalter

# ... (WLAN und API Einstellungen bleiben unberührt)

binary_sensor:
  - platform: gpio
    pin:
      number: GPIO04
      # Aktiviert den internen Pull-Up-Widerstand des ESP32
      # Geschlossener Kontakt wird als ON ausgegeben
      inverted: true
      mode:
        input: true
        pullup: true
    name: "Wasserstand Zisterne"
    # Die Device-Class legt die Darstellung in Home Assistant fest.
    # inverted: true setzt voraus, dass ein geschlossener Kontakt als „feucht“ gelten soll.
    device_class: moisture
    filters:
      # Wellenfilter & Entprellen: Der Zustand muss für 5 Sekunden stabil sein
      - delayed_on: 5s
      - delayed_off: 5s
Tipp für den Testaufbau Wenn du die Schaltung auf deinem Schreibtisch mit der Hand testen möchtest, können sich 5 Sekunden Verzögerung zäh anfühlen. Setze den Wert für den "Trockentest" gerne temporär auf 100ms herunter. Für den späteren Betrieb kannst du mit 5s beginnen und den Wert an die Bewegung der Flüssigkeit sowie die gewünschte Reaktionszeit anpassen. Bei einem zeitkritischen Überlaufschutz sollte die Verzögerung entsprechend kürzer gewählt und praktisch getestet werden.

Klicke auf 'INSTALL' und lasse das Log-Fenster nach dem Flashen geöffnet. ESPHome initialisiert den für GPIO 4 konfigurierten Binärsensor und zeigt dessen Einstellungen im Log an:

[13:30:40.816][C][gpio.binary_sensor:016]: GPIO Binary Sensor 'Wasserstand Zisterne'
[13:30:40.820][C][gpio.binary_sensor:232]:   Device Class: 'moisture'
[13:30:40.820][C][gpio.binary_sensor:152]:   Pin: GPIO4
[13:30:40.821][C][gpio.binary_sensor:061]:   Mode: interrupt
[13:30:40.824][C][gpio.binary_sensor:063]:   Interrupt Type: ANY_EDGE

Zustandsänderungen des Sensors werden (nach Ablauf der 5-sekündigen Filterzeit) ebenfalls im Log ausgegeben:

[13:31:25.000][S][binary_sensor]: 'Wasserstand Zisterne' >> ON
[13:31:50.000][S][binary_sensor]: 'Wasserstand Zisterne' >> OFF

Erweiterter Aufbau: Zwei Schwimmschalter für Min/Max-Füllstand

In vielen Szenarien reicht ein einzelner Sensor nicht aus. Für eine Pumpensteuerung können zwei Schaltpunkte sinnvoll sein: Der untere Schalter kann beispielsweise als Trockenlaufschutz dienen, während der obere Schalter das Leeren eines Behälters auslöst. Die konkrete Ein- und Ausschaltlogik hängt davon ab, ob die Pumpe den Behälter füllt oder leert.

Der ESP32 verfügt über mehrere GPIO-Pins, sodass sich mehrere Schalter getrennt auswerten lassen. Die Schalter können eine gemeinsame Masseverbindung verwenden, ihre Signalleitungen werden jedoch jeweils an einen eigenen GPIO angeschlossen. Für den zweiten Schalter nutzen wir in diesem Beispiel GPIO 05.

Sensor Schwimmschalter (Kabel 1) Schwimmschalter (Kabel 2)
Schalter 1 (Minimum) GND GPIO 04
Schalter 2 (Maximum) GND (kann ein zweiter GND-Pin sein) GPIO 05

ESPHome Code-Konfiguration für mehrere Sensoren

Die Konfiguration in ESPHome wird einfach um einen weiteren Eintrag unter binary_sensor ergänzt. Beide Sensoren erhalten eigene Namen und nutzen den praxisnahen 5-Sekunden-Filter.

name: esp32-schwimmschalter

# ... (WLAN und API Einstellungen bleiben unberührt)

binary_sensor:
  # Erster Sensor: Minimaler Füllstand
  - platform: gpio
    pin:
      number: GPIO04
      inverted: true
      mode:
        input: true
        pullup: true
    name: "Füllstand Minimum"
    device_class: moisture
    filters:
      - delayed_on: 5s
      - delayed_off: 5s

  # Zweiter Sensor: Maximaler Füllstand
  - platform: gpio
    pin:
      number: GPIO05
      inverted: true
      mode:
        input: true
        pullup: true
    name: "Füllstand Maximum"
    device_class: moisture
    filters:
      - delayed_on: 5s
      - delayed_off: 5s

Klicke erneut auf 'INSTALL' und lasse das Log-Fenster nach dem Flashen geöffnet. ESPHome initialisiert die für GPIO 4 und GPIO 5 konfigurierten Binärsensoren und zeigt deren Einstellungen im Log an:

[13:43:14.050][C][gpio.binary_sensor:016]: GPIO Binary Sensor 'Füllstand Minimum'
[13:43:14.053][C][gpio.binary_sensor:232]:   Device Class: 'moisture'
[13:43:14.053][C][gpio.binary_sensor:152]:   Pin: GPIO4
[13:43:14.053][C][gpio.binary_sensor:061]:   Mode: interrupt
[13:43:14.065][C][gpio.binary_sensor:063]:   Interrupt Type: ANY_EDGE
[13:43:14.088][C][gpio.binary_sensor:016]: GPIO Binary Sensor 'Füllstand Maximum'
[13:43:14.088][C][gpio.binary_sensor:232]:   Device Class: 'moisture'
[13:43:14.088][C][gpio.binary_sensor:152]:   Pin: GPIO5
[13:43:14.089][C][gpio.binary_sensor:061]:   Mode: interrupt
[13:43:14.089][C][gpio.binary_sensor:063]:   Interrupt Type: ANY_EDGE

Und die Zustandsänderungen im laufenden Betrieb:

[13:43:32.710][S][binary_sensor]: 'Füllstand Minimum' >> ON
[13:43:34.993][S][binary_sensor]: 'Füllstand Maximum' >> ON
[13:43:43.380][S][binary_sensor]: 'Füllstand Maximum' >> OFF
[13:43:46.499][S][binary_sensor]: 'Füllstand Minimum' >> OFF

Nachdem du diese Konfiguration über ESPHome auf den Mikrocontroller geladen hast, stehen dir in Home Assistant zwei separate Entitäten zur Verfügung. Mit diesen beiden Zuständen lassen sich Automatisierungen für Pumpensteuerungen oder Benachrichtigungen beim Erreichen definierter Füllstände erstellen. Bei Anwendungen, bei denen ein Ausfall Schäden verursachen kann, sollte die ESPHome- beziehungsweise Home-Assistant-Automatisierung durch geeignete elektrische Schutz- und Sicherheitsmechanismen ergänzt werden.

Verwendete Hardware-Komponenten

Folgende Komponenten kamen in diesem Projekt zum Einsatz:

Weitere Praxisprojekte

Aufbauend auf der ESP32 Ersteinrichtung können verschiedene Hardware-Komponenten und Sensoren an den Mikrocontroller angebunden werden. Bisher dokumentierte Projekte:

Ansteuerung eines 3-Farben RGB-LED-Moduls

Schritt-für-Schritt-Anleitung zum Anschluss mehrerer RGB-LED-Module mittels G-V-S Expansion Board und der Erstellung individueller Lichteffekte in ESPHome.

Temperaturmessung mit dem DS18B20 am ESP32

Schritt-für-Schritt-Anleitung zum physischen Anschluss des wasserdichten Sensors DS18B20 und der effizienten Auslesung mehrerer Fühler über den 1-Wire-Bus in ESPHome.

GPS-Tracker mit dem Beitian BE-220 am ESP32

Schritt-für-Schritt-Anleitung zur Einbindung des GPS-Moduls BE-220 in ESPHome und Visualisierung der Standortdaten in Home Assistant.

Zisternen-Füllstand mit dem JSN-SR04T am ESP32 messen

Schritt-für-Schritt-Anleitung zum Anschluss des wasserdichten Ultraschallsensors JSN-SR04T an einen ESP32 sowie zur Konfiguration der Entfernungsmessung in ESPHome.