Da der Markt leider keinen (kabelgebundenen) Luftqualitätsmonitor mit integrierter Lüftersteuerung zur Integration in Homeassistant und Apple Home bietet, musste etwas eigenes her.

Diese Eigenlösung basiert auf einem ESP32 Board mit PoE und verschiedenen Sensoren zur Messung von Temperatur, Luftfeuchtigkeit, Luftdruck, Kohlendioxid, Feinstaubpartikeln und flüchtigen organischen Verbindungen. Die hierbei verwendeten (und etwas teureren) Adafruit Sensoren sind bereits auf Platinen montiert und verfügen über einen Stemma Anschluss, so dass für diese keine Lötarbeiten erforderlich sind. Ausgelesen werden die Luftsensoren über den I2C Bus.

Zusätzlich wurde das ESP32 Board um angelötete Pin Header erweitert, um einen separaten zweiten I2C Bus bereitzustellen. Dieser wird für die Ansteuerung eines 0 - 10 Volt DAC Moduls zur Steuerung eines externen Abluftventilators genutzt. Durch die vorhandene Sensorbestückung war der erste I2C Bus bereits stark ausgelastet und daher nicht die optimale Wahl.

Das Gehäuse besteht aus zugeschnittenen Plexiglas Platten, in welche mithilfe einer angefertigten Bohrschablone die für die Montage erforderlichen Löcher gebohrt wurden. In die Hausautomation (Homeassistant bzw. Apple Home) eingebunden wird der Luftqualitätsmonitor über ESPHome.

Bild

Verwendete Komponenten

Inspiriert durch den AIR-1 sowie den AIR-Q fiel die Wahl für die Luftsensoren nach etwas Recherche auf nachfolgende Komponenten. Da die im SCD30 enthaltenen Sensoren für Temperatur und Luftfeuchtigkeit nur zur internen Unterstützung des Kohlendioxid Sensors dienen und sie aufgrund der Abwärme keine autark sinnvoll verwendbaren Werte liefern, kommt ein zusätzlicher BME280 für die Messung von Temperatur, Luftfeuchtigkeit und Luftdruck zum Einsatz. Hinsichtlich der flüchtigen organischen Verbindungen werden die vom SGP30 in der Maßeinheit "ppb" bereit gestellten Werte mithilfe eines zusätzlichen virtuellen Sensors für die Nutzung in Apple Home in die Maßeinheit "ug/m3" umgerechnet. Für die Kalibrierung des SCD30 Sensors auf 420 ppm (Freiluft) wird ein virtueller Schalter bereit gestellt. 

Zur Ansteuerung externen Abluftlüfters kommt zusätzlich ein DAC Modul (GP8403) zum Einsatz, welches ein analoges 0 - 10 Volt Steuersignal bereitstellt. Über dieses kann dann z. B. ein Helios M1/150 Abluftventilator (mit 0 - 10 Volt Regelung) gesteuert werden.

  • Olimex ESP32-POE-ISO Board
  • Olimex UEXT to STEMMA Adapter
  • Olimex UEXT Kabel
  • Olimex STEMMA Kabel
  • Adafruit SCD30 Sensor (Kohlendioxid)
  • Adafruit SGP30 Sensor (Flüchtige Organische Verbindungen)
  • Adafruit BME280 Sensor (Temperatur, Luftfeuchtigkeit und Luftdruck)
  • Adafruit PMSA003I Sensor (Feinstaubpartikel PM1.0, PM2.5, PM10.0)
  • Gravity GP8403 DAC Modul (0 - 10 Volt Lüftersteuerung)
  • Pin Header (für zweiten I2C Bus)
  • Plexiglas Zuschnitte (125mm x 105mm x 3mm)
  • Messing Abstandshalter (M2, M2.5, M3)
  • Schrauben (M2, M2.5, M3)
  • Bohrschablone
Bild

ESPHome Konfiguration

substitutions:
  name: espair
  friendly_name: "EspAir"
  encryption_key: "***"
  ota_password: "***"

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  name_add_mac_suffix: false

esp32:
  board: esp32dev
  framework:
    type: arduino

i2c:
  # Bus 1
  - id: i2c_bus_1
    sda: GPIO13
    scl: GPIO16
    scan: True
  # Bus 2
  - id: i2c_bus_2
    sda: GPIO32
    scl: GPIO33
    scan: True
  
logger:
  level: INFO

api:
  encryption:
    key: ${encryption_key}

