Bosch BME680/BSEC

ESP Home, Air Quality Sensor using the Bosch BME680 and their BSEC pre-compiled Library.

Use the ESP Home add-on in Home Assistant to create this, copying the source code from here and updating your Wi-Fi credentials, in this example the credentials are in a secrets file

esphome:
  name: aqssensor
  friendly_name: aqssensor

esp32:
  board: adafruit_feather_esp32_v2
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "dbm+2rK3urA2Q7nm7OXwaIwzh5yeXyr7igfADVETaqA="

ota:
  password: "e31550dc51a2f52f4b31235588ab6879"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "AQS Fallback Hotspot"
    password: "d9uf5oPpcwYf"

captive_portal:

i2c:
  sda: 22
  scl: 20
  scan: true
  id: bus_a

bme680_bsec:
    # i2c address
    # -----------
    # Common values are:
    # - 0x76
    # - 0x77
    # Default: 0x76
    address: 0x76

    # Temperature offset
    # ------------------
    # Useful if device is in enclosure and reads too high
    # Default: 0
    temperature_offset: 0
    # Sample rate
    # -----------
    # Available options:
    # - lp (low power - samples every 3 seconds)
    # - ulp (ultra low power - samples every 5 minutes)
    # Default: lp
    sample_rate: ulp
    # Interval at which to save BSEC state
    # ------------------------------------
    # Default: 6h
    state_save_interval: 6h

sensor:
  - platform: bme680_bsec
    temperature:
      name: "BME680 Temperature"
      id: BME680_temp
    pressure:
      name: "BME680 Pressure"
      id: BME680_pres
    humidity:
      name: "BME680 Humidity"
      id: BME680_humi
    iaq:
      name: "BME680 IAQ"
      id: iaq
    co2_equivalent:
      name: "BME680 CO2 Equivalent"
    breath_voc_equivalent:
      name: "BME680 Breath VOC Equivalent"

    gas_resistance:
      # Gas resistance in Ω
      name: "BME680 Gas Resistance"
      filters:
        - median

  - platform: scd4x
    measurement_mode: SINGLE_SHOT
    ambient_pressure_compensation_source: BME680_pres
    temperature_offset: 0
    co2:
      name: "SCD41 CO2 level"
      filters:
        - median
    temperature:
      name: "SCD41 Temperature"
    humidity:
     name: "SCD41 Humidity"
       
  - platform: sgp4x
    voc:
      name: "SGP40 VOC Index"
    nox:
      name: "SGP40 NOx Index"

    compensation:
      humidity_source: BME680_humi
      temperature_source: BME680_temp

text_sensor:
  - platform: bme680_bsec
    iaq_accuracy:
      name: "BME680 IAQ Accuracy"

  - platform: template
    name: "BME680 IAQ Classification"
    icon: "mdi:checkbox-marked-circle-outline"
    lambda: |-
      if ( int(id(iaq).state) <= 50) { return {"Excellent"}; } else if (int(id(iaq).state) >= 51 && int(id(iaq).state) <= 100) { return {"Good"}; } else if (int(id(iaq).state) >= 101 && int(id(iaq).state) <= 150) { return {"Lightly polluted"}; } else if (int(id(iaq).state) >= 151 && int(id(iaq).state) <= 200) { return {"Moderately polluted"}; } else if (int(id(iaq).state) >= 201 && int(id(iaq).state) <= 250) { return {"Heavily polluted"}; } else if (int(id(iaq).state) >= 251 && int(id(iaq).state) <= 350) { return {"Severely polluted"}; } else if (int(id(iaq).state) >= 351) {
        return {"Extremely polluted"};
      }
      else {
        return {"error"};
      }