Instant Update of Homeassistant Sensors in espHome

Hi Everybody,

i am using espHome to operate a eInk Status display of different values from my Homeassistant. When a value is updated in Homeassistant, it takes quite a long time until these values are updated on the ESP and the display is updated. For example:

  - platform: homeassistant
    entity_id: input_boolean.var_ei_timer_aktiv
    id: ei_aktiv
    internal: True
    on_state:
      then:
        - script.execute: update_screen

The state of this sensor should immidiately be available on my ESP device and shown on the screen. But it often takes more than 5-10 seconds or so.

Any ideas?

Thank you!

Jorin

Your log might help :slight_smile:

Hi! I do not understand. My question was how to make the updating of Homeassistant sensors in ESPHome faster (instantly). I am not sure how the checking of logs help. There, I can see that the sensor values are not instantly transmitted to/received by the ESPHome device…

What nickrout tries to tell you is that we don’t have a crystall ball. You are only posting a small part of your yaml, however the update of a screen is also depending on f.i. the update_interval you are using in the display statement but also what kind of sensors you are using and their update_interval. You are using a script, but we can’t see the content of that script, so how are we supposed to help you. See also How to help us help you - or How to ask a good question

Hi everybody,

alright, I did not think that the whole code would be relevant here as I recognized, that Homeassistant and ESPHome do not instantly sync updated variables. So when the state of my entity “input_boolean.var_ei_timer_aktiv” changes, this is not instantly updated in ESPHome, so the update_screen Script is not activated.
My question still is if there is a way to ensure that the update of the above mentioned variable can be instantly “pushed” to ESPHome.

Here is my full YAML:

# https://github.com/Madelena/esphome-weatherman-dashboard/tree/main


esphome:
  name: epaper2
  friendly_name: epaper2
  on_boot:
      priority: 200.0
      then:
        - component.update: my_display
        - wait_until:
            condition:
              lambda: 'return id(data_updated) == true;'
              # Wait a bit longer so all the items are received
        - delay: 5s
        - lambda: 'id(initial_data_received) = true;'
        - script.execute: update_screen


# Global variables for detecting if the display needs to be refreshed. (Thanks @paviro!)
globals:
  - id: data_updated
    type: bool
    restore_value: no
    initial_value: 'false'
  - id: initial_data_received
    type: bool
    restore_value: no
    initial_value: 'false'

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "XXX"

ota:
  password: "XXX"

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

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

    


text_sensor:

  - platform: homeassistant
    id: current_weather
    entity_id: sensor.current_weather
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  
  - platform: homeassistant
    entity_id: sensor.cond_0
    id: weather_condition_0
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.cond_1
    id: weather_condition_1
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.cond_2
    id: weather_condition_2
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.cond_3
    id: weather_condition_3
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.time_0
    id: weather_timestamp_0
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.time_1
    id: weather_timestamp_1
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.time_2
    id: weather_timestamp_2
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.time_3
    id: weather_timestamp_3
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  
  - platform: homeassistant
    entity_id: sensor.restmuell
    id: restmuell
    internal: true

  - platform: homeassistant
    entity_id: sensor.gelbersack
    id: gelbersack
    internal: true

  - platform: homeassistant
    entity_id: sensor.papiertonne
    id: papiertonne
    internal: true

  - platform: homeassistant
    entity_id: sensor.biotonne
    id: biotonne
    internal: true

binary_sensor:

  - platform: homeassistant
    entity_id: input_boolean.heizung_an
    id: heat
    internal: true
    on_state:
      then:
        - script.execute: update_screen

  - platform: homeassistant
    entity_id: input_boolean.kuche_eink_display_aktiv
    id: screen_on
    internal: True
    on_state:
      then:
        - script.execute: update_screen

  - platform: homeassistant
    entity_id: input_boolean.var_ei_timer_aktiv
    id: ei_aktiv
    internal: True
    on_state:
      then:
        - script.execute: update_screen




