Hi, I have an ESP32 board, CO2 Sensirion sensor scd4x and oled display ssd1306_i2c. Everything is closed in a IKEA Vindriktning box and because of this, the temperature sensor is probably overheating and showing wrong values . I wanted to solve this with deep_sleep. Unfortunately, the CO2 sensor gets the readings in 30s at the earliest. In between, the display shows zero values, although during deep_sleep it shows the last measurement.
Is there any way to disable the display update? I tried auto_clear_enabled: false, but ssd1306_i2c oled display has no member named auto_clear_enabled
My last tested setup is as follows (It may contain other errors)
Thank you
substitutions:
node_name: IKEA
GPIO_RGB_LED: GPIO25
I2C_SCL: GPIO22
I2C_SDA: GPIO21
SCD4x_update_interval: 60s
ADC_update_interval: 60s
aqi_co2_max_good: "800"
aqi_co2_max_acceptable: "1200"
aqi_pm2_5_avg_24h_max_good: "12"
aqi_pm2_5_avg_24h_max_acceptable: "25" # WHO 2006
aqi_message_bad: "Bad"
aqi_message_acceptable: "Acceptable"
aqi_message_good: "Good"
pm1006_pin_rx: GPIO16
pm1006_pin_tx: GPIO17
pm1006_update_interval: 5s
sensor_fan: GPIO12
globals:
- id: co2_value
type: double
restore_value: no
initial_value: '0'
- id: temp_value
type: double
restore_value: no
initial_value: '0'
- id: humi_value
type: double
restore_value: no
initial_value: '0'
- id: pm2_5_value
type: double
restore_value: no
initial_value: '0'
esphome:
name: ikea-semafor
#on_boot:
#priority: 600
#then:
#- lambda: id(oled_display).auto_clear_enabled('false');
esp32:
board: esp32dev
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
password: "8b73f0e42cc0038d8a5c1abecb2de6dd"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Ikea-Semafor Fallback Hotspot"
password: "jz9Dc4gerk7s"
captive_portal:
light:
- platform: fastled_clockless
chipset: WS2812B
pin: $GPIO_RGB_LED
num_leds: 3
restore_mode: ALWAYS_ON
#default_transition_length: 5s
rgb_order: GRB
name: "Signalizační RGB LED"
id: led_rgb
entity_category: diagnostic
script:
- id: evaluate_air_quality
then:
- deep_sleep.prevent: deep_sleep_1
- switch.turn_on: fan
- delay: 20s
- lambda: |-
id(pm2_5_value) = id(pm2_5_value_internal).state;
- switch.turn_off: fan
- if:
condition:
- lambda: 'return isnan(id(co2_value_internal).state);'
then:
- logger.log: "Waiting for CO2 sensor"
else:
- logger.log: "CO2 sensor is ready"
- lambda: |-
id(co2_value) = id(co2_value_internal).state;
id(temp_value) = id(temp_value_internal).state;
id(humi_value) = id(humi_value_internal).state;
- component.update: oled_display
- script.execute: update_aqi
- logger.log: "Go to deep sleep"
- deep_sleep.enter: deep_sleep_1
- id: update_aqi
mode: restart
then:
# Bad if at least one of the sensor values is bad
- if:
condition:
or:
- lambda: 'return (id(co2_value) > ${aqi_co2_max_acceptable});'
- sensor.in_range:
id: pm2_5_avg_24h
above: ${aqi_pm2_5_avg_24h_max_acceptable}
then:
- text_sensor.template.publish:
id: aqi
state: ${aqi_message_bad}
else:
# Acceptable if at least one of the sensor values is acceptable
- if:
condition:
or:
- lambda: 'return (id(co2_value) > ${aqi_co2_max_good});'
- sensor.in_range:
id: pm2_5_avg_24h
above: ${aqi_pm2_5_avg_24h_max_good}
then:
- text_sensor.template.publish:
id: aqi
state: ${aqi_message_acceptable}
else:
# Otherwise good (all of the sensor values are good)
- text_sensor.template.publish:
id: aqi
state: ${aqi_message_good}
switch:
- platform: gpio
pin: $sensor_fan
id: fan
name: "${node_name} ventilátor"
internal: true
icon: mdi:fan
entity_category: diagnostic
- platform: restart
name: "${node_name} restart"
i2c:
- id: bus_a
sda: $I2C_SDA
scl: $I2C_SCL
scan: True
uart:
rx_pin: ${pm1006_pin_rx}
tx_pin: ${pm1006_pin_tx}
baud_rate: 9600
sensor:
- platform: scd4x
i2c_id: bus_a
id: co2_sensor
address: 0x62
update_interval: ${SCD4x_update_interval}
automatic_self_calibration: true
co2:
name: "${node_name} CO₂"
id: co2_value_internal
internal: true
temperature:
name: "${node_name} teplota"
id: temp_value_internal
internal: true
humidity:
name: "${node_name} vlhkost"
id: humi_value_internal
- platform: pm1006
pm_2_5:
name: "${node_name} PM2.5"
id: pm2_5_value_internal
internal: true
update_interval: 20s
- platform: template
name: "${node_name} PM2.5 24h average"
id: pm2_5_avg_24h
icon: mdi:blur
unit_of_measurement: µg/m³
lambda: |-
return id(pm2_5_value_internal).state;
update_interval: 60s
filters:
- sliding_window_moving_average:
window_size: 1440 # = 24 hours x 60 minutes
send_every: 1
on_value:
then:
- script.execute: update_aqi
- platform: wifi_signal
name: "${node_name} WiFi Signal"
entity_category: diagnostic
disabled_by_default: true
# A textual presentation of the AQI: good, acceptable, bad
text_sensor:
- platform: template
name: "${node_name} Air Quality Index"
id: aqi
icon: mdi:air-filter
- platform: wifi_info
ip_address:
name: "${node_name} IP Address"
entity_category: diagnostic
disabled_by_default: true
ssid:
name: "${node_name} Connected SSID"
entity_category: diagnostic
disabled_by_default: true
bssid:
name: "${node_name} Connected BSSID"
entity_category: diagnostic
disabled_by_default: true
mac_address:
name: "${node_name} Mac Wifi Address"
entity_category: diagnostic
disabled_by_default: true
scan_results:
name: "${node_name} Latest Scan Result"
entity_category: diagnostic
disabled_by_default: true
font:
- file: 'fonts/arial.ttf'
id: font1
size: 14
glyphs:
- "1"
- "2"
- "3"
- "4"
- "5"
- "6"
- "7"
- "8"
- "9"
- "0"
- " "
- "nan"
- "µg/m³"
- "ppm"
- "°C"
- "%"
number:
- platform: template
name: "${node_name} intenzita jasu LED"
id: brightness
icon: "mdi:BrightnessPercent"
disabled_by_default: true
entity_category: config
min_value: 0
max_value: 100
step: 1
optimistic: true
on_value:
then:
- script.execute: update_aqi
- platform: template
name: "${node_name} kontrast displeje"
id: DISPLAY_contrast
icon: "mdi:contrast-circle"
disabled_by_default: true
entity_category: config
min_value: 0
max_value: 100
step: 1
optimistic: true
on_value:
then:
lambda: |-
if (id(DISPLAY_contrast).state) {
id(oled_display).set_contrast(x / 100);
} else {
id(oled_display).set_contrast(0.5);
}
interval:
- interval: 1min
then:
- script.execute: evaluate_air_quality
display:
- platform: ssd1306_i2c
id: oled_display
model: "SSD1306 128x32"
#address: 0x3C
auto_clear_enabled: false
lambda: |-
if(id(co2_value) > 0) {
ESP_LOGD("custom", "Aktualizace displeje");
it.printf(0, 0, id(font1), "%.0f ppm", id(co2_value));
it.printf(0, 16, id(font1), "%.0f µg/m³", id(pm2_5_value));
it.printf(126, 0, id(font1), TextAlign::TOP_RIGHT, "%.0f °C", id(temp_value));
it.printf(126, 16, id(font1), TextAlign::TOP_RIGHT, "%.0f %%", id(humi_value));
}
- platform: addressable_light
id: led_matrix_display
addressable_light_id: led_rgb
width: 1
height: 3
rotation: 180°
update_interval: 16ms
lambda: |-
Color red = Color(0xFF0000);
Color green = Color(0x00FF00);
Color yellow = Color(0xFFFF00);
if (id(aqi).state == "Bad") {
it.rectangle(0, 0, 1, 1, red);
} else if (id(aqi).state == "Acceptable") {
it.rectangle(0, 1, 1, 1, yellow);
} else if (id(aqi).state == "Good") {
it.rectangle(0, 2, 1, 1, green);
}
deep_sleep:
id: deep_sleep_1
run_duration: 2min
sleep_duration: 3min