Dropdown helper as display page selector: unreliable. What am I missing?

Hey everyone,

in order to make the 3 pages of my e-ink display manually and automated triggerable from within HA, I created a dropdown helper with the values page1, page2 and page3. That helper is “imported” to my esphome node via a HA textsensor, and is then used to switch between the pages.

Problem: that only works very unreliably. Most of the times I switch between pages via the dropdown, esphome node actually registers the changed value, triggers a display redraw, BUT: the page doesn’t actually change on the physical display.

Setup within HA for manual switching within the dashboard:
helper

Automation linked to a Tradfri button:

Example log output from esphome (the red changes redraw the display without changing the page, the green one works as expected and shows page2 on the physical display. The number of back and forth needed to get a successful change is random, no pattern recognizable so far):

The yaml of the node:

esphome:
  name: epaper

esp32:
  board: esp32doit-devkit-v1
  framework:
    type: arduino

# Enable logging
logger:

json:

# Enable Home Assistant API
api:
  password: ""

ota:
  password: ""

wifi:
  ssid: "XXXXXXX"
  password: "XXXXXXXX"

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

captive_portal:


font:
  - file: 'arial.ttf'
    id: font1
    size: 24
  - file: 'arial.ttf'
    id: font2
    size: 30

image:
  - file: "otter.bmp"
    id: otter_image
    resize: 296x128
  - file: "otterbitmap2.bmp"
    id: otter_icon
  - file: "otter_complete.bmp"
    id: otter_complete

time:
  - platform: homeassistant
    id: esptime
    

sensor:
  - platform: homeassistant
    id: outside_temperature
    entity_id: weather.home
    internal: true
    attribute: temperature

text_sensor:
  - platform: homeassistant
    id: outside_weather
    entity_id: weather.home
    internal: true
  - platform: homeassistant
    id: owm_forecast
    entity_id: weather.openweathermap
    internal: true
    attribute: forecast
  - platform: homeassistant
    id: pages
    entity_id: input_select.epaper_page
    on_value:
      then:
        - display.page.show: !lambda |-
            if (id(pages).state == "page1") {
              return page1;
            }
            else if (id(pages).state == "page2") {
              return page2;
            }
            else {
              return page3;
            }
        - component.update: eink
    internal: true

spi:
  clk_pin: 19
  mosi_pin: 18

display:
  - platform: waveshare_epaper
    cs_pin: 21
    dc_pin: 3
    busy_pin: 22
    reset_pin: 1
    model: 2.90inv2
    rotation: 90°
    update_interval: 1800s
    full_update_every: 1
    #reset_duration: 2ms
    id: eink
    
    pages:
      - id: page1
        lambda: |-
          it.image(0, 0, id(otter_complete));
          it.printf(80, 0, id(font1), "Hey, it is");
          if (id(outside_temperature).has_state()) {
          it.printf(80, 20, id(font2), "%.1f", id(outside_temperature).state);
          }
          it.printf(80, 50, id(font1), "degrees outside");
          it.printf(80, 70, id(font1), "and it is");
          if (id(outside_weather).has_state()) {
          it.printf(80, 90, id(font2), "%s", id(outside_weather).state.c_str());
          }
      - id: page2
        lambda: |-
          it.printf(0, 0, id(font1), "page2");
          if (id(owm_forecast).has_state())
          {
          DynamicJsonDocument doc(2048);
          deserializeJson(doc, (id(owm_forecast).state.c_str()));
          JsonArray root = doc.as<JsonArray>();
          JsonObject root_0 = root[0];
          float root_0_precipitation = root_0["precipitation"];
          it.printf(0,20, id(font1), "%.0f mm", root_0_precipitation);
          }
      - id: page3
        lambda: |-
          it.printf(0, 0, id(font1), "page3");

The whole compiling and flashing (via esphome commandline on windows10) goes through without a single warning or anything. Am I missing something here? Or is there a different approach (than the dropdown helper) to address esphome display pages from within HA that works both for manual dashboard changes AND automations?

Thanks a lot in advance!

For a moment I thought I had it :-/

But adding the id(…) part around the page1 etc entries didn’t make a difference:

  - platform: homeassistant
    id: pages
    entity_id: input_select.epaper_page
    on_value:
      then:
        - display.page.show: !lambda |-
            if (id(pages).state == "page1") {
              return id(page1);
            }
            else if (id(pages).state == "page2") {
              return id(page2);
            }
            else {
              return id(page3);
            }
        - component.update: eink
    internal: true

Or are automations not executed 100% strictly step by step? I’m now wondering if the redraw happens before the “return id…” part is fully finished.

Okay, damn, I got it. The redraw indeed happens too early, while there is still something going on with the page switch. Adding a delay of 3 seconds fixed it:

  - platform: homeassistant
    id: pageshelper
    entity_id: input_select.epaper_page
    on_value:
      then:
        - display.page.show: !lambda |-
            if (id(pageshelper).state == "page1") {
              return id(page1);
            }
            else if (id(pageshelper).state == "page2") {
              return id(page2);
            }
            else {
              return id(page3);
            }
        - delay: 3s
        - component.update: eink
    internal: true

Playing around a bit more it seems to be related to how much is “going on” on each page.