sensor:

  - platform: homeassistant
    id: obentemp
    entity_id: sensor.arbeitszimmer_thermostat_actual_temperature
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    id: untentemp
    entity_id: sensor.esszimmer_wandthermostat_actual_temperature
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    id: kindtemp
    entity_id: climate.kinderzimmer_thermostat
    attribute: current_temperature
    internal: True
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  
  #Wetterwerte
  - platform: homeassistant
    id: maxtemp
    entity_id: number.raspimatic_sv_aussentemperatur_max
    internal: True
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  
  - platform: homeassistant
    id: aussentemp
    entity_id: input_number.aussentemperatur
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.temp_0
    id: weather_temperature_0
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.temp_1
    id: weather_temperature_1
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.temp_2
    id: weather_temperature_2
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'

  - platform: homeassistant
    entity_id: sensor.temp_3
    id: weather_temperature_3
    internal: true
    on_value:
      then:
        - lambda: 'id(data_updated) = true;'
  
  - platform: homeassistant
    entity_id: input_number.var_ei_timer_count
    id: ei_count
    internal: True
    on_value:
      then:
        - script.execute: update_screen
  
 
  
 # - platform: rotary_encoder
 #   name: "Rotary Encoder"
 #   pin_a: 17
 #   pin_b: 5
 #   min_value: 1
 #   max_value: 2
 #   publish_initial_value: True
 #   id: rotary

 #   on_clockwise:
 #     - display.page.show_next: my_display
 #     - component.update: my_display
 #   on_anticlockwise:
 #     - display.page.show_previous: my_display
 #     - component.update: my_display

# switch:
#  - platform: gpio
#    pin:
#      number: 19
#      inverted: true
#    id: e_voltage

switch:
  - platform: restart
    name: "Küche eInk Restart"

# Script for updating screen - Refresh display 
script:
  - id: update_screen
    then:
      - lambda: 'id(data_updated) = false;'
      - component.update: my_display



time:
  - platform: homeassistant
    id: homeassistant_time
    on_time:
      - seconds: 0
        minutes: /15
        then:
          - if:
              condition:
                lambda: 'return id(data_updated) == true;'
              then:
                - if:
                    condition:
                      binary_sensor.is_on: screen_on
                    then:
                      - script.execute: update_screen


# Schnell benötigte Werte regelmäßig abrufen

#interval:
#  - interval: 1sec
#    then:
#     - component.update: ei_aktiv



