Skip to content

Commit ec3449e

Browse files
authored
Outdoor temp hum compensation (#21)
* Outdoor Temp and Humidity compensation Using latest calculation from AirGradient forums * Add fix for negative numbers until ESPHome fix is released
1 parent 3e25e88 commit ec3449e

4 files changed

Lines changed: 125 additions & 9 deletions

File tree

airgradient-open-air-o-1pst.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
substitutions:
66
name: "ag-open-air-o-1pst"
77
friendly_name: "AG Open Air O-1PST"
8-
config_version: 2.0.0
8+
config_version: 2.0.1
99
name_add_mac_suffix: "false" # Must have quotes around value
1010

1111
# Enable Home Assistant API

packages/sensor_pms5003t.yaml

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,23 +7,23 @@ sensor:
77
pm_2_5:
88
name: "PM 2.5"
99
id: pm_2_5
10-
device_class: pm25 # Added to report properly to HomeKit
10+
device_class: pm25 # Added to report properly to Homekit
1111
filters:
1212
- sliding_window_moving_average:
1313
window_size: 30
1414
send_every: 30
1515
pm_1_0:
1616
name: "PM 1.0"
1717
id: pm_1_0
18-
device_class: pm1 # Added to report properly to HomeKit
18+
device_class: pm1 # Added to report properly to Homekit
1919
filters:
2020
- sliding_window_moving_average:
2121
window_size: 30
2222
send_every: 30
2323
pm_10_0:
2424
name: "PM 10.0"
2525
id: pm_10_0
26-
device_class: pm10 # Added to report properly to HomeKit
26+
device_class: pm10 # Added to report properly to Homekit
2727
filters:
2828
- sliding_window_moving_average:
2929
window_size: 30
@@ -39,13 +39,25 @@ sensor:
3939
name: "Temperature"
4040
id: temp
4141
filters:
42+
# https://www.airgradient.com/blog/slr-temperature-example/
43+
# - lambda: return (x - 4.55) / 0.83; # Once the negative number issue fix is merged in https://github.com/esphome/issues/issues/3814
44+
- lambda: !lambda |-
45+
// Fix negative values for now
46+
if (x > 6000) {
47+
return (x - 6553.6 - 4.55) / 0.83;
48+
}
49+
return (x - 4.55) / 0.83;
4250
- sliding_window_moving_average:
4351
window_size: 30
4452
send_every: 30
4553
humidity:
4654
name: "Humidity"
4755
id: humidity
4856
filters:
57+
# https://www.airgradient.com/blog/linear-regression-improves-sensor-accuracy/
58+
# - lambda: return x * 1.500574 - 4.76;
59+
# https://forum.airgradient.com/t/open-air-outdoor-air-quality-monitor-humidity-readings-are-off/1171/2
60+
- lambda: return x * 1.3921 - 1.0245;
4961
- sliding_window_moving_average:
5062
window_size: 30
5163
send_every: 30
@@ -60,7 +72,7 @@ sensor:
6072
icon: "mdi:air-filter"
6173
accuracy_decimals: 0
6274
filters:
63-
- skip_initial: 10 # Need valid data from PM 2.5 sensor before able to calculate
75+
- skip_initial: 1 # Need valid data from PM 2.5 sensor before able to calculate
6476
lambda: |-
6577
// https://en.wikipedia.org/wiki/Air_quality_index#Computing_the_AQI
6678
// Borrowed from https://github.com/kylemanna/sniffer/blob/master/esphome/sniffer_common.yaml

packages/sensor_pms5003t_extended_life.yaml

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,24 +7,38 @@ sensor:
77
pm_2_5:
88
name: "PM 2.5"
99
id: pm_2_5
10-
device_class: pm25 # Added to report properly to HomeKit
10+
device_class: pm25 # Added to report properly to Homekit
1111
pm_1_0:
1212
name: "PM 1.0"
1313
id: pm_1_0
14-
device_class: pm1 # Added to report properly to HomeKit
14+
device_class: pm1 # Added to report properly to Homekit
1515
pm_10_0:
1616
name: "PM 10.0"
1717
id: pm_10_0
18-
device_class: pm10 # Added to report properly to HomeKit
18+
device_class: pm10 # Added to report properly to Homekit
1919
pm_0_3um:
2020
name: "PM 0.3"
2121
id: pm_0_3um
2222
temperature:
2323
name: "Temperature"
2424
id: temp
25+
filters:
26+
# https://www.airgradient.com/blog/slr-temperature-example/
27+
# - lambda: return (x - 4.55) / 0.83; # Once the negative number issue fix is merged in https://github.com/esphome/issues/issues/3814
28+
- lambda: !lambda |-
29+
// Fix negative values for now
30+
if (x > 6000) {
31+
return (x - 6553.6 - 4.55) / 0.83;
32+
}
33+
return (x - 4.55) / 0.83;
2534
humidity:
2635
name: "Humidity"
2736
id: humidity
37+
filters:
38+
# https://www.airgradient.com/blog/linear-regression-improves-sensor-accuracy/
39+
# - lambda: return x * 1.500574 - 4.76;
40+
# https://forum.airgradient.com/t/open-air-outdoor-air-quality-monitor-humidity-readings-are-off/1171/2
41+
- lambda: return x * 1.3921 - 1.0245;
2842
update_interval: 2min
2943

3044

@@ -37,7 +51,7 @@ sensor:
3751
icon: "mdi:air-filter"
3852
accuracy_decimals: 0
3953
filters:
40-
- skip_initial: 10 # Need valid data from PM 2.5 sensor before able to calculate
54+
- skip_initial: 1 # Need valid data from PM 2.5 sensor before able to calculate
4155
lambda: |-
4256
// https://en.wikipedia.org/wiki/Air_quality_index#Computing_the_AQI
4357
// Borrowed from https://github.com/kylemanna/sniffer/blob/master/esphome/sniffer_common.yaml
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
sensor:
2+
- platform: pmsx003
3+
# Default interval of updating every second, but using an average over the last 30 seconds/readings
4+
# PMS5003T with temperature and humidity https://esphome.io/components/sensor/pmsx003.html
5+
type: PMS5003T
6+
uart_id: pms5003_uart
7+
pm_2_5:
8+
name: "PM 2.5"
9+
id: pm_2_5
10+
device_class: pm25 # Added to report properly to Homekit
11+
filters:
12+
- sliding_window_moving_average:
13+
window_size: 30
14+
send_every: 30
15+
pm_1_0:
16+
name: "PM 1.0"
17+
id: pm_1_0
18+
device_class: pm1 # Added to report properly to Homekit
19+
filters:
20+
- sliding_window_moving_average:
21+
window_size: 30
22+
send_every: 30
23+
pm_10_0:
24+
name: "PM 10.0"
25+
id: pm_10_0
26+
device_class: pm10 # Added to report properly to Homekit
27+
filters:
28+
- sliding_window_moving_average:
29+
window_size: 30
30+
send_every: 30
31+
pm_0_3um:
32+
name: "PM 0.3"
33+
id: pm_0_3um
34+
filters:
35+
- sliding_window_moving_average:
36+
window_size: 30
37+
send_every: 30
38+
temperature:
39+
name: "Temperature"
40+
id: temp
41+
filters:
42+
- sliding_window_moving_average:
43+
window_size: 30
44+
send_every: 30
45+
humidity:
46+
name: "Humidity"
47+
id: humidity
48+
filters:
49+
- sliding_window_moving_average:
50+
window_size: 30
51+
send_every: 30
52+
53+
54+
- platform: template
55+
# Depends on another sensor providing an ID of pm_2_5 such as a pms5003
56+
name: "PM 2.5 AQI"
57+
id: pm_2_5_aqi
58+
update_interval: 5 min
59+
unit_of_measurement: "AQI"
60+
icon: "mdi:air-filter"
61+
accuracy_decimals: 0
62+
filters:
63+
- skip_initial: 1 # Need valid data from PM 2.5 sensor before able to calculate
64+
lambda: |-
65+
// https://en.wikipedia.org/wiki/Air_quality_index#Computing_the_AQI
66+
// Borrowed from https://github.com/kylemanna/sniffer/blob/master/esphome/sniffer_common.yaml
67+
if (id(pm_2_5).state <= 12.0) {
68+
// good
69+
return((50.0 - 0.0) / (12.0 - 0.0) * (id(pm_2_5).state - 0.0) + 0.0);
70+
} else if (id(pm_2_5).state <= 35.4) {
71+
// moderate
72+
return((100.0 - 51.0) / (35.4 - 12.1) * (id(pm_2_5).state - 12.1) + 51.0);
73+
} else if (id(pm_2_5).state <= 55.4) {
74+
// usg
75+
return((150.0 - 101.0) / (55.4 - 35.5) * (id(pm_2_5).state - 35.5) + 101.0);
76+
} else if (id(pm_2_5).state <= 150.4) {
77+
// unhealthy
78+
return((200.0 - 151.0) / (150.4 - 55.5) * (id(pm_2_5).state - 55.5) + 151.0);
79+
} else if (id(pm_2_5).state <= 250.4) {
80+
// very unhealthy
81+
return((300.0 - 201.0) / (250.4 - 150.5) * (id(pm_2_5).state - 150.5) + 201.0);
82+
} else if (id(pm_2_5).state <= 350.4) {
83+
// hazardous
84+
return((400.0 - 301.0) / (350.4 - 250.5) * (id(pm_2_5).state - 250.5) + 301.0);
85+
} else if (id(pm_2_5).state <= 500.4) {
86+
// hazardous 2
87+
return((500.0 - 401.0) / (500.4 - 350.5) * (id(pm_2_5).state - 350.5) + 401.0);
88+
} else {
89+
return(500);
90+
}

0 commit comments

Comments
 (0)