Ich stand vor der Herausforderung, dass wir im Gartenhaus, ganz am hinteren Ende des Gartens eine sehr schlechte Verbindung des Temperatur- und Luftfeuchtigkeits-Sensors bis zum Zigbee-Controller im Haus haben. Gerade jetzt im Winter wo es interessant gewesen wäre, haben wir wochenlang keine Verbindung gehabt.
Aus demselben Grund habe ich damals auch die ZigBee-Komponenten (Steckdose, Lichtschaltung) gegen WLAN-Komponenten getauscht.
Da ich vor vielen Jahren (tatsächlich schon 2019) schon einmal einen Temperatursensor für den Pool und die Luft am Pool gebaut habe, wollte ich das Projekt mal in die Neuzeit holen und dem Gartenhaus ebenfalls einen Sensor per WiFi spendieren.
Voraussetzungen
Damals habe ich den Sensor komplett selbst programmiert und die Daten per MQTT verteilt. Jede Anpassung und Updates erfordern aber, dass ich den MicroController an den Rechner anschließe.
Da ich in HomeAssistant eh schon auf ESPhome-Komponenten setze, sollte es also über den ESPhome-Builder über das Netzwerk (OTA = Over-the-Air) laufen.
Die Komponenten waren schnell zusammengestellt und bestellt.
- ESP32 C3 SuperMini (statt ESP8266)
- BME280 I2C Sensor für die Temperatur und Luftfeuchtigkeit (Bonus: Luftdruck)
Das Gerät wird zwar an einem USB-Netzteil (ich habe so eine schicke Zwischensteckdose, weil da immer mal wieder Geräte geladen werden müssen) betrieben, aber kann theoretisch auch mit Powerbank oder Batterie betrieben werden.
Zudem habe ich den ESP32C3 schon mit ESPhome geflasht — dazu gibt es reichlich gute Anleitungen im Netz.
Konzept
Das Gerät verbindet sich mit dem WLAN, was im Garten eine gute Abdeckung hat. Der Sensor liefert die Daten, auf die in HomeAssistant direkt per ESPhome zugegriffen werden kann. Das Gerät legt sich für 10 Minuten in den DeepSleep, bevor es zur nächsten Messung wieder aufwacht. Das ist sehr stromsprend.
Code
Der eigentliche Code ist sehr simpel. Ein paar Angeben zum Board, WiFi-Verbindung, und die Einstellungen, welche Pins für die I2C-Kommunikation verwendet werden. Zum Schluß (ab Zeile 28) dann die Konfiguration des Sensors mit den Namen, wie sie in Homeassistant auftauchen sollen.
esphome:
name: esphome-web-e25998
friendly_name: Poolhaus Klima
min_version: 2025.11.0
name_add_mac_suffix: false
platformio_options:
board_build.flash_mode: dio
esp32:
board: esp32-c3-devkitm-1
framework:
type: arduino
# Allow Over-The-Air updates
ota:
platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
power_save_mode: none
i2c:
sda: GPIO5
scl: GPIO6
scan: true
sensor:
- platform: bme280_i2c
temperature:
name: "BME280 Temperatur"
humidity:
name: "BME280 Luftfeuchtigkeit"
pressure:
name: "BME280 Luftdruck"
address: 0x76 // other 0x77
update_interval: 600s
Ich wollte dem Ganzen ja noch DeepSleep beibringen und bin dabei noch über eine Hürde gestolpert, die ich dir nicht vorenthalten will.
DeepSleep funktionierte schnell und unkompliziert. Aber dann wollte ich noch mal Anpassungen vornehmen, aber: Das Gerät ist offline.
Natürlich. Aber damit kann ich keine Updates mehr einspielen bzw. habe nur ein sehr kurzes Zeitfenster.
Also sorgt der folgende Code dafür, dass alle 10 Minuten der DeepSleep unterbrochen wird um eine neue Messung durchzuführen. Das dauert dann maximal 30 Sekunden.
Aber: Wenn es einen Reboot des Gerätes gab, soll es einen Slot von 5 Minuten geben.
Damit kann ich im Bedarfsfall das Gerät einmal neu starten und habe dann ein 5-Minuten-Fenster um neuen Code einzuspielen.
esphome:
name: esphome-web-e25998
friendly_name: Poolhaus Klima
on_boot:
priority: -100
then:
- delay: 1s
- component.update: bme280_comp
- if:
condition:
lambda: |-
// DeepSleep-Wakeup -> kurz wach bleiben
return esp_reset_reason() == ESP_RST_DEEPSLEEP;
then:
- logger.log: "Wake from DeepSleep -> staying awake 30s"
- delay: 30s
else:
- logger.log: "Reboot/Power-on/Reset -> staying awake 5min (OTA window)"
- delay: 5min
- deep_sleep.enter: deep_sleep_1
esp32:
board: esp32-c3-devkitm-1
framework:
type: arduino
logger:
api:
ota:
platform: esphome
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
power_save_mode: none
fast_connect: true
i2c:
sda: GPIO5
scl: GPIO6
scan: true
sensor:
- platform: bme280_i2c
id: bme280_comp
temperature:
name: "BME280 Temperatur"
humidity:
name: "BME280 Luftfeuchtigkeit"
pressure:
name: "BME280 Luftdruck"
address: 0x76 // other 0x77
update_interval: never
deep_sleep:
id: deep_sleep_1
sleep_duration: 10min