Skip to content

Commit 05c3c60

Browse files
committed
Add substitutions for pm25 correction formulas
1 parent a7160c8 commit 05c3c60

6 files changed

+209
-99
lines changed

packages/sensor_pms5003.yaml

Lines changed: 52 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,19 @@
11
---
2-
# Impliments PM2.5 correction algorithm supported by AirGradient from EPA
3-
# https://www.airgradient.com/documentation/correction-algorithms/
4-
# https://document.airnow.gov/airnow-fire-and-smoke-map-questions-and-answers.pdf
2+
substitutions:
3+
pm_2_5_scaling_factor: '1'
4+
pm_2_5_intercept: '0'
5+
56
sensor:
67
- platform: pmsx003
78
# Default interval of updating every second, but changing to 30 seconds to extend life but keep fan spinning
89
# PMS5003 https://esphome.io/components/sensor/pmsx003.html
910
type: PMSX003
1011
uart_id: pms5003_uart
1112
pm_2_5:
12-
name: "PM 2.5"
13-
id: pm_2_5
13+
name: "PM 2.5 Raw"
14+
id: pm_2_5_raw
1415
device_class: pm25 # Added to report properly to HomeKit
15-
filters:
16-
- lambda: |-
17-
float result = 0.0;
18-
if (x == 0.0) {
19-
result = 0.0;
20-
} else if (x < 30.0) {
21-
result = (0.524 * x) - (0.0862 * id(humidity_raw).state) + 5.75;
22-
} else if (x < 50.0) {
23-
result = (0.786 * (x / 20 - 3/2) + 0.524 * (1 - (x / 20 - 3/2))) * x - (0.0862 * id(humidity_raw).state) + 5.75;
24-
} else if (x < 210.0) {
25-
result = (0.786 * x) - (0.0862 * id(humidity_raw).state) + 5.75;
26-
} else if (x < 260.0) {
27-
result = (0.69 * (x / 50 - 21/5) + 0.786 * (1 - (x / 50 - 21/5))) * x - (0.0862 * id(humidity_raw).state * (1 - (x / 50 - 21/5))) + (2.966 * (x / 50 - 21/5)) + (5.75 * (1 - (x / 50 - 21/5))) + (8.84 * pow(10,-4) * pow(x,2) * (x / 50 - 21/5));
28-
} else {
29-
result = 2.966 + (0.69 * x) + (8.84 * pow(10,-4) * pow(x,2));
30-
}
31-
if (result <= 0.0) {
32-
return 0.0;
33-
} else {
34-
return result;
35-
}
16+
disabled_by_default: true
3617
pm_1_0:
3718
name: "PM 1.0"
3819
id: pm_1_0
@@ -47,6 +28,51 @@ sensor:
4728
filters:
4829
update_interval: 30s
4930

