SDS011 not updating at specified interval

Hello All,

I have two devices with identical hardware except one has an I2C SH1106 display while the other has no display. The other devices are:

  • NodeMCU CP2102 ESP-12E
  • SDS011 Air Quality Sensor
  • DHT11 Temp/Humidity sensor

The configs are also the same except for the ‘name’ parameters and the display stuff for the one that has the display.

Problem is the SDS011 on the device with no display updates every minute even though the config specifies an update interval of 10 minutes.

This is the config for the device that’s incorrectly getting the air quality values every minute.

esphome:
  name: downstairs
  platform: ESP8266
  board: esp12e

# Enable logging
logger:

# Enable Home Assistant API
api:
 password: !secret haapi_password

ota:
  password: !secret ota_password

wifi:
  networks:
  - ssid: !secret wifi1_ssid
    password: !secret wifi1_password
  - ssid: !secret wifi2_ssid
    password: !secret wifi2_password

  manual_ip:
    static_ip: x.x.x.x
    gateway: x.x.x.x
    subnet: x.x.x.x
    dns1: x.x.x.x
    dns2: x.x.x.x
  
  fast_connect: off

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Downstairs Fallback"
    password: !secret fb_password

captive_portal:

switch:
  - platform: restart
    name: "Downstairs Restart"

time:
  - platform: homeassistant
    id: esptime

uart:
  rx_pin: GPIO12
  tx_pin: GPIO14
  baud_rate: 9600

sensor:
- platform: dht
  pin: GPIO13
  update_interval: 60s
  temperature:
    name: "Downstairs Temperature"
    id: temperatureC
    force_update: true
    filters:
    - filter_out: nan
    - sliding_window_moving_average:
        window_size: 15
        send_every: 1
        send_first_at: 1
  humidity:
    name: "Downstairs Humidity"
    id: humidity
    force_update: true
    filters:
    - filter_out: nan
    - sliding_window_moving_average:
        window_size: 15
        send_every: 1
        send_first_at: 1
# DHT Filtering should be sending averaged values every 60 Seconds

- platform: sds011
  update_interval: 10min
  pm_2_5:
    name: "Downstairs PM <2.5µm"
    id: PM25
  pm_10_0:
    name: "Downstairs PM <10.0µm"
    id: PM100

- platform: template
  name: "Downstairs PM <2.5µm 1 Hour Avg"
  id: PM251Hour
  unit_of_measurement: 'µg/m³'
  update_interval: 10min
  state_class: measurement
  icon: mdi:chemical-weapon
  lambda: |-
    return (id(PM25).state);
  filters:
  - filter_out: nan
  - sliding_window_moving_average:
      window_size: 6
      send_every: 1
      send_first_at: 1

- platform: template
  name: "Downstairs PM <2.5µm 24 Hour Avg"
  id: PM2524Hour
  unit_of_measurement: 'µg/m³'
  update_interval: 60min
  state_class: measurement
  icon: mdi:chemical-weapon
  lambda: |-
    return (id(PM251Hour).state);
  filters:
  - filter_out: nan
  - sliding_window_moving_average:
      window_size: 24
      send_every: 1
      send_first_at: 1

- platform: template
  name: "Downstairs PM <10.0µm 1 Hour Avg"
  id: PM1001Hour
  unit_of_measurement: 'µg/m³'
  update_interval: 10min
  state_class: measurement
  icon: mdi:chemical-weapon
  lambda: |-
    return (id(PM100).state);
  filters:
  - filter_out: nan
  - sliding_window_moving_average:
      window_size: 6
      send_every: 1
      send_first_at: 1

- platform: template
  name: "Downstairs PM <10.0µm 24 Hour Avg"
  id: PM10024Hour
  unit_of_measurement: 'µg/m³'
  update_interval: 60min
  state_class: measurement
  icon: mdi:chemical-weapon
  lambda: |-
    return (id(PM1001Hour).state);
  filters:
  - filter_out: nan
  - sliding_window_moving_average:
      window_size: 24
      send_every: 1
      send_first_at: 1

