Skip to content

Commit 1b62020

Browse files
committed
Standardize config for Basic DIY kit
1 parent 627297d commit 1b62020

File tree

2 files changed

+114
-39
lines changed

2 files changed

+114
-39
lines changed

airgradient-basic.bin

564 KB
Binary file not shown.

airgradient-basic.yaml

Lines changed: 114 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
11
---
2-
# Instructions: https://esphome.io/guides/getting_started_hassio.html
2+
# Reference for substitutions: https://github.com/ajfriesen/ESPHome-AirGradient/blob/main/air-gradient-pro-diy.yaml
3+
substitutions:
4+
devicename: "ag-basic"
5+
upper_devicename: "AG Basic"
6+
7+
# Instructions: https://esphome.io/guides/getting_started_hassio.html
38
esphome:
4-
name: airgradient
5-
platform: ESP8266
9+
name: "${devicename}"
10+
friendly_name: "${upper_devicename}"
11+
name_add_mac_suffix: true # Set to false if you don't want part of the MAC address in the name
12+
13+
esp8266:
614
board: d1_mini
715

816
# Enable logging
@@ -24,8 +32,6 @@ wifi:
2432
ap: {}
2533
captive_portal:
2634

27-
# Configuration for AirGradient DIY v2 device
28-
# https://www.esphome-devices.com/devices/AirGradient-DIY/
2935

3036
uart:
3137
# https://esphome.io/components/uart.html#uart
@@ -35,6 +41,7 @@ uart:
3541
id: senseair_s8_uart
3642

3743
- rx_pin: D5
44+
tx_pin: D6
3845
baud_rate: 9600
3946
id: pms5003_uart
4047

@@ -44,62 +51,105 @@ i2c:
4451

4552
sensor:
4653
- platform: pmsx003
47-
# https://esphome.io/components/sensor/pmsx003.html?highlight=pms5003
54+
# https://esphome.io/components/sensor/pmsx003.html
4855
type: PMSX003
49-
pm_1_0:
50-
name: "Particulate Matter <1.0µm Concentration"
51-
id: pm1
52-
filters:
53-
- sliding_window_moving_average:
54-
window_size: 30
55-
send_every: 30
5656
pm_2_5:
57-
name: "Particulate Matter <2.5µm Concentration"
58-
id: pm2
59-
filters:
60-
- sliding_window_moving_average:
61-
window_size: 30
62-
send_every: 30
57+
name: "PM <2.5µm Concentration"
58+
id: pm_2_5
59+
on_value:
60+
lambda: |-
61+
// https://en.wikipedia.org/wiki/Air_quality_index#Computing_the_AQI
62+
// Borrowed from https://github.com/kylemanna/sniffer/blob/master/esphome/sniffer_common.yaml
63+
if (id(pm_2_5).state <= 12.0) {
64+
// good
65+
id(pm_2_5_aqi).publish_state((50.0 - 0.0) / (12.0 - 0.0) * (id(pm_2_5).state - 0.0) + 0.0);
66+
} else if (id(pm_2_5).state <= 35.4) {
67+
// moderate
68+
id(pm_2_5_aqi).publish_state((100.0 - 51.0) / (35.4 - 12.1) * (id(pm_2_5).state - 12.1) + 51.0);
69+
} else if (id(pm_2_5).state <= 55.4) {
70+
// usg
71+
id(pm_2_5_aqi).publish_state((150.0 - 101.0) / (55.4 - 35.5) * (id(pm_2_5).state - 35.5) + 101.0);
72+
} else if (id(pm_2_5).state <= 150.4) {
73+
// unhealthy
74+
id(pm_2_5_aqi).publish_state((200.0 - 151.0) / (150.4 - 55.5) * (id(pm_2_5).state - 55.5) + 151.0);
75+
} else if (id(pm_2_5).state <= 250.4) {
76+
// very unhealthy
77+
id(pm_2_5_aqi).publish_state((300.0 - 201.0) / (250.4 - 150.5) * (id(pm_2_5).state - 150.5) + 201.0);
78+
} else if (id(pm_2_5).state <= 350.4) {
79+
// hazardous
80+
id(pm_2_5_aqi).publish_state((400.0 - 301.0) / (350.4 - 250.5) * (id(pm_2_5).state - 250.5) + 301.0);
81+
} else if (id(pm_2_5).state <= 500.4) {
82+
// hazardous 2
83+
id(pm_2_5_aqi).publish_state((500.0 - 401.0) / (500.4 - 350.5) * (id(pm_2_5).state - 350.5) + 401.0);
84+
} else {
85+
id(pm_2_5_aqi).publish_state(500);
86+
}
87+
pm_1_0:
88+
name: "PM <1.0µm Concentration"
89+
id: pm_1_0
6390
pm_10_0:
64-
name: "Particulate Matter <10.0µm Concentration"
65-
id: pm10
66-
filters:
67-
- sliding_window_moving_average:
68-
window_size: 30
69-
send_every: 30
91+
name: "PM <10.0µm Concentration"
92+
id: pm_10_0
93+
pm_0_3um:
94+
name: "PM >0.3µm Count"
95+
id: pm_0_3um
96+
update_interval: 2min
7097
uart_id: pms5003_uart
7198

99+
- platform: template
100+
name: "PM <2.5 AQI"
101+
unit_of_measurement: "AQI"
102+
icon: "mdi:air-filter"
103+
accuracy_decimals: 0
104+
id: pm_2_5_aqi
72105

