DIY Indoor air quality monitoring with ESPhome

ESPhome makes integrating sensors with Home Assistant really easy.  I was quite impressed that it took less than 10 minutes for the software + config, and no code at all.

Here’s some info on my DIY indoor air quality monitor:

Data from these sensors:

HM3301:  PM1, PM2.5, PM10, AQI (US), CAQI(Europe).

SGP30:  TVOC (Total Volatile Organic Compounds), eCO2 (equivalent calculated CO2 from TVOC).

SCD30:  CO2 (using Non-Dispersive Infrared, NDIR), humidity, temperature. Better CO2 measurement than SGP30.

I bought the Grove version of these sensors, which made wiring super-easy. Suppliers were Mouser and Digikey.

NodeMCU was $4. Pack of 3 for $12 (Amazon, overseas suppliers, etc)

Mounted with 3M Command “Picture Hanging Strips”, megapack from Costco.

Research suggests mounting the sensors at the same level as people and away from doors/windows, similar to a thermostat. ie. not on the ceiling. CO2 is heavy. For example, when businesses store compressed CO2, they place their leak sensors close to the floor where CO2 settles. Mounting away from doors/windows helps to avoid drastic swings in measurements when those are opened.

Scale vs a soda can

USB Powered

Power cable: 2.1mm DC barrel to USB-A (Adafruit, Amazon, other vendors). Center pin is DC positive (+)

Monitoring Dashboard

InfluxDB integration for Home Assistant provides data for rendering in Grafana. Graph on a bad air day (smoke from wildfires):

Air quality data from HA stored in influxdb and rendered in grafana

The next day, indoor PM2.5 resumed ~50, then there was a spike of bad air quality in the afternoon, and then dropping to 12 (indoor) after midnight. “12” is on the border of green and yellow:

Bad air day: indoor PM2.5 mostly >50, then drops to 12 after outdoor PM2.5 drops and I increased indoor air filtering

Alexa Integration using Node Red

Using Home Assistant’s emulated Hue integration, I create a new virtual device called “smoke” and the approach in this thread.

This allows me to toggle the “smoke” device, which triggers a Node Red flow to get the current indoor and outdoor PM2.5 and say the results on all Echos in the house.

After parsing the command to toggle the “smoke” virtual device, this Node Red flow is executed. Alexa says, “Indoor air quality is X. Outdoor air quality is Y.”

Outdoor air quality is fetched using the approach in this thread (does not require a PurpleAir device, just one shared near you).

I also have a Node Red flow that watches the HM3301 PM2.5 state, and sends notifications via Alexa and iOS if the air quality exceeds a threshold or changes more than 5, but only if a notification hasn’t been sent in the last 30m.

Carbon Monoxide (CO)

For CO (carbon monoxide), I use normal detectors that look and act like a smoke alarm.


2 thoughts on “DIY Indoor air quality monitoring with ESPhome”

  1. Hey!

    I’ve been having issues getting my HM3301 to work. It seems powered via USB on my laptop or a desktop works fine as well as being plugged into a LI-ON battery bank. If I power the device via any of the wall USB chargers I have the values I get are insanely high and jump around a lot. I’ve been emailing the company and haven’t really been getting anywhere. I’m curious if you had the same issue or not? What sort of power adapter are you using?

    I’m pretty sure the unit I received is defective as I can’t seem to find anyone else mentioning the same issue.

    Nice post & website by the way 🙂

    Skylar Sadlier

  2. Thanks for a great guide
    I’m currently trying to use the HM3301 sensor with ESPHome.
    As I saw the sensor only has a 2 year life, under continuous operation, I’m trying to sleep then wake periodically to extend it. However when I wake the sensor back up the ESP32 can’t reestablish communication unless I reboot the MCU itself.
    Log reports “‘[W][hm3301.sensor:046]: Checksum validation failed”.
    Any way to solve this please? As I don’t want to have to reset the ESP constantly.


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.