Use ESPHome with e-ink Displays to blend in with your home decor!

And here is rest of my conf.

Sensors from templates.yaml

#================================
#=== ePaper display sensors
#================================
#template:
  # Bundle up all the data to send over to ePaper (ESPHome device).
  - trigger:
      platform: time_pattern
      minutes: "/1"
    sensor:
      - name: ePaper Data
        state: "OK"
        attributes:
          weather_condition_now: >
            {% set cond_now = states('sensor.weather_hourly') %}
            {% if states('sun.sun') == 'below_horizon' %}
                {% if cond_now == 'sunny' %} night {% elif cond_now == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond_now }} {% endif %}
            {% else %}
                {{ cond_now }}
            {% endif %}

          weather_condition_0: >
            {% set cond0 = state_attr('sensor.weather_hourly', 'forecast')[0].condition %}
            {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
            {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
            {% set cond0_time = as_timestamp(state_attr('sensor.weather_hourly', 'forecast')[0].datetime) %}
            {% if cond0_time < next_rising and next_rising < next_setting %}
                {% if cond0 == 'sunny' %} night {% elif cond0 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %}
            {% else %}
                {{ cond0 }}
            {% endif %}
          weather_temperature_0: >
            {{ state_attr('sensor.weather_hourly', 'forecast')[0].temperature | round }}
          weather_timestamp_0: >
            {{ as_timestamp(state_attr('sensor.weather_hourly', 'forecast')[0].datetime) | timestamp_custom('%H:%M') }}

          weather_condition_1: >
            {% set cond1 = state_attr('sensor.weather_hourly', 'forecast')[1].condition %}
            {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
            {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
            {% set cond1_time = as_timestamp(state_attr('sensor.weather_hourly', 'forecast')[1].datetime) %}
            {% if cond1_time < next_rising and next_rising < next_setting %}
                {% if cond1 == 'sunny' %} night {% elif cond1 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond1 }} {% endif %}
            {% else %}
                {{ cond1 }}
            {% endif %}
          weather_temperature_1: >
            {{ state_attr('sensor.weather_hourly', 'forecast')[1].temperature | round }}
          weather_timestamp_1: >
            {{ as_timestamp(state_attr('sensor.weather_hourly', 'forecast')[1].datetime) | timestamp_custom('%H:%M') }}

          weather_condition_2: >
            {% set cond2 = state_attr('sensor.weather_hourly', 'forecast')[2].condition %}
            {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
            {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
            {% set cond2_time = as_timestamp(state_attr('sensor.weather_hourly', 'forecast')[2].datetime) %}
            {% if cond2_time < next_rising and next_rising < next_setting %}
                {% if cond2 == 'sunny' %} night {% elif cond2 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond2 }} {% endif %}
            {% else %}
                {{ cond2 }}
            {% endif %}
          weather_temperature_2: >
            {{ state_attr('sensor.weather_hourly', 'forecast')[2].temperature | round }}
          weather_timestamp_2: >
            {{ as_timestamp(state_attr('sensor.weather_hourly', 'forecast')[2].datetime) | timestamp_custom('%H:%M') }}

          weather_condition_3: >
            {% set cond3 = state_attr('sensor.weather_hourly', 'forecast')[3].condition %}
            {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
            {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
            {% set cond3_time = as_timestamp(state_attr('sensor.weather_hourly', 'forecast')[3].datetime) %}
            {% if cond3_time < next_rising and next_rising < next_setting %}
                {% if cond3 == 'sunny' %} night {% elif cond3 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond3 }} {% endif %}
            {% else %}
                {{ cond3 }}
            {% endif %}
          weather_temperature_3: >
            {{ state_attr('sensor.weather_hourly', 'forecast')[3].temperature | round }}
          weather_timestamp_3: >
            {{ as_timestamp(state_attr('sensor.weather_hourly', 'forecast')[3].datetime) | timestamp_custom('%H:%M') }}
          weather_condition_4: >
            {% set cond4 = state_attr('sensor.weather_hourly', 'forecast')[4].condition %}
            {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
            {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
            {% set cond4_time = as_timestamp(state_attr('sensor.weather_hourly', 'forecast')[4].datetime) %}
            {% if cond4_time < next_rising and next_rising < next_setting %}
                {% if cond4 == 'sunny' %} night {% elif cond4 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond4 }} {% endif %}
            {% else %}
                {{ cond4 }}
            {% endif %}
          weather_temperature_4: >
            {{ state_attr('sensor.weather_hourly', 'forecast')[4].temperature | round }}
          weather_timestamp_4: >
            {{ as_timestamp(state_attr('sensor.weather_hourly', 'forecast')[4].datetime) | timestamp_custom('%H:%M') }}
          weather_temp_low: >
            {%set lowof = state_attr('sensor.weather_hourly','forecast') | selectattr('datetime','search', now().timestamp() | timestamp_custom('%Y-%m-%d')) |  map(attribute='temperature') | min %}{% if lowof is defined and lowof %}{{lowof}}{%endif%}
          weather_temp_high: >
            {%set highof = state_attr('sensor.weather_hourly','forecast') | selectattr('datetime','search', now().timestamp() | timestamp_custom('%Y-%m-%d')) |  map(attribute='temperature') | max %}{% if highof is defined and highof %}{{highof}}{%endif%}
          ulkolampotila: >
            {{ states('sensor.sensor_2_2_temperature') }}
          kosteus: >
            {{ states('sensor.lumi_lumi_weather_humidity') }}
          ilmanpaine: >
            {{ states('sensor.lumi_lumi_weather_pressure') }}
          tuuli: >
            {{ states('sensor.saa_tuulen_nopeus') }}
          tuuli_suunta: >
            {{ states('sensor.saa_tuulen_suunta') }}
          mh_lampotila: >
            {{ states('sensor.makuuhuone_lampotila') }}
          mh_kosteus: >
            {{ states('sensor.makuuhuone_kosteus') }}
          mh_valoisuus: >
            {{ states('sensor.makuuhuone_valoisuus') }}
          mh_pm25: >
            {{ states('sensor.makuuhuone_pm25') }}
          oh_lampotila: >
            {{ states('sensor.sensor_4_temperature') }}
          oh_kosteus: >
            {{ states('sensor.sensor_4_humidity') }}
          keittio_lampotila: >
            {{ states('sensor.keittio_zb_motion_temperature') }}
          keittio_valoisuus: >
            {{ states('sensor.keittio_zb_motion_illuminance') }}
          kph_lampotila: >
            {{ states('sensor.sensor_3_temperature') }}
          kph_kosteus: >
            {{ states('sensor.sensor_3_humidity') }}
          nordpool_current: >
            {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','today')[now().hour])) }}
          nordpool_min: >
            {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024',  'min')|float / 0.05) | round() * 0.05) }}
          nordpool_avg: >
            {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024',  'average')|float / 0.05) | round() * 0.05) }}
          nordpool_max: >
            {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024',  'max')|float / 0.05) | round() * 0.05) }}
          nordpool_1h: >
            {% if now().hour+1 >= 24 %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','tomorrow')[now().hour+1-24])) }}
            {% else %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','today')[now().hour+1])) }}
            {% endif %}
          nordpool_2h: >
            {% if now().hour+2 >= 24 %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','tomorrow')[now().hour+2-24])) }}
            {% else %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','today')[now().hour+2])) }}
            {% endif %}
          nordpool_3h: >
            {% if now().hour+3 >= 24 %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','tomorrow')[now().hour+3-24])) }}
            {% else %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','today')[now().hour+3])) }}
            {% endif %}
          nordpool_4h: >
            {% if now().hour+4 >= 24 %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','tomorrow')[now().hour+4-24])) }}
            {% else %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','today')[now().hour+4])) }}
            {% endif %}
          nordpool_5h: >
            {% if now().hour+5 >= 24 %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','tomorrow')[now().hour+5-24])) }}
            {% else %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','today')[now().hour+5])) }}
            {% endif %}
          nordpool_6h: >
            {% if now().hour+6 >= 24 %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','tomorrow')[now().hour+6-24])) }}
            {% else %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','today')[now().hour+6])) }}
            {% endif %}
          nordpool_7h: >
            {% if now().hour+7 >= 24 %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','tomorrow')[now().hour+7-24])) }}
            {% else %}
              {{ ((state_attr('sensor.nordpool_kwh_fi_eur_2_10_024','today')[now().hour+7])) }}
            {% endif %}
          nordpool_timestamp_1: >
            {{ (now()|as_timestamp + (60*60))|timestamp_custom("%H:00", True) }}
          nordpool_timestamp_2: >
            {{ (now()|as_timestamp + (60*120))|timestamp_custom("%H:00", True) }}
          nordpool_timestamp_3: >
            {{ (now()|as_timestamp + (60*180))|timestamp_custom("%H:00", True) }}
          nordpool_timestamp_4: >
            {{ (now()|as_timestamp + (60*240))|timestamp_custom("%H:00", True) }}
          nordpool_timestamp_5: >
            {{ (now()|as_timestamp + (60*320))|timestamp_custom("%H:00", True) }}
          nordpool_timestamp_6: >
            {{ (now()|as_timestamp + (60*360))|timestamp_custom("%H:00", True) }}
          nordpool_timestamp_7: >
            {{ (now()|as_timestamp + (60*420))|timestamp_custom("%H:00", True) }}
          total_hourly_energy: >
            {{ states('sensor.total_hourly_energy') }}
          total_daily_energy: >
            {{ states('sensor.total_energy_daily') }}
          nordpool_text: >
            {% set min_price = 10 |
              float %} {% set max_price = 20 | float %} {% set current_price =
              state_attr('sensor.nordpool_kwh_fi_eur_2_10_024', 'current_price') | float %}
            {% if current_price < min_price %}
              Sähkö on nyt halpaa, hinta on {{ states('sensor.nordpool_kwh_fi_eur_2_10_024', 'current_price') }} c/kWh
            {% elif current_price > min_price and current_price < max_price %} 
              Sähkö on nyt keskihintaista, hinta on {{ states('sensor.nordpool_kwh_fi_eur_2_10_024', 'current_price') }} c/kWh
            {% elif current_price > max_price %}
              Sähkö on nyt kallista, hinta on {{ states('sensor.nordpool_kwh_fi_eur_2_10_024', 'current_price') }} c/kWh
            {% endif %}

I update the display via automation twice an hour. At the second minute of every hour and when the weather forecast is updated. The weather forecast is updated at a random time approximately every hour, which is why it is updated when the latest information is available. In addition, someone has to be at home and awake for the display to be updated.

2 Likes

Hi All,
Ive been playing with this for the last few days, and i cant get this to work at all. I get a flashing noise screen about every second which alternates between black and white. I have tried using other people code straight as with no alterations… Just to see if i can get something on the screen… If i use Waveshare demo code that uploads a picture thats fine with no issues. so im going to guess there is something wrong with my pin set up

I have a Waveshare ESP32 and a 7.5 075bn-t7 V2 dispay screen, below is the output from the serial monitor

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13132
load:0x40080400,len:3036
entry 0x400805e4
[I][logger:158]: Log initialized
[C][ota:483]: There have been 2 suspected unsuccessful boot attempts.
[D][esp32.preferences:114]: Saving 1 preferences to flash...
[D][esp32.preferences:143]: Saving 1 preferences to flash: 0 cached, 1 written, 0 failed
[I][app:029]: Running through setup()...
[D][spi:039]: Setting up SPI bus...
[D][spi_device:379]: mode 0, data_rate 2000kHz
[C][wifi:038]: Setting up WiFi...
[C][wifi:051]: Starting WiFi...
[C][wifi:052]:   Local MAC: 94:B5:55:19:EA:40
[D][wifi:462]: Starting scan...
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[W][wifi:152]: Warning set: unspecified
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2451 ms).
[W][component:233]: Components should block for at most 30 ms.
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[D][wifi:477]: Found networks:
[I][wifi:521]: - 'TailWagNet' [redacted]▂▄▆█
[D][wifi:522]:     Channel: 1
[D][wifi:523]:     RSSI: -63 dB
[I][wifi:521]: - 'TailWagNet' [redacted]▂▄▆█
[D][wifi:522]:     Channel: 6
[D][wifi:523]:     RSSI: -71 dB
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[D][wifi:526]: - [redacted] [redacted]▂▄▆█
[I][wifi:303]: WiFi Connecting to 'TailWagNet'...
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2293 ms).
[W][component:233]: Components should block for at most 30 ms.
[I][wifi:594]: WiFi Connected!
[C][wifi:408]:   Local MAC: 94:B5:55:19:EA:40
[C][wifi:413]:   SSID: [redacted]
[C][wifi:416]:   IP Address: 192.168.1.163
[C][wifi:420]:   BSSID: [redacted]
[C][wifi:421]:   Hostname: 'e-paper-dashboard'
[C][wifi:423]:   Signal strength: -66 dB ▂▄▆█
[C][wifi:427]:   Channel: 1
[C][wifi:428]:   Subnet: 255.255.255.0
[C][wifi:429]:   Gateway: 192.168.1.1
[C][wifi:430]:   DNS1: 192.168.1.249
[C][wifi:431]:   DNS2: 0.0.0.0
[D][wifi:603]: Disabling AP...
[C][ota:096]: Over-The-Air Updates:
[C][ota:097]:   Address: e-paper-dashboard.local:3232
[C][ota:100]:   Using Password.
[C][ota:103]:   OTA version: 2.
[W][ota:107]: Last Boot was an unhandled reset, will proceed to safe mode in 8 restarts
[C][api:025]: Setting up Home Assistant API server...
[I][app:062]: setup() finished successfully!
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[W][wifi:165]: Warning cleared
[D][api:102]: Accepted 192.168.1.185
[W][component:232]: Component api took a long time for an operation (56 ms).
[W][component:233]: Components should block for at most 30 ms.
[I][app:102]: ESPHome version 2024.3.0 compiled on Mar 23 2024, 09:12:44
[C][wifi:580]: WiFi:
[C][wifi:408]:   Local MAC: 94:B5:55:19:EA:40
[C][wifi:413]:   SSID: [redacted]
[C][wifi:416]:   IP Address: 192.168.1.163
[C][wifi:420]:   BSSID: [redacted]
[C][wifi:421]:   Hostname: 'e-paper-dashboard'
[C][wifi:423]:   Signal strength: -65 dB ▂▄▆█
[C][wifi:427]:   Channel: 1
[C][wifi:428]:   Subnet: 255.255.255.0
[C][wifi:429]:   Gateway: 192.168.1.1
[C][wifi:430]:   DNS1: 192.168.1.249
[C][wifi:431]:   DNS2: 0.0.0.0
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2320 ms).
[W][component:233]: Components should block for at most 30 ms.
[C][logger:166]: Logger:
[C][logger:167]:   Level: DEBUG
[C][logger:169]:   Log Baud Rate: 115200
[C][logger:170]:   Hardware UART: UART0
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[D][api.connection:1159]: Home Assistant 2024.3.3 (192.168.1.185): Connected successfully
[C][spi:068]: SPI bus:
[C][spi:069]:   CLK Pin: GPIO13
[C][spi:070]:   SDI Pin: 
[C][spi:071]:   SDO Pin: GPIO14
[C][spi:076]:   Using HW SPI: SPI
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2426 ms).
[W][component:233]: Components should block for at most 30 ms.
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[C][waveshare_epaper:2033]: Waveshare E-Paper
[C][waveshare_epaper:2033]:   Rotations: 90 °
[C][waveshare_epaper:2033]:   Dimensions: 480px x 800px
[C][waveshare_epaper:2034]:   Model: 7.5in-bv2
[C][waveshare_epaper:2035]:   Reset Pin: GPIO26
[C][waveshare_epaper:2036]:   DC Pin: GPIO17
[C][waveshare_epaper:2037]:   Busy Pin: GPIO25
[C][waveshare_epaper:2038]:   Update Interval: 1.0s
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2419 ms).
[W][component:233]: Components should block for at most 30 ms.
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[C][captive_portal:088]: Captive Portal:
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2449 ms).
[W][component:233]: Components should block for at most 30 ms.
[C][mdns:115]: mDNS:
[C][mdns:116]:   Hostname: e-paper-dashboard
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[C][ota:096]: Over-The-Air Updates:
[C][ota:097]:   Address: e-paper-dashboard.local:3232
[C][ota:100]:   Using Password.
[C][ota:103]:   OTA version: 2.
[W][ota:107]: Last Boot was an unhandled reset, will proceed to safe mode in 8 restarts
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2432 ms).
[W][component:233]: Components should block for at most 30 ms.
[C][api:139]: API Server:
[C][api:140]:   Address: e-paper-dashboard.local:6053
[C][api:142]:   Using noise encryption: YES
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2455 ms).
[W][component:233]: Components should block for at most 30 ms.
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2455 ms).
[W][component:233]: Components should block for at most 30 ms.
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2455 ms).
[W][component:233]: Components should block for at most 30 ms.
[E][waveshare_epaper:159]: Timeout while displaying image!
[E][waveshare_epaper:159]: Timeout while displaying image!
[W][component:232]: Component display took a long time for an operation (2606 ms).
[W][component:233]: Components should block for at most 30 ms.
[E][waveshare_epaper:159]: Timeout while displaying image!

does anyone have any pointers, as already mentioned i know the screen works ok

Hi!

I updated to HA 2024.4 and got notified that I had to remove the “beat” part of “display_option” in the “time_date” platform.
Screenshot 2024-04-07 at 07.54.20

Now the weatherman data is not working, se log below. How to resolve?

Logger: homeassistant.helpers.sensor
Source: helpers/trigger_template_entity.py:209
First occurred: April 5, 2024 at 15:54:00 (2398 occurrences)
Last logged: 07:51:00

Error rendering state template for sensor.weatherman_data: UndefinedError: None has no element 0

Logger: homeassistant.helpers.template
Source: helpers/template.py:2558
First occurred: April 5, 2024 at 15:54:00 (2398 occurrences)
Last logged: 07:51:00

Template variable error: None has no element 0 when rendering ‘{% set cond0 = state_attr(‘weather.home’, ‘forecast’)[0].condition %} {% set next_setting = as_timestamp(state_attr(‘sun.sun’, ‘next_setting’)) %} {% set next_rising = as_timestamp(state_attr(‘sun.sun’, ‘next_rising’)) %} {% set cond0_time = as_timestamp(state_attr(‘weather.home’, ‘forecast’)[0].datetime) %} {% if cond0_time < next_rising and next_rising < next_setting %} {% if cond0 == ‘sunny’ %} night {% elif cond0 == ‘partlycloudy’ %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %} {% else %} {{ cond0 }} {% endif %}’

It´s a change in the weather integration “The previously deprecated forecast attribute of weather entities, has now been removed. Use the weather.get_forecasts service to get the forecast data instead.” There is no attributes anymore, this thread will give you some more information on how to use weather.get_forcasts

I haven’t found a way to call the weather.get_forcasts from ESPHome, don´t know if you can, so I have created a template sensor with all attributes

template:
  - trigger:
      - platform: time_pattern
        hours: /1
      - platform: homeassistant
        event: start
    action:
      - service: weather.get_forecasts
        data:
          type: hourly
        target:
          entity_id: weather.forecast_home
        response_variable: hourly
    sensor:
      - name: Weather Hourly
        state: "{{ states('weather.forecast_home') }}"
        attributes:
          temperature: "{{ state_attr('weather.forecast_home', 'temperature') }}"
          dew_point: "{{ state_attr('weather.forecast_home', 'dew_point') }}"
          temperature_unit: "{{ state_attr('weather.forecast_home', 'temperature_unit') }}"
          humidity: "{{ state_attr('weather.forecast_home', 'humidity') }}"
          cloud_coverage: "{{ state_attr('weather.forecast_home', 'cloud_coverage') }}"
          pressure: "{{ state_attr('weather.forecast_homee', 'pressure') }}"
          pressure_unit: "{{ state_attr('weather.forecast_home', 'pressure_unit') }}"
          wind_bearing: "{{ state_attr('weather.forecast_home', 'wind_bearing') }}"
          wind_speed: "{{ state_attr('weather.forecast_home', 'wind_speed') }}"
          wind_speed_unit: "{{ state_attr('weather.forecast_home', 'wind_speed_unit') }}"
          visibility_unit: "{{ state_attr('weather.forecast_home', 'visibility_unit') }}"
          precipitation_unit: "{{ state_attr('weather.forecast_home', 'precipitation_unit') }}"
          forecast: "{{ hourly['weather.forecast_home'].forecast }}"

If someone have a better way of doing this, please let me know :slight_smile:

@Stimo I get this error when I test in template editor: UndefinedError: ‘hourly’ is undefined. Same with Daily.
Did you ever get this problem?

In a previous post I posted my template. The top part shows how you can use the weather service directly, without first creating an extra template sensor in between like @Stimo suggested.
You can see how I changed the weather bits from the original Weatherman post in this example:

2 Likes

You can’t create that one in the template editor, you need to be able to get the respons_varible, so it needs to be inside an automation, script, or something similar. If you want to test it use it as a script and send it to notification or similar

1 Like

Thanks to @Edwin_D I managed to sort the sensor out without using an extra sensor, I have updated my GitHub with the complete code

1 Like

Hi! Are you able to provide input where things have changed in the code? I believe I have built my version on your code :slight_smile:

The changes are made in the sensor in Home Assistant that the ESP gets its data from, the sensor.weatherman_data. When attributes were removed from the Weather integration we needed to get those attributes using the service weather.get_forecasts instead. So that is now applied in the sensor.weatherman_data

So it´s first of all the trigger to that sensor,

  - trigger:
      platform: time_pattern
      minutes: "/1"
    action:
      - service: weather.get_forecasts
        data:
          type: hourly
        target:
          entity_id: weather.smhi_home
        response_variable: hourly

and then in the different templates for the attributes to get the response data provided from the weather integration

          weather_temperature_0: >
            {{  hourly["weather.smhi_home"].forecast[0].temperature | round }}

Let me know if there is anything special you are wondering

How did you get the model of “7.50in-bv2-rb” work?
When I attempt to configure it with that I get “Unknown value ‘7.50in-bv2-rb’, did you mean ‘7.50in-bv2’, ‘7.50in-bv3’, ‘7.50inv2’?.”

I want that red lol

Using twisterss custom version from this thread:

2 Likes

sorry for posting this massive file here but hopefully it helps other to figure out the new weather forecast WoW

---
trigger:
  platform: time_pattern
  minutes: "/4"
action:
  - service: weather.get_forecasts
    data:
      type: daily
    target:
      entity_id: weather.forecast_home
    response_variable: daily
sensor:
  - name: e-ink Display Data
    unique_id: e_ink_display_data
    icon: ios:display-2
    state: "OK"
    attributes:
      greeting: >
        {%- if now() > today_at('18:00') %}
          Good evening
        {%- elif now() > today_at('12:00') %}
          Good afternoon
        {%- elif now() > today_at('5:00') %}
          Good morning
        {%- else %}
          Good night
        {%- endif %}

      weather_condition_now: >
        {% set cond_now = states('weather.forecast_home') %}
        {% if states('sun.sun') == 'below_horizon' %}
            {% if cond_now == 'sunny' %} night {% elif cond_now == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond_now }} {% endif %}
        {% else %}
            {{ cond_now }}
        {% endif %}

      weather_condition_0: >
        {% set cond0 = daily["weather.forecast_home"].forecast[0].condition %}
        {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
        {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
        {% set cond0_time = as_timestamp(daily["weather.forecast_home"].forecast[0].datetime) %}
        {% if cond0_time > next_setting and cond0_time < next_rising %}
            {% if cond0 == 'sunny' %} night {% elif cond0 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %}
        {% else %}
            {{ cond0 }}
        {% endif %}
      weather_temperature_0: >
        {{  daily["weather.forecast_home"].forecast[0].temperature | round }}
        #{{ daily["weather.forecast_home"].forecast[0].temperature | round }}
      weather_timestamp_0: >
        {{ as_timestamp(daily["weather.forecast_home"].forecast[0].datetime) | timestamp_custom('%a') }}
      weather_condition_1: >
        {% set cond1 = daily["weather.forecast_home"].forecast[1].condition %}
        {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
        {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
        {% set cond1_time = as_timestamp(daily["weather.forecast_home"].forecast[1].datetime) %}
        {% if cond1_time > next_setting and cond1_time < next_rising %}
            {% if cond1 == 'sunny' %} night {% elif cond1 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond1 }} {% endif %}
        {% else %}
            {{ cond1 }}
        {% endif %}
      weather_temperature_1: >
        {{ daily["weather.forecast_home"].forecast[1].temperature | round }}
      weather_timestamp_1: >
        {{ as_timestamp(daily["weather.forecast_home"].forecast[1].datetime) | timestamp_custom('%a') }}
      weather_condition_2: >
        {% set cond2 = daily["weather.forecast_home"].forecast[2].condition %}
        {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
        {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
        {% set cond2_time = as_timestamp(daily["weather.forecast_home"].forecast[2].datetime) %}
        {% if cond2_time > next_setting and cond2_time < next_rising %}
            {% if cond2 == 'sunny' %} night {% elif cond2 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond2 }} {% endif %}
        {% else %}
            {{ cond2 }}
        {% endif %}
      weather_temperature_2: >
        {{ daily["weather.forecast_home"].forecast[2].temperature | round }}
      weather_timestamp_2: >
        {{ as_timestamp(daily["weather.forecast_home"].forecast[2].datetime) | timestamp_custom('%a') }}
      weather_condition_3: >
        {% set cond3 = daily["weather.forecast_home"].forecast[3].condition %}
        {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
        {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
        {% set cond3_time = as_timestamp(daily["weather.forecast_home"].forecast[3].datetime) %}
        {% if cond3_time > next_setting and cond3_time < next_rising %}
            {% if cond3 == 'sunny' %} night {% elif cond3 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond3 }} {% endif %}
        {% else %}
            {{ cond3 }}
        {% endif %}
      weather_temperature_3: >
        {{ daily["weather.forecast_home"].forecast[3].temperature | round }}
      weather_timestamp_3: >
        {{ as_timestamp(daily["weather.forecast_home"].forecast[3].datetime) | timestamp_custom('%a') }}
      afval_today: >
        {{ states('sensor.afvalinfo_thuis_trash_type_today') }}
      afval_tomorrow: >
        {{ states('sensor.afvalinfo_thuis_trash_type_tomorrow') }}
      travel_Best_time: >
        {{ state_attr('sensor.werk_best','duration') | round(2) }}
      travel_Best_name: >
        {{ state_attr('sensor.werk_best','friendly_name') }}
      travel_ASML_time: >
        {{ state_attr('sensor.werk_asml','duration') | round(2) }}
      travel_ASML_name: >
        {{ state_attr('sensor.werk_asml','friendly_name') }}
      travel_Euretco_time: >
        {{ state_attr('sensor.reistijd_hoeverlaken','duration') | round(2) }}
      travel_Euretco_name: >
        {{ state_attr('sensor.reistijd_hoeverlaken','friendly_name') }}
      sun_next_rising: >
        {{ state_attr('Sun.sun', 'next_rising') }}
      sun_next_setting: >
        {{ state_attr('Sun.sun', 'next_setting') }}
      moon_phase_icon: >
        {{ state_attr('sensor.moon_phase', 'icon') }}

      media_playing_status: >
        {{ states('media_player.keuken') }}
      media_playing_title: >
        {{ state_attr('media_player.keuken', 'media_title') | title }}
      media_playing_artist: >
        {{ state_attr('media_player.keuken', 'media_artist') | title }} (on {{ state_attr('media_player.office_sonos', 'media_channel') | title }})
2 Likes

I figure I’ll share mine too since I struggled to get my 2 different OpenWeatherMap APIs to work. This may provide some help to other folks who use daily and hourly forecasts together:

template:

  # Bundle up all the data to send over to e-ink ESPHome devices.
  # For the timestamps use: %H = 24hrs / %I = 12hrs
  # To add AM/PM add the following: {{ as_timestamp(state_attr('weather.openweathermap_hourly', 'forecast')[x].datetime) | timestamp_custom('%p') }}
  # original:             {{ as_timestamp(state_attr('weather.openweathermap_hourly', 'forecast')[6].datetime) | timestamp_custom('%I:00') }}
  - trigger:
      platform: time_pattern
      minutes: /1
    action:
      - service: weather.get_forecasts
        data:
          type: hourly
        target:
          entity_id:
            - weather.openweathermap_hourly
        response_variable: hourly
      - service: weather.get_forecasts
        data:
          type: daily
        target:
          entity_id:
            - weather.openweathermap
        response_variable: daily
    sensor:
      - name: Weather Data
        unique_id: weather_data
        state: "OK"
        attributes:
          greeting: >
            {%- if now() > today_at('18:00') %}
              Good evening
            {%- elif now() > today_at('12:00') %}
              Good afternoon
            {%- elif now() > today_at('5:00') %}
              Good morning
            {%- else %}
              Good night
            {%- endif %}

          # Current temperature + condition
          weather_now_temperature: >
            {{ hourly["weather.openweathermap_hourly"].forecast[0].temperature | round }}
          weather_now_condition: >
            {% set cond_now = hourly["weather.openweathermap_hourly"].forecast[0].condition %}
            {% if states('sun.sun') == 'below_horizon' %}
                {% if cond_now == 'sunny' %} night {% elif cond_now == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond_now }} {% endif %}
            {% else %}
                {{ cond_now }}
            {% endif %}

          # Hourly temperature + condition + timestamp (4x)
          weather_hourly_condition_0: >
            {% set cond0 = hourly["weather.openweathermap_hourly"].forecast[2].condition %}
            {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
            {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
            {% set cond0_time = as_timestamp(hourly["weather.openweathermap_hourly"].forecast[2].datetime) %}
            {% if cond0_time > next_setting and cond0_time < next_rising %}
                {% if cond0 == 'sunny' %} night {% elif cond0 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %}
            {% else %}
                {{ cond0 }}
            {% endif %}
          weather_hourly_temperature_0: >
            {{ hourly["weather.openweathermap_hourly"].forecast[2].temperature | round }}
          weather_hourly_timestamp_0: >
            {% set timestamp = as_timestamp(hourly["weather.openweathermap_hourly"].forecast[2].datetime) | timestamp_custom('%I:00') %} {{ timestamp.lstrip("0") }}{{ as_timestamp(hourly["weather.openweathermap_hourly"].forecast[2].datetime) | timestamp_custom('%p') }}

          weather_hourly_condition_1: >
            {% set cond0 = hourly["weather.openweathermap_hourly"].forecast[4].condition %}
            {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
            {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
            {% set cond0_time = as_timestamp(hourly["weather.openweathermap_hourly"].forecast[4].datetime) %}
            {% if cond0_time > next_setting and cond0_time < next_rising %}
                {% if cond0 == 'sunny' %} night {% elif cond0 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %}
            {% else %}
                {{ cond0 }}
            {% endif %}
          weather_hourly_temperature_1: >
            {{ hourly["weather.openweathermap_hourly"].forecast[4].temperature | round }}
          weather_hourly_timestamp_1: >
            {% set timestamp = as_timestamp(hourly["weather.openweathermap_hourly"].forecast[4].datetime) | timestamp_custom('%I:00') %} {{ timestamp.lstrip("0") }}{{ as_timestamp(hourly["weather.openweathermap_hourly"].forecast[4].datetime) | timestamp_custom('%p') }}

          weather_hourly_condition_2: >
            {% set cond0 = hourly["weather.openweathermap_hourly"].forecast[6].condition %}
            {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
            {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
            {% set cond0_time = as_timestamp(hourly["weather.openweathermap_hourly"].forecast[6].datetime) %}
            {% if cond0_time > next_setting and cond0_time < next_rising %}
                {% if cond0 == 'sunny' %} night {% elif cond0 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %}
            {% else %}
                {{ cond0 }}
            {% endif %}
          weather_hourly_temperature_2: >
            {{ hourly["weather.openweathermap_hourly"].forecast[6].temperature | round }}
          weather_hourly_timestamp_2: >
            {% set timestamp = as_timestamp(hourly["weather.openweathermap_hourly"].forecast[6].datetime) | timestamp_custom('%I:00') %} {{ timestamp.lstrip("0") }}{{ as_timestamp(hourly["weather.openweathermap_hourly"].forecast[6].datetime) | timestamp_custom('%p') }}

          weather_hourly_condition_3: >
            {% set cond0 = hourly["weather.openweathermap_hourly"].forecast[8].condition %}
            {% set next_setting = as_timestamp(state_attr('sun.sun', 'next_setting')) %}
            {% set next_rising = as_timestamp(state_attr('sun.sun', 'next_rising')) %}
            {% set cond0_time = as_timestamp(hourly["weather.openweathermap_hourly"].forecast[8].datetime) %}
            {% if cond0_time > next_setting and cond0_time < next_rising %}
                {% if cond0 == 'sunny' %} night {% elif cond0 == 'partlycloudy' %} night-partly-cloudy {% else %} {{ cond0 }} {% endif %}
            {% else %}
                {{ cond0 }}
            {% endif %}
          weather_hourly_temperature_3: >
            {{ hourly["weather.openweathermap_hourly"].forecast[8].temperature | round }}
          weather_hourly_timestamp_3: >
            {% set timestamp = as_timestamp(hourly["weather.openweathermap_hourly"].forecast[8].datetime) | timestamp_custom('%I:00') %} {{ timestamp.lstrip("0") }}{{ as_timestamp(hourly["weather.openweathermap_hourly"].forecast[8].datetime) | timestamp_custom('%p') }}

          # Daily temperature + condition + day of week (3x)
          weather_daily_condition_0: >
            {{ daily["weather.openweathermap"].forecast[1].condition }}
          weather_daily_temperature_0: >
            {{ daily["weather.openweathermap"].forecast[1].temperature | round }}
          weather_daily_timestamp_0: >
            {{ as_timestamp(daily["weather.openweathermap"].forecast[1].datetime) | timestamp_custom('%a') }}
          weather_daily_condition_1: >
            {{ daily["weather.openweathermap"].forecast[2].condition }}
          weather_daily_temperature_1: >
            {{ daily["weather.openweathermap"].forecast[2].temperature | round }}
          weather_daily_timestamp_1: >
            {{ as_timestamp(daily["weather.openweathermap"].forecast[2].datetime) | timestamp_custom('%a') }}
          weather_daily_condition_2: >
            {{ daily["weather.openweathermap"].forecast[3].condition }}
          weather_daily_temperature_2: >
            {{ daily["weather.openweathermap"].forecast[3].temperature | round }}
          weather_daily_timestamp_2: >
            {{ as_timestamp(daily["weather.openweathermap"].forecast[3].datetime) | timestamp_custom('%a') }}
          weather_daily_condition_3: >
            {{ daily["weather.openweathermap"].forecast[4].condition }}
          weather_daily_temperature_3: >
            {{ daily["weather.openweathermap"].forecast[4].temperature | round }}
          weather_daily_timestamp_3: >
            {{ as_timestamp(daily["weather.openweathermap"].forecast[4].datetime) | timestamp_custom('%a') }}

2 Likes

can you share your code please :upside_down_face:

Do you mean my esphome YAML?

It’s not necessary anymore, I don’t know how but everything started to work :innocent:

Hi,
I just found this project and wanted to use it as a first start to have a room “door sign” where people can see, if/when the room is booked (I do know that this is not a room sign, but I hoped to get this running to see how such a door sign can be made, and as a side effekt to have this nice think hanging on my wall). I wanted to use e-Paper to save battery power. Basic idea is to hang such an epaper next to the room, and have another “glue software” in HA, that reads the room bookings from Microsoft 365 outlook calender, and sends it thru HA to the esp32 e-paper. On the longer run, a button next to the room should book the next15 free minutes of this room. I have the gutt feeling that HA is perfect for “glueing” all this together.

I got the waveshare 7 in e-Paper and the e-Paper ESP32 driver board.
I installed successfully esphome and the needed drivers, and run

esphome run weatherman.yaml

With the yaml and font and image files from github:

and generated a secrets.yaml with my credentials.

but only get the following error


INFO ESPHome 2024.4.2
INFO Reading configuration weatherman.yaml...
ERROR Error while reading config: Invalid YAML syntax:

mapping values are not allowed here
  in "secrets.yaml", line 2, column 7

Is here any kind soul, that could give me a pointer how to continue, as I strongly assume, that I am doing things totally wrong as I am new to esphome.

many thanks
Juergen

Does your secrets look like that?

# Your Wi-Fi SSID and password
wifi_ssid: "NAME123"
wifi_password: "123456789"

Hi @AFSC ,
for sure noit :slight_smile: Many thanks. But still there where errors from esphome with the original weathermal.yaml. I than took

and it compiled just fine.

But when it tries to upload the binary on my mac, I get

INFO Upload with baud rate 460800 failed. Trying again with baud rate 115200.
esptool.py v4.7.0

Loaded custom configuration from /Users/ry90/egeling.cloud/heubergweg-haus/homeAssistant/epaper/esptool.cfg

Serial port /dev/cu.usbmodem54E20349931

Connecting.....

Chip is ESP32-D0WDQ6 (revision v1.0)

Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None

Crystal is 40MHz

MAC: 94:b5:55:1c:8a:74

Uploading stub...

ERROR Running command failed: Failed to write to target RAM (result was 01070000: Operation timed out)

As far as I googled this seems to be an issue with the mac. But I got espsomfy first binary installed with

–connect-attempts 0

swith, but here I have no luck. Did anyone here install the first firmware on a mac? If so, how? In the esptool.cfg I changed some timings, but obvious with no luck.

thanks for any pointer. I googled a lot, but without success.

thanks
Juergen