I build such display as well, very good WAF . Unfortunately got a very grainy picture. After trying different modes i decided to buy an additional epaper + driver (from dutch store tinytronics.nl where it was even cheaper than aliexpress) to figure out that the esp32 driverboards from china had a weak 3v3 powersupply. Connected a different esp32 board to the epd driver board and now all is well now i have to make a second display somewhere else
Decided to completely redesign it, latest iteration below:
I added temperature & pressure trend, air transparency (visibility), UV Index, wind strength & wind direction, moon phase with moon rise and moon set, two conditional warning icons (frost, strong wind just beside Celsius). Lastly, the display now shows Wi-Fi connection strength for the esp32 and battery level of Aqara sensor located outside.
I was so hyped by this project that I ordered an e-paper display right away
After some french translation and changes of the original template, there is my finished build :
I added my plants water level, with a warning icon when the percentage is below 10%.
I also bought stuff online to build a DIY weather station, so I plan to add detailed weather data on a second page and use a zigbee button to switch between pages.
The two major issues that I encountered is that you can’t easily print multi-line text (I wanted to display news title from a custom RSS feed), and that in the display lambda function, you can’t iterate over a homeassistant sensor returning an array of values.
Overall it’s an awesome project, thank you for sharing it !
Hello theggz! This looks amazing and I’m glad you like it!
We found a major problem with e-ink screens. If you have the display using white on black instead of black on white, please reduce the refresh interval down to every few hours to preserve the screen quality.
Change the line
update_interval: 5min
to something like 3h
since the information displayed on your screen does not need to be updated so frequently.
That also looks nice! would you mind sharing the .yaml (including HA templates?)
Not a problem, the code might need some clean-up though, but it works. The only issue I have is that I cannot compile the yaml if I am using secrets. ESPHome returns error, just change whatever needs to be changed to suit your needs. Oh, you would need to edit “weatherman” config to swap entitity names with yours.
# WEATHERMAN DASHBOARD
# For Home Assistant and ESPHome
# Designed by Madelena Mak 2022 - https://mmak.es
# Cue "Blame it on the Weatherman" by B*Witched!
esphome:
name: "weatherman"
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
wifi:
ssid: "CHANGEME"
password: "CHANGEME"
reboot_timeout: 300s
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esphome-Web-901078"
password: "WHATEVER"
# Include time
time:
- platform: homeassistant
id: esptime
#Include sun
sun:
latitude: CHANGEME
longitude: CHANGEME
# 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_time
size: 90
glyphs: [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ':']
- file: 'fonts/GothamRnd-Book.ttf'
id: font_weekday
size: 30
- file: 'fonts/GothamRnd-Book.ttf'
id: font_day
size: 65
glyphs: [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
- file: 'fonts/GothamRnd-Bold.ttf'
id: font_month
size: 40
- file: 'fonts/GothamRnd-Bold.ttf'
id: font_medium_bold
size: 40
#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
- 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
- "\U000F058E" # mdi-water-percent
- "\U000F04C5" # mdi-spedometer
- "\U000F0F29" # mdi-snowflake-alert
- "\U000F15FA" # mdi-windsock
- "\U000F19B3" # mdi-arrow-down-thin
- "\U000F19B2" # mdi-arrow-up-thin
- "\U000F19B4" # mdi-arrow-top-right-thin
- "\U000F19B7" # mdi-arrow-bottom-right-thin
- "\U000F00A5" # mdi-binoculars
- "\U000F018C" # mdi-compass-outline
- "\U000F05A9" # mdi-wifi
- "\U000F0928" # mdi-wifi-strength-4
- "\U000F0925" # mdi-wifi-strength-3
- "\U000F0922" # mdi-wifi-strength-2
- "\U000F091F" # mdi-wifi-strength-1
- "\U000F092B" # mdi-wifi-strength-alert-outline
- "\U000F0079" # mdi-battery
- "\U000F0082" # mdi-battery-90
- "\U000F0081" # mdi-battery-80
- "\U000F0080" # mdi-battery-70
- "\U000F007F" # mdi-battery-60
- "\U000F007E" # mdi-battery-50
- "\U000F007D" # mdi-battery-40
- "\U000F007C" # mdi-battery-30
- "\U000F007B" # mdi-battery-20
- "\U000F007A" # mdi-battery-10
- "\U000F10CD" # mdi-battery-alert-variant-outline
- "\U000F0E03" # mdi-thermometer-chevron-up
- "\U000F0E02" # mdi-thermometer-chevron-down
- "\U000F1A09" # mdi-triangle-small-down
- "\U000F1A0A" # mdi-triangle-small-up
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_mdi_medlarge
size: 60
glyphs:
- "\U000F058E" # mdi-water-percent
- "\U000F04C5" # mdi-spedometer
- "\U000F0F29" # mdi-snowflake-alert
- "\U000F15FA" # mdi-windsock
- "\U000F0F61" # mdi-moon-first-quarter
- "\U000F0F62" # mdi-moon-full
- "\U000F0F63" # mdi-moon-last-quarter
- "\U000F0F64" # mdi-moon-new
- "\U000F0F65" # mdi-moon-waning-crescent
- "\U000F0F66" # mdi-moon-waning-gibbous
- "\U000F0F67" # mdi-moon-waxing-crescent
- "\U000F0F68" # mdi-moon-waxing-gibbous
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_mdi_medium
size: 36
glyphs: *mdi-weather-glyphs
# Include Custom Titles
image:
- file: "images/weatherman-title-weather.png"
id: title_weather
type: BINARY
# Call Weather sensors from HA
sensor:
# Temperature - My Weather station
- platform: homeassistant
entity_id: weather.my_weather_station
attribute: temperature
id: weather_temperature
# Humidity - My Weather station
- platform: homeassistant
entity_id: weather.my_weather_station
attribute: humidity
id: weather_humidity
# Air pressure - My Weather station
- platform: homeassistant
entity_id: weather.my_weather_station
attribute: pressure
id: weather_pressure
# Wind Bearing - from Yr.no (built-in HA weather privider)
- platform: homeassistant
entity_id: weather.home
attribute: wind_bearing
id: wind_bearing
# Battery % for Aqara sensor
- platform: homeassistant
entity_id: sensor.zigbeeweather_battery
id: battery_percent
# Battery Voltage for Aqara sensor
- platform: homeassistant
entity_id: sensor.zigbeeweather_battery
attribute: voltage
id: battery_voltage
# Weatherman entities
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_0
id: weather_temperature_0
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_1
id: weather_temperature_1
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_2
id: weather_temperature_2
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_3
id: weather_temperature_3
# Strong Wind
- platform: homeassistant
entity_id: sensor.wind_warning
id: wind_warning
# Wind Speed
- platform: homeassistant
entity_id: weather.my_weather_station
attribute: wind_speed
id: wind_speed
# UV Index
- platform: homeassistant
entity_id: sensor.dundonald_uv_index_3_hourly
id: uv_index
# WiFi Signal
- platform: wifi_signal
name: "WiFi Signal Sensor"
id: wifisignal
update_interval: 20s
text_sensor:
# Pressure Trend
- platform: homeassistant
entity_id: binary_sensor.atmospheric_pressure
id: pressure_trend
# Temp Trend
- platform: homeassistant
entity_id: binary_sensor.outside_temperature
id: temp_trend
# Weather State
- platform: homeassistant
entity_id: weather.my_weather_station
id: weather_state
# Frost Risk
- platform: homeassistant
entity_id: sensor.weather_frostrisk
id: frost_risk
# # Weatherman entities
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_now
id: weather_condition_now
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_0
id: weather_condition_0
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_0
id: weather_timestamp_0
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_1
id: weather_condition_1
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_1
id: weather_timestamp_1
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_2
id: weather_condition_2
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_2
id: weather_timestamp_2
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_3
id: weather_condition_3
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_3
id: weather_timestamp_3
# Sunrise
- platform: sun
type: sunrise
id: sun_sunrise
format: "%H:%M"
# Sunset
- platform: sun
type: sunset
id: sun_sunset
format: "%H:%M"
# Visibility range from Met Office
- platform: homeassistant
entity_id: sensor.dundonald_visibility_distance_daily
id: visibility_range
# Moon phase
- platform: homeassistant
entity_id: sensor.moon
id: moon_phase
- platform: homeassistant
entity_id: sensor.moon_rise
id: moon_rise
- platform: homeassistant
entity_id: sensor.moon_set
id: moon_set
# Define colors
# This design is white on black so this is necessary.
color:
- id: color_black
red: 0%
green: 0%
blue: 0%
white: 50%
- id: color_white
red: 0%
green: 0%
blue: 0%
white: 0%
# Pins for Waveshare ePaper ESP Board
spi:
clk_pin: GPIO13
mosi_pin: GPIO14
# Now render everything on the ePaper screen.
display:
- platform: waveshare_epaper
cs_pin: GPIO15
dc_pin: GPIO27
busy_pin: GPIO25
reset_pin: GPIO26
model: 7.50inV2
update_interval: 60s
rotation: 90°
auto_clear_enabled: false
lambda: |-
// Map weather states to MDI characters.
std::map<std::string, std::string> visibility_short
{
{"20-40", "30"},
{"20-30", "25"},
{"10-20", "15"},
};
std::map<std::string, std::string> moon_icon_map
{
{"first_quarter", "\U000F0F61"},
{"full_moon", "\U000F0F62"},
{"last_quarter", "\U000F0F63"},
{"new_moon", "\U000F0F64"},
{"waning_crescent", "\U000F0F65"},
{"waning_gibbous", "\U000F0F66"},
{"waning_crescent", "\U000F0F67"},
{"waxing_gibbous", "\U000F0F68"},
};
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"},
};
// Fill background in black.
it.fill(color_white);
// ----------------------------------------------------------------------------------- Print full weekday name
it.strftime(340, 95, id(font_weekday), TextAlign::TOP_RIGHT, "%A", id(esptime).now());
// ----------------------------------------------------------------------------------- Print time in HH:MM format 335
it.strftime(340, 200, id(font_time), TextAlign::BASELINE_RIGHT, "%H:%M", id(esptime).now());
// TEST it.printf(315, 200, id(font_time), TextAlign::BASELINE_RIGHT, "88:88");
// ----------------------------------------------------------------------------------- Print day of the month
it.strftime(440, 95, id(font_day), TextAlign::TOP_RIGHT, "%d", id(esptime).now());
// ----------------------------------------------------------------------------------- Print abbreviated month name
it.strftime(440, 200, id(font_month), TextAlign::BASELINE_RIGHT, "%b", id(esptime).now());
// TEST it.printf(440, 200, id(font_month), TextAlign::BASELINE_RIGHT, "AAA");
// ----------------------------------------------------------------------------------- WiFi
if(id(wifisignal).has_state ()) {
if (id(wifisignal).state >= -50) {
// Excellent # mdi-wifi-strength-4 "\U000F0928" 255, 230
it.printf(85, 487, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "\U000F0928");
} else if (id(wifisignal).state >= -60) {
//Good # mdi-wifi-strength-3 "\U000F0925"
it.printf(85, 487, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "\U000F0925");
} else if (id(wifisignal).state >= -67) {
//Fair # mdi-wifi-strength-2 "\U000F0922"
it.printf(85, 487, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "\U000F0922");
} else if (id(wifisignal).state >= -70) {
//Weak # mdi-wifi-strength-1 "\U000F091F"
it.printf(85, 487, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "\U000F091F");
} else {
//Unlikely working signal # mdi-wifi-strength-alert-outline "\U000F092B"
it.printf(85, 487, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "\U000F092B");
}
}
// ----------------------------------------------------------------------------------- LOW BATTERY
if(id(battery_voltage).has_state ()) {
if(id(battery_voltage).state <= 2700) {
// Replace battery, less than 10% 420, 558 / 87
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F10CD");
} else if (id(battery_percent).state == 100) {
// "\U000F0079" # mdi-battery
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F0079");
} else if (id(battery_percent).state >= 90) {
// "\U000F0082" # mdi-battery-90
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F0082");
} else if (id(battery_percent).state >= 80) {
// "\U000F0081" # mdi-battery-80
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F0081");
} else if (id(battery_percent).state >= 70) {
// "\U000F0080" # mdi-battery-70
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F0080");
} else if (id(battery_percent).state >= 60) {
// "\U000F007F" # mdi-battery-60
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007F");
} else if (id(battery_percent).state >= 50) {
// "\U000F007E" # mdi-battery-50
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007E");
} else if (id(battery_percent).state >= 40) {
// "\U000F007D" # mdi-battery-40
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007D");
} else if (id(battery_percent).state >= 30) {
// "\U000F007C" # mdi-battery-30
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007C");
} else if (id(battery_percent).state >= 20) {
// "\U000F007B" # mdi-battery-20
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007B");
} else if (id(battery_percent).state >= 10) {
// "\U000F007A" # mdi-battery-10
it.printf(85, 567, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F007A");
}
}
// ----------------------------------------------------------------------------------- Print sunrise
if(id(sun_sunrise).has_state ()) {
it.printf(100, 235, id(font_mdi_medium), color_black, TextAlign::CENTER_RIGHT, "\U000F059C");
it.printf(105, 235, id(font_small_bold), color_black, TextAlign::CENTER_LEFT, "%s", id(sun_sunrise).state.c_str());
}
// ----------------------------------------------------------------------------------- Print sunset
if(id(sun_sunset).has_state ()) {
it.printf(455, 235, id(font_mdi_medium), color_black, TextAlign::CENTER_RIGHT, "\U000F059B");
it.printf(415, 235, id(font_small_bold), color_black, TextAlign::CENTER_RIGHT, "%s", id(sun_sunset).state.c_str());
}
// ----------------------------------------------------------------------------------- Print moonrise
if(id(moon_rise).has_state ()) {
it.printf(155, 260, id(font_mdi_medium), color_black, TextAlign::CENTER_RIGHT, "\U000F1A0A");
it.printf(155, 260, id(font_small_bold), color_black, TextAlign::CENTER_LEFT, "%s", id(moon_rise).state.c_str());
}
// ----------------------------------------------------------------------------------- Print moonset
if(id(moon_set).has_state ()) {
it.printf(400, 260, id(font_mdi_medium), color_black, TextAlign::CENTER_RIGHT, "\U000F1A09");
it.printf(365, 260, id(font_small_bold), color_black, TextAlign::CENTER_RIGHT, "%s", id(moon_set).state.c_str());
}
// Weather Section ------------------------------------------------------------------- PLACE NAME
// TEST it.image(20, 338, id(title_weather));
it.print(265, 280, id(font_weekday), color_black, TextAlign::TOP_CENTER, "DUNDONALD");
// ----------------------------------------------------------------------------------- WEATHER STATE ICON --------------- (110, 358)
it.printf(245, 335, id(font_mdi_large), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
// TEST it.printf(245, 340, id(font_mdi_large), color_black, TextAlign::TOP_CENTER, "\U000F0F35");
// ----------------------------------------------------------------------------------- MOON PHASE ICON ------------------
if(id(moon_phase).has_state ()) {
it.printf(265, 243, id(font_mdi_medlarge), color_black, TextAlign::CENTER, "%s", moon_icon_map[id(moon_phase).state.c_str()].c_str());
}
// ----------------------------------------------------------------------------------- HUMIDITY
if(id(weather_humidity).has_state ()) {
it.printf(100, 352, id(font_mdi_medium), color_black, TextAlign::BASELINE_RIGHT, "\U000F058E");
it.printf(145, 350, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "%s", "%");
it.printf(140, 350, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%2.0f", id(weather_humidity).state);
}
// ----------------------------------------------------------------------------------- VISIBILITY
if(id(visibility_range).has_state ()) {
it.printf(100, 400, id(font_mdi_medium), color_black, TextAlign::BASELINE_RIGHT, "\U000F00A5");
it.printf(140, 400, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%s", visibility_short[id(visibility_range).state.c_str()].c_str());
it.printf(145, 400, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "km");
}
// ----------------------------------------------------------------------------------- UV INDEX
if(id(uv_index).has_state ()) {
it.printf(100, 454, id(font_mdi_medium), color_black, TextAlign::BASELINE_RIGHT, "\U000F0F37");
it.printf(140, 450, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%2.0f", id(uv_index).state);
it.printf(145, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "UVI");
}
// ----------------------------------------------------------------------------------- PRESSURE
if(id(weather_pressure).has_state ()) {
// pressure trend
if(id(pressure_trend).state == "on") {
it.printf(325, 353, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F19B4");
} else if(id(pressure_trend).state == "off") {
it.printf(325, 352, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F19B7");
}
it.printf(410, 350, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%2.0f", id(weather_pressure).state);
it.printf(415, 350, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "hPa");
}
// TEST it.printf(410, 340, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "1888");
// ----------------------------------------------------------------------------------- WIND
if(id(wind_speed).has_state ()) {
it.printf(330, 400, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F15FA");
it.printf(410, 400, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%2.0f", id(wind_speed).state);
it.printf(415, 400, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "kmh");
if(id(wind_warning).state > 20) {
it.printf(415, 485, id(font_mdi_medium), color_black, TextAlign::TOP_LEFT, "\U000F15FA");
}
}
// TEST it.printf(420, 390, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "188");
// ----------------------------------------------------------------------------------- WIND DIRECTION & BEARING
if(id(wind_bearing).has_state ()) {
it.printf(330, 454, id(font_mdi_medium), color_black, TextAlign::BASELINE_CENTER, "\U000F018C");
it.printf(410, 450, id(font_weekday), color_black, TextAlign::BASELINE_RIGHT, "%2.0f", id(wind_bearing).state);
if (id(wind_bearing).state > 337.5) {
it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "N");
} else if(id(wind_bearing). state > 292.5) {
it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "NW");
} else if(id(wind_bearing). state > 247.5) {
it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "W");
} else if(id(wind_bearing). state > 202.5) {
it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "SW");
} else if(id(wind_bearing). state > 157.5) {
it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "S");
} else if(id(wind_bearing). state > 112.5) {
it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "SE");
} else if(id(wind_bearing). state > 67.5) {
it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "E");
} else if(id(wind_bearing). state > 22.5) {
it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "NE");
} else if(id(wind_bearing). state >= 0) {
it.printf(415, 450, id(font_small_bold), color_black, TextAlign::BASELINE_LEFT, "N");
}
}
// ----------------------------------------------------------------------------------- Frost Warning
if(id(frost_risk).has_state ()) {
if(id(frost_risk).state != "no_risk") {
it.printf(415, 565, id(font_mdi_medium), color_black, TextAlign::BASELINE_LEFT, "\U000F0F29");
}
}
// ----------------------------------------------------------------------------------- TEMPERATURE ---------------------- (310, 458)
if(id(weather_temperature).has_state ()) {
it.printf(410, 480, id(font_large_bold), color_black, TextAlign::TOP_RIGHT, "%2.0f°C", id(weather_temperature).state);
// TEST it.printf(410, 480, id(font_large_bold), color_black, TextAlign::TOP_RIGHT, "%s", "88°C");
}
if(id(temp_trend).has_state ()) {
if(id(temp_trend).state == "on") {
it.printf(123, 527, id(font_mdi_medium), color_black, TextAlign::CENTER, "\U000F0E03");
} else if(id(temp_trend).state == "off") {
it.printf(123, 527, id(font_mdi_medium), color_black, TextAlign::CENTER, "\U000F0E02");
}
}
if(id(weather_temperature_0).has_state ()) {
it.printf(90, 602, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_0).state.c_str());
it.printf(90, 626, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
it.printf(90, 674, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);
}
if(id(weather_temperature_1).has_state ()) {
it.printf(200, 602, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_1).state.c_str());
it.printf(200, 626, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
it.printf(200, 674, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_1).state);
}
if(id(weather_temperature_2).has_state ()) {
it.printf(315, 602, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_2).state.c_str());
it.printf(315, 626, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
it.printf(315, 674, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_2).state);
}
if(id(weather_temperature_3).has_state ()) {
it.printf(425, 602, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_3).state.c_str());
it.printf(425, 626, id(font_mdi_medium), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
it.printf(425, 674, id(font_small_bold), color_black, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_3).state);
}
captive_portal:
Template entities:
- sensor:
- name: "Moon Rise"
icon: "mdi:triangle-small-up"
state: >-
{% set x = states('sensor.astroweather_moon_next_rising') %}
{{ x[11:16] }}
- sensor:
- name: "Moon Set"
icon: "mdi:triangle-small-down"
state: >-
{% set x = states('sensor.astroweather_moon_next_setting') %}
{{ x[11:16] }}
The above comes from Astroweater integration available to install in HACS:
Wind warning is based on my custom weather entity, by changing [1] to other number you can chose how soon you will see the warning.
- sensor:
- name: "Wind Warning"
icon: "mdi:weather-windy"
unit_of_measurement: "km/h"
state: "{{state_attr('weather.my_weather_station', 'forecast')[1]['wind_speed']}}"
UV index sensor comes with MET Office integration. I also need to change source for the wind speed . I just noticed Met Office provides separate sensors in its integration, but if I remember correctly these are disabled by default. You can easily be change the identity name in the code once activated.
Temp trend:
- platform: trend
sensors:
outside_temperature:
entity_id: sensor.zigbeeweather_temperature
friendly_name: "Temperature Trend"
max_samples: 60
sample_duration: 10800
Pressure trend:
- platform: trend
sensors:
atmospheric_pressure:
entity_id: sensor.zigbeeweather_pressure
friendly_name: "Pressure Trend"
max_samples: 60
sample_duration: 21600
Lastly, frost risk is based on your current temperature, frost point and absolute humidit, quite reliable. Easily available through Thermal Comfort custom integration (HACS):
If I missed something, let me know. Hope it works without any issues.
This is awesome, I actually picked up the hardware months ago and am just now getting round to doing the build.
I’m pretty new to this level of ESPHome, What I want to do is get calendars lists to display. essentially to do lists. But I’m not getting anything showing up yet.
Is this enough to just get the titles of two of the lists to display?
I get no errors in the logs, but im not even getting
WAITING FOR DATA
Should the screen flash or anything on boot?
globals:
- id: data_updated
type: bool
restore_value: no
initial_value: 'false'
- id: initial_data_received
type: bool
restore_value: no
initial_value: 'false'
# 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']
# Check whether the display needs to be refreshed every minute,
# based on whether new data is received or motion is detected. (Thanks @paviro!)
time:
- platform: homeassistant
id: homeassistant_time
on_time:
- seconds: 0
minutes: /1
then:
- if:
condition:
lambda: 'return id(data_updated) == true;'
then:
- lambda: 'id(initial_data_received) = true;'
- if:
condition:
binary_sensor.is_on: motion_detected
then:
- logger.log: "Sensor data updated and activity in home detected: Refreshing display..."
- component.update: eink_display
- lambda: 'id(data_updated) = false;'
else:
- logger.log: "Sensor data updated but no activity in home - skipping display refresh."
# Check if motion is detected in the bathroom.
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.bathroom_motion_sensor
id: motion_detected
# Call calender sensors from HA.
sensor:
- platform: homeassistant
entity_id: calendar.home_assistant_tasks
id: home_assistant_tasks
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: calendar.alexa_to_do_list
id: alexa_to_do_list
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: calendar.alexa_shopping_list
id: alexa_shopping_list
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Define colors
# This design is white on black so this is necessary.
color:
- id: color_bg
red: 0%
green: 0%
blue: 0%
white: 0%
- id: color_text
red: 0%
green: 0%
blue: 0%
white: 100%
# 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: |-
// Fill background.
// it.fill(color_bg);
// Show loading screen before data is received.
if (id(initial_data_received) == false) {
it.printf(240, 390, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "WAITING FOR DATA...");
} else {
// To Do List
it.printf(240, 84, id(font_title), color_text, TextAlign::TOP_CENTER, "To Do");
// Shopping List Section
it.printf(240, 408, id(font_title), color_text, TextAlign::TOP_CENTER, "Shopping List");
}
captive_portal:
So been trying to tobbleshoot this and so far nothing.
ESP32 appears to be working.
Does the display flash when it gets powered?
Does ESPHome log writes to the display? (I get no info in the logs)
I also stripped everything out of the yaml
font:
- file: 'fonts/GothamRnd-Book.ttf'
id: font_small_book
size: 18
- file: "gfonts://Roboto"
id: roboto
size: 20
# 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: |-
it.print(0, 0, id(roboto), "Hello World!");
Still nothing, can anyone see anything wrong here?
Thanks
Changed the update intival,
[13:09:32][D][esp32.preferences:113]: Saving 1 preferences to flash...
[13:09:32][D][esp32.preferences:142]: Saving 1 preferences to flash: 0 cached, 1 written, 0 failed
So is this working as far as the ESP32 is concerned?
EDIT;
OK, I think I got it working. Was the display select on the board itself
Ok, so have gotten somewhere.
But the display is really bad. I seen people kind of allude to quality issues. But how did you fix it?
After turning it on, got this
Even though I thought it would be black text on white
Restarted again and now its sitting here
If anyone can give me any advise, would really appreciate it
# 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'
# 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']
# Check whether the display needs to be refreshed every minute,
# based on whether new data is received or motion is detected. (Thanks @paviro!)
time:
- platform: homeassistant
id: homeassistant_time
on_time:
- seconds: 0
minutes: /1
then:
- if:
condition:
lambda: 'return id(data_updated) == true;'
then:
- lambda: 'id(initial_data_received) = true;'
- if:
condition:
binary_sensor.is_on: motion_detected
then:
- logger.log: "Sensor data updated and activity in home detected: Refreshing display..."
- component.update: eink_display
- lambda: 'id(data_updated) = false;'
else:
- logger.log: "Sensor data updated but no activity in home - skipping display refresh."
# Check if motion is detected in the bathroom.
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.bathroom_motion_sensor
id: motion_detected
# Call calender sensors from HA.
sensor:
- platform: homeassistant
entity_id: calendar.home_assistant_tasks
id: home_assistant_tasks
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: calendar.alexa_to_do_list
id: alexa_to_do_list
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: calendar.alexa_shopping_list
id: alexa_shopping_list
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Define colors
# This design is white on black so this is necessary.
color:
- id: color_black
red: 0%
green: 0%
blue: 0%
white: 50%
- id: color_white
red: 0%
green: 0%
blue: 0%
white: 0%
# 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: 1h
rotation: 90°
lambda: |-
// Fill background.
// it.fill(color_bg);
// Show loading screen before data is received.
if (id(initial_data_received) == false) {
it.printf(240, 390, id(font_title), color_black, TextAlign::TOP_CENTER, "WAITING FOR DATA...");
} else {
// To Do List
it.printf(240, 84, id(font_title), color_black, TextAlign::TOP_CENTER, "To Do");
// Shopping List Section
it.printf(240, 408, id(font_title), color_black, TextAlign::TOP_CENTER, "Shopping List");
}
captive_portal:
I had something similar and discovered I had a three colour panel and after some googling found that someone had added support via an external component (YMMV)
Thanks for that, I knew I had the three colour one. I just didn’t know it wasn’t supported LOL
Do you think it safe? *he asks stranger on the internet" HAHA
But really thank you, had no idea that would be an issue
HARDWARE: ESP32 240MHz, 320KB RAM, 4MB Flash
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
Dependency Graph
|-- AsyncTCP-esphome @ 1.2.2
|-- WiFi @ 1.0
|-- FS @ 1.0
|-- Update @ 1.0
|-- ESPAsyncWebServer-esphome @ 2.1.0
| |-- AsyncTCP-esphome @ 1.2.2
|-- DNSServer @ 1.1.0
|-- ESPmDNS @ 1.0
|-- noise-c @ 0.1.4
| |-- libsodium @ 1.10018.1
|-- SPI @ 1.0
Compiling /data/to-do/.pioenvs/to-do/src/main.cpp.o
src/main.cpp: In function 'void setup()':
src/main.cpp:3702:63: error: invalid new-expression of abstract class type 'esphome::waveshare_epaper::WaveshareEPaper7P5InV2'
eink_display = new waveshare_epaper::WaveshareEPaper7P5InV2();
^
In file included from src/esphome.h:50:0,
from src/main.cpp:3:
src/esphome/components/waveshare_epaper/waveshare_epaper.h:312:7: note: because the following virtual functions are pure within 'esphome::waveshare_epaper::WaveshareEPaper7P5InV2':
class WaveshareEPaper7P5InV2 : public WaveshareEPaper {
^
In file included from src/esphome.h:20:0,
from src/main.cpp:3:
src/esphome/components/display/display_buffer.h:373:23: note: virtual esphome::display::DisplayType esphome::display::DisplayBuffer::get_display_type()
virtual DisplayType get_display_type() = 0;
^
*** [/data/to-do/.pioenvs/to-do/src/main.cpp.o] Error 1
========================== [FAILED] Took 5.83 seconds ==========================
Didnt like it, will open a FR with ESPHome
EDIT
Actually, I have the two colour I think. Lucky I checked
Waveshare 7.5inch E-Paper (B) E-Ink Raw Display 800×480 Pixels Red/Black/White Three-Color with SPI Interface Without PCB >170°Wide Viewing Angle Paper-Like Displaying Without Electricity
I just remember seeing “three colour” lol
7.50in B-type (red-black-white) I asked in one the related github issues if its supported. See if someone responds
How did you set it? A and ON? I have the same problem I think
I’m at work now, so cant check. But initially I did have it in the wrong position. It kinda works now. But its not great. Perhaps because the one I have has 2 colors in it.
Hi, I’m using part of your code to make a board, but I found some points where I get errors (maybe it’s me that I’m not the best at coding).
On the moon time and phase, I defined the sensor templates in HA, but when I compile the ESP32 I get these errors:
/config/eink-frame-1.yaml:356:110: error: request for member 'c_str' in 'moon_rise->esphome::homeassistant::HomeassistantSensor::<anonymous>.esphome::sensor::Sensor::state', which is of non-class type 'float'
it.printf(155, 260, id(font_small_bold), color_black, TextAlign::CENTER_LEFT, "%s", id(moon_rise).state.c_str());
^~~~~
/config/eink-frame-1.yaml:361:110: error: request for member 'c_str' in 'moon_set->esphome::homeassistant::HomeassistantSensor::<anonymous>.esphome::sensor::Sensor::state', which is of non-class type 'float'
it.printf(365, 260, id(font_small_bold), color_black, TextAlign::CENTER_RIGHT, "%s", id(moon_set).state.c_str());
^~~~~
/config/eink-frame-1.yaml:365:122: error: request for member 'c_str' in 'moon_phase->esphome::homeassistant::HomeassistantSensor::<anonymous>.esphome::sensor::Sensor::state', which is of non-class type 'float'
it.printf(265, 243, id(font_mdi_medlarge), color_black, TextAlign::CENTER, "%s", moon_icon_map[id(moon_phase).state.c_str()].c_str());
^~~~~
Also the moon phase is identified with a percentage, how does it maps to
std::map<std::string, std::string> moon_icon_map
since there are just names? Where is defined the correspondence?
Regarding the weather, what is sensor.weatherman_data source?
# # Weatherman entities
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_now
id: weather_condition_now
Thank you for any help you can give
Hi, unfortunately, my display died prematurely over Christmas, but I will try to help you as best I can, and as simply as possible (I am no expert either )
it.printf(155, 260, id(font_small_bold), color_black, TextAlign::CENTER_LEFT, "%s", id(moon_rise).state.c_str());
it.printf(365, 260, id(font_small_bold), color_black, TextAlign::CENTER_RIGHT, "%s", id(moon_set).state.c_str());
it.printf(265, 243, id(font_mdi_medlarge), color_black, TextAlign::CENTER, "%s", moon_icon_map[id(moon_phase).state.c_str()].c_str());
First, double check in Home Assistant in Dev tools if you have these sensors and if you can see their states:
sensor.moon
sensor.moon_rise
sensor.moon_set
If there is a problem with any of them, go to Settings / Devices / Integrations and check if you have Moon integration listed for the moon phase, and AstroWeather for the moon rise and moon set. Moon is a native integration, while AstroWeather can be installed via HACS, for which I provided a link previously.
The first sensor reports only the moon phase as a string (text) and not as a percentage. It seems to me you might be using some other sensor for this, hence the issue (possibly moon phase sensor from AstroWeather (???)).
Sensor ‘weatherman_data’ groups information from other weather / sensor entities into one sensor for the ease of use.
The code below is from the original project, I only modified it slightly to use the data from my own weather station and the forecast from Yr.no.
# Bundle up all the data to send over to Weatherman.
- sensor:
- name: "Weatherman Data"
state: "OK"
attributes:
weather_condition_now: >
{% set cond_now = states('weather.my_weather_station') %}
{% 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('weather.home_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('weather.home_hourly', '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: >
{{ state_attr('weather.home_hourly', 'forecast')[0].temperature | round }}
weather_timestamp_0: >
{{ as_timestamp(state_attr('weather.home_hourly', 'forecast')[0].datetime) | timestamp_custom('%I') | int }} {{ as_timestamp(state_attr('weather.home_hourly', 'forecast')[0].datetime) | timestamp_custom('%p') }}
weather_condition_1: >
{% set cond1 = state_attr('weather.home_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('weather.home_hourly', '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: >
{{ state_attr('weather.home_hourly', 'forecast')[1].temperature | round }}
weather_timestamp_1: >
{{ as_timestamp(state_attr('weather.home_hourly', 'forecast')[1].datetime) | timestamp_custom('%I') | int }} {{ as_timestamp(state_attr('weather.home_hourly', 'forecast')[1].datetime) | timestamp_custom('%p') }}
weather_condition_2: >
{% set cond2 = state_attr('weather.home_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('weather.home_hourly', '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: >
{{ state_attr('weather.home_hourly', 'forecast')[2].temperature | round }}
weather_timestamp_2: >
{{ as_timestamp(state_attr('weather.home_hourly', 'forecast')[2].datetime) | timestamp_custom('%I') | int }} {{ as_timestamp(state_attr('weather.home_hourly', 'forecast')[2].datetime) | timestamp_custom('%p') }}
weather_condition_3: >
{% set cond3 = state_attr('weather.home_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('weather.home_hourly', '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: >
{{ state_attr('weather.home_hourly', 'forecast')[3].temperature | round }}
weather_timestamp_3: >
{{ as_timestamp(state_attr('weather.home_hourly', 'forecast')[3].datetime) | timestamp_custom('%I') | int }} {{ as_timestamp(state_attr('weather.home_hourly', 'forecast')[3].datetime) | timestamp_custom('%p') }}
Hope this all helps.
Thank you for your reply. I fixed some things missing (moon sensor), but I still get errors on the same spot like if the return is not of correct type.
I checked in HA and I can see correctly the entities and attributes
/config/eink-frame-1.yaml:308:133: error: request for member 'c_str' in 'weather_condition_now->esphome::homeassistant::HomeassistantSensor::<anonymous>.esphome::sensor::Sensor::state', which is of non-class type 'float'
it.printf(245, 335, id(font_mdi_large), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
^~~~~
Are you aware of any documentation on how to construct these instructions?
Thanks
Hmm…
it.printf(245, 335, id(font_mdi_large), color_black, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
The code above only displays the weather state icon, which is assigned in the code below. I would check formatting i.e. missing quotation here:
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"},
};
The only documentation I used was the one from ESPHome and from the original project, plus a lot of trial and error until I figured it out.
Hi,
You said “connect the e-Paper screen to the driver board” does the screen come with the cable or does the driver board come with the cable or do I have to buy the cable seperatly ?
Amazing project !
Mine arrived with it.