Files
hassos_config/esphome/esp32-75epaper-keuken.yaml
2022-12-20 21:26:47 +01:00

643 lines
20 KiB
YAML

substitutions:
esp_name: "esp32-75epaper-keuken"
esphome:
name: ${esp_name}
comment: ${esp_name}
includes:
- common.h
esp32:
board: esp32dev
framework:
type: arduino
# Enable logging
logger:
external_components:
- source:
type: git
url: https://github.com/atomicmike/esphome.git
ref: waveshare-color-2022.6
components: [waveshare_epaper]
# Enable Home Assistant API
api:
encryption:
key: !secrets eink_display_api
ota:
password: !secret ota_password
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: ${esp_name} fallback
password: !secret fallback_password
#Include sun
sun:
latitude: !secret home_latitude
longitude: !secret home_longitude
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'
time:
- platform: homeassistant
id: esptime
on_time_sync:
- then:
- component.update: sunrise
- component.update: sunset
- logger.log: Time has been set and is valid!
on_time:
- minutes: 5
then:
- if:
condition:
lambda: 'return id(data_updated) == true;'
then:
- lambda: 'id(initial_data_received) = true;'
- logger.log: "Sensor data updated: Refreshing display..."
- component.update: eink_display
- lambda: 'id(data_updated) = false;'
- lambda: 'id(recorded_display_refresh) += 1;'
- lambda: 'id(display_last_update).publish_state(id(esptime).now().timestamp);'
else:
- logger.log: "No sensors updated - skipping display refresh."
button:
- platform: template
name: "Refresh screen"
id: refresh
icon: "mdi:emoticon-outline"
on_press:
- logger.log: "Button pressed"
- component.update: eink_display
# deep_sleep:
# run_duration: 15s
# sleep_duration: 1min
# 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', 'a', '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']
- 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/materialdesignicons-webfont.ttf
id: font_wifi
size: 20
glyphs:
- "\U000F091F"
- "\U000F0922"
- "\U000F0925"
- "\U000F0928"
- "\U000F092B"
# 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
- "\U000f010b" # mdi-car
- "\U000f0819" # trash
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_mdi_medlarge
size: 60
glyphs:
- "\U000f0f64" # new moon
- "\U000f0f67" # mdi-moon-waxing-crescent
- "\U000F0F61" # mdi-moon-first-quarter
- "\U000F0F68" # mdi-moon-waxing-gibbous
- "\U000F0F62" # mdi-moon-full
- "\U000F0F66" # mdi-moon-waning-gibbous
- "\U000F0F63" # mdi-moon-last-quarter
- "\U000F0F65" # mdi-moon-waning-crescent
- file: 'fonts/materialdesignicons-webfont.ttf'
id: font_mdi_medium
size: 36
glyphs: *mdi-weather-glyphs
sensor:
- platform: template
name: "${esp_name} Last Update"
device_class: timestamp
id: display_last_update
- platform: homeassistant
entity_id: weather.forecast_home
attribute: temperature
id: weather_temperature
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_temperature_0
id: weather_temperature_0
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_temperature_1
id: weather_temperature_1
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_temperature_2
id: weather_temperature_2
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_temperature_3
id: weather_temperature_3
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: travel_Best_time
id: travel_Best_time
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: travel_ASML_time
id: travel_ASML_time
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: travel_GGD_time
id: travel_GGD_time
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: wifi_signal
id: sensor_wifi_signal
name: "${esp_name} WiFi"
update_interval: 60s
on_value:
- component.update: sensor_wifi_signal_percentage
- platform: template
id: sensor_wifi_signal_percentage
name: "${esp_name} Wi-Fi Signal Percentage"
icon: "mdi:wifi"
unit_of_measurement: "%"
update_interval: never
lambda: |-
if (id(sensor_wifi_signal).state) {
if (id(sensor_wifi_signal).state <= -100 ) {
return 0;
} else if (id(sensor_wifi_signal).state >= -50) {
return 100;
} else {
return 2 * (id(sensor_wifi_signal).state + 100);
}
} else {
return NAN;
}
- platform: template
name: "${esp_name} Recorded Display Refresh"
lambda: 'return id(recorded_display_refresh);'
unit_of_measurement: "refreshes"
text_sensor:
- platform: homeassistant
entity_id: weather.forecast_home
id: weather_state
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_condition_now
id: weather_condition_now
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_condition_0
id: weather_condition_0
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_timestamp_0
id: weather_timestamp_0
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_condition_1
id: weather_condition_1
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_timestamp_1
id: weather_timestamp_1
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_condition_2
id: weather_condition_2
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_timestamp_2
id: weather_timestamp_2
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_condition_3
id: weather_condition_3
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: weather_timestamp_3
id: weather_timestamp_3
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: afval_today
id: afval_today
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: afval_tomorrow
id: afval_tomorrow
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: travel_Best_name
id: travel_Best_name
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: travel_ASML_name
id: travel_ASML_name
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.e_ink_display_data
attribute: travel_GGD_name
id: travel_GGD_name
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.moon_phase
#attribute: icon
id: moon_phase
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: homeassistant
entity_id: sensor.moon
id: moon
internal: true
# Sunrise
- platform: sun
type: sunrise
id: sun_sunrise
format: "%H:%M"
on_value:
then:
- lambda: 'id(data_updated) = true;'
# Sunset
- platform: sun
type: sunset
id: sun_sunset
format: "%H:%M"
on_value:
then:
- lambda: 'id(data_updated) = true;'
- platform: wifi_info
ssid:
name: "${esp_name} Connected SSID"
id: ssid
icon: mdi:wifi-strength-2
entity_category: diagnostic
bssid:
name: "${esp_name} Connected BSSID"
id: bssid
icon: mdi:wifi-strength-2
entity_category: diagnostic
mac_address:
name: "${esp_name} WiFi Mac Address"
id: macaddress
icon: mdi:wifi-strength-2
entity_category: diagnostic
- platform: sun
id: sunrise
name: Sun Next Sunrise
type: sunrise
format: "%H:%M"
internal: true
update_interval: never
- platform: sun
id: sunset
name: Sun Next Sunset
type: sunset
format: "%H:%M"
internal: true
update_interval: never
# 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%
- 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
cs_pin: GPIO27
dc_pin: GPIO16
busy_pin: GPIO25
reset_pin: GPIO26
#model: 7.50in-bV2
model: 7.50inv2b
#model: 7.50inv2
#model: 7.50inV2alt
update_interval: 1h
id: eink_display
rotation: 90°
lambda: |-
int xres = it.get_width();
int yres = it.get_height();
#define x_pad 10 // border padding
#define y_pad 10 // border padding
int wifi_x_a = xres-x_pad;
int wifi_y_a = yres-y_pad+2;
// Fill background in black.
it.fill(COLOR_OFF);
// wifi strength
// if (id(sensor_wifi_signal).has_state())
// {
if (id(sensor_wifi_signal).state >= -50) {
//Excellent
it.print(wifi_x_a, wifi_y_a, id(font_wifi), TextAlign::BASELINE_RIGHT, "󰤨");
ESP_LOGI("WiFi", "Excellent");
} else if (id(sensor_wifi_signal).state >= -60) {
//Good
it.print(wifi_x_a, wifi_y_a, id(font_wifi), TextAlign::BASELINE_RIGHT, "󰤥");
ESP_LOGI("WiFi", "Good");
} else if (id(sensor_wifi_signal).state >= -67) {
//Fair
it.print(wifi_x_a, wifi_y_a, id(font_wifi), TextAlign::BASELINE_RIGHT, "󰤢");
ESP_LOGI("WiFi", "Fair");
} else if (id(sensor_wifi_signal).state >= -70) {
//Weak
it.print(wifi_x_a, wifi_y_a, id(font_wifi), TextAlign::BASELINE_RIGHT, "󰤟");
ESP_LOGI("WiFi", "Weak");
} else {
//Unlikely working signal
it.print(wifi_x_a, wifi_y_a, id(font_wifi), TextAlign::BASELINE_RIGHT, "󰤫");
ESP_LOGI("WiFi", "Unlikely");
}
//}
// clock section
int clk_yoffset = 50;
int clk_xoffset = 310;
// Print full weekday name
it.strftime(clk_xoffset, clk_yoffset, id(font_weekday), TextAlign::TOP_RIGHT, "%A", id(esptime).now());
// Print time in HH:MM format 335
it.strftime(clk_xoffset, clk_yoffset+105, id(font_time), TextAlign::BASELINE_RIGHT, "%H:%M", id(esptime).now());
// Print day of the month
it.strftime(clk_xoffset+100, clk_yoffset, id(font_day), TextAlign::TOP_RIGHT, "%d", id(esptime).now());
// Print abbreviated month name
it.strftime(clk_xoffset+100, clk_yoffset+105, id(font_month), TextAlign::BASELINE_RIGHT, "%b", id(esptime).now());
int sry_offset = 200; //sunrise/set y-offset
// Print sunrise
it.printf(60, sry_offset, id(font_mdi_medium), COLOR_RED, TextAlign::CENTER_RIGHT, "\U000F059C");
if(id(sun_sunrise).has_state ()) {
it.printf(65, sry_offset, id(font_small_bold), TextAlign::CENTER_LEFT, "%s", id(sun_sunrise).state.c_str());
}
// Print sunset
it.printf(425, sry_offset, id(font_mdi_medium), COLOR_RED, TextAlign::CENTER_RIGHT, "\U000F059B");
if(id(sun_sunset).has_state ()) {
it.printf(385, sry_offset, id(font_small_bold), TextAlign::CENTER_RIGHT, "%s", id(sun_sunset).state.c_str());
}
// Moonphae
//it.printf(265, sry_offset, id(font_mdi_medlarge), TextAlign::CENTER, "%s", moon_icon_map[id(moon_phase).state.c_str()].c_str());
it.line(30, sry_offset+30, 420, sry_offset+30);
// Weather Section
int wy_offset = sry_offset + 60; //weather y offset
// WEATHER STATE ICON
it.printf(80, wy_offset, id(font_mdi_large), COLOR_RED, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_now).state.c_str()].c_str());
// TEMPERATURE
it.printf(410, wy_offset, id(font_large_bold), TextAlign::TOP_RIGHT, "%2.0f°C", id(weather_temperature).state);
int forecast_yoffset = wy_offset+30+108;
int fcst_xstart = 90;
int fcst_offset = 90;
it.printf(fcst_xstart, forecast_yoffset, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_0).state.c_str());
it.printf(fcst_xstart, forecast_yoffset+20, id(font_mdi_medium), COLOR_RED, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_0).state.c_str()].c_str());
it.printf(fcst_xstart, forecast_yoffset+72, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_0).state);
fcst_xstart += fcst_offset;
it.printf(fcst_xstart, forecast_yoffset, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_1).state.c_str());
it.printf(fcst_xstart, forecast_yoffset+20, id(font_mdi_medium), COLOR_RED, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_1).state.c_str()].c_str());
it.printf(fcst_xstart, forecast_yoffset+72, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_1).state);
fcst_xstart += fcst_offset;
it.printf(fcst_xstart, forecast_yoffset, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_2).state.c_str());
it.printf(fcst_xstart, forecast_yoffset+20, id(font_mdi_medium), COLOR_RED, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_2).state.c_str()].c_str());
it.printf(fcst_xstart, forecast_yoffset+72, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_2).state);
fcst_xstart += fcst_offset;
it.printf(fcst_xstart, forecast_yoffset, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(weather_timestamp_3).state.c_str());
it.printf(fcst_xstart, forecast_yoffset+20, id(font_mdi_medium), COLOR_RED, TextAlign::TOP_CENTER, "%s", weather_icon_map[id(weather_condition_3).state.c_str()].c_str());
it.printf(fcst_xstart, forecast_yoffset+72, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f°C", id(weather_temperature_3).state);
it.line(30, forecast_yoffset+102, 420, forecast_yoffset+102);
int drvtime_yoffset = forecast_yoffset+132;
int drvtime_xoffset = 40;
it.printf(drvtime_xoffset, drvtime_yoffset, id(font_mdi_medium), COLOR_RED, TextAlign::TOP_CENTER, "%s", weather_icon_map["car"].c_str());
it.printf(drvtime_xoffset+90, drvtime_yoffset, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(travel_Best_name).state.c_str());
it.printf(drvtime_xoffset+90, drvtime_yoffset+30, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f min", id(travel_Best_time).state);
it.printf(drvtime_xoffset+210, drvtime_yoffset, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(travel_ASML_name).state.c_str());
it.printf(drvtime_xoffset+210, drvtime_yoffset+30, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f min", id(travel_ASML_time).state);
it.printf(drvtime_xoffset+330, drvtime_yoffset, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(travel_GGD_name).state.c_str());
it.printf(drvtime_xoffset+330, drvtime_yoffset+30, id(font_small_bold), TextAlign::TOP_CENTER, "%2.0f min", id(travel_GGD_time).state);
it.line(30, drvtime_yoffset+60, 420, drvtime_yoffset+60);
int waste_yoffset = drvtime_yoffset+90;
int waste_xoffset = 60;
it.printf(waste_xoffset, waste_yoffset, id(font_mdi_medium), COLOR_RED, TextAlign::TOP_CENTER, "%s", weather_icon_map["trash"].c_str());
it.printf(waste_xoffset+100, waste_yoffset, id(font_small_bold), TextAlign::TOP_CENTER, "Vandaag:");
it.printf(waste_xoffset+260, waste_yoffset, id(font_small_bold), TextAlign::TOP_CENTER, "Morgen:");
it.printf(waste_xoffset+95, waste_yoffset+30, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(afval_today).state.c_str());
it.printf(waste_xoffset+255, waste_yoffset+30, id(font_small_bold), TextAlign::TOP_CENTER, "%s", id(afval_tomorrow).state.c_str());
// it.line(30, 400, 440, 400);
// it.printf(30, 520, id(font_mdi_medium), color_white, TextAlign::TOP_CENTER, "%s", moon_icon_map[id(moon_phace_icon).state.c_str()].c_str());
captive_portal: