ESPHome e-paper shows time but never temperature from HA sensor (SNZB-02WD via Z2M)

I want to show outdoor temperature from a Zigbee thermometer from HA on an ESP e-paper display. The thermometer works normally and I can see the entity values in the HA app. The value is numerical, not text (verified in developer tools)

What works:
display power/refresh, clock from HA time, periodic refresh.

What doesn’t work:
temperature never appears (fallback --.-°C). on_value never fires.

Hardware / Versions

  • Temp sensor: Sonoff SNZB-02WD via Zigbee2MQTT
  • Board: LaskaKit ESPink-Shelf-2.13 ESP32 e-Paper
  • ESPHome: 2025.10.3
  • HA ↔ ESPHome: Native API (encrypted), device added and online

Entity

  • Using: sensor.teplomer_venku_temperature
  • Verified in Developer Tools: pure numeric state (no unit in state string)

What I tried:

  • Top-level homeassistant: block is invalid (compilation error), so not using it.
  • Increased logging (VERY_VERBOSE) → no parsing errors, but on_value never logs, no updates from the HA regarding temperature
  • Time from HA works, so API link is fine.

I’ve spent quite a long time trying to troubleshoot this, maybe someone has some idea what to try next?

This is my config:

esphome:
  name: weather-display
  friendly_name: Weather Display

esp32:
  board: esp32dev
  framework:
    type: arduino

logger:
  baud_rate: 115200
  level: VERY_VERBOSE

api:
  encryption:
    key: "REDACTED"

ota:
  - platform: esphome
    password: "REDACTED"

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

sensor:
  - platform: homeassistant
    id: outdoor_temp
    entity_id: sensor.teplomer_venku_temperature
    internal: true
    on_value:
      - lambda: |-
          ESP_LOGI("ha", "Temp update: %.2f", id(outdoor_temp).state);
      - script.execute: epd_refresh   

font:
  - id: f_sm
    file: "gfonts://Roboto Mono"
    size: 18
  - id: f_lg
    file: "gfonts://Roboto"
    size: 28

spi:
  clk_pin: GPIO18
  mosi_pin: GPIO23

time:
  - platform: homeassistant
    id: now

display:
  - platform: waveshare_epaper
    id: epd
    cs_pin: GPIO5
    dc_pin: GPIO17
    busy_pin: GPIO4
    reset_pin: GPIO16
    model: 2.13in-ttgo-b74
    rotation: 90
    update_interval: never
    full_update_every: 10
    reset_duration: 2ms
    lambda: |-
      const int w = it.get_width(), h = it.get_height();
      it.fill(COLOR_OFF);
      it.rectangle(0, 0, w, h, COLOR_ON);
      it.printf(w/2, 10, id(f_sm), TextAlign::TOP_CENTER, "Outdoor");

      if (id(outdoor_temp).has_state()) {
        it.printf(w/2, h/2, id(f_lg), TextAlign::CENTER, "%.1f°C", id(outdoor_temp).state);
      } else {
        it.printf(w/2, h/2, id(f_lg), TextAlign::CENTER, "--.-°C");
      }

      auto t = id(now).now();
      if (t.is_valid()) it.strftime(w-2, h-2, id(f_sm), TextAlign::BOTTOM_RIGHT, "%H:%M", t);


switch:
  - platform: gpio
    pin: GPIO2
    id: epd_power
    internal: true
    restore_mode: ALWAYS_OFF

script:
  - id: epd_refresh
    mode: restart
    then:
      - switch.turn_on: epd_power
      - delay: 150ms         
      - component.update: epd
      - delay: 2000ms
      - switch.turn_off: epd_power

interval:
  - interval: 1min
    then:
      - homeassistant.service:
          service: homeassistant.update_entity
          data:
            entity_id: sensor.teplomer_venku_temperature
      - script.execute: epd_refresh

First of all remove this update action, now you are updating the sensor “upstream” in HA with the value available within your ESP. That makes no sense, because you only want to display the real value from HA.

Secondly, look at the logs form the ESP, you should see the setup of your outdoor_temp sensor and the initial value which is received

Also double check if you use the right sensor name from HA. I use a lot of HA sensors within my ESP’s and the only time if it’s not working I made a error in the sensor name. You could also test with another HA sensor.

If it’s still not working, please also post your logs.