ota:
  - platform: esphome
    password: ${ota_password}

ethernet:
  type: LAN8720
  mdc_pin: GPIO23
  mdio_pin: GPIO18
  clk_mode: GPIO17_OUT
  phy_addr: 0
  power_pin: GPIO12   
  use_address: ${ethernet_address}

sensor:
  # SGP30
  - platform: sgp30
    i2c_id: i2c_bus_1
    address: 0x58
    update_interval: 60s  
    store_baseline: yes
    eco2:
      name: "SGP30 eCO2"
      id: sgp30_eco2
      accuracy_decimals: 0
      internal: true
    tvoc:
      name: "SGP30 TVOC (ppb)"
      id: sgp30_tvoc_ppb
      accuracy_decimals: 0

  # SGP30 virtual
  - platform: template
    update_interval: 60s
    name: "SGP30 TVOC (ug)"
    id: sgp30_tvoc_ug
    icon: "mdi:radiator"
    lambda: return (id(sgp30_tvoc_ppb).state * 4.5);
    device_class: volatile_organic_compounds
    unit_of_measurement: "μg/m³"
    accuracy_decimals: 0

  # SCD30
  - platform: scd30
    i2c_id: i2c_bus_1
    address: 0x61
    update_interval: 60s  
    automatic_self_calibration: false
    #temperature_offset: 1.5 °C
    co2:
      name: "SCD30 CO2"
      id: scd30_co2
      accuracy_decimals: 0
    temperature:
      name: "SCD30 Temperature"
      id: scd30_temperature
      accuracy_decimals: 1
      internal: true
    humidity:
      name: "SCD30 Humidity"
      id: scd30_humidity
      accuracy_decimals: 0
      internal: true

  # BME280
  - platform: bme280_i2c
    i2c_id: i2c_bus_1
    address:  0x77
    update_interval: 60s  
    temperature:
      name: "BME280 Temperature"
      id: bme280_temperature
      accuracy_decimals: 1
    pressure:
      name: "BME280 Pressure"
      id: bme280_pressure
      accuracy_decimals: 0
    humidity:
      name: "BME280 Humidity"
      id: bme280_humidity
      accuracy_decimals: 0

  # PMSA003I
  - platform: pmsa003i
    i2c_id: i2c_bus_1
    address:  0x12
    update_interval: 60s  
    pm_1_0:
      name: "PMSA003I PM1.0"
      id: pmsa003i_pm1_0
      accuracy_decimals: 0
    pm_2_5:
      name: "PMSA003I PM2.5"
      id: pmsa003i_pm2_5
      accuracy_decimals: 0
    pm_10_0:
      name: "PMSA003I PM10.0"
      id: pmsa003i_pm10_0
      accuracy_decimals: 0
    pmc_0_3:
      name: "PMSA003I PMC >0.3µm"
      id: pmsa003i_pmc0_3
      accuracy_decimals: 0
      internal: true
    pmc_0_5:
      name: "PMSA003I PMC >0.5µm"
      id: pmsa003i_pmc0_5
      accuracy_decimals: 0
      internal: true
    pmc_1_0:
      name: "PMSA003I PMC >1µm"
      id: pmsa003i_pmc1_0
      accuracy_decimals: 0
      internal: true
    pmc_2_5:
      name: "PMSA003I PMC >2.5µm"
      id: pmsa003i_pmc2_5
      accuracy_decimals: 0
      internal: true
    pmc_5_0:
      name: "PMSA003I PMC >5µm"
      id: pmsa003i_pmc5_0
      accuracy_decimals: 0
      internal: true
    pmc_10_0:
      name: "PMSA003I PMC >10µm"
      id: pmsa003i_pmc10_0
      accuracy_decimals: 0
      internal: true

# GP8403
gp8403:
  id: dac_gp8403
  i2c_id: i2c_bus_2
  address: 0x58
  voltage: 10V
output:
  - platform: gp8403
    id: gp8403_dac_output_0
    gp8403_id: dac_gp8403
    channel: 0
fan:
  - platform: speed
    name: "Lüfter"
    output: gp8403_dac_output_0
    speed_count: 100

button:
  - platform: restart
    name: "ESP reboot"
    icon: mdi:power-cycle

  - platform: template
    name: "SCD30 CO2 calibrate (420)"
    icon: "mdi:molecule-co2"
    entity_category: "config"
    on_press:
      then:
        - scd30.force_recalibration_with_reference:
            value: 420.0
Bilder
Bilder
Bilder