CO2 Ampel mit ESPHome und Home Assistant

Um die Ansteckungsgefahr mit Corona-Viren in Innenräumen zu minimieren, soll regelmäßig gelüftet werden. Der CO2-Gehalt der Raumlauft ist ein guter Indikator dafür. Ich habe eine Lösung auf Basis von ESPHome gebastelt.
Bitte beachte: Dieser Beitrag ist mehr als 3 Jahre alt. Manche Links, Preise, Produkte und Aussagen sind vielleicht nicht mehr aktuell!

Das Corona-Virus wird uns wohl noch lange begleiten. Gerade in Räumen mit vielen Personen aus unterschiedlichen Haushalten ist die Ansteckungsgefahr hoch. Gleiches gilt aber schon lange für Grippeviren. Die US-Wissenschaftler Rudnick und Milton steckten dazu 30 Personen, darunter eine mit Grippe-Infektion 4 Stunden in einen Raum. Bei einem CO2-Gehalt in der Luft von 1000 ppm infizierten sich fünf Personen, bei 2000 ppm waren es schon 12 und bei 3000 ppm 15 Personen.

Ein niedriger CO2 Wert hat aber auch abseits von Infektionskrankheiten eine wichtige Bedeutung. Bei zu hohen CO2-Werten in der Raumluft sinkt die Aufmerksamkeit und Konzentration merklich und kann Kopfschmerzen und Müdigkeit verursachen, was gerade an Schulen beachtet werden sollte – auch ganz ohne Corona-Problematik.

Welche CO2 Werte sind für eine Ampel geeignet

Das war genau die Frage, die sich nach meinen Recherchen sehr schwer beantworten lässt. Gerne wird die Pettenkofer-Zahl, nach dem deutschen Hygieniker Prof. Max von Pettenkofer (1818-1901) genannt. Dieser fand heraus, dass 1.000 ppm CO2 der Grenzwert für eine gute Luftqualität sind. Allerdings gab es 1858 noch keine hochdichten Gebäudehüllen oder Isolierglasfenster. Zudem war der natürliche CO2 Gehalt in der Außenluft mit 350 ppm noch deutlich niedriger als heute mit durchschnittlich 400 ppm (in Städten oft 450 – 500 ppm). So fand die Pettenkofer-Zahl auch keinen Einzug mehr in die entsprechende DIN-Normen.

Melde dich zu meinem Newsletter an!

Du kannst dich jederzeit abmelden und ich verspreche: Kein Spam!

In der DIN 1946-2 ging man von 1.500 ppm als Grenzwert für den CO2-Gehalt in der Luft von Innenräumen aus, ohne aber wissenschaftliche Grundlagen dafür zu nennen. Diese DIN-Norm wurde durch die DIN 13779 ersetzt und hier wurden 4 IDA-Kategorien (In Door Air) definiert, die eine CO2 Konzentration über der Außenluft definieren:

KategorieBeschreibungErhöhung gegenüber Außenluft in ppmAbsoluter CO2 Gehalt bei 400 ppm CO2 in Außenluft
IDA 1Hohe Raumluftqualität<= 400 <= 800
IDA 2Mittlere Raumluftqualität> 400 – 600 > 800 – 1000
IDA 3Mäßige Raumluftqualität> 600 – 1000> 1000 – 1400
IDA 4Niedrige Raumluftqualität> 1000> 1400
Einteilung der Raumluftqualität in IDA-Kategorien

Wohnt man in einer belebten Innenstadt, kann man für die Außenluft schon Werte um 500 ppm annehmen und die absoluten Werten erhöhen sich entsprechend.

Lüftungs-Ampel mit ESPHome und MH-Z19B Sensor

Um die CO2-Belastung in der Luft messen zu können, benötigt man einen entsprechenden Sensor. Sehr gut verfügbar und relativ preiswert sind die CO2-Sensoren vom Typ MH-Z19B, die 25 Euro kosten. Diese Sensoren arbeiten nach dem NDIR-Prinzip. Eine kleine Glühlampe wird als breitbandige Infrarotquelle genutzt, damit eine Probenkammer durchleuchtet und dann über einen Filter auf einen Infrarotsensor geleitet. Der Filter ist dabei so schmalbandig ausgelegt, dass die CO2-Moleküle das Infrarotlicht absorbieren und somit weniger Licht auf den Sensor fällt. Je höher die CO2-Konzentration in der Messkammer, desto weniger Infrarotstrahlung fällt auf den Sensor.