31+
- platform: template
32+
# Implements PM2.5 correction algorithm supported by AirGradient from EPA and optionally batch specific corrections
33+
# https://www.airgradient.com/documentation/correction-algorithms/
34+
# https://document.airnow.gov/airnow-fire-and-smoke-map-questions-and-answers.pdf
35+
name: "PM 2.5"
36+
id: pm_2_5
37+
update_interval: 30s
38+
device_class: pm25 # Added to report properly to HomeKit
39+
unit_of_measurement: µg/m³
40+
icon: mdi:chemical-weapon
41+
accuracy_decimals: 0
42+
state_class: measurement
43+
lambda: |-
44+
// https://www.airgradient.com/blog/low-readings-from-pms5003/
45+
// Correction for sensor batches after 20231030
46+
float pm_2_5_calibrated_low = $pm_2_5_scaling_factor * id(pm_0_3um).state + $pm_2_5_intercept;
47+
float pm_2_5_calibrated = 0;
48+
if (pm_2_5_calibrated_low < 31) {
49+
pm_2_5_calibrated = pm_2_5_calibrated_low;
50+
} else {
51+
pm_2_5_calibrated = id(pm_2_5_raw).state;
52+
}
53+
if (pm_2_5_calibrated < 0) {
54+
pm_2_5_calibrated = 0;
55+
}
56+
// EPA Formula
57+
float result = 0.0;
58+
if (pm_2_5_calibrated == 0.0) {
59+
result = 0.0;
60+
} else if (pm_2_5_calibrated < 30.0) {
61+
result = (0.524 * pm_2_5_calibrated) - (0.0862 * id(humidity_raw).state) + 5.75;
62+
} else if (pm_2_5_calibrated < 50.0) {
63+
result = (0.786 * (pm_2_5_calibrated / 20 - 3/2) + 0.524 * (1 - (pm_2_5_calibrated / 20 - 3/2))) * pm_2_5_calibrated - (0.0862 * id(humidity_raw).state) + 5.75;
64+
} else if (pm_2_5_calibrated < 210.0) {
65+
result = (0.786 * pm_2_5_calibrated) - (0.0862 * id(humidity_raw).state) + 5.75;
66+
} else if (pm_2_5_calibrated < 260.0) {
67+
result = (0.69 * (pm_2_5_calibrated / 50 - 21/5) + 0.786 * (1 - (pm_2_5_calibrated / 50 - 21/5))) * pm_2_5_calibrated - (0.0862 * id(humidity_raw).state * (1 - (pm_2_5_calibrated / 50 - 21/5))) + (2.966 * (pm_2_5_calibrated / 50 - 21/5)) + (5.75 * (1 - (pm_2_5_calibrated / 50 - 21/5))) + (8.84 * pow(10,-4) * pow(pm_2_5_calibrated,2) * (pm_2_5_calibrated / 50 - 21/5));
68+
} else {
69+
result = 2.966 + (0.69 * pm_2_5_calibrated) + (8.84 * pow(10,-4) * pow(pm_2_5_calibrated,2));
70+
}
71+
if (result <= 0.0) {
72+
return 0.0;
73+
} else {
74+
return result;
75+
}
5076
5177
- platform: template
5278
# Depends on another sensor providing an ID of pm_2_5 such as a pms5003

packages/sensor_pms5003_extended_life.yaml

Lines changed: 51 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,19 @@
11
substitutions:
22
pm_update_interval: "2min"
3+
pm_2_5_scaling_factor: '1'
4+
pm_2_5_intercept: '0'
35

4-
# Impliments PM2.5 correction algorithm supported by AirGradient from EPA
5-
# https://www.airgradient.com/documentation/correction-algorithms/
6-
# https://document.airnow.gov/airnow-fire-and-smoke-map-questions-and-answers.pdf
76
sensor:
87
- platform: pmsx003
8+
# Default interval of updating every second, but changing to 30 seconds to extend life but keep fan spinning
99
# PMS5003 https://esphome.io/components/sensor/pmsx003.html
1010
type: PMSX003
1111
uart_id: pms5003_uart
1212
pm_2_5:
13-
name: "PM 2.5"
14-
id: pm_2_5
13+
name: "PM 2.5 Raw"
14+
id: pm_2_5_raw
1515
device_class: pm25 # Added to report properly to HomeKit
16-
filters:
17-
- lambda: |-
18-
float result = 0.0;
19-
if (x == 0.0) {
20-
result = 0.0;
21-
} else if (x < 30.0) {
22-
result = (0.524 * x) - (0.0862 * id(humidity_raw).state) + 5.75;
23-
} else if (x < 50.0) {
24-
result = (0.786 * (x / 20 - 3/2) + 0.524 * (1 - (x / 20 - 3/2))) * x - (0.0862 * id(humidity_raw).state) + 5.75;
25-
} else if (x < 210.0) {
26-
result = (0.786 * x) - (0.0862 * id(humidity_raw).state) + 5.75;
27-
} else if (x < 260.0) {
28-
result = (0.69 * (x / 50 - 21/5) + 0.786 * (1 - (x / 50 - 21/5))) * x - (0.0862 * id(humidity_raw).state * (1 - (x / 50 - 21/5))) + (2.966 * (x / 50 - 21/5)) + (5.75 * (1 - (x / 50 - 21/5))) + (8.84 * pow(10,-4) * pow(x,2) * (x / 50 - 21/5));
29-
} else {
30-
result = 2.966 + (0.69 * x) + (8.84 * pow(10,-4) * pow(x,2));
31-
}
32-
if (result <= 0.0) {
33-
return 0.0;
34-
} else {
35-
return result;
36-
}
16+
disabled_by_default: true
3717
pm_1_0:
3818
name: "PM 1.0"
3919
id: pm_1_0
@@ -47,6 +27,51 @@ sensor:
4727
id: pm_0_3um
4828
update_interval: $pm_update_interval
4929

