Skip to content

Instantly share code, notes, and snippets.

@pavelbinar
Created July 30, 2026 08:46
Show Gist options
  • Select an option

  • Save pavelbinar/d3667ee11a1fefc47cfe280fa5a03e4e to your computer and use it in GitHub Desktop.

Select an option

Save pavelbinar/d3667ee11a1fefc47cfe280fa5a03e4e to your computer and use it in GitHub Desktop.
ESPHome SEN66 update using the built-in sen6x component

SEN66 update for ESPHome 2026.7

The previous configuration used uELKO/esphome_external_components, which no longer compiles because ESPHome 2026.7 removed an API it depended on.

The updated configuration:

  • Uses ESPHome's built-in sen6x component.
  • Correctly treats PM1, PM2.5, PM4 and PM10 as cumulative values.
  • Removes the custom PM10 sum and unreliable custom IAQ calculation.
  • Keeps TVOC and CAQI explicitly labelled as estimates.
  • Stores API and OTA credentials in secrets.yaml.

Tested successfully with ESPHome 2026.7.3 on a Seeed XIAO ESP32-C6 and Sensirion SEN66.

The -4.5 °C temperature offset and +12% humidity offset in the configuration are specific to our enclosure and should be recalibrated for another build.

esphome:
name: air-quality-sensor
friendly_name: Air Quality Sensor
min_version: "2026.7.3"
esp32:
board: seeed_xiao_esp32c6
framework:
type: esp-idf
i2c:
sda: GPIO22
scl: GPIO23
scan: false
sensor:
- platform: sen6x
id: sen66
type: SEN66
pm_1_0:
name: "PM <1 µm"
id: sen66_pm_1_0
accuracy_decimals: 1
pm_2_5:
name: "PM ≤2.5 µm"
id: sen66_pm_2_5
accuracy_decimals: 1
pm_4_0:
name: "PM ≤4 µm"
id: sen66_pm_4_0
accuracy_decimals: 1
pm_10_0:
name: "PM ≤10 µm"
id: sen66_pm_10_0
accuracy_decimals: 1
co2:
name: "CO₂"
id: sen66_co2
accuracy_decimals: 0
temperature:
name: "Temperature"
accuracy_decimals: 1
id: sen66_temperature_top
humidity:
name: "Humidity"
accuracy_decimals: 0
id: sen66_humidity
voc:
name: "VOC Index"
id: sen66_voc_index
filters:
- sliding_window_moving_average:
window_size: 9
send_every: 1
nox:
name: "NOx Index"
id: sen66_nox_index
filters:
- sliding_window_moving_average:
window_size: 9
send_every: 1
update_interval: 10s
- platform: template
name: "Ambient Temperature"
id: sen66_ambient_temperature
unit_of_measurement: "°C"
accuracy_decimals: 1
device_class: temperature
state_class: measurement
update_interval: 10s
lambda: |-
return id(sen66_temperature_top).state + id(temperature_offset_input).state;
- platform: template
name: "Ambient Humidity"
id: sen66_ambient_humidity
unit_of_measurement: "%"
accuracy_decimals: 0
device_class: humidity
state_class: measurement
update_interval: 10s
lambda: |-
return id(sen66_humidity).state + id(humidity_offset_input).state;
- platform: template
name: "Estimated TVOC Molhave Equivalent"
id: sen66_estimated_tvoc_molhave
unit_of_measurement: "mg/m³"
accuracy_decimals: 2
device_class: volatile_organic_compounds
state_class: measurement
update_interval: 10s
lambda: |-
const float voc_index = id(sen66_voc_index).state;
if (isnan(voc_index) || voc_index < 1.0f || voc_index >= 501.0f) {
return NAN;
}
return ((log(501 - voc_index) - 6.24) * (-996.94)) * 0.001;
- platform: aqi
name: "PM CAQI Estimate"
id: sen66_pm_caqi_estimate
pm_2_5: sen66_pm_2_5
pm_10_0: sen66_pm_10_0
calculation_type: CAQI
accuracy_decimals: 0
state_class: measurement
number:
- platform: template
name: "Temperature Offset"
id: temperature_offset_input
optimistic: true
min_value: -10.0
max_value: 10.0
step: 0.05
initial_value: -4.5
restore_value: true
unit_of_measurement: "°C"
entity_category: config
mode: box
- platform: template
name: "Humidity Offset"
id: humidity_offset_input
optimistic: true
min_value: -20.0
max_value: 20.0
step: 1
initial_value: 12.0
restore_value: true
unit_of_measurement: "%"
entity_category: config
mode: box
logger:
level: INFO
api:
encryption:
key: !secret air_quality_sensor_api_encryption_key
ota:
- platform: esphome
password: !secret air_quality_sensor_ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment