I recently watched Jeff Gerling’s video on CO₂ levels, and how to monitor it. My home office is also in the basement, with no windows. So I paid attention to the air quality when setting up down here.
In addition to monitoring the CO₂ level, I’m also automatically ventilating the space when the air quality gets too bad.
Table of contents
CO₂ levels
- 250-400ppm
- Normal background concentration in outdoor ambient air
- 400-1,000ppm
- Concentrations typical of occupied indoor spaces with good air exchange
- 1,000-2,000ppm
- Complaints of drowsiness and poor air.
- 2,000-5,000 ppm
- Headaches, sleepiness and stagnant, stale, stuffy air. Poor concentration, loss of attention, increased heart rate and slight nausea may also be present.
The sensor
![](https://blog.cavelab.dev/2021/09/home-office-fan-co2-level/20210912_163745_hu65fbeab8a025d344287dfde06331c2e7_482462_800x0_resize_q80_lanczos.jpg)
I’ve purchased a Netatmo air quality sensor — it seemed to be the cheapest, and easiest way of reliably monitoring temperature, humidity, and CO₂. It sends me a notification if any of the values go above or below the “safe” zone.
It’s also very easy to add to Home Assistant, more on that below.
The fan
![](https://blog.cavelab.dev/2021/09/home-office-fan-co2-level/20210912_165721_hu44586f63127dbde8665b90dbd3409082_610857_800x0_resize_q80_lanczos.jpg)
The fan is a backward centrifugal extractor (RK 125L), capable of moving 168 m³/hour (99 ft³/min). I have a speed controller for the fan, but I mostly run it at full speed.
Our basement is about 40 m³ (1412 ft³) — so at full speed, the air is replaced 4.2 times per hour, theoretically. Meaning that it takes about 15 minutes to replace the air — again; theoretically.
Home Assistant
I’m using Home Assistant to automate the fan — based on the measured CO₂ level.
Controlling the fan
![](https://blog.cavelab.dev/2021/09/home-office-fan-co2-level/20210912_172335_huaf15f3a3e66b56325ed34750263c9851_482611_800x0_resize_q80_lanczos.jpg)
To control the fan I’m using a TP-Link HS110 smart plug. It also measures the watts used by the fan, and I use that to determine the fan speed step set on the controller.
Defining the smart plug:
tplink:
discovery: false
switch:
- host: 10.x.x.x
Figure out the fan speed step:
template:
- sensor:
- name: "Fan speed"
unit_of_measurement: 'step'
state: >
{%- if states.sensor.office_fan_current_consumption.state | int > 70 %}
5
{%- elif states.sensor.office_fan_current_consumption.state | int > 50 %}
4
{%- elif states.sensor.office_fan_current_consumption.state | int > 40 %}
3
{%- elif states.sensor.office_fan_current_consumption.state | int > 30 %}
2
{%- elif states.sensor.office_fan_current_consumption.state | int > 20 %}
1
{%- elif states.sensor.office_fan_current_consumption.state | int < 20 %}
0
{% else %}
fail
{%- endif %}
icon: >
{%- if states.sensor.office_fan_current_consumption.state | int > 3 %}
mdi:fan
{% else %}
mdi:fan-off
{%- endif %}
![](https://blog.cavelab.dev/2021/09/home-office-fan-co2-level/screenshot-hass-ventilation.png)
Reading the sensor
The Netatmo sensor is added as an integration, and to do that we need to define the API credentials:
netatmo:
client_id: xxxxxxxxxxxxxxxxxxxxxxxx
client_secret: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
This gives us access to the sensor data:
![](https://blog.cavelab.dev/2021/09/home-office-fan-co2-level/screenshot-hass-climate.png)
Automating the fan
I have a script that runs the fan for 15 minutes, this allows me to “manually” replace the air down here:
script:
vent_office:
alias: Ventilate office
sequence:
- service: switch.turn_on
data:
entity_id: switch.office_fan
- delay:
minutes: 15
- service: switch.turn_off
data:
entity_id: switch.office_fan
And the automation that starts the fan if the CO₂ level rises above 1200ppm:
- alias: Fan on auto
trigger:
platform: numeric_state
entity_id: sensor.netatmo_office_co2
above: 1200
action:
service: switch.turn_on
entity_id: switch.office_fan
- alias: Fan off auto
trigger:
platform: numeric_state
entity_id: sensor.netatmo_office_co2
below: 1200
action:
service: switch.turn_off
entity_id: switch.office_fan
![](https://blog.cavelab.dev/2021/09/home-office-fan-co2-level/screenshot-home-coach_hu492802d86de28432c70b2eca95704fb9_203400_800x0_resize_q80_lanczos.jpg)
The CO₂ level quickly drops when it hits the 1200ppm threshold, ensuring that the air down here never gets too bad 🙂
Last commit 2024-04-05, with message: Tag cleanup.