Ausgelesen wir der MH-Z19 per seriellem UART-Interface mit 9600 Baud, kann also ganz einfach angebunden werden. Wichtig ist, dass er mit 5 Volt versorgt wird. Er funktioniert zwar grundsätzlich auch mit 3,3 Volt, allerdings weichen die gemessenen Werte dann stark ab. Das Datenblatt nennt einen Spannungsbereich von 3,6 bis 5,2 Volt. Schön ist hingegen, dass man die seriellen RX/TX-Anschlüsse ohne Pegelkonverter an 3,3 Volt-GPIOs wie etwa am ESP8266 oder Raspberry Pi nutzen kann.

Prototyp mit MH-Z19 Sensor

Da ich den Sensor ohnehin mit Home Assistant (HA) nutzen wollte, musste das Rad dazu nicht neu erfunden werden und man muss das auch nicht von ganz vorne programmieren.

Home Assistant bringt mit ESPHome seine eigene Plattform für ESP-Microcontroller mit, die sich über Home Assistant flashen, programmieren und aktualisieren lässt. Außerdem werden sie über eine native API an HA angebunden und nicht per MQTT, was die ganze Sache noch schneller und komfortabler macht.

ESPHome-Verwaltung in Home Assistant
ESPHome-Verwaltung in Home Assistant

Wenn man einen jungfräulichen ESP, Wemos oder auch Sonoff vor sich hat, kann man die passende Firmware direkt in HA erstellen und kompilieren lassen. Entweder steckt man dann den Mikrocontroller an einem USB-Anschluss des HA-Rechners an und kann damit die Firmware direkt flashen oder man speichert sich die Binary-Datei und flasht sie z. B. mit einem Tool wie dem NodeMCU-Flasher oder dem ESPHome-Flasher auf einem anderen Rechner. Hatte man schon einmal eine Firmware wie Tasmota, ESPEasy (mein Favorit vor ESPHome) oder Espurna drauf, kann man die von HA erzeugte Firmware direkt über deren Firmware-Update aufspielen.

Wichtig zu wissen ist dabei, dass ESPHome im Gegensatz zu etwa Tasmota kein eigenes Webinterface hat. Sämtliche Konfiguration geht von Home Assistant aus.

Anschluss und Programmierung

Ich habe für meinen Prototyp einen einfachen ESP8266 mit Adapterplatine eingesetzt. An welche GPIOs der MH-Z19 und die anderen Bauteile angeschlossen werden müssen, hängt von eurem Board ab. Nach den Einstellungen für das WLAN und ggf. einen Fallback-Hotspot für den ESPHome, werden ab Zeile 34 die UART-Pins definiert. In meinem Fall ist das GPIO 4 für den RX-Pin und GPIO5 für den TX-Pin des Sensors. Die Baudrate wird auf 9600 bps eingestellt.

Die Bibliotheken für den MH-Z19 Sensor kennt Home Assistant schon und sie stehen ohne weitere Installation zur Verfügung. Die Sensor-Plattform wird ab Zeile 39 gesetzt. Mit on_value_range ab Zeile 44, können nun die LEDs angesteuert werden. Diese sind über 150 Ohm Widerstände an den GPIOs 16 (grün), 14 (gelb) und 12 (rot) angeschlossen und können mit den YAML-Anweisungen below, above und then entsprechend auf HIGH oder LOW gesetzt werden. Innerhalb Home Assistant werden die LEDs als switch-Plattform behandelt (ab Zeile 68).

esphome:
  name: co2
  platform: ESP8266
  board: esp01_1m

wifi:
  ssid: "MEINE-SSID"
  password: "MEIN-WLAN-PASSWORT"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Co2 Fallback Hotspot"
    password: "MEIN-PASSWORT"

captive_portal:

# Enable logging
logger:

# Enable Home Assistant API
api:
  password: "MEIN-API-PASSWORT"

#Service fuer HA definieren um Kalibrierung aus HA steuern zu koennen
  services:
    - service: mhz19_calibrate_zero
      then:
        - mhz19.calibrate_zero: sens1

ota:
  password: "MEIN-OTA-PASSWORT"
  
  
# Serielle Schnittstelle definieren
uart:
  rx_pin: GPIO4
  tx_pin: GPIO5
  baud_rate: 9600

# Sensor konfigurieren
sensor:
  - platform: mhz19
    co2:
      name: "MH-Z19 CO2 Value" #Entity-ID in HA
      id: co2val
      on_value_range: # Schwellwerte für die Ampel
        - below: 1200
          then:
            - switch.turn_on: green_pin
            - switch.turn_off: yellow_pin
            - switch.turn_off: red_pin
        - above: 1200
          then:
            - switch.turn_off: green_pin
            - switch.turn_off: red_pin
            - switch.turn_on: yellow_pin
        - above: 1800
          then:
            - switch.turn_off: green_pin
            - switch.turn_off: yellow_pin
            - switch.turn_on: red_pin
    temperature:
      name: "MH-Z19 Temperature"
    update_interval: 60s
    automatic_baseline_calibration: false
    id: sens1
    

# Switch Plattform und GPIOs fuer LEDs definieren
switch:        
  - platform: gpio
    pin: GPIO12
    id: red_pin
    name: "CO2 rot"
  - platform: gpio
    pin: GPIO14
    id: yellow_pin
    name: "CO2 gelb"
  - platform: gpio
    pin: GPIO16
    id: green_pin
    name: "CO2 grün"
Code-Sprache: YAML (yaml)

Mit dieser Konfiguration kann der ESPHome auch ohne Home Assistant als CO2-Ampel arbeiten, denn die LEDs werden direkt von der Logik auf dem ESPHome geschaltet.

Interessant ist die Zeile 63: Wird diese auf TRUE gesetzt, kann der MH-Z19 kalibriert werden. Dazu lässt man ihn 24 Stunden bei einer definierten CO2-Konzentration, also am besten in einem gut gelüfteten Raum ruhen. Bei guter Lüftung beträgt der CO2 Gehalt etwa 400 ppm. Der Sensor misst über den Kalibrierzeitraum die aktuelle Konzentration und schreibt den niedrigsten Wert als Baseline in sein EPROM, welcher dann als Referenz genommen wird. Danach stellt man die automatic_baseline_calibration wieder auf false.

Noch komfortabler geht es, wenn man einen Service für Home Assistant definiert, mit dem man die Kalibrierung aus HA aktivieren kann. Das geschieht in der ESPHome Konfiguration in Zeile 24.

Kalibrierung über einen Service in HA starten

In HA muss dann nur noch in den Developer Tools der Service ausgewählt und mit Call Service gestartet werden. Dabei sollte sich der Sensor wieder in einer Umgebung mit 400 ppm Kohlendioxid befinden. Nach einigen Stunden Kalibrierung startet man den ESP einfach neu. Damit beendet sich auch der Service und der Sensor arbeitet wieder im Normalbetrieb mit neuer Kalibrierung.

Der Sensor wird alle 60 Sekunden ausgelesen und die Werte zu Home Assistant übertragen. Über die Konsole von HA kann man sehen, was der neue ESPHome gerade macht:

Konsolen-Ausgabe des neuen ESPHome mit CO2 Ampel

Apropos Kalibrierung: nachts sind die CO2 Werte außen tatsächlich höher als am Tag. Der Grund dafür ist die geringere Photosynthese der Pflanzen. Gleiches gilt für die kalte Jahreszeit. Das ist selbst mit dem MH-Z19 messbar, hat aber wenig Einfluss auf die Kalibrierung, da es sich im 2-stelligen Bereich bewegt. Dieses Dokument zu „15 Jahre CO2 Messung in Hessen“ erklärt das sehr interessant.

Messwerte und Erfahrungen