30+
- platform: template
31+
# Implements PM2.5 correction algorithm supported by AirGradient from EPA and optionally batch specific corrections
32+
# https://www.airgradient.com/documentation/correction-algorithms/
33+
# https://document.airnow.gov/airnow-fire-and-smoke-map-questions-and-answers.pdf
34+
name: "PM 2.5"
35+
id: pm_2_5
36+
update_interval: $pm_update_interval
37+
device_class: pm25 # Added to report properly to HomeKit
38+
unit_of_measurement: µg/m³
39+
icon: mdi:chemical-weapon
40+
accuracy_decimals: 0
41+
state_class: measurement
42+
lambda: |-
43+
// https://www.airgradient.com/blog/low-readings-from-pms5003/
44+
// Correction for sensor batches after 20231030
45+
float pm_2_5_calibrated_low = $pm_2_5_scaling_factor * id(pm_0_3um).state + $pm_2_5_intercept;
46+
float pm_2_5_calibrated = 0;
47+
if (pm_2_5_calibrated_low < 31) {
48+
pm_2_5_calibrated = pm_2_5_calibrated_low;
49+
} else {
50+
pm_2_5_calibrated = id(pm_2_5_raw).state;
51+
}
52+
if (pm_2_5_calibrated < 0) {
53+
pm_2_5_calibrated = 0;
54+
}
55+
// EPA Formula
56+
float result = 0.0;
57+
if (pm_2_5_calibrated == 0.0) {
58+
result = 0.0;
59+
} else if (pm_2_5_calibrated < 30.0) {
60+
result = (0.524 * pm_2_5_calibrated) - (0.0862 * id(humidity_raw).state) + 5.75;
61+
} else if (pm_2_5_calibrated < 50.0) {
62+
result = (0.786 * (pm_2_5_calibrated / 20 - 3/2) + 0.524 * (1 - (pm_2_5_calibrated / 20 - 3/2))) * pm_2_5_calibrated - (0.0862 * id(humidity_raw).state) + 5.75;
63+
} else if (pm_2_5_calibrated < 210.0) {
64+
result = (0.786 * pm_2_5_calibrated) - (0.0862 * id(humidity_raw).state) + 5.75;
65+
} else if (pm_2_5_calibrated < 260.0) {
66+
result = (0.69 * (pm_2_5_calibrated / 50 - 21/5) + 0.786 * (1 - (pm_2_5_calibrated / 50 - 21/5))) * pm_2_5_calibrated - (0.0862 * id(humidity_raw).state * (1 - (pm_2_5_calibrated / 50 - 21/5))) + (2.966 * (pm_2_5_calibrated / 50 - 21/5)) + (5.75 * (1 - (pm_2_5_calibrated / 50 - 21/5))) + (8.84 * pow(10,-4) * pow(pm_2_5_calibrated,2) * (pm_2_5_calibrated / 50 - 21/5));
67+
} else {
68+
result = 2.966 + (0.69 * pm_2_5_calibrated) + (8.84 * pow(10,-4) * pow(pm_2_5_calibrated,2));
69+
}
70+
if (result <= 0.0) {
71+
return 0.0;
72+
} else {
73+
return result;
74+
}
5075
5176
- platform: template
5277
# Depends on another sensor providing an ID of pm_2_5 such as a pms5003

