homeassistant-config/esphome/epaperframe.yaml

436 lines
15 KiB
YAML

esphome:
name: epaperframe
platform: ESP32
board: nodemcu-32s
on_boot:
priority: -10
then:
- delay: 10s
- component.update: epaper
wifi:
ssid: "Voltage-legacy"
password: !secret voltage_legacy_psk
use_address: epaperframe.home
power_save_mode: high
fast_connect: on
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Epaperframe Fallback Hotspot"
password: !secret fallback_psk
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
password: !secret api
# encryption:
# key: !secret apikey
ota:
password: !secret ota
# Refresh screen on button click
binary_sensor:
- platform: gpio
pin:
number: GPIO18
mode: INPUT_PULLUP
inverted: True
name: "Refresh screen"
internal: True
on_click:
then:
- logger.log:
level: INFO
format: 'Button pressed, refreshing screen!'
- component.update: epaper
# DHT22 sensor
sensor:
- platform: dht
model: dht22
pin: 22
temperature:
name: "Temperatur"
humidity:
name: "Luftfeuchtigkeit"
update_interval: 60s
# WiFi signal strength
- platform: wifi_signal
name: "WiFi Signalstärke"
id: wifisignal
update_interval: 60s
- platform: homeassistant
entity_id: sensor.wohnzimmer_feinstaub_pm_2_5um
id: pm25_livingroom
- platform: homeassistant
entity_id: sensor.wohnzimmer_temperatur
id: temp_livingroom
- platform: homeassistant
entity_id: sensor.wohnzimmer_luftfeuchtigkeit
id: humid_livingroom
- platform: homeassistant
entity_id: sensor.temperatur_aussen
id: temp_outdoor
- platform: homeassistant
entity_id: sensor.luftfeuchtigkeit_aussen
id: humid_outdoor
- platform: homeassistant
entity_id: sensor.schlafzimmer_luftdruck
id: airpressure
- platform: homeassistant
entity_id: zone.home
attribute: latitude
id: home_lat
- platform: homeassistant
entity_id: zone.home
attribute: longitude
id: home_long
text_sensor:
- platform: homeassistant
entity_id: sun.sun
id: sun_state
internal: True
# - platform: homeassistant
# entity_id: sun.sun
# id: sun_rise
# attribute: next_rising
# internal: True
# - platform: homeassistant
# entity_id: sun.sun
# id: sun_set
# attribute: next_setting
# internal: True
- platform: sun
name: "Nächster Sonnenaufgang"
id: sun_rise
type: sunrise
format: "%H:%M"
internal: True
- platform: sun
name: "Nächster Sonnenuntergang"
id: sun_set
type: sunset
format: "%H:%M"
internal: True
- platform: homeassistant
entity_id: sensor.moon
id: moonphase
# Webserver configuration entry
web_server:
port: 80
# css_include: "esphome-docs/_static/webserver-v1.min.css"
# css_url: ""
# js_include: "../../../esphome-docs/_static/webserver-v1.min.js"
# js_url: ""
auth:
username: admin
password: !secret web_server_password
sun:
latitude: id(home_lat)
longitude: id(home_long)
id: sun_sun
time:
- platform: homeassistant
id: homeassistant_time
# Font definitions
font:
- file: 'fonts/Roboto-Medium.ttf'
id: roboto_med_30
size: 30
- file: 'fonts/Roboto-Regular.ttf'
id: footer_font
size: 15
glyphs:
['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z','å', 'ä', 'ö', '/','º','µ','³','ß']
- file: 'fonts/Roboto-Regular.ttf'
id: big_sensor_unit
size: 20
glyphs:
['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', 'å', 'ä', 'ö', '/','º','µ','³','ß']
- file: 'fonts/Roboto-Medium.ttf'
id: sub_sensor_font
size: 30
glyphs:
['&', '@', '!', ',', '.', '"', '%', '(', ')', '+', '-', '_', ':', '°', '0',
'1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z', 'å', 'ä', 'ö', '/','º','µ','³','ß']
- file: 'fonts/Roboto-Bold.ttf'
id: big_sensor_font
size: 80
- file: 'fonts/materialdesignicons-webfont.ttf'
id: mdi_small
size: 31
glyphs: [
'󰔏', # mdi-themometer
'󰖎', # mdi-water-percent
'󰂵', # mdi-blur (pm2.5)
'󰟤', # mdi-co2
'󰊚', # mdi-gauge (air pressure)
'󰖙', # mdi-weather-sunny
'󰖛', # mdi-weather-sunset-down
'󰖜', # mdi-weather-sunset-up
'󰽡', # mdi-moon-first-quarter
'󰽢', # mdi-moon-full
'󰽣', # mdi-moon-last-quarter
'󰽤', # mdi-moon-new
'󰽥', # mdi-moon-waning-crescent
'󰽦', # mdi-moon-waning-gibbous
'󰽧', # mdi-moon-waxing-crescent
'󰽨', # mdi-moon-waxing-gibbous
]
- file: 'fonts/materialdesignicons-webfont.ttf'
id: mdi_wifi
size: 20
glyphs: [
# Wifi
'󰤫', # mdi-wifi-strength-alert-outline
'󰤟', # mdi-wifi-strength-1
'󰤢', # mdi-wifi-strength-2
'󰤥', # mdi-wifi-strength-3
'󰤨' # mdi-wifi-strength-4
]
- file: 'fonts/materialdesignicons-webfont.ttf'
id: mdi_med
size: 33
glyphs: [
'󰀦' # mdi-alert
]
spi:
clk_pin: 23
mosi_pin: 32
display:
- platform: waveshare_epaper
id: epaper
cs_pin: 27
dc_pin: 26
busy_pin: 33
reset_pin: 25
model: 7.50in
# full_update_every: 30 # not supported on this display
update_interval: never
lambda: |-
int pm25_danger_thres = 40;
float outdoor_temp = id(temp_outdoor).state;
int outdoor_humid = int(id(humid_outdoor).state);
float air_pressure = id(airpressure).state;
float livingroom_temp = id(temp_livingroom).state;
int livingroom_humid = int(id(humid_livingroom).state);
int livingroom_pm25 = int(id(pm25_livingroom).state);
// Format: 2021-10-08T05:40:47.467076+00:00
//struct tm tm;
//strptime(id(sun_rise).state.c_str(), '%Y-%m-%dT%H:%M:%S.%f%z');
//std::string sunrise = printf("%d:%d", tm.tm_hour, tm.tm_min);
/* OUTSIDE */
it.print(10, 10, id(big_sensor_unit), "Umwelt");
// Draw the outline of a rectangle with the top left at [78,21], a width of 305 and a height of 3
it.filled_rectangle(86, 21, 297, 3);
if(id(sun_state).has_state()) {
ESP_LOGI("Sun", "State of the sun: %s", id(sun_state).state.c_str());
ESP_LOGD("Sun", "Sunset: %s", id(sun_set).state.c_str());
ESP_LOGD("Sun", "Sunrise ESPHOME: %s", id(sun_rise).state.c_str());
//ESP_LOGD("Sun", "Sunrise ESPHOME: %s, Sunrise HA: %s", id(sun_rise).state.c_str(), sunrise.c_str());
//ESP_LOGD("Location", "Latitude: %f, Longitude: %f", id(home_lat).state, id(home_long).state);
//if(id(sun_state).state == "above_horizon") {
it.print(10, 75, id(mdi_small), TextAlign::BASELINE_LEFT, "󰖜"); //sun-up
it.printf(50, 75, id(big_sensor_unit), TextAlign::BASELINE_LEFT, "%s", id(sun_rise).state.c_str());
it.print(135, 75, id(mdi_small), TextAlign::BASELINE_LEFT, "󰖛"); //sun-down
it.printf(175, 75, id(big_sensor_unit), TextAlign::BASELINE_LEFT, "%s", id(sun_set).state.c_str());
//it.strftime(50, 75, id(footer_font), TextAlign::BASELINE_LEFT, "Nächster Sonnenuntergang %d.%m.%Y %H:%M", id(sun_set).state.c_str());
//}
//else {
//it.print(10, 75, id(mdi_small), TextAlign::BASELINE_LEFT, "󰖛"); //sun-down
//it.strftime(50, 75, id(footer_font), TextAlign::BASELINE_LEFT, "Nächster Sonnenaufgang %d.%m.%Y %H:%M", id(sun_rise));
//}
}
it.print(250, 115, id(mdi_small), TextAlign::BASELINE_CENTER, "󰊚"); //air-pressure
it.print(375, 75, id(mdi_small), TextAlign::BASELINE_CENTER, "󰔏"); //thermometer
it.print(375, 115, id(mdi_small), TextAlign::BASELINE_CENTER, "󰖎"); //water-percent
if(outdoor_temp > -100 && outdoor_temp < 100) {
it.printf(357, 75, id(sub_sensor_font), TextAlign::BASELINE_RIGHT, "%2.1fºC", outdoor_temp);
}
else {
it.print(357, 75, id(sub_sensor_font), TextAlign::BASELINE_RIGHT, " - ºC");
}
if(outdoor_humid >=0 && outdoor_humid <= 100) {
it.printf(357, 115, id(sub_sensor_font), TextAlign::BASELINE_RIGHT, "%3d%%", outdoor_humid);
}
else {
it.print(357, 115, id(sub_sensor_font), TextAlign::BASELINE_RIGHT, " - %");
}
if(air_pressure < 1200 && air_pressure >=800) { //Has valid value
it.printf(228, 115, id(sub_sensor_font), TextAlign::BASELINE_RIGHT, "%4.1fhPa", air_pressure);
}
else { //Invalid or error value
it.print(228, 115, id(sub_sensor_font), TextAlign::BASELINE_RIGHT, "- hPa");
}
/* Moon phase display */
if(id(moonphase).has_state()) {
int x = 10;
int y = 116;
if (id(moonphase).state == "new_moon") {
// new moon
it.print(x, y, id(mdi_small), TextAlign::BASELINE_LEFT, "󰽤");
ESP_LOGI("Moonphase", "new moon");
} else if (id(moonphase).state == "waxing_crescent") {
// waxing crescent
it.print(x, y, id(mdi_small), TextAlign::BASELINE_LEFT, "󰽧");
ESP_LOGI("Moonphase", "waxing crescent");
} else if (id(moonphase).state == "first_quarter") {
// first_quarter
it.print(x, y, id(mdi_small), TextAlign::BASELINE_LEFT, "󰽡");
ESP_LOGI("Moonphase", "first quarter");
} else if (id(moonphase).state == "waxing_gibbous") {
// waxing gibbous
it.print(x, y, id(mdi_small), TextAlign::BASELINE_LEFT, "󰽨");
ESP_LOGI("Moonphase", "waxing gibbous");
} else if (id(moonphase).state == "full_moon") {
// full moon
it.print(x, y, id(mdi_small), TextAlign::BASELINE_LEFT, "󰽢");
ESP_LOGI("Moonphase", "full moon");
} else if (id(moonphase).state == "waning_gibbous") {
// waning gibbous
it.print(x, y, id(mdi_small), TextAlign::BASELINE_LEFT, "󰽦");
ESP_LOGI("Moonphase", "waning gibbous");
} else if (id(moonphase).state == "last_quarter") {
// last quarter
it.print(x, y, id(mdi_small), TextAlign::BASELINE_LEFT, "󰽣");
ESP_LOGI("Moonphase", "last quarter");
} else if (id(moonphase).state == "waning_crescent") {
// waning crescent
it.print(x, y, id(mdi_small), TextAlign::BASELINE_LEFT, "󰽥");
ESP_LOGI("Moonphase", "waning crescent");
} else {
// N/A
it.print(x, y, id(sub_sensor_font), TextAlign::BASELINE_LEFT, "-");
ESP_LOGE("Moonphase", "No data");
}
}
/* INSIDE */
int offsetY = 137;
it.print(10, 10 + offsetY, id(big_sensor_unit), "INSIDE");
it.filled_rectangle(78, 21 + offsetY, 305, 3);
it.print(10, 114 + offsetY, id(big_sensor_unit), TextAlign::BASELINE_LEFT, "PM2.5");
it.print(375, 75 + offsetY, id(mdi_small), TextAlign::BASELINE_CENTER, "󰔏"); //thermometer
it.print(375, 115 + offsetY, id(mdi_small), TextAlign::BASELINE_CENTER, "󰖎"); //water-percent
if(livingroom_temp > -100 && livingroom_temp < 100){
it.printf(357, 75 + offsetY, id(sub_sensor_font), TextAlign::BASELINE_RIGHT , "%2.1fºC", livingroom_temp);
}else{
it.print(357, 75 + offsetY, id(sub_sensor_font), TextAlign::BASELINE_RIGHT , " - ºC");
}
if(livingroom_humid >=0 && livingroom_humid <= 100){
it.printf(357, 115 + offsetY, id(sub_sensor_font), TextAlign::BASELINE_RIGHT , "%3d%%", livingroom_humid);
}else{
it.print(357, 115 + offsetY, id(sub_sensor_font), TextAlign::BASELINE_RIGHT , " - %");
}
if(livingroom_pm25 < 255 && livingroom_pm25 >=0){
if (livingroom_pm25 > 99){
it.printf(205, 114 + offsetY, id(big_sensor_font), TextAlign::BASELINE_RIGHT , "%3d", livingroom_pm25);
it.print(210, 114 + offsetY, id(big_sensor_unit),TextAlign::BASELINE_LEFT, "µg/m³");
}else{
it.printf(175, 114 + offsetY, id(big_sensor_font), TextAlign::BASELINE_RIGHT , "%2d", livingroom_pm25);
it.print(180, 114 + offsetY, id(big_sensor_unit),TextAlign::BASELINE_LEFT, "µg/m³");
}
if(livingroom_pm25 >= pm25_danger_thres){
it.print(37, 87 + offsetY, id(mdi_med), TextAlign::BASELINE_CENTER, "󰀦"); //warning
}
}
else{
it.print(175, 114 + offsetY, id(big_sensor_font), TextAlign::BASELINE_RIGHT , "- ");
it.print(180, 114 + offsetY, id(big_sensor_unit),TextAlign::BASELINE_LEFT, "µg/m³");
}
/* FOOTER */
it.strftime(610, 374 , id(footer_font), TextAlign::BASELINE_RIGHT , "Letzte Aktualisierung %d.%m.%Y %H:%M", id(homeassistant_time).now());
/* WiFi Signal Strenght */
if(id(wifisignal).has_state()) {
int x = 626;
int y = 376;
if (id(wifisignal).state >= -50) {
//Excellent
it.print(x, y, id(mdi_wifi), TextAlign::BASELINE_CENTER, "󰤨");
ESP_LOGI("WiFi", "Excellent");
} else if (id(wifisignal).state >= -60) {
//Good
it.print(x, y, id(mdi_wifi), TextAlign::BASELINE_CENTER, "󰤥");
ESP_LOGI("WiFi", "Good");
} else if (id(wifisignal).state >= -75) {
//Fair
it.print(x, y, id(mdi_wifi), TextAlign::BASELINE_CENTER, "󰤢");
ESP_LOGI("WiFi", "Fair");
} else if (id(wifisignal).state >= -100) {
//Weak
it.print(x, y, id(mdi_wifi), TextAlign::BASELINE_CENTER, "󰤟");
ESP_LOGI("WiFi", "Weak");
} else {
//Unlikely working signal
it.print(x, y, id(mdi_wifi), TextAlign::BASELINE_CENTER, "󰤫");
ESP_LOGI("WiFi", "Unlikely");
}
}