Dear community,
yesterday, I have implemented a ESP32 with a BME680 to measure the air quality in our living room.
The sensor is providing data: temperature and humidity seem to be in an expected range, but the VOCs are just way off.
I do have to old Airthings Wave Plus devices: one in the basement, one in the second floor.
I can see the radon coming from the basement to the second floor. there is a correlation between values in the basement and in the second floor. So there is an airflow going upward through the house…
VOCs in the basement are very low, VOCs in the second floor jump up and down. (50 - 1100 ppb)
The newly BME680 is running for almost 12h and VOC values are way to high. If this was true, the sensor in the second floor (screenshot red ) would be much higher.
Question: who has experience with this sensor? Is this expected behaviour? How long does the calibration period take? (BME680 Numeric IAQ Accuracy is switching between 2 and 3.)
Any help is very much appreciated.
ESPHome yaml
# sources:
# https://esphome.io/components/sensor/airthings_ble
# https://esphome.io/components/sensor/bme680_bsec.html
# Variablen
substitutions:
device_name: "esphome-wohnzimmer2"
friendly_name: "Wohnzimmer2"
node_name: "esphome_wohnzimmer2"
device_description: "Sensor liest den Airthings Wave Plus Sensor im Keller via Bluetooth aus und liefert Daten ĂĽber den BME680"
# ESPHome Core Configuration
esphome:
name: '${device_name}'
friendly_name: '${friendly_name}'
comment: '${device_description}'
# Loop, der nach erfolgreicher WLAN-Verbindung und Zeitabfrage ausgefĂĽhrt wird
on_boot:
priority: -100 # Setze die Priorität niedriger als die WLAN-Verbindung (standardmäßig -10)
then:
- while:
condition:
not:
lambda: 'return id(homeassistant_time).now().is_valid();'
then:
- delay: 1s # Warte eine Sekunde, bevor erneut ĂĽberprĂĽft wird
- lambda: |-
// Sobald die Zeit verfĂĽgbar ist, berechne den Boot-Zeitpunkt
id(${node_name}_last_boot_time).publish_state(
id(homeassistant_time).now().timestamp - (int) id(${node_name}_uptime_seconds).state
);
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
level: DEBUG
# Airthings Wave Plus finden
esp32_ble_tracker:
# airthings_ble:
# Enable Home Assistant API
api:
encryption:
key: "j...x"
ota:
- platform: esphome
password: "e7....1c"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
# Set this to the IP of the ESP
static_ip: 192.168.30.26
# Set this to the IP address of the router. Often ends with .1
gateway: 192.168.30.1
# The subnet of the network. 255.255.255.0 works for most home networks.
subnet: 255.255.255.0
use_address: ${node_name}.internal
domain: .internal
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: '${device_name}'
password: "Bf...6"
captive_portal:
# Zeit von HomeAssistant abfragen -> für Last Boot nötig
time:
- platform: homeassistant
id: homeassistant_time
switch:
- platform: restart
name: "ESPHome '${friendly_name}' neu starten"
# Airthings Wave Plus einbinden
ble_client:
- mac_address: A4:DA:32:B9:5A:A5
id: awp_Keller
# i2c-config fĂĽr BME680-Sensor
i2c:
sda: GPIO21
scl: GPIO22
scan: false
id: bus_a
bme680_bsec:
id: bme680_internal
address: 0x77
temperature_offset: 0
iaq_mode: static
supply_voltage: 3.3V
sample_rate: ulp
state_save_interval: 6h
sensor:
# Airthings Wave Plus Keller
- platform: airthings_wave_plus
name: '${friendly_name} Keller'
ble_client_id: awp_Keller
update_interval: 5min # default
battery_update_interval: 24h # default
temperature:
name: "Keller Temperatur"
id: awp_Keller_temp
radon:
name: "Keller Radon"
id: awp_Keller_Radon
radon_long_term:
name: "Keller Radon Long Term"
id: awp_Keller_Radon_long
pressure:
name: "Keller Luftdruck"
id: awp_Keller_pressure
humidity:
name: "Keller Feuchtigkeit"
id: awp_Keller_humidity
co2:
name: "Keller CO2"
id: awp_Keller_co2
tvoc:
name: "Keller VOC"
id: awp_Keller_voc
illuminance:
name: "Keller ambient light"
id: awp_Keller_light
battery_voltage:
name: "Keller Batterie Spannung"
id: awp_Keller_volt
# Airthings Wave Plus Keller: Batterieanzeige in %
- platform: copy
source_id: awp_Keller_volt
name: 'Keller Battery Level'
id: awp_Keller_battery
unit_of_measurement: "%"
device_class: battery
accuracy_decimals: 0
filters:
- calibrate_linear:
- 2.2 -> 0
- 3.1 -> 100
# Airthings Wave Plus Keller: Taupunkt berechnen
- platform: template
name: "Keller Taupunkt"
lambda: |-
return (243.5*(log(id(awp_Keller_humidity).state/100)+((17.67*id(awp_Keller_temp).state)/
(243.5+id(awp_Keller_temp).state)))/(17.67-log(id(awp_Keller_humidity).state/100)-
((17.67*id(awp_Keller_temp).state)/(243.5+id(awp_Keller_temp).state))));
device_class: temperature
state_class: measurement
unit_of_measurement: °C
update_interval: 5min
icon: 'mdi:thermometer-water'
# Example configuration entry for BME680
# - platform: bme680
# temperature:
# name: "BME680 Temperature"
# pressure:
# name: "BME680 Pressure"
# humidity:
# id: "humidity"
# name: "BME680 Humidity"
# gas_resistance:
# id: "gas_resistance"
# name: "BME680 Gas Resistance"
# i2c_id: bus_a
# address: 0x77
# update_interval: 60s
# - platform: template
# name: "BME680 Indoor Air Quality"
# id: iaq
# icon: "mdi:gauge"
# # calculation: comp_gas = log(R_gas[ohm]) + 0.04 log(Ohm)/%rh * hum[%rh]
# lambda: |-
# return log(id(gas_resistance).state) + 0.04 * id(humidity).state;
# state_class: "measurement"
- platform: bme680_bsec
# ID of the bme680_bsec component to use for the next sensors.
# Useful when working with multiple devices
bme680_bsec_id: bme680_internal
temperature:
# Temperature in °C
name: "BME680 Temperature"
filters:
- median:
window_size: 5
send_every: 1
send_first_at: 1
pressure:
# Pressure in hPa
name: "BME680 Pressure"
sample_rate: ulp
filters:
- median:
window_size: 5
send_every: 1
send_first_at: 1
accuracy_decimals: 0
humidity:
# Relative humidity %
name: "BME680 Humidity"
sample_rate: ulp
filters:
- median:
window_size: 5
send_every: 1
send_first_at: 1
accuracy_decimals: 0
gas_resistance:
# Gas resistance in Ω
name: "BME680 Gas Resistance"
filters:
- median:
window_size: 5
send_every: 1
send_first_at: 1
iaq:
# Indoor air quality value
name: "BME680 IAQ"
id: iaq
filters:
- median:
window_size: 5
send_every: 1
send_first_at: 1
iaq_accuracy:
# IAQ accuracy as a numeric value of 0, 1, 2, 3
name: "BME680 Numeric IAQ Accuracy"
co2_equivalent:
# CO2 equivalent estimate in ppm
name: "BME680 CO2 Equivalent"
filters:
- median:
window_size: 5
send_every: 1
send_first_at: 1
accuracy_decimals: 0
breath_voc_equivalent:
# Volatile organic compounds equivalent estimate in ppm
name: "BME680 Breath VOC Equivalent Source"
id: voc_source
internal: true
filters:
- median:
window_size: 5
send_every: 1
send_first_at: 1
- platform: template
name: "BME680 Breath VOC Equivalent"
id: BME680_voc_calc
lambda: |-
return ( (id(voc_source).state) * 1000) ;
device_class: volatile_organic_compounds_parts
state_class: measurement
unit_of_measurement: ppb
accuracy_decimals: 0
update_interval: 5min
icon: 'mdi:molecule'
# Last Boot Sensor definieren (Berechnung findet einmalig beim Boot statt)
- platform: uptime
id: ${node_name}_uptime_seconds
name: "Uptime Sekunden"
internal: true
- platform: template
name: "Last Boot"
id: ${node_name}_last_boot_time
device_class: timestamp
entity_category: diagnostic
accuracy_decimals: 0
update_interval: never # Kein regelmäßiges Update nötig
text_sensor:
# Air Quality-Angaben
- platform: template
name: "BME680 IAQ Classification"
icon: "mdi:checkbox-marked-circle-outline"
lambda: |-
if (int(id(iaq).state) <= 50) {
return {"Excellent"};
}
else if (int(id(iaq).state) <= 100) {
return {"Good"};
}
else if (int(id(iaq).state) <= 150) {
return {"Lightly polluted"};
}
else if (int(id(iaq).state) <= 200) {
return {"Moderately polluted"};
}
else if (int(id(iaq).state) <= 250) {
return {"Heavily polluted"};
}
else if (int(id(iaq).state) <= 350) {
return {"Severely polluted"};
}
else if (int(id(iaq).state) <= 500) {
return {"Extremely polluted"};
}
else {
return {"unknown"};
}
# Send IP Address of ESP-device
- platform: wifi_info
ip_address:
name: IP Address
- platform: bme680_bsec
iaq_accuracy:
# IAQ accuracy as a text value of Stabilizing, Uncertain, Calibrating, Calibrated
name: "BME680 IAQ Accuracy"
EDIT
I have put the sensor in a freshly printed case (PLA). I have read that PLA emits VOCs during printing, but I found no information about emiting VOCs afterwards as well?
EDIT2
AFAIK, there should be a correlation between gas resistance and VOC-values?
I have gone back to the documentation and have realised that ESPhome recommends to use this:
So I did.
I am still very disappointed by this sensor. VOC-values are still x-times to high - although not jumping around anymore - and temperature is 7°C too high.
The temperature offset is configurable, but the VOCs are not - AFAIK.
Has anybody the same experiences? Is there someone, who can explain, how to properly configure this sensor? Any help is very much appreciate.
new ESPhome yaml
# sources:
# https://esphome.io/components/sensor/airthings_ble
# https://esphome.io/components/sensor/bme68x_bsec2.html
# Variablen
substitutions:
device_name: "esphome-wohnzimmer2"
friendly_name: "Wohnzimmer2"
node_name: "esphome_wohnzimmer2"
device_description: "Sensor liest den Airthings Wave Plus Sensor im Keller via Bluetooth aus und liefert Daten ĂĽber den BME680"
# ESPHome Core Configuration
esphome:
name: '${device_name}'
friendly_name: '${friendly_name}'
comment: '${device_description}'
# Loop, der nach erfolgreicher WLAN-Verbindung und Zeitabfrage ausgefĂĽhrt wird
on_boot:
priority: -100 # Setze die Priorität niedriger als die WLAN-Verbindung (standardmäßig -10)
then:
- while:
condition:
not:
lambda: 'return id(homeassistant_time).now().is_valid();'
then:
- delay: 1s # Warte eine Sekunde, bevor erneut ĂĽberprĂĽft wird
- lambda: |-
// Sobald die Zeit verfĂĽgbar ist, berechne den Boot-Zeitpunkt
id(${node_name}_last_boot_time).publish_state(
id(homeassistant_time).now().timestamp - (int) id(${node_name}_uptime_seconds).state
);
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
level: DEBUG
# Airthings Wave Plus finden
esp32_ble_tracker:
# airthings_ble:
# Enable Home Assistant API
api:
encryption:
key: "xxx"
ota:
- platform: esphome
password: "xxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
# Set this to the IP of the ESP
static_ip: 192.168.30.26
# Set this to the IP address of the router. Often ends with .1
gateway: 192.168.30.1
# The subnet of the network. 255.255.255.0 works for most home networks.
subnet: 255.255.255.0
use_address: ${node_name}.internal
domain: .internal
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: '${device_name}'
password: "xxx"
captive_portal:
# Zeit von HomeAssistant abfragen -> für Last Boot nötig
time:
- platform: homeassistant
id: homeassistant_time
switch:
- platform: restart
name: "ESPHome '${friendly_name}' neu starten"
# Airthings Wave Plus einbinden
ble_client:
- mac_address: A4:DA:32:B9:5A:A5
id: awp_Keller
# i2c-config fĂĽr BME680-Sensor
i2c:
sda: GPIO21
scl: GPIO22
scan: false
id: bus_a
bme68x_bsec2_i2c:
address: 0x77
model: bme680
operating_age: 28d
sample_rate: ULP
supply_voltage: 3.3V
temperature_offset: 0
state_save_interval: 6h
sensor:
# Airthings Wave Plus Keller
- platform: airthings_wave_plus
name: '${friendly_name} Keller'
ble_client_id: awp_Keller
update_interval: 5min # default
battery_update_interval: 24h # default
temperature:
name: "Keller Temperatur"
id: awp_Keller_temp
radon:
name: "Keller Radon"
id: awp_Keller_Radon
radon_long_term:
name: "Keller Radon Long Term"
id: awp_Keller_Radon_long
pressure:
name: "Keller Luftdruck"
id: awp_Keller_pressure
humidity:
name: "Keller Feuchtigkeit"
id: awp_Keller_humidity
co2:
name: "Keller CO2"
id: awp_Keller_co2
tvoc:
name: "Keller VOC"
id: awp_Keller_voc
illuminance:
name: "Keller ambient light"
id: awp_Keller_light
battery_voltage:
name: "Keller Batterie Spannung"
id: awp_Keller_volt
# Airthings Wave Plus Keller: Batterieanzeige in %
- platform: copy
source_id: awp_Keller_volt
name: 'Keller Battery Level'
id: awp_Keller_battery
unit_of_measurement: "%"
device_class: battery
accuracy_decimals: 0
filters:
- calibrate_linear:
- 2.2 -> 0
- 3.1 -> 100
# Airthings Wave Plus Keller: Taupunkt berechnen
- platform: template
name: "Keller Taupunkt"
lambda: |-
return (243.5*(log(id(awp_Keller_humidity).state/100)+((17.67*id(awp_Keller_temp).state)/
(243.5+id(awp_Keller_temp).state)))/(17.67-log(id(awp_Keller_humidity).state/100)-
((17.67*id(awp_Keller_temp).state)/(243.5+id(awp_Keller_temp).state))));
device_class: temperature
state_class: measurement
unit_of_measurement: °C
update_interval: 5min
icon: 'mdi:thermometer-water'
# Konfiguration fĂĽr BME680 Sensor
- platform: bme68x_bsec2
temperature:
name: "BME680 Temperature"
pressure:
name: "BME680 Pressure"
accuracy_decimals: 0
humidity:
name: "BME680 Humidity"
accuracy_decimals: 0
iaq:
name: "BME680 IAQ"
id: iaq
co2_equivalent:
name: "BME680 CO2 Equivalent"
accuracy_decimals: 0
breath_voc_equivalent:
name: "BME680 Breath VOC Equivalent original"
id: voc_source
internal: false
- platform: template
name: "BME680 Breath VOC Equivalent"
id: BME680_voc_calc
lambda: |-
return ( (id(voc_source).state) * 1000) ;
device_class: volatile_organic_compounds_parts
state_class: measurement
unit_of_measurement: ppb
accuracy_decimals: 0
update_interval: 5min
icon: 'mdi:molecule'
# Last Boot Sensor definieren (Berechnung findet einmalig beim Boot statt)
- platform: uptime
id: ${node_name}_uptime_seconds
name: "Uptime Sekunden"
internal: true
- platform: template
name: "Last Boot"
id: ${node_name}_last_boot_time
device_class: timestamp
entity_category: diagnostic
accuracy_decimals: 0
update_interval: never # Kein regelmäßiges Update nötig
text_sensor:
- platform: bme68x_bsec2
iaq_accuracy:
name: "BME680 IAQ Accuracy"
# Air Quality-Angaben
- platform: template
name: "BME680 IAQ Classification"
update_interval: 5min
lambda: |-
if ( int(id(iaq).state) <= 50) {
return {"Excellent"};
}
else if (int(id(iaq).state) >= 51 && int(id(iaq).state) <= 100) {
return {"Good"};
}
else if (int(id(iaq).state) >= 101 && int(id(iaq).state) <= 150) {
return {"Lightly polluted"};
}
else if (int(id(iaq).state) >= 151 && int(id(iaq).state) <= 200) {
return {"Moderately polluted"};
}
else if (int(id(iaq).state) >= 201 && int(id(iaq).state) <= 250) {
return {"Heavily polluted"};
}
else if (int(id(iaq).state) >= 251 && int(id(iaq).state) <= 350) {
return {"Severely polluted"};
}
else if (int(id(iaq).state) >= 351) {
return {"Extremely polluted"};
}
else {
return {"error"};
}
# Send IP Address of ESP-device
- platform: wifi_info
ip_address:
name: IP Address
Karosm
(Karosm)
November 4, 2024, 3:42pm
3
That’s a lot… Do you have it inside an enclosure?
It could mess up temperature compensation for other values as well.
You will never find two VOC-sensors that output same value. Also CO2 equivalent will never be like true NDIR sensor output, because it’s just an estimation based on VOCs.
Hi @Karosm ,
thank you for your reply.
Yes, I have designed my own case. I just opened it up to improve ventilation - but doesn’t seem to change anything.
Well, I am aware that sensors are not at all an exact thing - well, at least in that price segment. But I was expecting something comparable ? My goal is to define a template, indicating when opening the windows would be a good idea. (logic based on air quality, radon, temperature, dew point (indoor vs. outdoor))
Karosm
(Karosm)
November 4, 2024, 4:35pm
5
For temp, RH and pressure yes. For VOC no.
But for your use case it’s enough to detect relative values and that’s IAQ should give you.
But until you find out why temp is off so much, I wouldn’t trust that sensor.
1 Like
Well, I assume, the temperature is too high, because the gas resistance sensor heats up to do his measurement. I could try to force the sensor to take values at different times, and average them with a filter.
Do you know, what happens, if I configure the temperature offset for the BME680? (There is a configuration variable on top level of the sensor.) Will this affect only temperature or all sensor value calculation, such as VOC and CO2?
WallyR
(Wally)
November 4, 2024, 10:44pm
7
As said VOC sensors will give you a relative value.
What you can do is try to make a translation table between your VOC sensors.
Place them side by side to each other. Run a couple of days and compare the graphs.
Then switch their places around and do it again.
Next put them on top of each other and do it again.
Then switch them around here too and do it again.
schneich:
Do you know, what happens, if I configure the temperature offset for the BME680? (There is a configuration variable on top level of the sensor.) Will this affect only temperature or all sensor value calculation, such as VOC and CO2?
I found some posts indicating that the temperature offset will have an influence on the other values as well. The BSEC-library should do the calculation, but I haven’t had the time to properly test it.
Unfortunately, I was not able to find the source on the bosch website to support this.
Thank you for the proposal. Well, I decided to focus on the IAQ-values. That should - in theory - be sufficient for my use case.
But if I compare the IAQ-value from the BME680 to my AirthingsWave Plus, the BME680 indicates “moderately polluted” (IAQ of 160, just after closing the windows), where as the Airthings sensor provides an all green state. (Outside air quality here in Switzerland is usually very very good, so I tend to believe the Airthings… )
In the end, they both should tell me to open the windows at the same sate of indoor air quality.
I will do some more research and try to find a way to get rid off the temperature differences. Might even re-design my casing.
EDIT: is there a cheap and exact CO2-sensor? If VOC-sensors are just useless, exact CO2-values would be a feasible work around…
Karosm
(Karosm)
November 5, 2024, 10:47pm
9
Not really, good NDIR sensors are expensive. But compared to VOC sensors Co2 equivalent even the cheapest one are way better.
Senseair S8, MH-Z19, SCD40 …
any recommendations?
btw: someone has had the same issue and opened up a github issue
opened 01:19AM - 23 Oct 24 UTC
### The problem
I have been going crazy trying to get my BME680 sensors worki… ng the `bme68x_bsec2_i2c` component. The temperature and humidity values are WAY off (I cannot speak for the other sensor values, since I don't have many other sources for pressure, gas, VOCs, etc.).
After seeing all the complaints online about incorrect/high values, I was about to throw all my BME680s in the trash when I decided to try the _regular_ `bme680` component. Turns out there doesn't seem to be any issues with the sensors themselves... but with the `bme68x_bsec2_i2c` component.
**The `bme680` component seems to work perfectly well with all values stable and within specified tolerances.**
Here are the problems I am seeing:
- When setting the `bme68x_bsec2_i2c.sample_rate` to **LP**, the temperature begins to fluctuate every few seconds between +2°F and +6°F above actual.
- When using **ULP**, the temp jumps to +10°F above actual after about 5 minutes.
- If I try to mix them by setting the `bme68x_bsec2_i2c.sample_rate` to **ULP** and ANY of the individual sensors (temp/humidity/pressure) to **LP**, I get the following error and the component fails to load:<br>`Communication failed (BSEC2 status: 14, BME68X status: 0)`
- The humidity is off as well.
- I did't record any of the specifics, but I can if it helps.
I have tested with several sensors/boards/configurations, all with the same, repeatable results.
- I tested 4 or 5 sensors so far from 2 different vendors
- [Amazon](https://www.amazon.com/gp/product/B0BXKW2KVC)
- [AliExpress](https://www.aliexpress.us/item/3256805784068021.html)
- Tested with the following boards:
- ESP32-WROVER
- Waveshare ESP32-S3-Zero
- Olimex ESP32-POE-ISO-EA-IND
- **The sensors are NOT IN ENCLOSURES** (yet)
- The boards/sensors are all in different rooms of my house with good ventilation and away from any heat sources
- All the sensors have been connected with long enough wires to keep them away from the boards and other components
- I have tried with and without other components at the same time (e.g. DHT22, AHT20, APDS9960, LD2410C, SSD1306)
- Tested using both the "recommended" and "latest" versions of the Arduino framework
- The component does not work on ESP-IDF (yet? 🤞)
I noticed there are newer versions of Bosch libraries, but I haven't had time to delve into the process of using them.
I can only assume there is an issue with how the heater is being used. There are settings for the heater in the `bme680` component but not in the `bme68x_bsec2_i2c` component.
### Which version of ESPHome has the issue?
2024.10.0
### What type of installation are you using?
Home Assistant Add-on
### Which version of Home Assistant has the issue?
N/A
### What platform are you using?
ESP32
### Board
ESP32-WROVER, Waveshare ESP32-S3-Zero, Olimex ESP32-POE-ISO-EA
### Component causing the issue
bme68x_bsec2_i2c
### Example YAML snippet
```yaml
esphome:
name: ${name}
name_add_mac_suffix: false
friendly_name: ${friendly_name}
comment: ${comment}
area: ${area}
esp32:
board: ${board} # Tested using esp-wrover-kit, adafruit_feather_esp32s3, esp32-poe-iso
framework:
type: arduino
psram: # Using this on supported boards
logger:
api:
encryption:
key: !secret api_key
ota:
- platform: esphome
password: !secret ota_pass
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
fast_connect: true
reboot_timeout: 5min
enable_on_boot: true
bluetooth_proxy:
active: true
cache_services: true
esp32_ble_tracker:
scan_parameters:
active: true
web_server:
port: 80
version: 3
ota: false
# local: true
include_internal: false
i2c:
sda: GPIO21
scl: GPIO22
scan: true
id: bus_a
bme68x_bsec2_i2c:
id: bme680_sensor
address: 0x77
model: bme680
operating_age: 28d
# sample_rate: LP # LP fluctuates every few seconds between +2°F and +6°F above actual
sample_rate: ULP # ULP jumps to +10°F above actual about 5 minutes after booting
supply_voltage: 3.3V
sensor:
- platform: bme68x_bsec2
bme68x_bsec2_id: bme680_sensor
temperature:
id: sensor_temperature
name: "BME680 Temperature"
# sample_rate: LP # Causes the component to fail with "BSEC2 status: 14"
pressure:
id: sensor_pressure
name: "BME680 Pressure"
on_value:
- component.update: sensor_altitude
# sample_rate: LP # Causes the component to fail with "BSEC2 status: 14"
humidity:
id: sensor_humidity
name: "BME680 Relative Humidity"
# sample_rate: LP # Causes the component to fail with "BSEC2 status: 14"
gas_resistance:
id: sensor_gas_resistance
name: "BME680 Gas Resistance"
iaq:
id: sensor_iaq
name: "BME680 Indoor Air Quality"
on_value:
- component.update: sensor_iaq_classification
iaq_static:
id: sensor_iaq_static
name: "BME680 IAQ Static"
iaq_accuracy:
id: sensor_iaq_accuracy
name: "BME680 IAQ Accuracy"
co2_equivalent:
id: sensor_co2
name: "BME680 CO2 Equivalent"
breath_voc_equivalent:
id: sensor_breath_voc
name: "BME680 Breath VOC Equivalent"
###############################################################
# Configuration of the regular BME680 component, which seems to be working so far:
sensor:
- platform: bme680
address: 0x77
update_interval: 30s
iir_filter: 31x
heater:
temperature: 320 # Default
duration: 150ms # Default
temperature:
id: sensor_temperature
name: "BME680 Temperature"
oversampling: 16x
pressure:
id: sensor_pressure
name: "BME680 Pressure"
oversampling: 16x
humidity:
id: sensor_humidity
name: "BME680 Relative Humidity"
oversampling: 16x
gas_resistance:
id: sensor_gas_resistance
name: "BME680 Gas Resistance"
```
### Anything in the logs that might be useful for us?
```txt
This shows the error when bme68x_bsec2_i2c.sample_rate is "ULP" and one or more of the individual temp, humidity, pressure sensors are set to "LP".
[18:45:55][C][i2c.arduino:071]: I2C Bus:
[18:45:55][C][i2c.arduino:072]: SDA Pin: GPIO21
[18:45:55][C][i2c.arduino:073]: SCL Pin: GPIO22
[18:45:55][C][i2c.arduino:074]: Frequency: 50000 Hz
[18:45:55][C][i2c.arduino:086]: Recovery: bus successfully recovered
[18:45:55][I][i2c.arduino:096]: Results from i2c bus scan:
[18:45:55][I][i2c.arduino:102]: Found i2c device at address 0x38
[18:45:55][I][i2c.arduino:102]: Found i2c device at address 0x39
[18:45:55][I][i2c.arduino:102]: Found i2c device at address 0x77
[18:45:56][C][bme68x_bsec2_i2c.sensor:029]: Address: 0x77
[18:45:56][C][bme68x_bsec2.sensor:060]: BME68X via BSEC2:
[18:45:56][C][bme68x_bsec2.sensor:063]: BSEC2 version: 2.5.0.2
[18:45:56][C][bme68x_bsec2.sensor:065]: BSEC2 configuration blob:
[18:45:56][C][bme68x_bsec2.sensor:066]: Configured: YES
[18:45:56][C][bme68x_bsec2.sensor:068]: Size: 2063
[18:45:56][E][bme68x_bsec2.sensor:073]: Communication failed (BSEC2 status: 14, BME68X status: 0)
[18:45:56][C][bme68x_bsec2.sensor:079]: Operating age: 28 days
[18:45:56][C][bme68x_bsec2.sensor:080]: Sample rate: ULP
[18:45:56][C][bme68x_bsec2.sensor:081]: Voltage: 3.3V
[18:45:56][C][bme68x_bsec2.sensor:082]: State save interval: 21600000ms
[18:45:56][C][bme68x_bsec2.sensor:083]: Temperature offset: 0.00
[18:45:56][C][bme68x_bsec2.sensor:086]: Temperature 'BME680 Temperature'
[18:45:56][C][bme68x_bsec2.sensor:086]: Device Class: 'temperature'
[18:45:56][C][bme68x_bsec2.sensor:086]: State Class: 'measurement'
[18:45:56][C][bme68x_bsec2.sensor:086]: Unit of Measurement: '°C'
[18:45:56][C][bme68x_bsec2.sensor:086]: Accuracy Decimals: 1
[18:45:56][C][bme68x_bsec2.sensor:086]: Icon: 'mdi:thermometer'
[18:45:56][C][bme68x_bsec2.sensor:087]: Sample rate: LP
[18:45:56][C][bme68x_bsec2.sensor:088]: Pressure 'BME680 Pressure'
[18:45:56][C][bme68x_bsec2.sensor:088]: Device Class: 'atmospheric_pressure'
[18:45:56][C][bme68x_bsec2.sensor:088]: State Class: 'measurement'
[18:45:56][C][bme68x_bsec2.sensor:088]: Unit of Measurement: 'hPa'
[18:45:56][C][bme68x_bsec2.sensor:088]: Accuracy Decimals: 1
[18:45:56][C][bme68x_bsec2.sensor:088]: Icon: 'mdi:gauge'
[18:45:56][C][bme68x_bsec2.sensor:089]: Sample rate: Default
[18:45:56][C][bme68x_bsec2.sensor:090]: Humidity 'BME680 Relative Humidity'
[18:45:56][C][bme68x_bsec2.sensor:090]: Device Class: 'humidity'
[18:45:56][C][bme68x_bsec2.sensor:090]: State Class: 'measurement'
[18:45:56][C][bme68x_bsec2.sensor:090]: Unit of Measurement: '%'
[18:45:56][C][bme68x_bsec2.sensor:090]: Accuracy Decimals: 1
[18:45:56][C][bme68x_bsec2.sensor:090]: Icon: 'mdi:water-percent'
[18:45:56][C][bme68x_bsec2.sensor:091]: Sample rate: Default
[18:45:56][C][bme68x_bsec2.sensor:092]: Gas resistance 'BME680 Gas Resistance'
[18:45:56][C][bme68x_bsec2.sensor:092]: State Class: 'measurement'
[18:45:56][C][bme68x_bsec2.sensor:092]: Unit of Measurement: 'Ω'
[18:45:56][C][bme68x_bsec2.sensor:092]: Accuracy Decimals: 0
[18:45:56][C][bme68x_bsec2.sensor:092]: Icon: 'mdi:gas-cylinder'
[18:45:56][C][bme68x_bsec2.sensor:093]: CO2 equivalent 'BME680 CO2 Equivalent'
[18:45:56][C][bme68x_bsec2.sensor:093]: State Class: 'measurement'
[18:45:56][C][bme68x_bsec2.sensor:093]: Unit of Measurement: 'ppm'
[18:45:56][C][bme68x_bsec2.sensor:093]: Accuracy Decimals: 1
[18:45:56][C][bme68x_bsec2.sensor:093]: Icon: 'mdi:test-tube'
[18:45:56][C][bme68x_bsec2.sensor:094]: Breath VOC equivalent 'BME680 Breath VOC Equivalent'
[18:45:56][C][bme68x_bsec2.sensor:094]: State Class: 'measurement'
[18:45:56][C][bme68x_bsec2.sensor:094]: Unit of Measurement: 'ppm'
[18:45:56][C][bme68x_bsec2.sensor:094]: Accuracy Decimals: 1
[18:45:56][C][bme68x_bsec2.sensor:094]: Icon: 'mdi:test-tube'
[18:45:56][C][bme68x_bsec2.sensor:095]: IAQ 'BME680 Indoor Air Quality'
[18:45:56][C][bme68x_bsec2.sensor:095]: State Class: 'measurement'
[18:45:56][C][bme68x_bsec2.sensor:095]: Unit of Measurement: 'IAQ'
[18:45:56][C][bme68x_bsec2.sensor:095]: Accuracy Decimals: 0
[18:45:56][C][bme68x_bsec2.sensor:095]: Icon: 'mdi:gauge'
[18:45:56][C][bme68x_bsec2.sensor:096]: IAQ static 'BME680 IAQ Static'
[18:45:56][C][bme68x_bsec2.sensor:096]: State Class: 'measurement'
[18:45:56][C][bme68x_bsec2.sensor:096]: Unit of Measurement: 'IAQ'
[18:45:56][C][bme68x_bsec2.sensor:096]: Accuracy Decimals: 0
[18:45:56][C][bme68x_bsec2.sensor:096]: Icon: 'mdi:gauge'
[18:45:56][C][bme68x_bsec2.sensor:097]: Numeric IAQ accuracy 'BME680 IAQ Accuracy'
[18:45:56][C][bme68x_bsec2.sensor:097]: State Class: 'measurement'
[18:45:56][C][bme68x_bsec2.sensor:097]: Unit of Measurement: ''
[18:45:56][C][bme68x_bsec2.sensor:097]: Accuracy Decimals: 0
[18:45:56][C][bme68x_bsec2.sensor:097]: Icon: 'mdi:checkbox-marked-circle-outline'
[18:45:56][C][bme68x_bsec2.sensor:100]: IAQ accuracy 'BME680 IAQ Accuracy'
[18:45:56][C][bme68x_bsec2.sensor:100]: Icon: 'mdi:checkbox-marked-circle-outline'
[18:45:56][E][component:082]: Component bme68x_bsec2 is marked FAILED
```
### Additional information
This is a screenshot of the values when using the "LP" sample_rate:
<img width="598" alt="Screenshot 2024-10-22 at 9 24 26 PM" src="https://github.com/user-attachments/assets/4fbee550-d21a-4bb8-857d-13a407c3e4b7">
This is when using the "ULP" sample_rate:
<img width="580" alt="Screenshot 2024-10-22 at 9 26 25 PM" src="https://github.com/user-attachments/assets/6a5b5390-2650-4260-b829-11181aacd96e">
Actual temperature at the time was about **72** F.
Karosm
(Karosm)
November 6, 2024, 7:52pm
11
schneich:
any recommendations?
Not really, depends on price/availability. Also SCD in aliexpress cost 1/3 compared to other markets, so I expect those to be something else than (first grade) products form Sensirion.
How are the temp values with bme680 component?
I just used the old BME680 component. This is running now for 10min and temperature readings and humidity seems to be fine. IAQ seems to be a bit low.
There is one thing unclear to me in the documentation: the calculation of the IAQ.
There is this example provided:
# calculation: comp_gas = log(R_gas[ohm]) + 0.04 log(Ohm)/%rh * hum[%rh]
The actual calculation (-> lambda) is then a bit different:
- platform: template
name: "BME680 Indoor Air Quality"
id: iaq
icon: "mdi:gauge"
# calculation: comp_gas = log(R_gas[ohm]) + 0.04 log(Ohm)/%rh * hum[%rh]
lambda: |-
return log(id(gas_resistance).state) + 0.04 * id(humidity).state;
state_class: "measurement"
Source: BME680 Temperature+Pressure+Humidity+Gas Sensor — ESPHome
What is correct?
Karosm
(Karosm)
November 6, 2024, 8:19pm
13
That’s good. Maybe your sensor is ok.
schneich:
What is correct?
I don’t know. I don’t care. Consider it as a relative output. Compare values after few hours of open windows to few days of closed.
Well, if the math is wrong, there is probably not the intended output?
I will keep it running for a couple of days and then reconsider my strategy/choosing of a different sensor.
Karosm
(Karosm)
November 6, 2024, 8:48pm
15
I’m trying to say, there is not wrong or right. There is no formula based on math or physics to give right output. There are different VOC sensors measuring several (different) gases different way and there are different formulas to give some output. Take it like this: output 1 or 10 doesn’t matter. But 2 is twice as 1 and 20 is twice as 10.
Turns out, there was a bug in the BME68x component . After installing the newest version, VOC readings got more stable and IAQ seems to make sense. I decided to follow your recommendation and focus on the IAQ-values and not too much an VOC and CO2 values.