Cheap 15$ Air quality monitor: ESP32, Bluetooth & Home assistant
If you are a DIY lover, the first sensors you look at are : temperature sensor and airquality sensor. #Metoo.
I have started with the temperature sensor in this article and found that amazing. I decided to go try the airquality monitoring.
I wanted something cheap, and ideally with bluetooth to connect it easily to my ESP32 and Home assistant, I found that Airbox WP6003 can do the job.
Requirements:
Aliexpress:
ESP32-DevKitC board : Buy here from aliexpress
Airbox WP6003 Bluetooth : Buy here from aliexpress
Collecting information
BLE devices normally has characteristics that can be access using an ID. These characteristics contains the data. This is the easiest way.
However some manufacturers have decided to make it more complicated and to not store this information in a characteristic. The data is sent using a notification only
. This is the case for WP6003.
To see what I am talking about, execute the following command on your linux shell:
$ gatttool -I -b XX:XX:XX:XX:XX:XX
[XX:XX:XX:XX:XX:XX] connect
# you should be connected now to the airbox
...
# wait some minutes... A notification should appear
Notification handle = 0x0012 value: 0a 16 02 0e 0d 2d 00 c3 58 02 03 39 00 83 01 00 02 dc
# If you don't want to wait, execute the commands below to receive the data instantly
[XX:XX:XX:XX:XX:XX][LE]> char-write-req 0x0013 0100
Characteristic value was written successfully
[XX:XX:XX:XX:XX:XX][LE]> char-write-cmd 0x0010 aa15031a000935
Notification handle = 0x0012 value: aa 15 03 1a 00 09 35
[XX:XX:XX:XX:XX:XX][LE]> char-write-cmd 0x0010 ab
Notification handle = 0x0012 value: 0a 16 02 0e 0d 2d 00 c3 58 02 03 39 00 83 01 00 02 dc
Decoding the information
Alright, we have all we want :) NOOOO ! It is not that easy because you should to figure out where are the 4 data we are looking for:
- CO2
- HCHO
- TVOC
- TEMPERATURE
I know that for the notification above, I had the following values on my application:
co2 : 582 => we should look for 582 => HEX : 0x0246
temperature 19.5 => we should look for 195 => HEX : 0xc3
hcho: 0.116 => we should look for 116 => HEX : 0x83
tvoc: 0.825 => we should look for 825 => HEX : 0x0339
By comparing the notification data and the data above, we can understand that:
Notification handle = 0x0012 value: 0a 16 02 0e 0d 2d 00 c3 58 02 03 39 00 83 01 00 02 dc
19.5 825 116 732 - (150)
temp tvoc hcho
Receive data in ESPHOME
Esphome had recently an update to receive the notification. This update will provide us the byte array as received by the device.
All we should do is to parse the data and extract the values from the byte array and set the data as a sensor value.
esphome:
name: livingroom
platform: ESP32
board: esp32doit-devkit-v1
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable logging
logger:
# Enable Home Assistant API
api:
web_server:
port: 80
ota:
time:
- platform: homeassistant
id: homeassistant_time
# Example configuration entry
switch:
- platform: restart
name: "Living Room Restart"
# Enable Bluetooth scanning for this ESP32
esp32_ble_tracker:
# CHANGE mac_address to your airquality box wp6003
ble_client:
- mac_address: XX:XX:XX:XX:XX:XX
id: airquality
sensor:
- platform: template
name: "Xiaomei temperature"
id: xiaomei_temperature
device_class: "temperature"
state_class: "measurement"
unit_of_measurement: "°C"
- platform: template
name: "CO2"
id: xiaomei_co2
device_class: "carbon_dioxide"
state_class: "measurement"
unit_of_measurement: "ppm"
- platform: template
name: "TVOC"
id: xiaomei_tvoc
state_class: "measurement"
unit_of_measurement: "mg/m3"
- platform: template
name: "HCHO"
id: xiaomei_hcho
state_class: "measurement"
unit_of_measurement: "mg/m3"
- platform: ble_client
ble_client_id: airquality
name: "Airquality level"
service_uuid: "fff0"
characteristic_uuid: "fff4"
icon: "mdi:air"
update_interval: never
notify: true
lambda: |-
uint8_t* pdata = (uint8_t*) x.data();
float temperature = float((pdata[6] << 8) + pdata[7]) / 10;
float tvoc = float((pdata[10] << 8) + pdata[11]) / 1000;
float hcho = float((pdata[12] << 8) + pdata[13]) / 1000;
float co2 = (pdata[16] << 8) + pdata[17] - 150;
id(xiaomei_temperature).publish_state(temperature);
id(xiaomei_hcho).publish_state(hcho);
id(xiaomei_tvoc).publish_state(tvoc);
id(xiaomei_co2).publish_state(co2);
return (float)x.size();
Flash the esp32 with the above configuration
Connect ESPHome to Home assistant
Now that your esp32 is ready and connected to the airquality wp6003 box, connect the esp32 to home assistant if it’s not connected yet.
Refer to this article if you want to connect it.
Home assistant Demo
Now that your home assistant is connected and collecting the air info from the ESP32 and WP6003 box, you can create a card in your dashboard as I do.