- platform: template
  name: "Downstairs PM2.5µm 24 Hour AQI"
  id: SDS011_PM25_AQI
  unit_of_measurement: 'AQI'
  update_interval: 60min
  state_class: measurement
  icon: mdi:chemical-weapon
  accuracy_decimals: 1
  lambda: |-
    if ((id(PM2524Hour).state) > 300.0)
    { return round((((500.0 - 301.0)/(500.4 - 250.5)) * ((id(PM2524Hour).state) - 250.5) + 301.0));
    }
    else if ((id(PM2524Hour).state) > 200.0 and (id(PM2524Hour).state) <= 300.0)
    { return round((((300.0 - 201.0)/(250.4 - 150.5)) * ((id(PM2524Hour).state) - 150.5) + 201.0));
    }
    else if ((id(PM2524Hour).state) > 150.0 and (id(PM2524Hour).state) <= 200.0)
    { return round((((200.0 - 151.0)/(150.4 - 55.5)) * ((id(PM2524Hour).state) - 55.5) + 151.0));
    }
    else if ((id(PM2524Hour).state) > 100.0 and (id(PM2524Hour).state) <= 150.0)
    { return round((((150.0 - 101.0)/(55.4 - 35.5)) * ((id(PM2524Hour).state) - 35.5) + 101.0));
    }
    else if ((id(PM2524Hour).state) > 50.0 and (id(PM2524Hour).state) <= 100.0)
    { return round((((100.0 - 51.0)/(35.4 - 12.1)) * ((id(PM2524Hour).state) - 12.1) + 51.0));
    }
    else
    { return round((((50.0 - 0.0)/(12.0 - 0.0)) * ((id(PM2524Hour).state) - 0.0) + 0.0));
    }

- platform: template
  name: "Downstairs PM10.0µm 24 Hour AQI"
  id: SDS011_PM100_AQI
  unit_of_measurement: 'AQI'
  update_interval: 60min
  state_class: measurement
  icon: mdi:chemical-weapon
  accuracy_decimals: 1
  lambda: |-
    if ((id(PM10024Hour).state) > 300.0)
    { return round((((500.0 - 301.0)/(500.4 - 250.5)) * ((id(PM10024Hour).state) - 250.5) + 301.0));
    }
    else if ((id(PM10024Hour).state) > 200.0 and (id(PM10024Hour).state) <= 300.0)
    { return round((((300.0 - 201.0)/(250.4 - 150.5)) * ((id(PM10024Hour).state) - 150.5) + 201.0));
    }
    else if ((id(PM10024Hour).state) > 150.0 and (id(PM10024Hour).state) <= 200.0)
    { return round((((200.0 - 151.0)/(150.4 - 55.5)) * ((id(PM10024Hour).state) - 55.5) + 151.0));
    }
    else if ((id(PM10024Hour).state) > 100.0 and (id(PM10024Hour).state) <= 150.0)
    { return round((((150.0 - 101.0)/(55.4 - 35.5)) * ((id(PM10024Hour).state) - 35.5) + 101.0));
    }
    else if ((id(PM10024Hour).state) > 50.0 and (id(PM10024Hour).state) <= 100.0)
    { return round((((100.0 - 51.0)/(35.4 - 12.1)) * ((id(PM10024Hour).state) - 12.1) + 51.0));
    }
    else
    { return round((((50.0 - 0.0)/(12.0 - 0.0)) * ((id(PM10024Hour).state) - 0.0) + 0.0));
    }

- platform: template
  name: "Downstairs PM10.0µm 1 Hour AQI"
  id: SDS011_PM100_1Hour_AQI
  unit_of_measurement: 'AQI'
  update_interval: 10min
  state_class: measurement
  icon: mdi:chemical-weapon
  accuracy_decimals: 1
  lambda: |-
    if ((id(PM1001Hour).state) > 300.0)
    { return round((((500.0 - 301.0)/(500.4 - 250.5)) * ((id(PM1001Hour).state) - 250.5) + 301.0));
    }
    else if ((id(PM1001Hour).state) > 200.0 and (id(PM1001Hour).state) <= 300.0)
    { return round((((300.0 - 201.0)/(250.4 - 150.5)) * ((id(PM1001Hour).state) - 150.5) + 201.0));
    }
    else if ((id(PM1001Hour).state) > 150.0 and (id(PM1001Hour).state) <= 200.0)
    { return round((((200.0 - 151.0)/(150.4 - 55.5)) * ((id(PM1001Hour).state) - 55.5) + 151.0));
    }
    else if ((id(PM1001Hour).state) > 100.0 and (id(PM1001Hour).state) <= 150.0)
    { return round((((150.0 - 101.0)/(55.4 - 35.5)) * ((id(PM1001Hour).state) - 35.5) + 101.0));
    }
    else if ((id(PM1001Hour).state) > 50.0 and (id(PM1001Hour).state) <= 100.0)
    { return round((((100.0 - 51.0)/(35.4 - 12.1)) * ((id(PM1001Hour).state) - 12.1) + 51.0));
    }
    else
    { return round((((50.0 - 0.0)/(12.0 - 0.0)) * ((id(PM1001Hour).state) - 0.0) + 0.0));
    }