# Include custom fonts
font:
  - file: 'fonts/GothamRnd-Book.ttf'
    id: font_small_book
    size: 18
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_large_bold
    size: 108
    glyphs: [' ', '-', '°', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C']
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_title
    size: 54
    glyphs: ['W', 'E', 'A', 'T', 'H', 'R', 'L', 'I', 'N', ' ']
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_medium_bold
    size: 30
    # glyphs: [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'M', 'I', 'N']
  - file: 'fonts/GothamRnd-Bold.ttf'
    id: font_small_bold
    size: 18
    # glyphs: [' ', '-', '°', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C', 'M', 'I', 'N']


  # Include Material Design Icons font
  # Thanks to https://community.home-assistant.io/t/display-materialdesign-icons-on-esphome-attached-to-screen/199790/16
  # Iconliste: https://pictogrammers.com/library/mdi/
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_mdi_large
    size: 96
    glyphs: &mdi-weather-glyphs
      - "\U000F0590" # mdi-weather-cloudy
      - "\U000F0F2F" # mdi-weather-cloudy-alert
      - "\U000F0E6E" # mdi-weather-cloudy-arrow-right
      - "\U000F0591" # mdi-weather-fog
      - "\U000F0592" # mdi-weather-hail
      - "\U000F0F30" # mdi-weather-hazy
      - "\U000F0898" # mdi-weather-hurricane
      - "\U000F0593" # mdi-weather-lightning
      - "\U000F067E" # mdi-weather-lightning-rainy
      - "\U000F0594" # mdi-weather-night
      - "\U000F0F31" # mdi-weather-night-partly-cloudy
      - "\U000F0595" # mdi-weather-partly-cloudy
      - "\U000F0F32" # mdi-weather-partly-lightning
      - "\U000F0F33" # mdi-weather-partly-rainy
      - "\U000F0F34" # mdi-weather-partly-snowy
      - "\U000F0F35" # mdi-weather-partly-snowy-rainy
      - "\U000F0596" # mdi-weather-pouring
      - "\U000F0597" # mdi-weather-rainy
      - "\U000F0598" # mdi-weather-snowy
      - "\U000F0F36" # mdi-weather-snowy-heavy
      - "\U000F067F" # mdi-weather-snowy-rainy
      - "\U000F0599" # mdi-weather-sunny
      - "\U000F0F37" # mdi-weather-sunny-alert
      - "\U000F14E4" # mdi-weather-sunny-off
      - "\U000F059A" # mdi-weather-sunset
      - "\U000F059B" # mdi-weather-sunset-down
      - "\U000F059C" # mdi-weather-sunset-up
      - "\U000F0F38" # mdi-weather-tornado
      - "\U000F059D" # mdi-weather-windy
      - "\U000F059E" # mdi-weather-windy-variant
      - "\U000F0438" # Heizung
      - "\U000F1AE1" # Timer play
      - "\U000F1AD0" # Timer finished
 
  - file: 'fonts/materialdesignicons-webfont.ttf'
    id: font_mdi_medium
    size: 36
    glyphs: *mdi-weather-glyphs

  - file: 'fonts/Antenna-Bold.ttf'
    id: font1
    size: 36
    
  - file: 'fonts/Antenna-Bold.ttf'
    id: font2
    size: 24

  - file: 'fonts/Antenna-Bold.ttf'
    id: font3
    size: 48

spi:
  clk_pin: GPIO13
  mosi_pin: GPIO14

color:
  - id: color_bg
    red: 0%
    green: 0%
    blue: 0%
    white: 100%
  - id: color_text
    red: 100%
    green: 100%
    blue: 100%
    white: 0%

display:
  - platform: waveshare_epaper
    cs_pin: GPIO15
    dc_pin: GPIO27
    busy_pin: GPIO25
    reset_pin: GPIO26
    model: 7.50inv2
    update_interval: never
    reset_duration: 2ms
    id: my_display
    rotation: 90
    pages:
      - id: page1
        lambda: |-
          // Map weather states to MDI characters.
          std::map<std::string, std::string> weather_icon_map
            {
              {"cloudy", "\U000F0590"},
              {"cloudy-alert", "\U000F0F2F"},
              {"cloudy-arrow-right", "\U000F0E6E"},
              {"fog", "\U000F0591"},
              {"hail", "\U000F0592"},
              {"hazy", "\U000F0F30"},
              {"hurricane", "\U000F0898"},
              {"lightning", "\U000F0593"},
              {"lightning-rainy", "\U000F067E"},
              {"night", "\U000F0594"},
              {"clear-night", "\U000F0594"},
              {"night-partly-cloudy", "\U000F0F31"},
              {"partlycloudy", "\U000F0595"},
              {"partly-lightning", "\U000F0F32"},
              {"partly-rainy", "\U000F0F33"},
              {"partly-snowy", "\U000F0F34"},
              {"partly-snowy-rainy", "\U000F0F35"},
              {"pouring", "\U000F0596"},
              {"rainy", "\U000F0597"},
              {"snowy", "\U000F0598"},
              {"snowy-heavy", "\U000F0F36"},
              {"snowy-rainy", "\U000F067F"},
              {"sunny", "\U000F0599"},
              {"sunny-alert", "\U000F0F37"},
              {"sunny-off", "\U000F14E4"},
              {"sunset", "\U000F059A"},
              {"sunset-down", "\U000F059B"},
              {"sunset-up", "\U000F059C"},
              {"tornado", "\U000F0F38"},
              {"windy", "\U000F059D"},
              {"windy-variant", "\U000F059E"},
              {"radiator", "\U000F0438"},
              {"timer-run", "\U000F1AE1"},
              {"timer-finish", "\U000F1AD0"}
            };

          int breite = it.get_width();
          int hoehe = it.get_height();

          int muellzahl = 0;
          int muellmorgen = 0;

          //Schauen, wie viele Mülltonnen heute geleert werden

          if (id(restmuell).state == "Heute") {muellzahl = muellzahl + 1;
          } else {}
          if (id(gelbersack).state == "Heute") {muellzahl = muellzahl + 1;
          } else {}
          if (id(papiertonne).state == "Heute") {muellzahl = muellzahl + 1;
          } else {}
          if (id(biotonne).state == "Heute") {muellzahl = muellzahl + 1;
          } else {}

          //Schauen, wie viele Mülltonnen morgen geleert werden

          if (id(restmuell).state == "Morgen") {muellmorgen = muellmorgen + 1;
          } else {}
          if (id(gelbersack).state == "Morgen") {muellmorgen = muellmorgen + 1;
          } else {}
          if (id(papiertonne).state == "Morgen") {muellmorgen = muellmorgen + 1;
          } else {}
          if (id(biotonne).state == "Morgen") {muellmorgen = muellmorgen + 1;
          } else {}


          





          
          // Show loading screen before data is received and Sleeping Screen
          if (id(initial_data_received) == false) {
          it.printf(240, 390, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "WAITING FOR DATA...");
          } else if (id(screen_on).state == false) {
          it.printf(240, 390, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "ZZZZ...");
          } else {
          
          // Weather Section
          
          it.printf(240, 84, id(font_title), color_text, TextAlign::TOP_CENTER, "WETTER");
          
          it.printf(100, 158, id(font_mdi_large), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(current_weather).state.c_str()].c_str());

          it.printf(300, 158, id(font_large_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(aussentemp).state);

          it.printf(240, 265, id(font_medium_bold), color_text, TextAlign::TOP_CENTER, "Max: %2.0f°C", id(maxtemp).state);

          it.printf(105, 310, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_0).state.c_str());
          it.printf(105, 334, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
          it.printf(105, 382, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);


          it.printf(195, 310, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_1).state.c_str());
          it.printf(195, 334, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
          it.printf(195, 382, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_1).state);

          it.printf(285, 310, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_2).state.c_str());
          it.printf(285, 334, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
          it.printf(285, 382, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_2).state);

          it.printf(375, 310, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_3).state.c_str());
          it.printf(375, 334, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
          it.printf(375, 382, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_3).state);

          
          // Innentemperaturen
          it.printf(240, 430, id(font_medium_bold), color_text, TextAlign::TOP_CENTER, "INNEN");

          it.printf(150, 475, id(font_small_book), color_text, TextAlign::TOP_CENTER, "Unten");
          it.printf(150, 505, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(untentemp).state);

          it.printf(240, 475, id(font_small_book), color_text, TextAlign::TOP_CENTER, "Oben");
          it.printf(240, 505, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(obentemp).state);

          it.printf(330, 475, id(font_small_book), color_text, TextAlign::TOP_CENTER, "Marina");
          it.printf(330, 505, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(kindtemp).state);

          //Weitere Werte
          it.printf(240, 565, id(font_medium_bold), color_text, TextAlign::TOP_CENTER, "HOMEASSISTANT");

          //Heizung

          it.printf(105, 610, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map["radiator"].c_str());
          
          

          it.printf(105, 650, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%s", id(heat).state ? "An" : "Aus");


          // Trennlinie unten

          it.line(240, 605, 240, 690);
          
          //Mülltonnen von heute anzeigen

          //Aktuelle Stunde ziehen

          char hrs[17];
          time_t currTime2 = id(homeassistant_time).now().timestamp;
          int hour = strftime(hrs, sizeof(hrs), "%H", localtime(&currTime2));

          int muellpos = 637;



          if (muellzahl > 0) {
            it.printf(255, 615, id(font_small_book), color_text, TextAlign::TOP_LEFT, "Abfall heute:");
            if (id(restmuell).state == "Heute") {
              it.printf(255, muellpos, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "Rest");
              muellpos = muellpos + 20;
            } else {}
            if (id(gelbersack).state == "Heute") {
              it.printf(255, muellpos, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "Gelb");
              muellpos = muellpos + 20;
            } else {}
            if (id(papiertonne).state == "Heute") {
              it.printf(255, muellpos, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "Papier");
              muellpos = muellpos + 20;
            } else {}
            if (id(biotonne).state == "Heute") {
              it.printf(255, muellpos, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "Bio");
            } else {}
          } 
          else if (muellzahl == 0 && muellmorgen > 0) {
            it.printf(255, 615, id(font_small_book), color_text, TextAlign::TOP_LEFT, "Abfall morgen:");
            if (id(restmuell).state == "Morgen") {
              it.printf(255, muellpos, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "Rest");
              muellpos = muellpos + 20;
            } else {}
            if (id(gelbersack).state == "Morgen") {
              it.printf(255, muellpos, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "Gelb");
              muellpos = muellpos + 20;
            } else {}
            if (id(papiertonne).state == "Morgen") {
              it.printf(255, muellpos, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "Papier");
              muellpos = muellpos + 20;
            } else {}
            if (id(biotonne).state == "Morgen") {
              it.printf(255, muellpos, id(font_small_bold), color_text, TextAlign::TOP_LEFT, "Bio");
            } else {}
          }
          else if (muellzahl == 0 && muellmorgen == 0) {
            it.printf(255, 615, id(font_small_book), color_text, TextAlign::TOP_LEFT, "Heute kein Abfall");
          }
          else {}

          
          //Eier Timer Anzeige

          

          int timerposition = 40;

          for (int i = 1; i <= id(ei_count).state; i++) {
              
              it.printf(timerposition, 705, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map["timer-finish"].c_str());
              timerposition = timerposition + 30;
          }

          if (id(ei_aktiv).state == true){
            it.printf(timerposition, 705, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map["timer-run"].c_str());
          }
          

          // Refresh Timestamp, wenn Timer inaktiv
          // Code by EnsconcE from https://community.home-assistant.io/t/esphome-show-time/348903
          
          if (id(ei_count).state == 0 && id(ei_aktiv).state == false){
          char str[17];
          time_t currTime = id(homeassistant_time).now().timestamp;
          strftime(str, sizeof(str), "%H:%M", localtime(&currTime));
          it.printf(240, 710, id(font_small_book), color_text, TextAlign::TOP_CENTER, "AKTUALISIERT UM %s", str);
          }
          else {}
          }





