Hey guys. Thought it best to start my own thread instead of junking up the other one that I’ve been inspired from. I am new to all this and as such keep coming up against new challenges.
I’ve been inspired by this thread here Use ESPHome with e-ink Displays to blend in with your home decor!
So far I’ve got HA running on a VM within Ubuntu (Linux). I’ve set up Studio Code Server to edit my YAMLs via VS Code from my Windows machine. ESPHome was set up on my Windows machine via ESPHome Web to flash the basic WiFi config in order to then add ESPHome from the Add-on store and added my ESP32 device from there… This has taken a while to get to this point having initially set up on my Synology NAS and using docker but discovering not having the add-on store so going through a tonne of troubleshooting to get to where I am now (!)
Anyway, enough of the history and onto where I’m at now…
This is my framed waveshare eink display of which I have some fake data (aside from the date and current temperature which is being displayed in the temperature ‘High’ area currently)
Kind of got the gist of things having brought in the temperature attribute by way of:
sensor:
- platform: homeassistant
entity_id: weather.forecast_home
attribute: temperature
id: temperature
display:
lambda: |-
it.printf(348, 335, id(font_large), TextAlign::TOP_CENTER, "%.0f°C", id(temperature).state);
Full code is:
esphome:
name: "frame"
on_boot:
priority: 200.0
then:
- wait_until:
condition:
lambda: 'return id(data_updated) == true;'
# Wait a bit longer so all the items are received
- component.update: eink_display
- delay: 5s
- logger.log: "Initial sensor data received: Refreshing display..."
- lambda: 'id(initial_data_received) = true;'
# - script.execute: update_screen
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
# 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'
- id: recorded_display_refresh
type: int
restore_value: yes
initial_value: '0'
script:
- id: update_screen
then:
- lambda: 'id(data_updated) = false;'
- component.update: eink_display
- lambda: 'id(recorded_display_refresh) += 1;'
# Wifi information
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: nada
password: nothinga
manual_ip:
# Set this to the IP of the ESP
static_ip: 192.168.1.48
# Set this to the IP address of the router. Often ends with .1
gateway: 192.168.1.1
# The subnet of the network. 255.255.255.0 works for most home networks.
subnet: 255.255.255.0
time:
- platform: homeassistant
id: homeassistant_time
timezone: Pacific/Auckland
on_time:
- seconds: 0
minutes: /1
then:
- if:
condition:
lambda: 'return id(data_updated) == true;'
then:
- logger.log: "Sensor data updated and activity in home detected: Refreshing display..."
- script.execute: update_screen
else:
- logger.log: "No sensors updated - skipping display refresh."
image:
- file: "images/panda.png"
id: panda
type: BINARY
# Include custom fonts
font:
- file: 'fonts/GothamRnd-Book.ttf'
id: font_small_book
size: 22
- file: 'fonts/GothamRnd-Book.ttf'
id: font_medium
size: 55
#glyphs: [' ', '-', '°', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C']
- file: 'fonts/GothamRnd-Bold.ttf'
id: font_title
size: 45
- file: 'fonts/GothamRnd-Book.ttf'
id: font_large
size: 70
# glyphs: [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '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: 22
# glyphs: [' ', '-', '°', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C', 'M', 'I', 'N']
- file:
type: gfonts
family: Caveat
weight: 700
id: caveat_bold
size: 45
# Include Material Design Icons font
# Thanks to https://community.home-assistant.io/t/display-materialdesign-icons-on-esphome-attached-to-screen/199790/16
- 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
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_mdi_medium
size: 60
glyphs: *mdi-weather-glyphs
sensor:
- platform: homeassistant
entity_id: weather.forecast_home
attribute: temperature
id: temperature
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Pins for Waveshare ePaper ESP Board
spi:
clk_pin: GPIO13
mosi_pin: GPIO14
# Now render everything on the ePaper screen.
display:
- platform: waveshare_epaper
id: eink_display
cs_pin: GPIO15
dc_pin: GPIO27
busy_pin: GPIO25
reset_pin: GPIO26
reset_duration: 2ms
model: 7.50inV2
update_interval: never
rotation: 90°
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"},
{"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"},
};
it.print(240, 80, id(font_medium_bold), TextAlign::TOP_CENTER, "Welcome");
it.print(240, 120, id(font_medium_bold), TextAlign::TOP_CENTER, "Catherine and Guests");
it.print(240, 180, id(font_medium), TextAlign::TOP_CENTER, "Hanmer Springs");
it.strftime(240, 245, id(font_title), TextAlign::TOP_CENTER, "%A %b %d", id(homeassistant_time).now());
if(id(temperature).has_state()) {
it.printf(132, 335, id(font_large), TextAlign::TOP_CENTER, "4°C");
}
it.print(130, 410, id(font_small_book), TextAlign::TOP_CENTER, "Low");
if(id(temperature).has_state()) {
it.printf(348, 335, id(font_large), TextAlign::TOP_CENTER, "%.0f°C", id(temperature).state);
}
it.print(350, 410, id(font_small_book), TextAlign::TOP_CENTER, "High");
it.print(75, 475, id(font_small_book), TextAlign::TOP_CENTER, "1pm");
it.print(185, 475, id(font_small_book), TextAlign::TOP_CENTER, "2pm");
it.print(295, 475, id(font_small_book), TextAlign::TOP_CENTER, "3pm");
it.print(405, 475, id(font_small_book), TextAlign::TOP_CENTER, "4pm");
it.printf(75, 505, id(font_mdi_medium), TextAlign::TOP_CENTER, "\U000F0595");
it.printf(185, 505, id(font_mdi_medium), TextAlign::TOP_CENTER, "\U000F0598");
it.printf(295, 505, id(font_mdi_medium), TextAlign::TOP_CENTER, "\U000F0599");
it.printf(405, 505, id(font_mdi_medium), TextAlign::TOP_CENTER, "\U000F0597");
it.print(75, 575, id(font_small_bold), TextAlign::TOP_CENTER, "9°C");
it.print(185, 575, id(font_small_bold), TextAlign::TOP_CENTER, "13°C");
it.print(295, 575, id(font_small_bold), TextAlign::TOP_CENTER, "15°C");
it.print(405, 575, id(font_small_bold), TextAlign::TOP_CENTER, "14°C");
it.filled_rectangle(0, 655, 480, 155);
it.print(240, 680, id(caveat_bold), COLOR_OFF, TextAlign::TOP_CENTER, "Cottage on Harrogate");
captive_portal:
But what I want to do is bring in the Forecast High and Low Temperature from my Accuweather integration. These are nested attributes which I can test in the template editor like so:
So I’d have assumed that this should be possible to be brought in a similar way that I have with current temperature. Yet for some reason this isnt possible using attribute: forecast[0].temperature
like you can with just attribute: temperature
sensor:
- platform: homeassistant
entity_id: weather.Accuweather_Home
attribute: forecast[0].temperature
id: temperature
Seems strange to me but hey ho. So it seems I need to use templates instead but for some reason I just can’t figure this part out. If anyone can just throw me up some code to copy from to make this work, then I’m sure I’ll have an ‘aha’ moment in understanding this as I know its likely very simple to implement. I think I’m just fogged up from all the troubleshooting I’ve had to do to get to this point.
Much appreciated.