packages/sensor_pms5003t.yaml

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
---
2+
substitutions:
3+
pm_2_5_scaling_factor: '1'
4+
pm_2_5_intercept: '0'
5+
16
sensor:
27
- platform: pmsx003
38
# Default interval of updating every second, but changing to 30 seconds to extend life but keep fan spinning
@@ -55,7 +60,7 @@ sensor:
5560
return result;
5661
5762
- platform: template
58-
# Impliments PM2.5 correction algorithm supported by AirGradient from EPA
63+
# Implements PM2.5 correction algorithm supported by AirGradient from EPA and optionally batch specific corrections
5964
# https://www.airgradient.com/documentation/correction-algorithms/
6065
# https://document.airnow.gov/airnow-fire-and-smoke-map-questions-and-answers.pdf
6166
name: "PM 2.5"
@@ -67,25 +72,39 @@ sensor:
6772
accuracy_decimals: 0
6873
state_class: measurement
6974
lambda: |-
75+
// https://www.airgradient.com/blog/low-readings-from-pms5003/
76+
// Correction for sensor batches after 20231030
77+
float pm_2_5_calibrated_low = $pm_2_5_scaling_factor * id(pm_0_3um).state + $pm_2_5_intercept;
78+
float pm_2_5_calibrated = 0;
79+
if (pm_2_5_calibrated_low < 31) {
80+
pm_2_5_calibrated = pm_2_5_calibrated_low;
81+
} else {
82+
pm_2_5_calibrated = id(pm_2_5_raw).state;
83+
}
84+
if (pm_2_5_calibrated < 0) {
85+
pm_2_5_calibrated = 0;
86+
}
87+
// EPA Formula
7088
float result = 0.0;
71-
if (id(pm_2_5_raw).state == 0.0) {
89+
if (pm_2_5_calibrated == 0.0) {
7290
result = 0.0;
73-
} else if (id(pm_2_5_raw).state < 30.0) {
74-
result = (0.524 * id(pm_2_5_raw).state) - (0.0862 * id(humidity_raw).state) + 5.75;
75-
} else if (id(pm_2_5_raw).state < 50.0) {
76-
result = (0.786 * (id(pm_2_5_raw).state / 20 - 3/2) + 0.524 * (1 - (id(pm_2_5_raw).state / 20 - 3/2))) * id(pm_2_5_raw).state - (0.0862 * id(humidity_raw).state) + 5.75;
77-
} else if (id(pm_2_5_raw).state < 210.0) {
78-
result = (0.786 * id(pm_2_5_raw).state) - (0.0862 * id(humidity_raw).state) + 5.75;
79-
} else if (id(pm_2_5_raw).state < 260.0) {
80-
result = (0.69 * (id(pm_2_5_raw).state / 50 - 21/5) + 0.786 * (1 - (id(pm_2_5_raw).state / 50 - 21/5))) * id(pm_2_5_raw).state - (0.0862 * id(humidity_raw).state * (1 - (id(pm_2_5_raw).state / 50 - 21/5))) + (2.966 * (id(pm_2_5_raw).state / 50 - 21/5)) + (5.75 * (1 - (id(pm_2_5_raw).state / 50 - 21/5))) + (8.84 * pow(10,-4) * pow(id(pm_2_5_raw).state,2) * (id(pm_2_5_raw).state / 50 - 21/5));
91+
} else if (pm_2_5_calibrated < 30.0) {
92+
result = (0.524 * pm_2_5_calibrated) - (0.0862 * id(humidity_raw).state) + 5.75;
93+
} else if (pm_2_5_calibrated < 50.0) {
94+
result = (0.786 * (pm_2_5_calibrated / 20 - 3/2) + 0.524 * (1 - (pm_2_5_calibrated / 20 - 3/2))) * pm_2_5_calibrated - (0.0862 * id(humidity_raw).state) + 5.75;
95+
} else if (pm_2_5_calibrated < 210.0) {
96+
result = (0.786 * pm_2_5_calibrated) - (0.0862 * id(humidity_raw).state) + 5.75;
97+
} else if (pm_2_5_calibrated < 260.0) {
98+
result = (0.69 * (pm_2_5_calibrated / 50 - 21/5) + 0.786 * (1 - (pm_2_5_calibrated / 50 - 21/5))) * pm_2_5_calibrated - (0.0862 * id(humidity_raw).state * (1 - (pm_2_5_calibrated / 50 - 21/5))) + (2.966 * (pm_2_5_calibrated / 50 - 21/5)) + (5.75 * (1 - (pm_2_5_calibrated / 50 - 21/5))) + (8.84 * pow(10,-4) * pow(pm_2_5_calibrated,2) * (pm_2_5_calibrated / 50 - 21/5));
8199
} else {
82-
result = 2.966 + (0.69 * id(pm_2_5_raw).state) + (8.84 * pow(10,-4) * pow(id(pm_2_5_raw).state,2));
100+
result = 2.966 + (0.69 * pm_2_5_calibrated) + (8.84 * pow(10,-4) * pow(pm_2_5_calibrated,2));
83101
}
84102
if (result <= 0.0) {
85103
return 0.0;
86104
} else {
87105
return result;
88106
}
107+
89108
- platform: template
90109
# Depends on another sensor providing an ID of pm_2_5 such as a pms5003
91110
name: "PM 2.5 AQI"

packages/sensor_pms5003t_2.yaml

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
---
12
# Used for a second PMS5003T in the same device, such as the Open Air O-1PPT
23
sensor:
34
- platform: pmsx003
@@ -56,7 +57,7 @@ sensor:
5657
return result;
5758
5859
- platform: template
59-
# Impliments PM2.5 correction algorithm supported by AirGradient from EPA
60+
# Implements PM2.5 correction algorithm supported by AirGradient from EPA and optionally batch specific corrections
6061
# https://www.airgradient.com/documentation/correction-algorithms/
6162
# https://document.airnow.gov/airnow-fire-and-smoke-map-questions-and-answers.pdf
6263
name: "PM 2.5 (2)"
@@ -68,19 +69,32 @@ sensor:
6869
accuracy_decimals: 0
6970
state_class: measurement
7071
lambda: |-
72+
// https://www.airgradient.com/blog/low-readings-from-pms5003/
73+
// Correction for sensor batches after 20231030
74+
float pm_2_5_calibrated_low = $pm_2_5_scaling_factor * id(pm_0_3um_2).state + $pm_2_5_intercept;
75+
float pm_2_5_calibrated = 0;
76+
if (pm_2_5_calibrated_low < 31) {
77+
pm_2_5_calibrated = pm_2_5_calibrated_low;
78+
} else {
79+
pm_2_5_calibrated = id(pm_2_5_2_raw).state;
80+
}
81+
if (pm_2_5_calibrated < 0) {
82+
pm_2_5_calibrated = 0;
83+
}
84+
// EPA Formula
7185
float result = 0.0;
72-
if (id(pm_2_5_2_raw).state == 0.0) {
86+
if (pm_2_5_calibrated == 0.0) {
7387
result = 0.0;
74-
} else if (id(pm_2_5_2_raw).state < 30.0) {
75-
result = (0.524 * id(pm_2_5_2_raw).state) - (0.0862 * id(humidity_raw).state) + 5.75;
76-
} else if (id(pm_2_5_2_raw).state < 50.0) {
77-
result = (0.786 * (id(pm_2_5_2_raw).state / 20 - 3/2) + 0.524 * (1 - (id(pm_2_5_2_raw).state / 20 - 3/2))) * id(pm_2_5_2_raw).state - (0.0862 * id(humidity_raw).state) + 5.75;
78-
} else if (id(pm_2_5_2_raw).state < 210.0) {
79-
result = (0.786 * id(pm_2_5_2_raw).state) - (0.0862 * id(humidity_raw).state) + 5.75;
80-
} else if (id(pm_2_5_2_raw).state < 260.0) {
81-
result = (0.69 * (id(pm_2_5_2_raw).state / 50 - 21/5) + 0.786 * (1 - (id(pm_2_5_2_raw).state / 50 - 21/5))) * id(pm_2_5_2_raw).state - (0.0862 * id(humidity_raw).state * (1 - (id(pm_2_5_2_raw).state / 50 - 21/5))) + (2.966 * (id(pm_2_5_2_raw).state / 50 - 21/5)) + (5.75 * (1 - (id(pm_2_5_2_raw).state / 50 - 21/5))) + (8.84 * pow(10,-4) * pow(id(pm_2_5_2_raw).state,2) * (id(pm_2_5_2_raw).state / 50 - 21/5));
88+
} else if (pm_2_5_calibrated < 30.0) {
89+
result = (0.524 * pm_2_5_calibrated) - (0.0862 * id(humidity_raw).state) + 5.75;
90+
} else if (pm_2_5_calibrated < 50.0) {
91+
result = (0.786 * (pm_2_5_calibrated / 20 - 3/2) + 0.524 * (1 - (pm_2_5_calibrated / 20 - 3/2))) * pm_2_5_calibrated - (0.0862 * id(humidity_raw).state) + 5.75;
92+
} else if (pm_2_5_calibrated < 210.0) {
93+
result = (0.786 * pm_2_5_calibrated) - (0.0862 * id(humidity_raw).state) + 5.75;
94+
} else if (pm_2_5_calibrated < 260.0) {
95+
result = (0.69 * (pm_2_5_calibrated / 50 - 21/5) + 0.786 * (1 - (pm_2_5_calibrated / 50 - 21/5))) * pm_2_5_calibrated - (0.0862 * id(humidity_raw).state * (1 - (pm_2_5_calibrated / 50 - 21/5))) + (2.966 * (pm_2_5_calibrated / 50 - 21/5)) + (5.75 * (1 - (pm_2_5_calibrated / 50 - 21/5))) + (8.84 * pow(10,-4) * pow(pm_2_5_calibrated,2) * (pm_2_5_calibrated / 50 - 21/5));
8296
} else {
83-
result = 2.966 + (0.69 * id(pm_2_5_2_raw).state) + (8.84 * pow(10,-4) * pow(id(pm_2_5_2_raw).state,2));
97+
result = 2.966 + (0.69 * pm_2_5_calibrated) + (8.84 * pow(10,-4) * pow(pm_2_5_calibrated,2));
8498
}
8599
if (result <= 0.0) {
86100
return 0.0;

packages/sensor_pms5003t_2_extended_life.yaml

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
---
12
# Used for a second PMS5003T in the same device, such as the Open Air O-1PPT
23
substitutions:
34
pm_update_interval: "2min"
@@ -59,31 +60,44 @@ sensor:
5960
return result;
6061
6162
- platform: template
62-
# Impliments PM2.5 correction algorithm supported by AirGradient from EPA
63+
# Implements PM2.5 correction algorithm supported by AirGradient from EPA and optionally batch specific corrections
6364
# https://www.airgradient.com/documentation/correction-algorithms/
6465
# https://document.airnow.gov/airnow-fire-and-smoke-map-questions-and-answers.pdf
6566
name: "PM 2.5 (2)"
6667
id: pm_2_5_2
67-
update_interval: 30s
68+
update_interval: $pm_update_interval
6869
device_class: pm25 # Added to report properly to HomeKit
6970
unit_of_measurement: µg/m³
7071
icon: mdi:chemical-weapon
7172
accuracy_decimals: 0
7273
state_class: measurement
7374
lambda: |-
75+
// https://www.airgradient.com/blog/low-readings-from-pms5003/
76+
// Correction for sensor batches after 20231030
77+
float pm_2_5_calibrated_low = $pm_2_5_scaling_factor * id(pm_0_3um_2).state + $pm_2_5_intercept;
78+
float pm_2_5_calibrated = 0;
79+
if (pm_2_5_calibrated_low < 31) {
80+
pm_2_5_calibrated = pm_2_5_calibrated_low;
81+
} else {
82+
pm_2_5_calibrated = id(pm_2_5_2_raw).state;
83+
}
84+
if (pm_2_5_calibrated < 0) {
85+
pm_2_5_calibrated = 0;
86+
}
87+
// EPA Formula
7488
float result = 0.0;
75-
if (id(pm_2_5_2_raw).state == 0.0) {
89+
if (pm_2_5_calibrated == 0.0) {
7690
result = 0.0;
77-
} else if (id(pm_2_5_2_raw).state < 30.0) {
78-
result = (0.524 * id(pm_2_5_2_raw).state) - (0.0862 * id(humidity_raw).state) + 5.75;
79-
} else if (id(pm_2_5_2_raw).state < 50.0) {
80-
result = (0.786 * (id(pm_2_5_2_raw).state / 20 - 3/2) + 0.524 * (1 - (id(pm_2_5_2_raw).state / 20 - 3/2))) * id(pm_2_5_2_raw).state - (0.0862 * id(humidity_raw).state) + 5.75;
81-
} else if (id(pm_2_5_2_raw).state < 210.0) {
82-
result = (0.786 * id(pm_2_5_2_raw).state) - (0.0862 * id(humidity_raw).state) + 5.75;
83-
} else if (id(pm_2_5_2_raw).state < 260.0) {
84-
result = (0.69 * (id(pm_2_5_2_raw).state / 50 - 21/5) + 0.786 * (1 - (id(pm_2_5_2_raw).state / 50 - 21/5))) * id(pm_2_5_2_raw).state - (0.0862 * id(humidity_raw).state * (1 - (id(pm_2_5_2_raw).state / 50 - 21/5))) + (2.966 * (id(pm_2_5_2_raw).state / 50 - 21/5)) + (5.75 * (1 - (id(pm_2_5_2_raw).state / 50 - 21/5))) + (8.84 * pow(10,-4) * pow(id(pm_2_5_2_raw).state,2) * (id(pm_2_5_2_raw).state / 50 - 21/5));
91+
} else if (pm_2_5_calibrated < 30.0) {
92+
result = (0.524 * pm_2_5_calibrated) - (0.0862 * id(humidity_raw).state) + 5.75;
93+
} else if (pm_2_5_calibrated < 50.0) {
94+
result = (0.786 * (pm_2_5_calibrated / 20 - 3/2) + 0.524 * (1 - (pm_2_5_calibrated / 20 - 3/2))) * pm_2_5_calibrated - (0.0862 * id(humidity_raw).state) + 5.75;
95+
} else if (pm_2_5_calibrated < 210.0) {
96+
result = (0.786 * pm_2_5_calibrated) - (0.0862 * id(humidity_raw).state) + 5.75;
97+
} else if (pm_2_5_calibrated < 260.0) {
98+
result = (0.69 * (pm_2_5_calibrated / 50 - 21/5) + 0.786 * (1 - (pm_2_5_calibrated / 50 - 21/5))) * pm_2_5_calibrated - (0.0862 * id(humidity_raw).state * (1 - (pm_2_5_calibrated / 50 - 21/5))) + (2.966 * (pm_2_5_calibrated / 50 - 21/5)) + (5.75 * (1 - (pm_2_5_calibrated / 50 - 21/5))) + (8.84 * pow(10,-4) * pow(pm_2_5_calibrated,2) * (pm_2_5_calibrated / 50 - 21/5));
8599
} else {
86-
result = 2.966 + (0.69 * id(pm_2_5_2_raw).state) + (8.84 * pow(10,-4) * pow(id(pm_2_5_2_raw).state,2));
100+
result = 2.966 + (0.69 * pm_2_5_calibrated) + (8.84 * pow(10,-4) * pow(pm_2_5_calibrated,2));
87101
}
88102
if (result <= 0.0) {
89103
return 0.0;

0 commit comments

Comments
 (0)