captive_portal:

Hi,

mea culpa. Yesterday, I found out that the problem was a faulty configuration of the eInk Display that lead to slow execution of the program. Now it works just fine.

Best,

Jorin

@jeybey if you don’t mind, what was the faulty configuration you describe? I think I might have made the same mistake…

I was also searching for the answer “how long does it take for Home Assistant to get entities from an ESPHome device?” to find this thread.

Probably the entity in question is related to the number of refreshes made to the screen which is changed just before the device is sent to deepsleep mode, not giving enough time for the device to transmit the data to HA.

At first I thought my device was getting 2 refreshes at once but some careful analysis reveals that its just HA was getting the new number until the device woke again.

I would think the solution here is to put some delay of 10-15s before the device enters deepsleep. I’m testing it myself now so I can at least tell you that 5s is not enough.

PS. GitHub - trip5/ESPHome-eInk-Boards: Weather & Tasks Boards for ESPHome

The update is practically instant, certainly won’t take 5s unless something is configured wrong.

Thanks nickrout, I believe it should be near-instant but the eink refresh can take some time (5-27s) and blocks the rest of the ESPHome functions (the logs will show “Timeout while displaying image!” at least once).

I didn’t realize until now that the OP doesn’t include deepsleep, but nonetheless, I’m still pretty certain at this point the ESP can’t do anything else while the eink screen is refreshing.

Edit (how to fix): add something like update_interval: 15s to the sensor that isn’t being caught quickly enough by HA.

If the eink blocks then that would/could introduce problems. In general components shouldn’t block, but I don’t have detailed knowledge of how einks work.