- platform: template
  name: "Downstairs PM2.5µm 1 Hour AQI"
  id: SDS011_PM25_1Hour_AQI
  unit_of_measurement: 'AQI'
  update_interval: 10min
  state_class: measurement
  icon: mdi:chemical-weapon
  accuracy_decimals: 1
  lambda: |-
    if ((id(PM251Hour).state) > 300.0)
    { return round((((500.0 - 301.0)/(500.4 - 250.5)) * ((id(PM251Hour).state) - 250.5) + 301.0));
    }
    else if ((id(PM251Hour).state) > 200.0 and (id(PM251Hour).state) <= 300.0)
    { return round((((300.0 - 201.0)/(250.4 - 150.5)) * ((id(PM251Hour).state) - 150.5) + 201.0));
    }
    else if ((id(PM251Hour).state) > 150.0 and (id(PM251Hour).state) <= 200.0)
    { return round((((200.0 - 151.0)/(150.4 - 55.5)) * ((id(PM251Hour).state) - 55.5) + 151.0));
    }
    else if ((id(PM251Hour).state) > 100.0 and (id(PM251Hour).state) <= 150.0)
    { return round((((150.0 - 101.0)/(55.4 - 35.5)) * ((id(PM251Hour).state) - 35.5) + 101.0));
    }
    else if ((id(PM251Hour).state) > 50.0 and (id(PM251Hour).state) <= 100.0)
    { return round((((100.0 - 51.0)/(35.4 - 12.1)) * ((id(PM251Hour).state) - 12.1) + 51.0));
    }
    else
    { return round((((50.0 - 0.0)/(12.0 - 0.0)) * ((id(PM251Hour).state) - 0.0) + 0.0));
    }

text_sensor:
- platform: template
  name: "Downstairs PM2.5µm 1 Hour AQI Index"
  id: SDS011_PM25_1Hour_AQI_Index
  update_interval: 10min
  icon: mdi:chemical-weapon
  lambda: |-
    if ((id(SDS011_PM25_1Hour_AQI).state) > 300.0)
    { return {"Hazardous"};
    }
    else if ((id(SDS011_PM25_1Hour_AQI).state) > 200.0 and (id(SDS011_PM25_1Hour_AQI).state) <= 300.0)
    { return {"Very Unhealthy"};
    }
    else if ((id(SDS011_PM25_1Hour_AQI).state) > 150.0 and (id(SDS011_PM25_1Hour_AQI).state) <= 200.0)
    { return {"Unhealthy"};
    }
    else if ((id(SDS011_PM25_1Hour_AQI).state) > 100.0 and (id(SDS011_PM25_1Hour_AQI).state) <= 150.0)
    { return {"Unhealthy for Sensitive Groups"};
    }
    else if ((id(SDS011_PM25_1Hour_AQI).state) > 50.0 and (id(SDS011_PM25_1Hour_AQI).state) <= 100.0)
    { return {"Moderate"};
    }
    else
    { return {"Good"};
    }

- platform: template
  name: "Downstairs PM2.5µm 24 Hour AQI Index"
  id: SDS011_PM25_24Hour_AQI_Index
  update_interval: 10min
  icon: mdi:chemical-weapon
  lambda: |-
    if ((id(SDS011_PM25_AQI).state) > 300.0)
    { return {"Hazardous"};
    }
    else if ((id(SDS011_PM25_AQI).state) > 200.0 and (id(SDS011_PM25_AQI).state) <= 300.0)
    { return {"Very Unhealthy"};
    }
    else if ((id(SDS011_PM25_AQI).state) > 150.0 and (id(SDS011_PM25_AQI).state) <= 200.0)
    { return {"Unhealthy"};
    }
    else if ((id(SDS011_PM25_AQI).state) > 100.0 and (id(SDS011_PM25_AQI).state) <= 150.0)
    { return {"Unhealthy for Sensitive Groups"};
    }
    else if ((id(SDS011_PM25_AQI).state) > 50.0 and (id(SDS011_PM25_AQI).state) <= 100.0)
    { return {"Moderate"};
    }
    else
    { return {"Good"};
    }

