Files
microenv/microenv.yaml
Joshua M. Boniface c6dd8ea4b5 Convert to SGP41 sensor
SGP30's were too unreliable, so swap to the SGP41 and its adjusted
configurations. We leverage the same algorithm and values as the
AirGradient One to ensure consistency.
2025-06-21 19:59:43 -04:00

256 lines
6.3 KiB
YAML

---
###############################################################################
# MicroEnv v1.0 ESPHome configuration
###############################################################################
#
# Copyright (C) 2025 Joshua M. Boniface <joshua@boniface.me>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
###############################################################################
esphome:
name: microenv
name_add_mac_suffix: true
friendly_name: "MicroEnv Sensor"
project:
name: "Joshua Boniface.microenv"
version: "1.0"
min_version: 2025.5.0
dashboard_import:
package_import_url: github://joshuaboniface/microenv/microenv.yaml
esp32:
board: esp32-c3-devkitm-1
variant: esp32c3
framework:
type: esp-idf
preferences:
flash_write_interval: 15sec
globals:
# Defaults to -5 due to heating from the ESP
- id: temperature_offset
type: float
restore_value: true
initial_value: "-5.0"
- id: humidity_offset
type: float
restore_value: true
initial_value: "0.0"
logger:
level: INFO
baud_rate: 115200
api:
reboot_timeout: 15min
ota:
platform: esphome
web_server:
port: 80
captive_portal:
mdns:
disabled: false
wifi:
ap: {}
domain: ""
output_power: 8.5dB
reboot_timeout: 15min
power_save_mode: none
i2c:
- id: i2c_bus
sda: GPIO21
scl: GPIO20
scan: true
sensor:
- platform: sgp4x
voc:
name: "SGP41 VOC Index"
id: sgp41_voc_index
accuracy_decimals: 0
icon: mdi:molecule
filters:
- sliding_window_moving_average: # We take a reading every 15 seconds, but calculate the sliding
window_size: 12 # average over 12 readings i.e. 60 seconds/1 minute to normalize
send_every: 3 # brief spikes while still sending a value every 15 seconds.
nox:
name: "SGP41 NOx Index"
id: sgp41_nox_index
accuracy_decimals: 0
icon: mdi:molecule
filters:
- sliding_window_moving_average:
window_size: 12
send_every: 3
compensation:
temperature_source: sht45_temperature
humidity_source: sht45_humidity
store_baseline: true
update_interval: 5s
- platform: template
name: "SGP41 TVOC (µg/m³)"
id: sgp41_tvoc_ugm3
lambda: |-
float i = id(sgp41_voc_index).state;
if (i < 1) return NAN;
float tvoc = (log(501.0 - i) - 6.24) * -878.53;
return tvoc;
unit_of_measurement: "µg/m³"
accuracy_decimals: 0
- platform: template
name: "SGP41 TVOC (ppb)"
id: sgp41_tvoc_ppb
lambda: |-
float tvoc_ugm3 = id(sgp41_tvoc_ugm3).state;
float tvoc_ppm = tvoc_ugm3 * 0.436; // ppb estimated using isobutylene MW (56.1 g/mol)
return tvoc_ppm;
unit_of_measurement: "ppb"
accuracy_decimals: 0
- platform: template
name: "SGP41 eCO2 (approx ppm)"
id: sgp41_eco2_ppm
lambda: |-
float tvoc_ppb = id(sgp41_tvoc_ppb).state;
float eco2_ppm = 400.0 + 1.5 * tvoc_ppb;
if (eco2_ppm > 2000) eco2_ppm = 2000;
return eco2_ppm;
unit_of_measurement: "ppm"
accuracy_decimals: 0
- platform: sht4x
temperature:
name: "SHT45 Temperature"
id: sht45_temperature
accuracy_decimals: 1
filters:
- offset: !lambda return id(temperature_offset);
- sliding_window_moving_average:
window_size: 4
send_every: 1
humidity:
name: "SHT45 Relative Humidity"
id: sht45_humidity
accuracy_decimals: 1
filters:
- offset: !lambda return id(humidity_offset);
- sliding_window_moving_average:
window_size: 4
send_every: 1
heater_max_duty: 0.0
update_interval: 15s
- platform: absolute_humidity
name: "SHT45 Absolute Humidity"
temperature: sht45_temperature
humidity: sht45_humidity
id: sht45_absolute_humidity
- platform: template
name: "SHT45 Dew Point"
icon: mdi:thermometer-water
id: sht45_dew_point
unit_of_measurement: "°C"
lambda: |-
float temp = id(sht45_temperature).state;
float rh = id(sht45_humidity).state;
if (isnan(temp) || isnan(rh)) return NAN;
float a = 17.27, b = 237.7;
float alpha = ((a * temp) / (b + temp)) + log(rh / 100.0);
return (b * alpha) / (a - alpha);
update_interval: 15s
- platform: wifi_signal
name: "WiFi Signal"
update_interval: 60s
entity_category: diagnostic
- platform: uptime
name: "Uptime"
update_interval: 60s
entity_category: diagnostic
text_sensor:
- platform: version
name: "ESPHome Version"
entity_category: diagnostic
- platform: wifi_info
ip_address:
name: "WiFi IP Address"
ssid:
name: "WiFi SSID"
bssid:
name: "WiFi BSSID"
mac_address:
name: "WiFi MAC Address"
button:
- platform: restart
name: "ESP32 Restart"
icon: mdi:power-cycle
entity_category: diagnostic
- platform: factory_reset
name: "ESP32 Factory Reset"
icon: mdi:restart-alert
entity_category: diagnostic
number:
# Temperature offset:
# A calibration from -30 to +5 for the temperature sensor
- platform: template
name: "Temperature Offset"
id: temperature_offset_setter
min_value: -30
max_value: 10
step: 0.1
lambda: |-
return id(temperature_offset);
set_action:
then:
- globals.set:
id: temperature_offset
value: !lambda 'return float(x);'
# Humidity offset:
# A calibration from -20 to +20 for the humidity sensor
- platform: template
name: "Humidity Offset"
id: humidity_offset_setter
min_value: -20
max_value: 20
step: 0.1
lambda: |-
return id(humidity_offset);
set_action:
then:
- globals.set:
id: humidity_offset
value: !lambda 'return float(x);'