The corona virus will probably be with us for a long time. The risk of infection is particularly high in rooms with many people from different households. However, the same has long applied to influenza viruses. US scientists Rudnick and Milton put 30 people, including one with a flu infection, in a room for 4 hours. At a CO2 content in the air of 1000 ppm, five people became infected, at 2000 ppm it was already 12 and at 3000 ppm 15 people.
However, a low CO2 value also has an important meaning apart from infectious diseases. If CO2 levels in the room air are too high, attention and concentration noticeably decrease and can cause headaches and fatigue, which should be considered especially in schools - even without the corona problem.
⚠ [affiliate] Keine Produkte mit Cache für home-assistant.
Bitte affiliate-sync --lang en ausführen.
Which CO2 values are suitable for a traffic light
This was exactly the question that, according to my research, is very difficult to answer. The Pettenkofer number, named after the German hygienist Prof. Max von Pettenkofer (1818-1901), is often cited. He found that 1,000 ppm CO2 is the limit for good air quality. However, in 1858 there were no highly sealed building envelopes or insulating glass windows. In addition, the natural CO2 content in the outside air was still significantly lower at 350 ppm than today with an average of 400 ppm (in cities often 450 - 500 ppm). Thus, the Pettenkofer number also no longer found its way into the corresponding DIN standards.
In DIN 1946-2, 1,500 ppm was assumed as the limit for the CO2 content in the air of indoor spaces, but without citing scientific foundations for this. This DIN standard was replaced by DIN 13779 and here 4 IDA categories (Indoor Door Air) were defined, which define a CO2 concentration above the outside air:
CategoryDescriptionIncrease compared to outside air in ppmAbsolute CO2 content at 400 ppm CO2 in outside airIDA 1High indoor air quality<= 400 <= 800 IDA 2Medium indoor air quality> 400 - 600 > 800 - 1000IDA 3Moderate indoor air quality> 600 - 1000> 1000 - 1400IDA 4Low indoor air quality> 1000> 1400Classification of indoor air quality in IDA categories
If you live in a busy city center, you can assume values around 500 ppm for the outside air and the absolute values increase accordingly.
Ventilation traffic light with ESPHome and MH-Z19B sensor
To be able to measure the CO2 load in the air, you need a corresponding sensor. Very well available and relatively affordable are the CO2 sensors of type MH-Z19B , which cost 25 euros. These sensors work according to the NDIR principle. A small incandescent lamp is used as a broadband infrared source to illuminate a sample chamber and then directed via a filter onto an infrared sensor. The filter is designed to be so narrow-band that the CO2 molecules absorb the infrared light and thus less light falls on the sensor. The higher the CO2 concentration in the measuring chamber, the less infrared radiation falls on the sensor.
The MH-Z19 is read out via a serial UART interface at 9600 baud, so it can be connected very easily. It is important that it is supplied with 5 volts. Although it basically also works with 3.3 volts, the measured values then deviate significantly. The datasheet specifies a voltage range of 3.6 to 5.2 volts. On the other hand, it’s nice that the serial RX/TX connections can be used without a level converter on 3.3 volt GPIOs such as on the ESP8266 or Raspberry Pi.

Since I wanted to use the sensor with Home Assistant (HA) anyway, the wheel didn’t have to be reinvented for this and you don’t have to program it from scratch either.
Home Assistant comes with ESPHome ESPHomeFramework for configuring ESP32/ESP8266 microcontrollers that automatically integrate into Home Assistant. Ideal for DIY sensors and actuators , its own platform for ESP microcontrollers, which can be flashed, programmed and updated via Home Assistant. Furthermore, they are connected via a native API APIApplication Programming Interface – defined interface through which programs communicate. Home Assistant offers a REST and a WebSocket API (e.g. for MCP) to HA and not via MQTT MQTTLightweight publish/subscribe messaging protocol. Used in smart homes to exchange sensor data and control commands between devices , which makes the whole thing even faster and more convenient.