- platform: template
  name: "Downstairs PM10.0µm 1 Hour AQI Index"
  id: SDS011_PM100_1Hour_AQI_Index
  update_interval: 60min
  icon: mdi:chemical-weapon
  lambda: |-
    if ((id(SDS011_PM100_1Hour_AQI).state) > 300.0)
    { return {"Hazardous"};
    }
    else if ((id(SDS011_PM100_1Hour_AQI).state) > 200.0 and (id(SDS011_PM100_1Hour_AQI).state) <= 300.0)
    { return {"Very Unhealthy"};
    }
    else if ((id(SDS011_PM100_1Hour_AQI).state) > 150.0 and (id(SDS011_PM100_1Hour_AQI).state) <= 200.0)
    { return {"Unhealthy"};
    }
    else if ((id(SDS011_PM100_1Hour_AQI).state) > 100.0 and (id(SDS011_PM100_1Hour_AQI).state) <= 150.0)
    { return {"Unhealthy for Sensitive Groups"};
    }
    else if ((id(SDS011_PM100_1Hour_AQI).state) > 50.0 and (id(SDS011_PM100_1Hour_AQI).state) <= 100.0)
    { return {"Moderate"};
    }
    else
    { return {"Good"};
    }

- platform: template
  name: "Downstairs PM10.0µm 24 Hour AQI Index"
  id: SDS011_PM100_24Hour_AQI_Index
  update_interval: 60min
  icon: mdi:chemical-weapon
  lambda: |-
    if ((id(SDS011_PM100_AQI).state) > 300.0)
    { return {"Hazardous"};
    }
    else if ((id(SDS011_PM100_AQI).state) > 200.0 and (id(SDS011_PM100_AQI).state) <= 300.0)
    { return {"Very Unhealthy"};
    }
    else if ((id(SDS011_PM100_AQI).state) > 150.0 and (id(SDS011_PM100_AQI).state) <= 200.0)
    { return {"Unhealthy"};
    }
    else if ((id(SDS011_PM100_AQI).state) > 100.0 and (id(SDS011_PM100_AQI).state) <= 150.0)
    { return {"Unhealthy for Sensitive Groups"};
    }
    else if ((id(SDS011_PM100_AQI).state) > 50.0 and (id(SDS011_PM100_AQI).state) <= 100.0)
    { return {"Moderate"};
    }
    else
    { return {"Good"};
    }

- platform: wifi_info
  ip_address:
    name: Downstairs IP Address
  ssid:
    name: Downstairs Connected SSID
  bssid:
    name: Downstairs Connected BSSID
  mac_address:
    name: Downstairs Mac Wifi Address

And a few log entries showing the SDS updating every minute.

[10:27:19][C][wifi_info:009]: WifiInfo IPAddress 'Downstairs IP Address'
[10:27:19][C][wifi_info:010]: WifiInfo SSID 'Downstairs Connected SSID'
[10:27:19][C][wifi_info:011]: WifiInfo BSSID 'Downstairs Connected BSSID'
[10:27:54][D][dht:048]: Got Temperature=25.5°C Humidity=31.0%
[10:27:54][D][sensor:131]: 'Downstairs Temperature': Sending state 25.50000 °C with 1 decimals of accuracy
[10:27:54][D][sensor:131]: 'Downstairs Humidity': Sending state 31.00000 % with 0 decimals of accuracy
[10:28:01][D][sds011:169]: Got PM2.5 Concentration: 3.7 µg/m³, PM10.0 Concentration: 8.3 µg/m³
[10:28:01][D][sensor:131]: 'Downstairs PM <2.5µm': Sending state 3.70000 µg/m³ with 1 decimals of accuracy
[10:28:01][D][sensor:131]: 'Downstairs PM <10.0µm': Sending state 8.30000 µg/m³ with 1 decimals of accuracy
[10:28:54][D][dht:048]: Got Temperature=25.8°C Humidity=31.0%
[10:28:54][D][sensor:131]: 'Downstairs Temperature': Sending state 25.65000 °C with 1 decimals of accuracy
[10:28:54][D][sensor:131]: 'Downstairs Humidity': Sending state 31.00000 % with 0 decimals of accuracy
[10:29:01][D][sds011:169]: Got PM2.5 Concentration: 4.0 µg/m³, PM10.0 Concentration: 9.3 µg/m³
[10:29:01][D][sensor:131]: 'Downstairs PM <2.5µm': Sending state 4.00000 µg/m³ with 1 decimals of accuracy
[10:29:01][D][sensor:131]: 'Downstairs PM <10.0µm': Sending state 9.30000 µg/m³ with 1 decimals of accuracy

