This is my first DIY project for Home Assistant.
I wanted to make indoor air quality sensor with temperature, humidity and radiation monitoring.
Parts I have used:
- Wemos D1 mini ESP8266
- Wemos BMP180 shield
- Wemos DHT22 shield
- Wemos Tripler Base
- PMS7003 dust sensor https://ru.aliexpress.com/item/32639894148.html?spm=a2g0s.9042311.0.0.274233edZH03fd
- DIY Geiger kit https://ru.aliexpress.com/item/33024491826.html?spm=a2g0s.9042311.0.0.274233edZH03fd
- D150W box 92x52x147mm
- MicroUSB cable
- KIT of plastic M3 screws
- wires
Tools:
- Soldering iron
- glue gun
This is the prototype:
This is the construction process:
And the final product:
Here is ESPhome config:
esphome:
name: indoor_air_sensor
platform: ESP8266
board: d1_mini
wifi:
ssid: "Z-WiFi"
password: "***"
manual_ip:
static_ip: ***
gateway: ***
subnet: ***
logger:
level: WARN
api:
password: "***"
ota:
password: "***"
uart:
rx_pin: GPIO3
baud_rate: 9600
i2c:
sda: D2
scl: D1
scan: True
sensor:
- platform: dht
pin: D0
temperature:
name: "Bedroom temp"
humidity:
name: "Bedroom humidity"
model: DHT22
update_interval: 60s
- platform: pmsx003
type: PMSX003
pm_1_0:
name: "Bedroom dust <1.0µm"
pm_2_5:
name: "Bedroom dust <2.5µm"
pm_10_0:
name: "Bedroom dust <10.0µm"
- platform: bmp085
temperature:
name: "Bedroom temp (BMP180)"
pressure:
name: "Atmospheric pressure"
update_interval: 60s
- platform: pulse_counter
pin: D5
name: "Radiation level"
unit_of_measurement: 'µSv/h'
filters:
- lambda: return x / 123.147092360319;
To convert Geiger counter pulse into µSv/h you need to get your Geiger tube characteristics.
And this is the Air Quality Intex (AQI) calculator. I use 24-hour formula it is easier, but I am planning to implement AQI NowCast formula because it is more dynamic.
- platform: sql
queries:
- name: 'Pm 2.5 24 hour avg'
query: >
SELECT ROUND(AVG(state),2) 'value'
FROM states
WHERE entity_id = 'sensor.bedroom_dust_2_5um'
AND state != 'unknown'
AND state != ''
AND created > datetime('now', '-24 hours')
GROUP BY DATE(entity_id);
column: 'value'
- platform: template
sensors:
aqi_category:
friendly_name: '24 hour AQI'
value_template: >
{% set vv = states('sensor.pm_2_5_day_avg')|float %}
{% if vv > 0 and vv <= 12 %}
GOOD
{% elif vv > 12 and vv <= 35.4 %}
MODERATE
{% elif vv > 35.5 and vv <= 55.4 %}
NHEALTHY FOR SENSITIVE
{% elif vv > 55.5 and vv <= 150.4 %}
UNHEALTHY
{% elif vv > 150.5 and vv <= 250.4 %}
VERY UNHEALTHY
{% elif vvt > 250.5 %}
HAZARDOUS
{% else %}
UNKNOWN
{% endif %}
It shows:
- Air quality index
- PM 1.0 particle concentration
- PM 2.5 particle concentration
- PM 10.0 particle concentration
- Radiation level (in µSv/h)
- Temperature
- Humidity
- Atmospheric pressure
UPDATE: had to switch to SQL sensor for average because of the performance problem.