Ich habe die Messwerte mit meinem Airthings Wave Plus verglichen und die Messwerte korrelieren sehr gut. Die CO2-Ampel springt nun beim Überschreiten von 1200 ppm CO2 gelb und ab 1800 ppm rot. Lüftet man mehrere Minuten, wird die CO2-Ampel wieder grün.

Ein dauerhafter Wert von unter 1000 ist selbst in einem Raum mit 25 qm nur zwei Personen dauerhaft nicht möglich. Spätestens nach 2 Stunden überschreitet der Wert die 1000er Marke, bewegt sich aber dann bei Werten bis maximal 1500 ppm. 5 Minuten Stoßlüften mit offener Terrassentür senkt den Wert dann wieder an die 400er Grenze.

Schöne Diagramme Influx und Grafana

24 Stunden CO2-Messung im Homeoffice mit 2 Personen

Diese Messwerte erfasse ich mit der InfluxDB und dem Visualisierungs-Tool Grafana, das in Home Assistant einfach nachinstalliert werden kann. Die Auswertung für den Verlauf sieht in Grafana so aus:

Grafana Einstellungen und Query für die Verlaufsanzeige

Die „Gauge“ Anzeige so:

In Grafana kann man auch Schwellwerte konfigurieren, die nicht nur der optischen Anzeige dienen, sondern auch aktiv für Benachrichtigungen eingesetzt werden können. Grafana unterstützt hier neben E-Mail auch Telegram, Slack, Microsoft Teams oder Google Hangouts. Eine Übersicht dazu gibt es HIER. Ich ziehe es jedoch vor, die Benachrichtigungen direkt aus Home Assistant heraus zu machen, dann habe ich nicht unterschiedliche Systeme.

Da die Werte nun auch in Home Assistant zur Verfügung stehen können sie hier z. B. genutzt werden, um ebenfalls Benachrichtigungen per Telegram zu versenden oder als Alexa Sprachnachricht mit freundlicher Aufforderung zu Lüften. Das kann Grafana nicht.

Die CO2-Ampel in Home Assistant

Die LEDs zeigen ihren Status als Schalter an. Ebenso könnte man Home Assistant und die Switches der Ampel dazu nutzen einen automatischen Fensterantrieb und ein Lüftungssystem zu steuern.

Was kommt noch?

Der Sensor läuft nun seit dem 30. Oktober ohne Probleme und animiert uns dazu öfter zu lüften, als wie es sonst getan hätten. Nicht weil wir uns vor Corona schützen wollen, sondern weil die Luft angenehmer ist und man sich so im Homeoffice besser und länger konzentrieren kann.

Nun muss ich noch eine Platine dafür entwerfen. Ein BME280 Sensor für Luftfeuchtigkeit und genaue Temperaturmessung kommt auch noch drauf und ein kleiner Lautsprecher erinnert mit dezentem Piepsen dran, wieder mal das Fenster aufzumachen – oder auch zu schließen, wenn die Temperatur zu stark abfällt. Noch ein schönes Gehäuse gedruckt und fertig ist die CO2 Ampel für weniger als 40 Euro.

Melde dich zu meinem Newsletter an!

Du kannst dich jederzeit abmelden und ich verspreche: Kein Spam!


Die mit Sternchen (*) gekennzeichneten Verweise sind sogenannte Provision-Links. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen.Wenn du auf so einen Verweislink klickst und über diesen Link einkaufst, bekomme ich von deinem Einkauf eine Provision. Für dich verändert sich der Preis nicht und du unterstützt damit meine Arbeit. Preisänderungen und Irrtümer vorbehalten.