And the config for the device that updates at the correct 10 minute interval

esphome:
  name: testnodemcu
  platform: ESP8266
  board: esp12e

# Enable logging
logger:

# Enable Home Assistant API
api:
 password: !secret haapi_password

ota:
  password: !secret ota_password

wifi:
  networks:
  - ssid: !secret wifi1_ssid
    password: !secret wifi1_password
  - ssid: !secret wifi2_ssid
    password: !secret wifi2_password

  manual_ip:
    static_ip: x.x.x.x
    gateway: x.x.x.x
    subnet: x.x.x.x
    dns1: x.x.x.x
    dns2: x.x.x.x
  
  fast_connect: off

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "TestnodeMCU Fallback"
    password: !secret fb_password

captive_portal:

switch:
  - platform: restart
    name: "NodeMCU Restart"

i2c:
  sda: GPIO4
  scl: GPIO5

time:
  - platform: homeassistant
    id: esptime

uart:
  rx_pin: GPIO12
  tx_pin: GPIO14
  baud_rate: 9600

sensor:
- platform: dht
  pin: GPIO13
  update_interval: 60s
  temperature:
    name: "NodeMCU Temperature"
    id: "temperatureC"
    force_update: true
    filters:
    - filter_out: nan
    - sliding_window_moving_average:
        window_size: 15
        send_every: 1
        send_first_at: 1
  humidity:
    name: "NodeMCU Humidity"
    id: "humidity"
    force_update: true
    filters:
    - filter_out: nan
    - sliding_window_moving_average:
        window_size: 15
        send_every: 1
        send_first_at: 1
# DHT Filtering should be sending averaged values every 60 Seconds

- platform: sds011
  update_interval: 10min
  pm_2_5:
    name: "PM <2.5µm"
    id: "PM25"
  pm_10_0:
    name: "PM <10.0µm"
    id: PM100

- platform: template
  name: "PM <2.5µm 1 Hour Avg"
  id: PM251Hour
  unit_of_measurement: 'µg/m³'
  update_interval: 10min
  state_class: measurement
  icon: mdi:chemical-weapon
  lambda: |-
    return (id(PM25).state);
  filters:
  - filter_out: nan
  - sliding_window_moving_average:
      window_size: 6
      send_every: 1
      send_first_at: 1

- platform: template
  name: "PM <2.5µm 24 Hour Avg"
  id: PM2524Hour
  unit_of_measurement: 'µg/m³'
  update_interval: 60min
  state_class: measurement
  icon: mdi:chemical-weapon
  lambda: |-
    return (id(PM251Hour).state);
  filters:
  - filter_out: nan
  - sliding_window_moving_average:
      window_size: 24
      send_every: 1
      send_first_at: 1

- platform: template
  name: "PM <10.0µm 1 Hour Avg"
  id: PM1001Hour
  unit_of_measurement: 'µg/m³'
  update_interval: 10min
  state_class: measurement
  icon: mdi:chemical-weapon
  lambda: |-
    return (id(PM100).state);
  filters:
  - filter_out: nan
  - sliding_window_moving_average:
      window_size: 6
      send_every: 1
      send_first_at: 1

- platform: template
  name: "PM <10.0µm 24 Hour Avg"
  id: PM10024Hour
  unit_of_measurement: 'µg/m³'
  update_interval: 60min
  state_class: measurement
  icon: mdi:chemical-weapon
  lambda: |-
    return (id(PM1001Hour).state);
  filters:
  - filter_out: nan
  - sliding_window_moving_average:
      window_size: 24
      send_every: 1
      send_first_at: 1

