DIY Air Quality Monitors for Home Assistant

The upgraded IKEA air quality monitors I did work great, but the LED indication isn’t great for a bedroom and the fan noise was annoying in my office. So I wanted to create a couple of my own devices for those locations. I used:

The SEN50 is a big upgrade over the PM sensors used in the IKEA devices and I used the Si7021 in place of the BME280 I had used because I think they’re a bit better. I soldered 47µF electrolytic capacitors from a big kit I’ve had (similar on Amazon) to the ENS150 modules to improve their power.

Then I attached 5 of the crimped wires to a 6P JST connector, which is what the SEN50 modules require. I’m note sure why buying the actual cable for these SEN50s are so expensive, but I got the entire JST kit for cheaper than a couple of the special cables.

All three sensors communicate with the microcontroller over I²C, so a breadboard test was easy to wire up. The SEN50 does require 5 volts instead of 3.3, so I’m glad I checked.

The ESPHome YAML code is very similar to the code used for the modified IKEA air quality monitors.

substitutions:
  slug: demo
  friendly: Demo

esphome:
  name: ${slug}-wemos-d1
  friendly_name: ${friendly} Wemos D1

esp8266:
  board: d1_mini

logger:
  #level: WARN

api:
  encryption:
    key: 'xxx'

ota:
  - platform: esphome
    password: "xxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: xxx
    gateway: xxx
    subnet: 255.255.255.0

i2c:
  frequency: 50kHz

sensor:
  - platform: sen5x
    pm_1_0:
      name: PM 1µm
      accuracy_decimals: 0
    pm_2_5:
      name: PM 2.5µm
      accuracy_decimals: 0
    pm_4_0:
      name: PM 4µm
      accuracy_decimals: 0
    pm_10_0:
      name: PM 10µm
      accuracy_decimals: 0

  - platform: htu21d
    model: SI7021
    temperature:
      name: Temperature
      id: ${slug}_temp
    humidity:
      name: Humidity
      id: ${slug}_humid

  - platform: aht10
    variant: AHT20
    temperature:
      name: AHT21 Temperature
      id: ${slug}_aht21_temp
    humidity:
      name: AHT21 Humidity
      id: ${slug}_aht21_humid

  - platform: ens160_i2c
    address: 0x53
    eco2:
      name: CO²
    tvoc:
      name: VOC
    aqi:
      id: demo_aqi
      name: AQI
    compensation:
      temperature: ${slug}_aht21_temp
      humidity: ${slug}_aht21_humid

text_sensor:
  - platform: template
    name: AQI Rating
    lambda: |-
      switch ( (int) ( id( ${slug}_aqi ).state ) ) {
        case 1: return {"Excellent"};
        case 2: return {"Good"};
        case 3: return {"Moderate"};
        case 4: return {"Poor"};
        case 5: return {"Unhealthy"};
        default: return {"N/A"};
      }

These resources helped out:

The project boxes had some standoffs on the bottom, which I snipped off and then sanded with a rotary tool. I pulled out my box of proto boards and found a size almost exactly double what I needed, so I cut out a sliver and ended up with a piece for each box. I also cut vent holes for the SEN50 sensors.

In order to get everything to fit I decided to put the microcontroller on the bottom of the board. After mocking things up I did all of the soldering. I was hoping to be able to mount everything with connectors so it could easily be taken apart, but there wasn’t enough room and I didn’t want bigger boxes.

I did some continuity testing along the way and everything worked when I connected power. With the boards ready I cut more access and ventilation holes in the boxes.

I soldered the Si7021 on to its wires outside of the enclosure so it wouldn’t be exposed to unnecessary heat and used hot gun to secure everything.

I’m really happy with how these turned out. Here’s a view of the office data on my Home Assistant dashboard.

This was definitely a project where I wished I had a 3D printer to design custom boxes. Some day, when I’m caught up on my project list and can give it proper attention. I know if I get one now I’ll spend a ton of time with it and neglect other projects in my pipeline.

Home Assistant Air Quality Monitors from IKEA Vindriktning

IKEA recently discontinued Vindriktning, their older air quality monitor.

Inside the device, they put a cubic PM1006K particle sensor. I bought three for $16.95 each last year, because I’d seen people hack them by adding sensors and a Wi-Fi microcontroller to send all of the data to Home Assistant. For my modding I bought:

The YouTube video linked above is a great guide to follow. I didn’t connect wires to the fan or the light sensor since I had no use for them. I also didn’t stack my sensors because I wanted the BME280 to be outside of the enclosure, where it would be less affected by the heat produced by the ENS160 and D1.

Even with the sensor outside of the case, the BME280 still reads high, because it heats itself up. I actually tested different lengths of wires and placements of the sensor before realizing I was still going to have to adjust the data. An ESPHome filter made the adjustment easy, which I did individually for each unit after comparing to a mobile Ecobee thermostat sensor. This is the code from the unit for my shop.

substitutions:
  slug: shop
  friendly: Shop

esphome:
  name: ${slug}-air-quality
  friendly_name: ${friendly} Air Quality

esp8266:
  board: d1_mini

logger:
  level: WARN

api:
  encryption:
    key: 'xxx'

ota:
  - platform: esphome
    password: 'xxx'

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  manual_ip:
    static_ip: xxx
    gateway: xxx
    subnet: 255.255.255.0

i2c:
  frequency: 100kHz

uart:
  - rx_pin: D7
    baud_rate: 9600

sensor:
  - platform: pm1006
    pm_2_5:
      name: PM 2.5µm

  - platform: bme280_i2c
    address: 0x76
    temperature:
      name: Temperature
      id: ${slug}_temp
      filters:
        - offset: -3.38
    humidity:
      name: Humidity
      id: ${slug}_humid
      filters:
        - offset: 7.63
    iir_filter: 16x

  - platform: aht10
    variant: AHT20
    temperature:
      name: AHT21 Temperature
      id: ${slug}_aht21_temp
    humidity:
      name: AHT21 Humidity
      id: ${slug}_aht21_humid

  - platform: ens160_i2c
    address: 0x53
    eco2:
      name: CO²
    tvoc:
      name: VOC
    aqi:
      id: ${slug}_aqi
      name: AQI
    compensation:
      temperature: ${slug}_aht21_temp
      humidity: ${slug}_aht21_humid

text_sensor:
  - platform: template
    name: AQI Rating
    lambda: |-
      switch ( (int) ( id( ${slug}_aqi ).state ) ) {
        case 1: return {"Excellent"};
        case 2: return {"Good"};
        case 3: return {"Moderate"};
        case 4: return {"Poor"};
        case 5: return {"Unhealthy"};
        default: return {"N/A"};
      }

These resources were a huge help when I wired everything up and made changes to the YAML code:

Here is how I’m displaying the data on one of my Home Assistant dashboards.

As I was working on this project I knew I wanted a couple more air quality monitors around the house, which will be finished soon.

Update: I’ve had to make a small update by adding a 47uF capacitor to each ENS160 board, because they have power issues, causing the reading to stop for periods of time. My boards matched up with the right ones in the picture at that link. Here’s a picture of another ENS160 I modified, since it was a tight squeeze to made the modification on the devices I posted about here with everything already wired up. I also realized I was powering these through the 3V3 pin instead of VIN, so I fixed that.

I’ve also improved the display of the data on my dashboard by using mini-graph-card.