20 Kommentare

  1. Hallo, Ich möchte mich für den Artikel bedanken! Ich hatte die Schaltung mit der Arduino-SW entwickelt und wollte – wegen der graphischen Oberfläche bzw. Langzeitbeobachtung – das ganze in HomeAssistant überführen. Leider tue ich mich mit dem YAML sehr schwer! Die Ampel, die in der Arduino-Oberflächge kein Problem war, habe ich nicht hinbekommen. Daher DANKE!
    PS: Ich habe eine Doppel-LED gn-rt verwendet, wenn beide LED’s eingeschaltet sind, entsteht ein annäherndes gelb. Als Netzteil habe ich ein RPI-Netzteil mit 5,1V für den MH-Z19b, der D1-Mini macht sich selbst dann die 3,3V.

  2. Hallo,

    danke für den guten Artikel. Hast du für den Aufbau ein schönes Gehäuse gefunden?

    Gruß
    Marius

    • Hallo Marius,
      Ich habe zur Zeit zwei CO2-Aufbauten im Wohnzimmer. Das eine funktioniert schon seit 2022 mit einem MH-Z14A super und ist in einem ArduiTouch Wandgehäuseset! Bzw. der Sensor ist Außerhalb, weil er zu groß ist. Da war dann auch noch ein recht genauer BME280-Sensor für Temperatur, Luftfeuchtigkeit und Luftdruck. Dieser Sensor wurde im Gehäuse durch den ESP immer aufgeheizt. Nun habe ich ihn auch ausgelagert – und noch räumlich vom MH-Z14a getrent. – der muss für die Messung auch aufgeheizt werden und erhöht dadurch die Temperatur am BME280 – je nach Abstand – bis zu 1°C!
      Im Brettaufbau fällt das garnicht so stark auf! Der ESP8266 heizt durch das WLAN und der CO2-Sensor muss ja eh geheizt werden (daher ist die Temperaturfunktion auch nicht wirklich zu gebrauchen). Meine – sehr persönliche Meinung – ist, das ein Temperatursensor auf weniger als +-0,5°C genau sein sollte (bei mir ist der Wohlfühlbereich zwischen 19 und 20°C).
      Deshalb werde ich für den jetzt gerade aufgebauten zweiten Sensor mit der Ampel (der dann auch nicht im Wohnzimme bleiben wird) – ein Gehäuse mit drei getrennten Kammern für ESP+Display+LED, MH-Z19C, und BME280 bzw. SI7021 (ohne Luftdruck) vorsehen.
      Leider habe ich jetzt aber auch festgestellt, das mein MH-Z19c Sensor ab und zu rumzickt (wie Thorsten beschrieben hat) – mein Sensor ist übrigens auch von BerryBase (mit denen ich bisher nie Probleme hatte)! Es scheint auch bei mir kein Spannungsproblem zu sein. Daher werde ich die Sensoren mal tauschen müssen. Es könnte aber auch am Steckbrett liegen, oder ???
      Ich werd mich wieder melden, wenn ich etwas verwertbares habe.

  3. Auch ich habe mir den tollen sensor nachgebaut, allerdings mit einem NodeMCU v3 – ESP8266. Zu dem habe ich noch einen kleinen Taster eingebaut, mit dem ich zwischen MH-Z19 (pin HD) und GND des ESP8266 eine Hardware-Kalibrierung durchführen kann. (Dafür muss man den Sensor für ca. 20 Min. an die frische Luft stellen und dann für 7 Sekunden die Brücke zwischen HD und GND herstellen) Aber nun zu meinem Problem. Meine Sensordaten schwanken extrem, ohne dass sich am CO2 Gehalt der Luft viel ändert. Das sind innerhalb von 5 Minuten teilweise mehrfache Schwankungen von 400ppm. Ich habe die Konstanz der Spannung in Verdacht, allerdings hat der Einsatz eines stärkeren USB Laders keine Änderung herbeigeführt. Hast du vielleicht eine mögliche Ursache für das Problem? Fake Sensor kann ich ausschließen, da ich diesen bei BerryBase bestellt habe. (Ist übrigens ein MH-Z19C)
    Viele Grüße
    Thorsten

  4. Vielen Dank für Ihr voll funktionsfähiges Beispiel.
    Ich war beim Ausführen des Kalibrierungs service hängen geblieben, aber jetzt habe ich ihn am Laufen. 🙂

  5. Toller Artikel! Nur bin ich leider ein Elektro-DAU und frage mich gerade, wie man das alles verdratet. Vielleicht habe ich es nur überlesen, aber ich finde im Artikel leider nichts.
    Du erwähnst zum Schluss noch eine Platine. Hast du du schon was gemacht? Würdest du die auch zum Kauf anbieten?

    • Für solche recht einfachen Aufbauten kann man eine Streifenrasterplatine oder ein Perfboard nehmen z. B. https://amzn.to/3CTSBdr Ich bin eher der Streifenraster-Typ. Ich mag das Rumgekleckse mit Lötzinn auf den Perfboard nicht so.

      Extra eine Platine dafür zu entwerfen und herstellen zu lassen (auch wenn die China-Fertiger extrem preiswert sind) lohnt sich nicht, wenn man nur 1 oder 2 Stück davon braucht.
      Löterfahrung und Vorkenntnisse in diesem Bereich sollte man aber schon haben. Es gibt jede Menge Youtube Videos, die das ganz ordentlich erklären (wenngleich auch viele Pfeifen mit vielen Views dabei sind, die selbst keine Ahnung haben 😉 )

      Grüße aus Franken nach Franken 🙂

      • Ja da schau her, auch aus Franken, der schönsten Gegend der Welt.
        Danke für die Info. Ich hab nur gefragt, weil du die Platine erwähnt hast. Was ich aber nach wie vor nicht finde, ist ein Plan für die Verdrahtung. Bin ich (zu) blind?

        Gruß
        Marco

        • Das hab ich nicht explizit aufgeführt, da das aus dem Code hervorgeht und mancher vielleicht stattdessen einen ESP32 oder einen anderen Controller verwenden will.

        • Schade. Dann bin ich da raus 🙁 Dafür reichen meine Kenntnisse leider nicht aus.
          Trotzdem danke!!!

        • Schaffst du schon! Beitrag genau lesen, Code ansehen – da sind die ganzen GPIOs beschrieben und ein bisschen googeln. Man muss das verstehen, damit man das sinnvoll anwenden, erweitern und sich später bei Problemen selbst helfen kann.

        • Hmm. Ich traue mir schon einiges zu, aber mit ESP usw. habe ich wirklich noch nie was gemacht 🙁

        • Dann am besten erst einmal einen Wemos Mini Pro o. ä. besorgen und etwas damit experimentieren und Erfahrung sammeln (LED blinken lassen etc.).

  6. Hallo, der Aufbau funktioniert soweit. Im Bild der Verdrahtung ist auch noch ein Buzzer zu sehen, der jedoch nicht in der Programmierung auftaucht. Gibt es dazu noch ein aktuelles yaml-file ?

  7. Danke für den ausführlichen Artikel!
    Ich hab ein MH-Z19B, das ich einfach nicht zum laufen bringe. Schön langsam glaube ich es ist defekt und werde mir ein neues bestellen.
    Hab ich das richtig verstanden, dass du es mit 3,3V direkt am ESP betreibst?
    Ich überlege nämlich gerade ob ich ein anderes bestellen soll das auch einen 5V Pin hat. Das NodeMCU ESP32 dürfte 5V vom USB durchreichen können.

    ich Messe übrigens schon sehr lange mit einem teuren Awair meine Luftqualität und habe die Erfahrung gemacht, dass ich bereits ab 800ppm steigende Müdigkeit und sinkende Konzentrationsfähigkeit bemerke.
    ich versuche den Wert immer unter 1000 zu halten.

    • Nein, wie im Text beschrieben, wird der Sensor selbst mit 5 Volt betrieben – dafür ist er auch ausgelegt, da sonst die kleine Glühlampe darin zu schwach leuchtet und die Messwerte falsch sind.
      Im Zweifelsfall würde ich dir empfehlen, den Sensor mit einem einfachen Skript mit einem Arduino zu testen um sicherzustellen, dass er auch funktioniert und es sich nicht nur um ein Software- oder Pegelproblem handelt.

      • Danke für die schnelle Antwort! Ich habe schon verschiedenste Setups probiert und der Sensor scheint einfach nicht zu funktionieren.
        Danke für die Erklärung mit den 5V, so habe ich es die letzten mal auch probiert mit einer zusätzlichen 5V Stromquelle. Ich hab mir jetzt NodeMCU ESP32 und einen neuen Sensor bestellt und hoffe, dass es damit dann endlich funktioniert ?

Schreibe einen Kommentar zu MarcoAntworten abbrechen

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