- platform: template
  name: "PM2.5µm 24 Hour AQI"
  id: SDS011_PM25_AQI
  unit_of_measurement: 'AQI'
  update_interval: 60min
  state_class: measurement
  icon: mdi:chemical-weapon
  accuracy_decimals: 1
  lambda: |-
    if ((id(PM2524Hour).state) > 300.0)
    { return round((((500.0 - 301.0)/(500.4 - 250.5)) * ((id(PM2524Hour).state) - 250.5) + 301.0));
    }
    else if ((id(PM2524Hour).state) > 200.0 and (id(PM2524Hour).state) <= 300.0)
    { return round((((300.0 - 201.0)/(250.4 - 150.5)) * ((id(PM2524Hour).state) - 150.5) + 201.0));
    }
    else if ((id(PM2524Hour).state) > 150.0 and (id(PM2524Hour).state) <= 200.0)
    { return round((((200.0 - 151.0)/(150.4 - 55.5)) * ((id(PM2524Hour).state) - 55.5) + 151.0));
    }
    else if ((id(PM2524Hour).state) > 100.0 and (id(PM2524Hour).state) <= 150.0)
    { return round((((150.0 - 101.0)/(55.4 - 35.5)) * ((id(PM2524Hour).state) - 35.5) + 101.0));
    }
    else if ((id(PM2524Hour).state) > 50.0 and (id(PM2524Hour).state) <= 100.0)
    { return round((((100.0 - 51.0)/(35.4 - 12.1)) * ((id(PM2524Hour).state) - 12.1) + 51.0));
    }
    else
    { return round((((50.0 - 0.0)/(12.0 - 0.0)) * ((id(PM2524Hour).state) - 0.0) + 0.0));
    }

- platform: template
  name: "PM10.0µm 24 Hour AQI"
  id: SDS011_PM100_AQI
  unit_of_measurement: 'AQI'
  update_interval: 60min
  state_class: measurement
  icon: mdi:chemical-weapon
  accuracy_decimals: 1
  lambda: |-
    if ((id(PM10024Hour).state) > 300.0)
    { return round((((500.0 - 301.0)/(500.4 - 250.5)) * ((id(PM10024Hour).state) - 250.5) + 301.0));
    }
    else if ((id(PM10024Hour).state) > 200.0 and (id(PM10024Hour).state) <= 300.0)
    { return round((((300.0 - 201.0)/(250.4 - 150.5)) * ((id(PM10024Hour).state) - 150.5) + 201.0));
    }
    else if ((id(PM10024Hour).state) > 150.0 and (id(PM10024Hour).state) <= 200.0)
    { return round((((200.0 - 151.0)/(150.4 - 55.5)) * ((id(PM10024Hour).state) - 55.5) + 151.0));
    }
    else if ((id(PM10024Hour).state) > 100.0 and (id(PM10024Hour).state) <= 150.0)
    { return round((((150.0 - 101.0)/(55.4 - 35.5)) * ((id(PM10024Hour).state) - 35.5) + 101.0));
    }
    else if ((id(PM10024Hour).state) > 50.0 and (id(PM10024Hour).state) <= 100.0)
    { return round((((100.0 - 51.0)/(35.4 - 12.1)) * ((id(PM10024Hour).state) - 12.1) + 51.0));
    }
    else
    { return round((((50.0 - 0.0)/(12.0 - 0.0)) * ((id(PM10024Hour).state) - 0.0) + 0.0));
    }

- platform: template
  name: "PM10.0µm 1 Hour AQI"
  id: SDS011_PM100_1Hour_AQI
  unit_of_measurement: 'AQI'
  update_interval: 10min
  state_class: measurement
  icon: mdi:chemical-weapon
  accuracy_decimals: 1
  lambda: |-
    if ((id(PM1001Hour).state) > 300.0)
    { return round((((500.0 - 301.0)/(500.4 - 250.5)) * ((id(PM1001Hour).state) - 250.5) + 301.0));
    }
    else if ((id(PM1001Hour).state) > 200.0 and (id(PM1001Hour).state) <= 300.0)
    { return round((((300.0 - 201.0)/(250.4 - 150.5)) * ((id(PM1001Hour).state) - 150.5) + 201.0));
    }
    else if ((id(PM1001Hour).state) > 150.0 and (id(PM1001Hour).state) <= 200.0)
    { return round((((200.0 - 151.0)/(150.4 - 55.5)) * ((id(PM1001Hour).state) - 55.5) + 151.0));
    }
    else if ((id(PM1001Hour).state) > 100.0 and (id(PM1001Hour).state) <= 150.0)
    { return round((((150.0 - 101.0)/(55.4 - 35.5)) * ((id(PM1001Hour).state) - 35.5) + 101.0));
    }
    else if ((id(PM1001Hour).state) > 50.0 and (id(PM1001Hour).state) <= 100.0)
    { return round((((100.0 - 51.0)/(35.4 - 12.1)) * ((id(PM1001Hour).state) - 12.1) + 51.0));
    }
    else
    { return round((((50.0 - 0.0)/(12.0 - 0.0)) * ((id(PM1001Hour).state) - 0.0) + 0.0));
    }

