Czujnik BME280:
I2C Wiring | ESP NodeMCU Pinout |
---|---|
SCL | D1 |
SDA | D2 |
VIN | 3V |
GND | G |
SPS30:
I2C Wiring | ESP NodeMCU Pinout |
---|---|
5V | VIN |
SCL | D1 |
SDA | D2 |
GND | G |
SEL | G |
Uwaga:
Połączenie magistrali I2C z czujnika SPS30 i czujnika BME280, czyli SDA i SCL przychodzi do tego samego pinu na ESP8266 kolejno D1 i D2
Kod dla ESPhome
Kod:
esphome:
name: bme280-sps30
friendly_name: BME280-SPS30
esp8266:
board: nodemcuv2
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "cgj0jOsPfqjzdZyouseaPlUytt/hKep8ZswWVxYETBs="
ota:
password: "3af9681f0aea9a701ff2a978070aefd3"
wifi:
ssid: "MY_WIFI_NETWORK_SSID"
password: "12345678"
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esphome-Web-BME280"
password: "12345678"
captive_portal:
i2c:
id: bus_a
sda: D2
scl: D1
scan: True
sensor:
- platform: bme280
i2c_id: bus_a
temperature:
name: "Temperature"
id: bme280_temperature
oversampling: 16x
pressure:
name: "Pressure"
id: bme280_pressure
humidity:
name: "Humidity"
id: bme280_humidity
address: 0x76
update_interval: 15s
- platform: template
name: "Altitude"
lambda: |-
const float STANDARD_SEA_LEVEL_PRESSURE = 1013.25; //in hPa, see note
return ((id(bme280_temperature).state + 273.15) / 0.0065) *
(powf((STANDARD_SEA_LEVEL_PRESSURE / id(bme280_pressure).state), 0.190234) - 1); // in meter
update_interval: 15s
icon: 'mdi:signal'
unit_of_measurement: 'm'
- platform: absolute_humidity
name: "Absolute Humidity"
temperature: bme280_temperature
humidity: bme280_humidity
- platform: template
name: "Dew Point"
lambda: |-
return (243.5*(log(id(bme280_humidity).state/100)+((17.67*id(bme280_temperature).state)/
(243.5+id(bme280_temperature).state)))/(17.67-log(id(bme280_humidity).state/100)-
((17.67*id(bme280_temperature).state)/(243.5+id(bme280_temperature).state))));
unit_of_measurement: °C
icon: 'mdi:thermometer-alert'
- platform: template
name: "Equivalent sea level pressure"
lambda: |-
const float STANDARD_ALTITUDE = 0.6; // in meters, see note
return id(bme280_pressure).state / powf(1 - ((0.0065 * STANDARD_ALTITUDE) /
(id(bme280_temperature).state + (0.0065 * STANDARD_ALTITUDE) + 273.15)), 5.257); // in hPa
update_interval: 15s
unit_of_measurement: 'hPa'
- platform: sps30
i2c_id: bus_a
pm_1_0:
name: "PM <1µm Weight concentration"
id: "SPS30_PM_1_0"
accuracy_decimals: 2
pm_2_5:
name: "PM <2.5µm Weight concentration"
id: "SPS30_PM_2_5"
accuracy_decimals: 2
pm_4_0:
name: "PM <4µm Weight concentration"
id: "SPS30_PM_4_0"
accuracy_decimals: 2
pm_10_0:
name: "PM <10µm Weight concentration"
id: "SPS30_PM_10_0"
accuracy_decimals: 2
pmc_0_5:
name: "PM <0.5µm Number concentration"
id: "SPS30_PMC_0_5"
accuracy_decimals: 2
pmc_1_0:
name: "PM <1µm Number concentration"
id: "SPS30_PMC_1_0"
accuracy_decimals: 2
pmc_2_5:
name: "PM <2.5µm Number concentration"
id: "SPS30_PMC_2_5"
accuracy_decimals: 2
pmc_4_0:
name: "PM <4µm Number concentration"
id: "SPS30_PMC_4_0"
accuracy_decimals: 2
pmc_10_0:
name: "PM <10µm Number concentration"
id: "SPS30_PMC_10_0"
accuracy_decimals: 2
address: 0x69
update_interval: 10s
- platform: template
name: "PM 2.5 24h average"
id: pm_2_5_avg
icon: mdi:chemical-weapon
unit_of_measurement: µg/m³
lambda: |-
return id(SPS30_PM_2_5).state;
update_interval: 60s
filters:
- sliding_window_moving_average:
window_size: 1440 # = 24 hours x 60 minutes
send_every: 1
on_value:
then:
- script.execute: update_aqi
- platform: template
name: "PM 10 24h average"
id: pm_10_avg
icon: mdi:chemical-weapon
unit_of_measurement: µg/m³
lambda: |-
return id(SPS30_PM_10_0).state;
update_interval: 60s
filters:
- sliding_window_moving_average:
window_size: 1440 # = 24 hours x 60 minutes
send_every: 1
on_value:
then:
- script.execute: update_aqi
# This is a "helper" template sensor which is doing 30 sec moving average of PM2.5
# I use it for sensing in automations controlling purifiers (with Home Assistant),
# in order to remove the outlier values and making the control more smooth
- platform: template
name: "PM2.5 median"
id: pm2_5_median
icon: mdi:chemical-weapon
unit_of_measurement: µg/m³
lambda: |-
return id(SPS30_PM_2_5).state;
update_interval: 1s
filters:
- median:
window_size: 30
send_every: 30
send_first_at: 15
- platform: uptime
id: uptime_sec
text_sensor:
- platform: template
name: "Uptime"
lambda: |-
int seconds = (id(uptime_sec).state);
int days = seconds / (24 * 3600);
seconds = seconds % (24 * 3600);
int hours = seconds / 3600;
seconds = seconds % 3600;
int minutes = seconds / 60;
seconds = seconds % 60;
return { (String(days) +"d " + String(hours) +"h " + String(minutes) +"m "+ String(seconds) +"s").c_str() };
icon: mdi:clock-start
update_interval: 30s
- platform: template
name: "Air Quality Index"
id: aqi
icon: mdi:air-filter
# This script is called on every update of the relevant sensor values.
script:
- id: update_aqi
mode: restart
then:
# Bad if at least one of the sensor values is bad
- if:
condition:
or:
- sensor.in_range:
id: pm_2_5_avg
above: 25
- sensor.in_range:
id: pm_10_avg
above: 50
then:
- text_sensor.template.publish:
id: aqi
state: "Zła jakość powietrza"
else:
# Acceptable if at least one of the sensor values is acceptable
- if:
condition:
or:
- sensor.in_range:
id: pm_2_5_avg
above: 12
- sensor.in_range:
id: pm_10_avg
above: 25
then:
- text_sensor.template.publish:
id: aqi
state: "Akceptowalna jakość powietrza"
else:
# Otherwise good (all of the sensor values are good)
- text_sensor.template.publish:
id: aqi
state: "Dobra jakość powietrza"