Implement improved AQ calculation
Implements an AQ calculation from [1], which should hopefully provide a more stable, sensible value for the air quality. This also adds a configurable gas ceiling level, needed for full calibration and explained in the README. [1] https://github.com/thstielow/raspi-bme680-iaq The human text ratings are still a work-in-progress.
This commit is contained in:
parent
c324689b19
commit
3088a6393b
17
README.md
17
README.md
@ -29,7 +29,7 @@ Note: Once programmed, the output LED will flash continuously until connected
|
|||||||
to HomeAssistant, and a bit longer to establish if the wake word
|
to HomeAssistant, and a bit longer to establish if the wake word
|
||||||
functionality is enabled. This is by design, so you know if your sensors
|
functionality is enabled. This is by design, so you know if your sensors
|
||||||
are connected or not. If you do not want this, comment out the
|
are connected or not. If you do not want this, comment out the
|
||||||
`light.turn_on` block starting on line 54 of the ESPHome configuration
|
`light.turn_on` block starting on line 38 of the ESPHome configuration
|
||||||
to disable this functionality.
|
to disable this functionality.
|
||||||
|
|
||||||
For more details, please [see my blog post on the SuperSensor project](https://www.boniface.me/the-supersensor/).
|
For more details, please [see my blog post on the SuperSensor project](https://www.boniface.me/the-supersensor/).
|
||||||
@ -59,6 +59,21 @@ The SuperSensor's voice functionality can be completely disabled if voice
|
|||||||
support is not desired. This defeats most of the point of the SuperSensor,
|
support is not desired. This defeats most of the point of the SuperSensor,
|
||||||
but can be done if desired.
|
but can be done if desired.
|
||||||
|
|
||||||
|
### Gas Ceiling
|
||||||
|
|
||||||
|
The AQ (air quality) calculation from the BME680 requires a "maximum"/ceiling
|
||||||
|
threshold for the gas resistance value in clean air after some operation
|
||||||
|
time. The value defaults to 200,000 to provide an initial baseline, but
|
||||||
|
should be calibrated manually by:
|
||||||
|
|
||||||
|
1. Turning on the Supersensor in a known-clean environment (e.g. a sealed
|
||||||
|
container in fresh air).
|
||||||
|
2. Leave the sensor on for 4-6 hours to burn in the sensor.
|
||||||
|
3. Setting this to the maximum value of the Gas Resistance sensor.
|
||||||
|
|
||||||
|
This value will then define what "100% air quality" represents, and the
|
||||||
|
Supersensor can then be moved to its normal operating location.
|
||||||
|
|
||||||
### Light Threshold Control
|
### Light Threshold Control
|
||||||
|
|
||||||
The SuperSensor features a "light presence" binary sensor based on the light
|
The SuperSensor features a "light presence" binary sensor based on the light
|
||||||
|
@ -57,6 +57,11 @@ esp32:
|
|||||||
board: esp32dev
|
board: esp32dev
|
||||||
|
|
||||||
globals:
|
globals:
|
||||||
|
- id: gas_ceiling
|
||||||
|
type: int
|
||||||
|
restore_value: yes
|
||||||
|
initial_value: "200000"
|
||||||
|
|
||||||
- id: pir_hold_time
|
- id: pir_hold_time
|
||||||
type: int
|
type: int
|
||||||
restore_value: yes
|
restore_value: yes
|
||||||
@ -499,18 +504,26 @@ sensor:
|
|||||||
filters:
|
filters:
|
||||||
- median
|
- median
|
||||||
|
|
||||||
- platform: template
|
|
||||||
name: "BME680 IAQ"
|
|
||||||
id: bme680_iaq
|
|
||||||
icon: "mdi:gauge"
|
|
||||||
# caulculation: comp_gas = log(R_gas[ohm]) + 0.04 log(Ohm)/%rh * hum[%rh]
|
|
||||||
lambda: |-
|
|
||||||
return log(id(bme680_gas_resistance).state) + 0.04 * id(bme680_humidity).state;
|
|
||||||
|
|
||||||
- platform: absolute_humidity
|
- platform: absolute_humidity
|
||||||
name: "BME680 Absolute Humidity"
|
name: "BME680 Absolute Humidity"
|
||||||
temperature: bme680_temperature
|
temperature: bme680_temperature
|
||||||
humidity: bme680_humidity
|
humidity: bme680_humidity
|
||||||
|
id: bme680_absolute_humidity
|
||||||
|
|
||||||
|
- platform: template
|
||||||
|
name: "BME680 AQ"
|
||||||
|
id: bme680_aq
|
||||||
|
icon: "mdi:gauge"
|
||||||
|
# Calculation from https://github.com/thstielow/raspi-bme680-iaq
|
||||||
|
lambda: |-
|
||||||
|
float ph_slope = 0.03;
|
||||||
|
float comp_gas = id(bme680_gas_resistance).state * pow(2.718281, (ph_slope * id(bme680_absolute_humidity).state));
|
||||||
|
float gas_ratio = pow((comp_gas / id(gas_ceiling)), 2);
|
||||||
|
if (gas_ratio > 1) {
|
||||||
|
gas_ratio = 1.0;
|
||||||
|
}
|
||||||
|
float air_quality = gas_ratio * 100;
|
||||||
|
return (int)air_quality;
|
||||||
|
|
||||||
- platform: tsl2591
|
- platform: tsl2591
|
||||||
address: 0x29
|
address: 0x29
|
||||||
@ -598,29 +611,26 @@ sensor:
|
|||||||
|
|
||||||
text_sensor:
|
text_sensor:
|
||||||
- platform: template
|
- platform: template
|
||||||
name: "BME680 IAQ Classification"
|
name: "BME680 AQ Classification"
|
||||||
icon: "mdi:air-filter"
|
icon: "mdi:air-filter"
|
||||||
update_interval: 15s
|
update_interval: 15s
|
||||||
lambda: |-
|
lambda: |-
|
||||||
int iaq = int(id(bme680_iaq).state);
|
int aq = int(id(bme680_aq).state);
|
||||||
if (iaq <= 50) {
|
if (aq >= 90) {
|
||||||
return {"Excellent"};
|
return {"Excellent"};
|
||||||
}
|
}
|
||||||
else if (iaq <= 100) {
|
else if (aq >= 80) {
|
||||||
return {"Good"};
|
return {"Good"};
|
||||||
}
|
}
|
||||||
else if (iaq <= 150) {
|
else if (aq >= 70) {
|
||||||
return {"Fair"};
|
return {"Fair"};
|
||||||
}
|
}
|
||||||
else if (iaq <= 200) {
|
else if (aq >= 60) {
|
||||||
return {"Moderate"};
|
return {"Moderate"};
|
||||||
}
|
}
|
||||||
else if (iaq <= 250) {
|
else if (aq >= 50) {
|
||||||
return {"Bad"};
|
return {"Bad"};
|
||||||
}
|
}
|
||||||
else if (iaq <= 350) {
|
|
||||||
return {"Very Bad"};
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
return {"Terrible"};
|
return {"Terrible"};
|
||||||
}
|
}
|
||||||
@ -698,6 +708,20 @@ switch:
|
|||||||
entity_category: diagnostic
|
entity_category: diagnostic
|
||||||
|
|
||||||
number:
|
number:
|
||||||
|
- platform: template
|
||||||
|
name: "Gas Ceiling"
|
||||||
|
id: gas_ceiling_setter
|
||||||
|
min_value: 25000
|
||||||
|
max_value: 350000
|
||||||
|
step: 1000
|
||||||
|
lambda: |-
|
||||||
|
return id(gas_ceiling);
|
||||||
|
set_action:
|
||||||
|
then:
|
||||||
|
- globals.set:
|
||||||
|
id: gas_ceiling
|
||||||
|
value: !lambda 'return int(x);'
|
||||||
|
|
||||||
# PIR Hold Time:
|
# PIR Hold Time:
|
||||||
# The number of seconds after motion detection for the PIR sensor to remain held on
|
# The number of seconds after motion detection for the PIR sensor to remain held on
|
||||||
- platform: template
|
- platform: template
|
||||||
|
Loading…
x
Reference in New Issue
Block a user