- platform: template
  name: "PM2.5µm 1 Hour AQI"
  id: SDS011_PM25_1Hour_AQI
  unit_of_measurement: 'AQI'
  update_interval: 10min
  state_class: measurement
  icon: mdi:chemical-weapon
  accuracy_decimals: 1
  lambda: |-
    if ((id(PM251Hour).state) > 300.0)
    { return round((((500.0 - 301.0)/(500.4 - 250.5)) * ((id(PM251Hour).state) - 250.5) + 301.0));
    }
    else if ((id(PM251Hour).state) > 200.0 and (id(PM251Hour).state) <= 300.0)
    { return round((((300.0 - 201.0)/(250.4 - 150.5)) * ((id(PM251Hour).state) - 150.5) + 201.0));
    }
    else if ((id(PM251Hour).state) > 150.0 and (id(PM251Hour).state) <= 200.0)
    { return round((((200.0 - 151.0)/(150.4 - 55.5)) * ((id(PM251Hour).state) - 55.5) + 151.0));
    }
    else if ((id(PM251Hour).state) > 100.0 and (id(PM251Hour).state) <= 150.0)
    { return round((((150.0 - 101.0)/(55.4 - 35.5)) * ((id(PM251Hour).state) - 35.5) + 101.0));
    }
    else if ((id(PM251Hour).state) > 50.0 and (id(PM251Hour).state) <= 100.0)
    { return round((((100.0 - 51.0)/(35.4 - 12.1)) * ((id(PM251Hour).state) - 12.1) + 51.0));
    }
    else
    { return round((((50.0 - 0.0)/(12.0 - 0.0)) * ((id(PM251Hour).state) - 0.0) + 0.0));
    }

text_sensor:
- platform: template
  name: "PM2.5µm 1 Hour AQI Index"
  id: SDS011_PM25_1Hour_AQI_Index
  update_interval: 10min
  icon: mdi:chemical-weapon
  lambda: |-
    if ((id(SDS011_PM25_1Hour_AQI).state) > 300.0)
    { return {"Hazardous"};
    }
    else if ((id(SDS011_PM25_1Hour_AQI).state) > 200.0 and (id(SDS011_PM25_1Hour_AQI).state) <= 300.0)
    { return {"Very Unhealthy"};
    }
    else if ((id(SDS011_PM25_1Hour_AQI).state) > 150.0 and (id(SDS011_PM25_1Hour_AQI).state) <= 200.0)
    { return {"Unhealthy"};
    }
    else if ((id(SDS011_PM25_1Hour_AQI).state) > 100.0 and (id(SDS011_PM25_1Hour_AQI).state) <= 150.0)
    { return {"Unhealthy for Sensitive Groups"};
    }
    else if ((id(SDS011_PM25_1Hour_AQI).state) > 50.0 and (id(SDS011_PM25_1Hour_AQI).state) <= 100.0)
    { return {"Moderate"};
    }
    else
    { return {"Good"};
    }

- platform: template
  name: "PM2.5µm 24 Hour AQI Index"
  id: SDS011_PM25_24Hour_AQI_Index
  update_interval: 10min
  icon: mdi:chemical-weapon
  lambda: |-
    if ((id(SDS011_PM25_AQI).state) > 300.0)
    { return {"Hazardous"};
    }
    else if ((id(SDS011_PM25_AQI).state) > 200.0 and (id(SDS011_PM25_AQI).state) <= 300.0)
    { return {"Very Unhealthy"};
    }
    else if ((id(SDS011_PM25_AQI).state) > 150.0 and (id(SDS011_PM25_AQI).state) <= 200.0)
    { return {"Unhealthy"};
    }
    else if ((id(SDS011_PM25_AQI).state) > 100.0 and (id(SDS011_PM25_AQI).state) <= 150.0)
    { return {"Unhealthy for Sensitive Groups"};
    }
    else if ((id(SDS011_PM25_AQI).state) > 50.0 and (id(SDS011_PM25_AQI).state) <= 100.0)
    { return {"Moderate"};
    }
    else
    { return {"Good"};
    }

