Skip to content

Commit 436bd66

Browse files
authored
Merge pull request #148 from MallocArray/pm25_correction_formula
Add substitutions for pm25 correction formulas
2 parents 0b8ef35 + b4be6f4 commit 436bd66

17 files changed

+314
-121
lines changed

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,21 +8,20 @@ ESPHome yaml files for AirGradient devices to maintain the research and accuracy
88

99
## [Configuration](/configuration.md)
1010

11+
## [Calibration](/calibration.md)
12+
1113
## Breaking Changes
1214

1315
* 5.0.0 is a major version upgrade as switching to esp-idf is not fully supported via OTA. Highly recommend doing one USB flash of 5.0.0 and later to the AirGradient ONE and OpenAir devices to reformat the storage to support esp-idf. Future updates can be done Over-The-Air without issue.
1416
* If not done, the device is likely to reboot at some point and switch to the standby partition, returning to a version prior to 5.0.0
1517
* [Seeing an Old Firmware Version After Update? Here's Why & How to Fix It · Issue #1821 · Blackymas/NSPanel_HA_Blueprint](https://github.com/Blackymas/NSPanel_HA_Blueprint/issues/1821)
1618
* [Read/Write bootloader, partition table and any partition via OTA by angelnu · Pull Request #5535 · esphome/esphome](https://github.com/esphome/esphome/pull/5535)
17-
* Aware of errors in the logs stating `esp_task_wdt_reconfigure(615): Invalid arguments`
18-
* Tracking [Watchdog config hardcoded core mask · Issue #6767 · esphome/issues](https://github.com/esphome/issues/issues/6767)
19-
* 5.0.0 switches ONE and OpenAir models (based on ESP32) to the esp-idf framework, freeing up some memory and allowing other advanced features such as bluetooth_proxy and esp32_improv. If the previous Arduino framework is desired, change the board to `airgradient_esp32-c3_board-arduino.yaml`
20-
* If attempting to add BT and BLE support, may need to remove the captive_portal package to free up enough space [Issue #115](https://github.com/MallocArray/airgradient_esphome/issues/115)
2119

2220
## Changes
2321

24-
* Added optional package for using LED bar on AirGradient ONE to reflect TVOC values
25-
* Added examples of Home Assistant automation to disable the display and LED at a scheduled time in configuration.md
22+
* Added optional substitutions to implement batch-specific PM2.5 corrections using values provided by AirGradient
23+
[See details in the packages.md file under the PMS5003 section.](packages.md#sensor_pms5003yaml)
24+
* Restored logging to default values as it no longer repeats messages about components taking too long to complete
2625

2726
## Features
2827

@@ -68,4 +67,5 @@ Many added features can be found in HomeAssistant by going to Settings>Devices a
6867

6968
More features are planned to be added to this repo
7069

71-
- [ ] PMS5003 model specific correction algorithms
70+
- [X] PMS5003 model specific correction algorithms
71+
- [ ] Deprecate Extended Life packages and use a substitution to allow for adjusting update_interval

calibration.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Calibration
2+
3+
Many of the official calibration algorithms from AirGradient are also implemented in this repository.
4+
https://www.airgradient.com/documentation/calibration-algorithms/
5+
6+
## EPA PM2.5 Calibration
7+
8+
This algorithm is applied by default to all PMS5003(t) sensors in this repository. If it is desired to not apply this and instead use raw values from the sensors, replace the package file with the one ending with `_uncorrected.yaml`
9+
10+
## Batch Specific PM2.5 Calibration
11+
12+
AirGradient detected that PMS5003 sensors after 2023-10-30 used a different manufacturer calibration that results in lower PM2.5 values under low concentrations. AirGradient has developed an algorithm and tested values to correct these values when they are less than 31 ug/m3
13+
14+
In this repo, 2 substitution values can be adjusted to apply the calibration. In the main YAML file for the device, add a substitutions item and the follow parameters if not already present.
15+
16+
```yaml
17+
substitutions:
18+
pm_2_5_scaling_factor: '1'
19+
pm_2_5_intercept: '0'
20+
```
21+
22+
Adjust the scaling factor and intercept specific to your requirements. The values from AirGradient can be found in the AirGradient Dashboard site under Hardware>Advanced Settings>PM 2.5
23+
24+
Under "Special formulas by specific batch" select a batch that matches the label on the sensor inside of your AirGradient, and take note of the `Scaling Factor` and `Offset` values to copy to the ESPHome YAML file.
25+
26+
Refer to the AirGradient page for the most current values, and they are planning on adding device specific formulas in the future
27+
https://app.airgradient.com/settings/hardware
28+
29+
| Batch ID | Scaling Factor | Offset |
30+
|---------------------|------------------|--------|
31+
| PMS5003_20231030 | 0.02838 | 0 |
32+
| PMS5003_20231218 | 0.03525 | 0 |
33+
| PMS5003_20240104 | 0.02896 | 0 |
34+
35+
https://www.airgradient.com/blog/update-on-pms5003-calibration/
36+
37+
## Temperature and Humidity Calibration for Open Air Outdoor monitors
38+
39+
The algorithm from AirGradient for the PMS5003T sensors used in the Open Air for both Temperature and Humidity are applied by default. If it is desired to not apply this and instead use raw values from the sensors, replace the package file with the one ending with `_uncorrected.yaml`

packages.md

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ binary_sensor:
6161
For devices that use the ESP32-C3 the CPU clock can be lowered from default 160
6262
MHz to 80 MHz to save power. The higher default clock is not needed for the
6363
calculations that even the AirGradient One by default has to do to interact
64-
with all the sernsors, display, LEDs and so on. If you suspect this causes
64+
with all the sensors, display, LEDs and so on. If you suspect this causes
6565
problems, look at the ESPHome log or enable the `diagnostic_esp32.yaml` package
6666
and look at "Loop Time".
6767

@@ -199,6 +199,14 @@ By default collects readings every second. Since this device has a limited lifes
199199
Collects readings every 2 minutes by default, but can be modified by adding an entry under substitutions, ensuring the value is surrounded by double quotes
200200
`pm_update_interval: "2min"`
201201
202+
Can also apply batch or device specific correction formulas. See [calibration.md](calibration.md) for more details.
203+
204+
```yaml
205+
substitutions:
206+
pm_2_5_scaling_factor: '1'
207+
pm_2_5_intercept: '0'
208+
```
209+
202210
## sensor_pms5003t_2_extended_life.yaml
203211
204212
Configures a second Plantower PMS5003T sensor when 2 are installed, such as the Open Air Model O-1PPT. Reports PM2.5, Temperature, and Humidity.
@@ -212,6 +220,14 @@ By default collects readings every second. Since this device has a limited lifes
212220
Collects readings every 2 minutes by default, but can be modified by adding an entry under substitutions, ensuring the value is surrounded by double quotes
213221
`pm_update_interval: "2min"`
214222

223+
Can also apply batch or device specific correction formulas. See [calibration.md](calibration.md) for more details.
224+
225+
```yaml
226+
substitutions:
227+
pm_2_5_scaling_factor: '1'
228+
pm_2_5_intercept: '0'
229+
```
230+
215231
## sensor_pms5003t_2.yaml
216232

217233
Configures a second Plantower PMS5003T sensor when 2 are installed, such as the Open Air Model O-1PPT. Reports PM 2.5, Temperature, and Humidity.
@@ -231,6 +247,14 @@ By default collects readings every second. Since this device has a limited lifes
231247
Collects readings every 2 minutes by default, but can be modified by adding an entry under substitutions, ensuring the value is surrounded by double quotes
232248
`pm_update_interval: "2min"`
233249
250+
Can also apply batch or device specific correction formulas. See [calibration.md](calibration.md) for more details.
251+
252+
```yaml
253+
substitutions:
254+
pm_2_5_scaling_factor: '1'
255+
pm_2_5_intercept: '0'
256+
```
257+
234258
## sensor_pms5003t_uncorrected.yaml
235259
236260
Configures a Plantower PMS5003T sensor. Reports PM 2.5, Temperature, and Humidity.
@@ -243,6 +267,14 @@ Configures a Plantower PMS5003T sensor. Reports PM 2.5, Temperature, and Humidi
243267
244268
Also applies a compensation algorithm from AirGradient to correct temperature and humidity readings when used inside of the Open Air enclosure
245269
270+
Can also apply batch or device specific correction formulas. See [calibration.md](calibration.md) for more details.
271+
272+
```yaml
273+
substitutions:
274+
pm_2_5_scaling_factor: '1'
275+
pm_2_5_intercept: '0'
276+
```
277+
246278
## sensor_pms5003_uncorrected.yaml
247279
248280
Configures a Plantower PMS5003 sensor using raw values from the sensor
@@ -259,6 +291,14 @@ https://www.airgradient.com/documentation/correction-algorithms/
259291
260292
Reports PM 2.5, PM 10, PM 1.0, PM 0.3, and Air Quality Index based on the current readings.
261293
294+
Can also apply batch or device specific correction formulas. See [calibration.md](calibration.md) for more details.
295+
296+
```yaml
297+
substitutions:
298+
pm_2_5_scaling_factor: '1'
299+
pm_2_5_intercept: '0'
300+
```
301+
262302
## sensor_s8.yaml
263303
264304
Configures a Senseair S8 sensor.

packages/airgradient_api_d1_mini.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ interval:
1717
wifi: !lambda return to_string(id(wifi_dbm).state);
1818
rco2: !lambda return to_string(id(co2).state);
1919
pm01: !lambda return to_string(id(pm_1_0).state);
20-
pm02: !lambda return to_string(id(pm_2_5).state);
20+
pm02: !lambda return to_string(id(pm_2_5_raw).state);
21+
pm02Compensated: !lambda return to_string(id(pm_2_5).state);
2122
pm10: !lambda return to_string(id(pm_10_0).state);
2223
pm003Count: !lambda return to_string(id(pm_0_3um).state);
2324
atmp: !lambda return to_string(id(temp_raw).state);

packages/airgradient_api_d1_mini_insecure.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ interval:
1717
wifi: !lambda return to_string(id(wifi_dbm).state);
1818
rco2: !lambda return to_string(id(co2).state);
1919
pm01: !lambda return to_string(id(pm_1_0).state);
20-
pm02: !lambda return to_string(id(pm_2_5).state);
20+
pm02: !lambda return to_string(id(pm_2_5_raw).state);
21+
pm02Compensated: !lambda return to_string(id(pm_2_5).state);
2122
pm10: !lambda return to_string(id(pm_10_0).state);
2223
pm003Count: !lambda return to_string(id(pm_0_3um).state);
2324
atmp: !lambda return to_string(id(temp_raw).state);

packages/airgradient_api_d1_mini_no_sgp41.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ interval:
1717
wifi: !lambda return to_string(id(wifi_dbm).state);
1818
rco2: !lambda return to_string(id(co2).state);
1919
pm01: !lambda return to_string(id(pm_1_0).state);
20-
pm02: !lambda return to_string(id(pm_2_5).state);
20+
pm02: !lambda return to_string(id(pm_2_5_raw).state);
21+
pm02Compensated: !lambda return to_string(id(pm_2_5).state);
2122
pm10: !lambda return to_string(id(pm_10_0).state);
2223
pm003Count: !lambda return to_string(id(pm_0_3um).state);
2324
atmp: !lambda return to_string(id(temp_raw).state);

packages/airgradient_api_esp32-c3.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ interval:
1717
wifi: !lambda return to_string(id(wifi_dbm).state);
1818
rco2: !lambda return to_string(id(co2).state);
1919
pm01: !lambda return to_string(id(pm_1_0).state);
20-
pm02: !lambda return to_string(id(pm_2_5).state);
20+
pm02: !lambda return to_string(id(pm_2_5_raw).state);
21+
pm02Compensated: !lambda return to_string(id(pm_2_5).state);
2122
pm10: !lambda return to_string(id(pm_10_0).state);
2223
pm003Count: !lambda return to_string(id(pm_0_3um).state);
2324
atmp: !lambda return to_string(id(temp_raw).state);

packages/airgradient_d1_mini_board.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
substitutions:
2-
config_version: 5.2.1
2+
config_version: 5.3.0
33

44
esphome:
55
name: "${name}"
@@ -18,8 +18,6 @@ esp8266:
1818
# Enable logging
1919
# https://esphome.io/components/logger.html
2020
logger:
21-
logs:
22-
component: ERROR # Hiding warning messages about component taking a long time https://github.com/esphome/issues/issues/4717
2321

2422
uart:
2523
# https://esphome.io/components/uart.html#uart

packages/airgradient_esp32-c3_board-arduino.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
substitutions:
2-
config_version: 5.2.1
2+
config_version: 5.3.0
33

44
esphome:
55
name: "${name}"
@@ -17,8 +17,6 @@ esp32:
1717
# Enable logging
1818
# https://esphome.io/components/logger.html
1919
logger:
20-
logs:
21-
component: ERROR # Hiding warning messages about component taking a long time https://github.com/esphome/issues/issues/4717
2220

2321
uart:
2422
# https://esphome.io/components/uart.html#uart

packages/airgradient_esp32-c3_board.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
substitutions:
2-
config_version: 5.2.1
2+
config_version: 5.3.0
33

44
esphome:
55
name: "${name}"
@@ -19,8 +19,6 @@ esp32:
1919
# Enable logging
2020
# https://esphome.io/components/logger.html
2121
logger:
22-
logs:
23-
component: ERROR # Hiding warning messages about component taking a long time https://github.com/esphome/issues/issues/4717
2422

2523
uart:
2624
# https://esphome.io/components/uart.html#uart

0 commit comments

Comments
 (0)