If you have a virgin ESP, Wemos or also Sonoff in front of you, you can have the appropriate firmware created and compiled directly in HA. You either plug the microcontroller into a USB port of the HA computer and can flash the firmware directly with it, or you save the binary file and flash it, for example, with a tool like the NodeMCU Flasher or the ESPHome Flasher on another computer. If you already had firmware such as Tasmota TasmotaOpen source firmware for ESP8266/ESP32-based smart home devices (sockets, lights, relays). Replaces manufacturer firmware for local control without cloud , ESPEasy (my favorite before ESPHome) or Espurna on it, you can flash the firmware generated by HA directly via their firmware update.
It is important to know that ESPHome, in contrast to Tasmota, for example, does not have its own web interface. All configuration is done from Home Assistant.
Connection and programming
For my prototype, I used a simple ESP8266 with adapter board. Which GPIOs the MH-Z19 and the other components need to be connected to depends on your board. After the settings for the WiFi and possibly a fallback hotspot for the ESPHome, the UART pins are defined from line 34. In my case, this is GPIO 4 for the RX pin and GPIO5 for the TX pin of the sensor. The baud rate is set to 9600 bps.
Home Assistant already knows the libraries for the MH-Z19 sensor and they are available without further installation. The sensor platform is set from line 39. With on_value_range from line 44, the LEDs can now be controlled. These are connected via 150 ohm resistors to GPIOs 16 (green), 14 (yellow) and 12 (red) and can be set to HIGH or LOW accordingly with the YAML YAMLData format (YAML Ain’t Markup Language). Used in Home Assistant for configurations, automations and scenes. Easy to read but error-prone with incorrect indentation instructions below, above and then. Within Home Assistant, the LEDs are treated as a switch platform (from line 68).
|
|
With this configuration, the ESPHome can also work as a CO2 traffic light without Home Assistant, because the LEDs are switched directly by the logic on the ESPHome.
Line 63 is interesting: If this is set to TRUE, the MH-Z19 can be calibrated. To do this, let it rest for 24 hours at a defined CO2 concentration, i.e. best in a well-ventilated room. With good ventilation, the CO2 content is about 400 ppm. The sensor measures the current concentration over the calibration period and writes the lowest value as a baseline into its EPROM, which is then used as a reference. Afterwards, set automatic_baseline_calibration back to false.
It’s even more convenient if you define a service for Home Assistant with which you can activate the calibration from HA. This is done in the ESPHome configuration in line 24.

In HA, you then only need to select the service in the Developer Tools and start it with Call Service. The sensor should again be in an environment with 400 ppm carbon dioxide. After a few hours of calibration, simply restart the ESP. This also ends the service and the sensor works again in normal operation with new calibration.
The sensor is read every 60 seconds and the values are transmitted to Home Assistant. Via the console of HA, you can see what the new ESPHome is currently doing:

Speaking of calibration: at night, the CO2 values outside are actually higher than during the day. The reason for this is the lower photosynthesis of plants. The same applies to the cold season. This is even measurable with the MH-Z19, but has little influence on the calibration, as it is in the double-digit range. This document on “15 Years of CO2 Measurement in Hesse” explains this very interestingly.
Measurements and experiences
I compared the measured values with my Airthings Wave Plus and the measured values correlate very well. The CO2 traffic light now turns yellow when exceeding 1200 ppm CO2 and red from 1800 ppm. If you ventilate for several minutes, the CO2 traffic light turns green again.
A permanent value of under 1000 is not possible even in a room of 25 sqm with only two people. After 2 hours at the latest, the value exceeds the 1000 mark, but then moves at values up to a maximum of 1500 ppm. 5 minutes of burst ventilation with the terrace door open then lowers the value back to the 400 limit.
Nice diagrams with Influx and Grafana

I record these measurements with InfluxDB and the visualization tool Grafana, which can be easily installed afterwards in Home Assistant. The evaluation for the history looks like this in Grafana:

The “Gauge” display like this:

In Grafana, you can also configure threshold values that not only serve for visual display, but can also be actively used for notifications. Grafana supports not only email here, but also Telegram, Slack, Microsoft Teams or Google Hangouts. An overview of this is available HERE . However, I prefer to make the notifications directly from Home Assistant, then I don’t have different systems.
Since the values are now also available in Home Assistant, they can be used here, for example, to also send notifications via Telegram or as an Alexa voice message with a friendly request to ventilate. Grafana can’t do that.

The LEDs show their status as switches. Likewise, you could use Home Assistant and the switches of the traffic light to control an automatic window actuator and a ventilation system.
What’s next?
The sensor has been running without problems since October 30 and encourages us to ventilate more often than we would have otherwise. Not because we want to protect ourselves from Corona, but because the air is more pleasant and you can concentrate better and longer in the home office this way.
Now I still need to design a circuit board for it. A BME280 sensor for humidity and accurate temperature measurement will also be added, and a small speaker will remind you with a subtle beep to open the window again - or to close it if the temperature drops too much. Print a nice housing and the CO2 traffic light is ready for less than 40 euros.
What do you think? Leave a comment!
Share your thoughts, questions or experiences with the community.