- platform: template
  name: "PM10.0µm 1 Hour AQI Index"
  id: SDS011_PM100_1Hour_AQI_Index
  update_interval: 60min
  icon: mdi:chemical-weapon
  lambda: |-
    if ((id(SDS011_PM100_1Hour_AQI).state) > 300.0)
    { return {"Hazardous"};
    }
    else if ((id(SDS011_PM100_1Hour_AQI).state) > 200.0 and (id(SDS011_PM100_1Hour_AQI).state) <= 300.0)
    { return {"Very Unhealthy"};
    }
    else if ((id(SDS011_PM100_1Hour_AQI).state) > 150.0 and (id(SDS011_PM100_1Hour_AQI).state) <= 200.0)
    { return {"Unhealthy"};
    }
    else if ((id(SDS011_PM100_1Hour_AQI).state) > 100.0 and (id(SDS011_PM100_1Hour_AQI).state) <= 150.0)
    { return {"Unhealthy for Sensitive Groups"};
    }
    else if ((id(SDS011_PM100_1Hour_AQI).state) > 50.0 and (id(SDS011_PM100_1Hour_AQI).state) <= 100.0)
    { return {"Moderate"};
    }
    else
    { return {"Good"};
    }

- platform: template
  name: "PM10.0µm 24 Hour AQI Index"
  id: SDS011_PM100_24Hour_AQI_Index
  update_interval: 60min
  icon: mdi:chemical-weapon
  lambda: |-
    if ((id(SDS011_PM100_AQI).state) > 300.0)
    { return {"Hazardous"};
    }
    else if ((id(SDS011_PM100_AQI).state) > 200.0 and (id(SDS011_PM100_AQI).state) <= 300.0)
    { return {"Very Unhealthy"};
    }
    else if ((id(SDS011_PM100_AQI).state) > 150.0 and (id(SDS011_PM100_AQI).state) <= 200.0)
    { return {"Unhealthy"};
    }
    else if ((id(SDS011_PM100_AQI).state) > 100.0 and (id(SDS011_PM100_AQI).state) <= 150.0)
    { return {"Unhealthy for Sensitive Groups"};
    }
    else if ((id(SDS011_PM100_AQI).state) > 50.0 and (id(SDS011_PM100_AQI).state) <= 100.0)
    { return {"Moderate"};
    }
    else
    { return {"Good"};
    }

- platform: wifi_info
  ip_address:
    name: NodeMCU IP Address
  ssid:
    name: NodeMCU Connected SSID
  bssid:
    name: NodeMCU Connected BSSID
  mac_address:
    name: NodeMCU Mac Wifi Address

font:
  - file: "fonts/Calibri Regular.ttf"
    id: calibri_16
    size: 16

display:
  - platform: ssd1306_i2c
    model: "SH1106 128x64"
    address: 0x3C
    brightness: 20%
    external_vcc: true
    update_interval: 5s
    lambda: |-
      it.printf(1, 1, id(calibri_16), "Temp: %.1f°", ((id(temperatureC).state * 1.8) + 32.0));
      it.printf(1,16, id(calibri_16), "Humidity: %.1f%%", id(humidity).state);
      it.printf(1,32, id(calibri_16), "PM 2.5: %.1f", id(PM25).state);
      it.printf(1,48, id(calibri_16), "PM 10.0: %.1f", id(PM100).state);

Any ideas as to why?
Thanks

1 Like

Hi.

I have no experience with the sds011, but according to documentation. The update_interval is sent to the sensor by the uart. The sensor can work in only rx mode.

So maybe it fails to set the update_intervall by the tx pin.
The things that you could check is the connection to the sensor.
Loose cable, wrong pin/GPIO on the tx.
I could also be a bug or faulty sensor but that is harder to check.
I hope you find it.

/Mattias

1 Like

thanks! I had exactly this issue. Turned out that my RX connection on the sensor side was loose. After fixing it and re-installing firmware (first with update_interval: 0min and subsequently again with update_interval 10min) it worked.