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: sensor.moon id: moonphase - 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 # 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(78, 21, 305, 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(sub_sensor_font), 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(sub_sensor_font), 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(10, 115, id(mdi_small), TextAlign::BASELINE_LEFT, "󰊚"); //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(50, 115, id(sub_sensor_font), TextAlign::BASELINE_LEFT, "%4.1fhPa", air_pressure); } else { //Invalid or error value it.print(50, 115, id(sub_sensor_font), TextAlign::BASELINE_LEFT, "- hPa"); } /* 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"); } }