As a tribute to this great project herewith my version to inspire others.
I am not sure about easier examples, but I suggest you to do few elements at a time and figure out little by little. When it’s ok you add another part of code
Nise project. Have orderd the components and started working on my sensors in HA, but I’m struggeling to validate my configuration.
In configuration.yaml i got: sensor: !include_dir_list sensors/
and in folder sensors i got: Weatherman_motion.yaml
The content of the file is:
platform: template
sensors:
binary_sensor:
name: "Weatherman Motion Detected"
unique_id: "dfa78de7-d761-425f-9731-86f1af332eac"
device_class: "occupancy"
delay_off: 1min
state: >-
{% if states('binary_sensor.motion_sensor_home_security_motion_detection_3') == 'on' or states('binary_sensor.lumi_lumi_sensor_magnet_73cfb702_on_off') == 'on' %}
on
{% else -%}
off
{% endif -%}
The template is working, but something is wrong in my format?
When i push test configuration it just keep spinning.
Kind of frusterating that i can not figure out the error…
Same structure and “error” on the weather template sensors…
if it’s a template, shouldn’t it be something like:
template: !include configurations/general/template.yaml
and then in the file something like:
- sensor:
- name: potenza_istantanea_totale_PT_PI
unit_of_measurement: 'W'
state: '{{ states("sensor.shelly_shem_bcff4dfcd7bf_1_current_consumption") |float + states("sensor.shelly_shem_bcff4dfce165_1_current_consumption") | float }}'
I have 2 of these working, and since the update of ESPHome to properly support the V7,5altV2, the quality has improved a lot, no more greasy pictures.
But I DO have a kind of “burn in”-effect. Of course, this does not exactly exist on an ePaper, but you know what I mean.
Any way to really clean the screen?
This is my config:
display:
- platform: waveshare_epaper
cs_pin: GPIO15
dc_pin: GPIO27
busy_pin: GPIO25
reset_pin: GPIO26
reset_duration: 2ms
model: 7.50inV2alt
update_interval: 60s
what is the effect? Can you share a picture?
Have you tried with
auto_clear_enabled: True
?
Autoclear does not do anything for me (isn’t it defaulted to “true” if not set?).
So I tried adding a routine that fills the screen black and then white for a minute every 24 hours. Below is my code, but it doesn’t work as expected; I am getting just a white screen after reboot and the code never seems to continue. What am I doing wrong?
display:
lambda: |-
if (millis() % 86400000 < 120000) {
// Within the first 2 minutes of the day
epaper_display->fill(esphome::Color(0));
epaper_display->display(); // Display the black screen
delay(60000); // 1 minute delay in milliseconds
epaper_display->fill(esphome::Color(1));
epaper_display->display();
delay(60000);
} else {
.....Rest of my normal display routine....
I had to specify it otherwise it didn’t properly clear my screen
My code is the follwing and I don’t have your problem
display:
- platform: waveshare_epaper
cs_pin: GPIO15
dc_pin: GPIO27
busy_pin: GPIO25
reset_pin: GPIO26
model: 7.50inV2alt
update_interval: 1200s
rotation: 90°
auto_clear_enabled: True
lambda: |-
The only difference is the
reset_duration: 2ms
that I haven’t set
The new ESPHome 2023.12.0 - 20th December 2023 seems to break the shutdown, restart och refresh functions. I can´t find what causes this, anyone has any ideea?
# Creates buttons in Home Assistant to
button:
- platform: shutdown
name: "Weatherman - Shutdown"
- platform: restart
name: "Weatherman - Restart"
- platform: template
name: "Weatherman - Refresh Screen"
entity_category: config
on_press:
- script.execute: update_screen
Chceck if ids were not renamed. Some of mine were renamed by adding underscore and number to the ids, so the old ones were not active.
I’m not sure at what point ESPhome broke this as I haven’t had to update the display in many, many months (it’s actually still running on the old FW) but now it’s so far out of date I copied the ESPhome data to a new file so that I can avoid breaking things while testing to compile.
However I am stuck, I do not understand why it will not compile. Below is the error and my ESPhome yaml, any help would be appreciated!
INFO ESPHome 2023.12.1
INFO Reading configuration /config/esphome/frontdoor-epaper1.yaml...
INFO Detected timezone 'Canada/Eastern'
WARNING GPIO15 is a strapping PIN and should only be used for I/O with care.
Attaching external pullup/down resistors to strapping pins can cause unexpected failures.
See https://esphome.io/guides/faq.html#why-am-i-getting-a-warning-about-strapping-pins
INFO Generating C++ source...
Traceback (most recent call last):
File "/usr/local/bin/esphome", line 33, in <module>
sys.exit(load_entry_point('esphome', 'console_scripts', 'esphome')())
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/esphome/esphome/__main__.py", line 1041, in main
return run_esphome(sys.argv)
^^^^^^^^^^^^^^^^^^^^^
File "/esphome/esphome/__main__.py", line 1028, in run_esphome
rc = POST_CONFIG_ACTIONS[args.command](args, config)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/esphome/esphome/__main__.py", line 407, in command_compile
exit_code = write_cpp(config)
^^^^^^^^^^^^^^^^^
File "/esphome/esphome/__main__.py", line 192, in write_cpp
generate_cpp_contents(config)
File "/esphome/esphome/__main__.py", line 204, in generate_cpp_contents
CORE.flush_tasks()
File "/esphome/esphome/core/__init__.py", line 679, in flush_tasks
self.event_loop.flush_tasks()
File "/esphome/esphome/coroutine.py", line 246, in flush_tasks
next(task.iterator)
File "/esphome/esphome/__main__.py", line 184, in wrapped
await coro(conf)
File "/esphome/esphome/coroutine.py", line 80, in coro
ret = yield from _flatten_generator(gen)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/esphome/esphome/coroutine.py", line 132, in _flatten_generator
to_send = yield from val.__await__()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/esphome/esphome/components/display/__init__.py", line 119, in register_display
await cg.register_component(var, config)
File "/esphome/esphome/cpp_helpers.py", line 56, in register_component
raise ValueError(
ValueError: Component ID einkdisplay was not declared to inherit from Component, or was registered twice. Please create a bug report with your configuration.
sorry had to split my post and slightly shorten the code at the bottom (too long):
ESPhome yaml:
# 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: "frontdoor-epaper-1"
on_boot:
priority: 200.0
then:
- component.update: einkdisplay
- wait_until:
condition:
lambda: 'return id(data_updated) == true;'
# Wait a bit longer so all the items are received
- 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
external_components:
- source:
type: git
url: https://github.com/atomicmike/esphome.git
ref: waveshare-color-2023.10
components: [ waveshare_epaper ]
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: !secret base64_key
ota:
password: !secret esphome_ota_pass
wifi:
ssid: !secret iot_wifi_ssid
password: !secret iot_wifi_pass
button:
- platform: shutdown
name: "Front Door eInk1 - Shutdown"
- platform: restart
name: "Front Door eInk1 - Restart"
- platform: template
name: "Front Door eInk1 - Refresh Screen"
entity_category: config
on_press:
- script.execute: update_screen
# Check if motion is detected or front door opened
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.weatherman_motion_detected
id: motion_detected
# 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 for updating screen - Refresh display and publish refresh count and time. (Thanks @paviro!)
script:
- id: update_screen
then:
- lambda: 'id(data_updated) = false;'
- component.update: einkdisplay
- lambda: 'id(recorded_display_refresh) += 1;'
- lambda: 'id(display_last_update).publish_state(id(homeassistant_time).now().timestamp);'
# 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:
- if:
condition:
binary_sensor.is_on: motion_detected
then:
- logger.log: "Sensor data updated and activity in home detected: Refreshing display..."
- script.execute: update_screen
else:
- logger.log: "Sensor data updated but no activity in home - skipping display refresh."
else:
- logger.log: "No sensors updated - skipping display refresh."
#Include sun
sun:
latitude: 47.68441276121833
longitude: -71.51268632342236
# 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
sensor:
# Create sensors for monitoring Weatherman remotely.
- platform: template
name: "Front Door eInk1 - Display Last Update"
device_class: timestamp
entity_category: "diagnostic"
id: display_last_update
- platform: template
name: "Front Door eInk1 - Recorded Display Refresh"
accuracy_decimals: 0
unit_of_measurement: "Refreshes"
state_class: "total_increasing"
entity_category: "diagnostic"
lambda: 'return id(recorded_display_refresh);'
- platform: wifi_signal
name: "Front Door eInk1 - WiFi Signal Strength"
id: wifisignal
unit_of_measurement: "dBm"
entity_category: "diagnostic"
update_interval: 60s
# Temperature - My Weather station
- platform: homeassistant
entity_id: weather.batcave_owp
attribute: temperature
id: weather_temperature
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Humidity - My Weather station
- platform: homeassistant
entity_id: weather.batcave_owp
attribute: humidity
id: weather_humidity
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Air pressure - My Weather station
- platform: homeassistant
entity_id: weather.batcave_owp
attribute: pressure
id: weather_pressure
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Wind Bearing - from Yr.no (built-in HA weather privider)
- platform: homeassistant
entity_id: weather.forecast_home
attribute: wind_bearing
id: wind_bearing
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Battery % for Aqara sensor
- platform: homeassistant
entity_id: sensor.bedroom_tandh_battery
id: battery_percent
# Battery Voltage for Aqara sensor
- platform: homeassistant
entity_id: sensor.bedroom_tandh_battery
attribute: voltage
id: battery_voltage
# Weatherman entities
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_0
id: weather_temperature_0
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_1
id: weather_temperature_1
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_2
id: weather_temperature_2
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_3
id: weather_temperature_3
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Strong Wind
- platform: homeassistant
entity_id: sensor.wind_warning
id: wind_warning
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Wind Speed
- platform: homeassistant
entity_id: weather.batcave_owp
attribute: wind_speed
id: wind_speed
on_value:
then:
- lambda: 'id(data_updated) = true;'
# UV Index
- platform: homeassistant
entity_id: sensor.current_uv_index
id: uv_index
on_value:
then:
- lambda: 'id(data_updated) = true;'
text_sensor:
# Pressure Trend
- platform: homeassistant
entity_id: binary_sensor.atmospheric_pressure
id: pressure_trend
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Temp Trend
- platform: homeassistant
entity_id: binary_sensor.outside_temperature
id: temp_trend
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Weather State
- platform: homeassistant
entity_id: sensor.batcave_owp_condition
id: weather_state
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Frost Risk
- platform: homeassistant
entity_id: sensor.weather_frostrisk
id: frost_risk
on_value:
then:
- lambda: 'id(data_updated) = true;'
# # Weatherman entities
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_now
id: weather_condition_now
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_0
id: weather_condition_0
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_0
id: weather_timestamp_0
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_1
id: weather_condition_1
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_1
id: weather_timestamp_1
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_2
id: weather_condition_2
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_2
id: weather_timestamp_2
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_3
id: weather_condition_3
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_3
id: weather_timestamp_3
on_value:
then:
- lambda: 'id(data_updated) = true;'
# 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.batcave_owp_visibility
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_RED
red: 100%
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: einkdisplay
cs_pin: GPIO15
dc_pin: GPIO27
busy_pin:
number: GPIO25
inverted: True
reset_pin: GPIO26
reset_duration: 3ms
model: 7.50inv2b
update_interval: never
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"},
That was the case, thanks! They hade created a new entity with _2 in the end
The images are loaded from this heading
// --WEATHER STATE ICON
You just need the make sure the entity matches your accuweather ID.
There are icons from memory that load here that you must have.
Here is my take on e-ink dashboard for weekly calendar/forecast/events.
Wanted to use the big screen of Inkplate10 for most of static HA daily data.
Been wanting to try building this for so long and eventually got the hardware for Christmas. Been playing with it today, got things working but currently the text colour is black with the background a kind of grey (off white) colour. Is there any way to force it to have black background and white text?
I’ve played with different code under the ‘color:’ tag but no luck. Screen it a Waveshare 800×480, 7.5inch black and white.
My yaml looks like this:
# 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: esp32-frame
friendly_name: ESP32 Frame
on_boot:
priority: 200.0
then:
- component.update: eink_display
- wait_until:
condition:
lambda: 'return id(data_updated) == true;'
# Wait a bit longer so all the items are received
- 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 Webserver
web_server:
port: 80
include_internal: True
# Enable Home Assistant API
api:
encryption:
key: "r4ecKKcwJefUSaz45RD0Ztv2JEVitpXS2nmZhIKvY84="
ota:
button:
- platform: shutdown
name: "Weatherman - Shutdown"
- platform: restart
name: "Weatherman - Restart"
- platform: template
name: "Weatherman - Refresh Screen"
entity_category: config
on_press:
- script.execute: update_screen
# Global variables for detecting if the display needs to be refreshed. (Thanks @paviro!)
globals:
- id: data_updated
type: bool
restore_value: no
initial_value: 'false'
- id: initial_data_received
type: bool
restore_value: no
initial_value: 'false'
- id: recorded_display_refresh
type: int
restore_value: yes
initial_value: '0'
# Script for updating screen - Refresh display and publish refresh count and time. (Thanks @paviro!)
script:
- id: update_screen
then:
- lambda: 'id(data_updated) = false;'
- component.update: eink_display
- lambda: 'id(recorded_display_refresh) += 1;'
- lambda: 'id(display_last_update).publish_state(id(homeassistant_time).now().timestamp);'
# 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:
- if:
condition:
binary_sensor.is_on: motion_detected
then:
- logger.log: "Sensor data updated and activity in home detected: Refreshing display..."
- script.execute: update_screen
else:
- logger.log: "Sensor data updated but no activity in home - skipping display refresh."
else:
- logger.log: "No sensors updated - skipping display refresh."
# Wifi information
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
manual_ip:
# Set this to the IP of the ESP
static_ip: 192.168.60.200
# Set this to the IP address of the router. Often ends with .1
gateway: 192.168.60.1
# The subnet of the network. 255.255.255.0 works for most home networks.
subnet: 255.255.255.0
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Esphome-Web-1C8A6C"
password: "ujvis6zPKIhT"
# 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: ['B', 'D', 'S', 'Y', 'W', 'E', 'A', 'T', 'H', 'R', 'L', 'I', 'N', ' ']
- file: 'fonts/GothamRnd-Bold.ttf'
id: font_medium_bold
size: 30
# glyphs: [' ', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'M', 'I', 'N']
- file: 'fonts/GothamRnd-Bold.ttf'
id: font_small_bold
size: 18
# glyphs: [' ', '-', '°', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'C', 'M', 'I', 'N']
# Include Material Design Icons font
# Thanks to https://community.home-assistant.io/t/display-materialdesign-icons-on-esphome-attached-to-screen/199790/16
- 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: 36
glyphs: *mdi-weather-glyphs
# Include Custom Titles
# image:
# - file: "images/weatherman-title-train.png"
# id: title_train
# type: BINARY
# - file: "images/weatherman-title-weather.png"
# id: title_weather
# type: BINARY
# Check if motion is detected in the living room.
binary_sensor:
- platform: homeassistant
entity_id: binary_sensor.motion_sensor_bathroom_sink_hue_occupancy
id: motion_detected
sensor:
# Create sensors for monitoring Weatherman remotely.
- platform: template
name: "Weatherman - Display Last Update"
device_class: timestamp
entity_category: "diagnostic"
id: display_last_update
- platform: template
name: "Weatherman - Recorded Display Refresh"
accuracy_decimals: 0
unit_of_measurement: "Refreshes"
state_class: "total_increasing"
entity_category: "diagnostic"
lambda: 'return id(recorded_display_refresh);'
- platform: homeassistant
entity_id: weather.kings_langley_hourly
attribute: temperature
id: weather_temperature
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_0
id: weather_temperature_0
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_1
id: weather_temperature_1
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_2
id: weather_temperature_2
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_temperature_3
id: weather_temperature_3
on_value:
then:
- lambda: 'id(data_updated) = true;'
text_sensor:
- platform: homeassistant
entity_id: weather.kings_langley_hourly
id: weather_state
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_now
id: weather_condition_now
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_0
id: weather_condition_0
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_0
id: weather_timestamp_0
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_1
id: weather_condition_1
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_1
id: weather_timestamp_1
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_2
id: weather_condition_2
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_2
id: weather_timestamp_2
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_condition_3
id: weather_condition_3
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: weather_timestamp_3
id: weather_timestamp_3
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: train_status
id: train_status
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: train_status_manhattan
id: train_status_manhattan
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.weatherman_data
attribute: train_status_canarsie
id: train_status_canarsie
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%
- id: color_text
red: 100%
green: 100%
blue: 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.50inV2alt
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"},
};
// 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 {
// Weather Section
// it.image(0, 88, id(title_weather));
it.printf(240, 84, id(font_title), color_text, TextAlign::TOP_CENTER, "WEATHER");
it.printf(100, 158, id(font_mdi_large), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
it.printf(300, 158, id(font_large_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature).state);
it.printf(105, 282, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_0).state.c_str());
it.printf(105, 306, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
it.printf(105, 354, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);
it.printf(195, 282, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_1).state.c_str());
it.printf(195, 306, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
it.printf(195, 354, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_1).state);
it.printf(285, 282, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_2).state.c_str());
it.printf(285, 306, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
it.printf(285, 354, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_2).state);
it.printf(375, 282, id(font_small_book), color_text, TextAlign::TOP_CENTER, "%s", id(weather_timestamp_3).state.c_str());
it.printf(375, 306, id(font_mdi_medium), color_text, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
it.printf(375, 354, id(font_small_bold), color_text, TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_3).state);
it.printf(240, 400, id(font_title), color_text, TextAlign::TOP_CENTER, "BIRTHDAYS");
// Refresh Timestamp
// Code by EnsconcE from https://community.home-assistant.io/t/esphome-show-time/348903
char str[17];
time_t currTime = id(homeassistant_time).now().timestamp;
strftime(str, sizeof(str), "%H:%M", localtime(&currTime));
it.printf(240, 710, id(font_small_book), color_text, TextAlign::TOP_CENTER, "REFRESHED AT %s", str);
}
captive_portal:
Try this:
color:
- id: color_text
red: 0%
green: 0%
blue: 0%
white: 50%
- id: color_bg
red: 0%
green: 0%
blue: 0%
white: 0%
I’m new to this e-paper thing, but added this section so hope I’m doing it correctly (about the inverted busy pin)
display:
-
- platform: waveshare_epaper*
- id: eink_display*
- cs_pin: GPIO15*
- dc_pin: GPIO27*
- busy_pin:*
*** number: GPIO25***
*** inverted: true*** - reset_pin: GPIO26*
- reset_duration: 2ms*
- model: 7.50inV2*
- update_interval: never*
Hello, I am also in the process of creating a picture frame. After big problems with the weather integration (hourly forecast) I finally managed to get it running.
Since the time in the clock jump code is output with e.g. 7PM I would like to convert this to 19:00
I’m not sure if I have to work with timestamp_custom or if I should specify something else? Thank you