73106
- platform: senseair
74107
# https://esphome.io/components/sensor/senseair.html
75108
co2:
76109
name: "SenseAir S8 CO2 Value"
77110
id: co2
111+
filters:
112+
- skip_initial: 2
113+
- clamp:
114+
min_value: 400 # 419 as of 2023-06 https://gml.noaa.gov/ccgg/trends/global.html
78115
update_interval: 30s
116+
id: senseair_s8
79117
uart_id: senseair_s8_uart
80118

119+
# - platform: sht4x
120+
# # SHT41 https://esphome.io/components/sensor/sht4x.html
121+
# temperature:
122+
# name: "Temperature"
123+
# id: temp
124+
# humidity:
125+
# name: "Humidity"
126+
# id: humidity
127+
# address: 0x44
81128

82129
- platform: sht3xd
83-
# https://esphome.io/components/sensor/sht3xd.html?highlight=sht31
130+
# SHT30 https://esphome.io/components/sensor/sht3xd.html
84131
temperature:
85132
name: "Temperature"
86133
id: temp
87134
humidity:
88135
name: "Humidity"
89136
id: humidity
90137
address: 0x44
91-
update_interval: 30s
92-
138+
heater_enabled: false # Only enable if in conditions that may have high condensation
93139

94140
- platform: wifi_signal
95141
name: "WiFi Signal"
96-
update_interval: 30s
97-
id: airgradient_wifi_signal
142+
id: wifi_dbm
143+
update_interval: 60s
98144

145+
- platform: uptime
146+
name: Uptime Sensor
147+
id: device_uptime
148+
update_interval: 10s
99149

100150
# - platform: sgp30
101151
# # https://esphome.io/components/sensor/sgp30.html
102-
# # Unable to get to work when OLED shield is connected
152+
# # Unable to get to work when OLED shield is also connected
103153
# eco2:
104154
# name: "eCO2"
105155
# id: eco2
@@ -110,7 +160,9 @@ sensor:
110160
# accuracy_decimals: 1
111161
# update_interval: 30s
112162

113-
163+
- platform: uptime
164+
name: Uptime Sensor
165+
id: airgradient_basement_uptime
114166

115167
font:
116168
# Font to use on the display
@@ -132,7 +184,7 @@ display:
132184
- id: display_pm2
133185
lambda: |-
134186
it.print(0, 0, id(font1), "PM2");
135-
it.printf(64, 24, id(font1), TextAlign::TOP_RIGHT, "%.0f",id(pm2).state);
187+
it.printf(64, 24, id(font1), TextAlign::TOP_RIGHT, "%.0f",id(pm_2_5).state);
136188
- id: display_co2
137189
lambda: |-
138190
it.print(0, 0, id(font1), "CO2");
@@ -158,6 +210,28 @@ display:
158210
# it.print(0, 0, id(font1), "TVOC");
159211
# it.printf(64, 24, id(font1), TextAlign::TOP_RIGHT, "%.0f",id(tvoc).state);
160212

213+
button:
214+
# https://github.com/esphome/issues/issues/2444
215+
- platform: template
216+
name: SenseAir S8 Calibration
217+
id: senseair_s8_calibrate_button
218+
on_press:
219+
then:
220+
- senseair.background_calibration: senseair_s8
221+
- delay: 70s
222+
- senseair.background_calibration_result: senseair_s8
223+
- platform: template
224+
name: SenseAir S8 Enable Automatic Calibration
225+
id: senseair_s8_enable_calibrate_button
226+
on_press:
227+
then:
228+
- senseair.abc_enable: senseair_s8
229+
- platform: template
230+
name: SenseAir S8 Disable Automatic Calibration
231+
id: senseair_s8_disable_calibrate_button
232+
on_press:
233+
then:
234+
- senseair.abc_disable: senseair_s8
161235

162236
http_request:
163237
# Used to support POST request to send data to AirGradient
@@ -171,7 +245,7 @@ interval:
171245
- display.page.show_next: oled_display
172246
- component.update: oled_display
173247

174-
- interval: 300s # 5 minutes to avoid overloading API
248+
- interval: 300s
175249
# Send data to AirGradient API server
176250
then:
177251
- http_request.post:
@@ -180,12 +254,13 @@ interval:
180254
return "http://hw.airgradient.com/sensors/airgradient:" + get_mac_address().substr(6,11) + "/measures";
181255
headers:
182256
Content-Type: application/json
183-
# "!lambda return to_string(id(pm2).state);" Converts sensor output from double to string
257+
# "!lambda return to_string(id(pm_2_5).state);" Converts sensor output from double to string
184258
json:
185-
wifi: id(airgradient_wifi_signal).state
186-
pm02: !lambda return to_string(id(pm2).state);
259+
wifi: !lambda return to_string(id(wifi_dbm).state);
260+
pm01: !lambda return to_string(id(pm_1_0).state);
261+
pm02: !lambda return to_string(id(pm_2_5).state);
262+
pm10: !lambda return to_string(id(pm_10_0).state);
263+
pm003_count: !lambda return to_string(id(pm_0_3um).state);
187264
rco2: !lambda return to_string(id(co2).state);
188265
atmp: !lambda return to_string(id(temp).state);
189266
rhum: !lambda return to_string(id(humidity).state);
190-
# tvoc: !lambda return to_string(id(tvoc).state);
191-
verify_ssl: false

0 commit comments

Comments
 (0)