esphome: name: epaper75 esp32: board: esp32dev framework: type: arduino # Enable logging logger: # Enable Home Assistant API api: encryption: key: "tY/skPnkQn1sZRBYYJ4LL571z+aA1P463WvaX58ju2w=" ota: platform: esphome wifi: ssid: !secret wifi_ssid password: !secret wifi_password # Enable fallback hotspot (captive portal) in case wifi connection fails ap: ssid: "Epaper75 Fallback Hotspot" password: "FALLBACKPW" captive_portal: # Example configuration entry spi: clk_pin: 13 mosi_pin: 14 i2c: sda: 21 scl: 22 scan: True # --- Fonts -------------------------------------------------------------------- font: - file: 'fonts/OpenSans-Bold.ttf' id: openSansBold_font 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/OpenSans-Bold.ttf' id: watch_font size: 90 glyphs: [':', ".", '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] # https://pictogrammers.github.io/@mdi/font/6.5.95/ Unicodes - file: 'fonts/materialdesignicons-webfont.ttf' id: materialdesign_icons_25 size: 25 glyphs: [ "\U000F050F", # mdi-thermometer "\U000F0F55", # mdi-home-thermometer-outline "\U000F0F54", # mdi-home-thermometer "\U000F058E", # mdi-water-percent "\U000F029A", # mdi-gauge "\U000F059B", # mdi-weather-sunset "\U000F059C", # mdi-weather-sunrise "\U000F10C2", # mdi-thermometer-high "\U000F10C3", # mdi-thermometer-low "\U000F192D", # mid-transmission-tower-import "\U000F0D9C", # mdi-solar-pannel-larg "\U000F19A5" # mdi-solar-compas ] - file: 'fonts/materialdesignicons-webfont.ttf' id: materialdesign_icons_32 size: 32 glyphs: [ "\U000F091F", # mdi-wifi-strength-1 "\U000F0922", # mdi-wifi-strength-2 "\U000F0925", # mdi-wifi-strength-3 "\U000F0928", # mdi-wifi-strength-4 "\U000F092B", # mdi-wifi-strength-alert-outline "\U000F0590", # weather-cloudy "\U000F0F2F", # weather-cloudy-alert "\U000F0E6E", # weather-cloudy-arrow-right "\U000F0591", # weather-fog "\U000F0592", # weather-hail "\U000F0F30", # weather-hazy "\U000F0898", # weather-hurricane "\U000F0593", # weather-lightning "\U000F067E", # weather-lightning-rainy "\U000F0594", # weather-night "\U000F0F31", # weather-night-partly-cloudy "\U000F0595", # weather-partly-cloudy "\U000F0F32", # weather-partly-lightning "\U000F0F33", # weather-partly-rainy "\U000F0F34", # weather-partly-snowy "\U000F0F35", # weather-partly-snowy-rainy "\U000F0596", # weather-pouring "\U000F0597", # weather-rainy "\U000F0598", # weather-snowy "\U000F0F36", # weather-snowy-heavy "\U000F067F", # weather-snowy-rainy "\U000F0599", # weather-sunny "\U000F0F37", # weather-sunny-alert "\U000F14E4", # weather-sunny-off "\U000F059A", # weather-sunset "\U000F059B", # weather-sunset-down "\U000F059C", # weather-sunset-up "\U000F0F38", # weather-tornado "\U000F059D", # weather-windy "\U000F059E" # weather-windy-variant ] - file: 'fonts/materialdesignicons-webfont.ttf' id: materialdesign_icons_50 size: 80 glyphs: [ "\U000F0590", # weather-cloudy "\U000F0F2F", # weather-cloudy-alert "\U000F0E6E", # weather-cloudy-arrow-right "\U000F0591", # weather-fog "\U000F0592", # weather-hail "\U000F0F30", # weather-hazy "\U000F0898", # weather-hurricane "\U000F0593", # weather-lightning "\U000F067E", # weather-lightning-rainy "\U000F0594", # weather-night "\U000F0F31", # weather-night-partly-cloudy "\U000F0595", # weather-partly-cloudy "\U000F0F32", # weather-partly-lightning "\U000F0F33", # weather-partly-rainy "\U000F0F34", # weather-partly-snowy "\U000F0F35", # weather-partly-snowy-rainy "\U000F0596", # weather-pouring "\U000F0597", # weather-rainy "\U000F0598", # weather-snowy "\U000F0F36", # weather-snowy-heavy "\U000F067F", # weather-snowy-rainy "\U000F0599", # weather-sunny "\U000F0F37", # weather-sunny-alert "\U000F14E4", # weather-sunny-off "\U000F059A", # weather-sunset "\U000F059B", # weather-sunset-down "\U000F059C", # weather-sunset-up "\U000F0F38", # weather-tornado "\U000F059D", # weather-windy "\U000F059E" # weather-windy-variant ] # --- Display Layout ----------------------------------------------------------- display: - platform: waveshare_epaper cs_pin: 15 dc_pin: 27 busy_pin: 25 reset_pin: 26 model: 7.50inv2 update_interval: 60s lambda: | int x, y; // Grid it.line(0, 108, 800, 108); // Horizontal header it.line(0, 440, 800, 440); // Horizontal footer it.line(266, 108, 266, 440); // Vertical first line // Sunrise / Sunset it.printf(30, 40, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F059C"); it.printf(70, 40, id(openSansBold_font), TextAlign::BOTTOM_LEFT, id(epaper_sunrise).state.c_str()); it.printf(30, 70, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F059B"); it.printf(70, 70, id(openSansBold_font), TextAlign::BOTTOM_LEFT, id(epaper_sunset).state.c_str()); // Temperature inside / outside it.printf(135, 40, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F0F54"); it.printf(165, 40, id(openSansBold_font), TextAlign::BOTTOM_LEFT, "%.1f °C", id(inside_temperatur).state); // use your own temp sensor it.printf(135, 65, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F029A"); it.printf(165, 70, id(openSansBold_font), TextAlign::BOTTOM_LEFT, "%.1f %%", id(inside_humidity).state);// use your own temp sensor //Time it.strftime(530, 100, id(watch_font),TextAlign::BOTTOM_LEFT, "%H:%M", id(time_homeassistant).now()); it.strftime(520, 110, id(openSansBold_font),TextAlign::BOTTOM_LEFT, "%A, %d.%m.%y, KW %W", id(time_homeassistant).now()); // Current weather // https://www.home-assistant.io/integrations/weather/ // weahtericon;temperature;humidity,pressure;wind_speed // ex. data: cloudy;5,9;50;1025,6;16,9 std::map weatherMap = { std::make_pair("exceptional","\U000F0F2F"), std::make_pair("cloudy","\U000F0590"), std::make_pair("cloudy-alert","\U000F0F2F"), std::make_pair("fog","\U000F0591"), std::make_pair( "hail","\U000F0592"), std::make_pair( "hazy","\U000F0F30"), std::make_pair( "hurricane","\U000F0898"), std::make_pair( "lightning","\U000F0593"), std::make_pair( "lightning-rainy","\U000F067E"), std::make_pair( "night","\U000F0594"), std::make_pair( "clear-night","\U000F0594"), std::make_pair( "night-partly-cloudy","\U000F0F31"), std::make_pair( "partly-cloudy","\U000F0595"), std::make_pair( "partlycloudy","\U000F0595"), std::make_pair( "partly-lightning","\U000F0F32"), std::make_pair( "partly-rainy","\U000F0F33"), std::make_pair( "partly-snowy","\U000F0F34"), std::make_pair( "partly-snowy-rainy","\U000F0F35"), std::make_pair( "pouring","\U000F0596"), std::make_pair( "rainy","\U000F0597"), std::make_pair( "snowy","\U000F0598"), std::make_pair( "snowy-heavy","\U000F0F36"), std::make_pair( "snowy-rainy","\U000F067F"), std::make_pair( "sunny","\U000F0599"), std::make_pair( "sunny-alert","\U000F0F37"), std::make_pair( "sunny-off","\U000F14E4"), std::make_pair( "tornado","\U000F0F38"), std::make_pair( "windy","\U000F059D"), std::make_pair( "windy-variant","\U000F059E")}; if(id(epaper_weather_actual).has_state()) { std::string actualWeatherCSV = id(epaper_weather_actual).state; //("cloudy;5,9;50;1025,6;16,9"); ESP_LOGI("Weather today", "%s", actualWeatherCSV.c_str()); std::size_t current, previous = 0; char delim = ';'; current = actualWeatherCSV.find(delim); x = 30; y = 200; for (int i=0; i<5; i++) { const char * value = actualWeatherCSV.substr(previous, current - previous).c_str(); if(i == 0) { // icon std::string unicodeWeatherIcon = weatherMap.at(value); it.printf(x , y, id(materialdesign_icons_50), TextAlign::BASELINE_LEFT, unicodeWeatherIcon.c_str()); y = 120; x = x + 90; } else if (i == 1) { // temperature it.printf(x, y, id(openSansBold_font), TextAlign::BASELINE_LEFT,"%s °C", value); } else if (i == 2) { // humidity it.printf(x, y, id(openSansBold_font), TextAlign::BASELINE_LEFT,"%s %s", value, "%"); } else if (i == 3) { // pressure it.printf(x, y, id(openSansBold_font), TextAlign::BASELINE_LEFT,"%s hPa", value); } else if (i == 4) { // windpeed it.printf(x, y, id(openSansBold_font), TextAlign::BASELINE_LEFT,"%s km/h", value); } y += 25; previous = current + 1; current = actualWeatherCSV.find(delim, previous); } } it.printf(35, 300, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F192D"); it.printf(75, 300, id(openSansBold_font), TextAlign::BOTTOM_LEFT, "%.1f W", id(gesammtverbrauch).state); it.printf(35, 330, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F0D9C"); it.printf(75, 330, id(openSansBold_font), TextAlign::BOTTOM_LEFT, "%.1f W", id(sollar_power).state); it.print(160, 327, id(openSansBold_font), TextAlign::BOTTOM_LEFT, "___"); it.printf(35, 360, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F19A5"); it.printf(75, 360, id(openSansBold_font), TextAlign::BOTTOM_LEFT, "%.1f W", id(solar_forcast_now).state); it.print(160, 359, id(openSansBold_font), TextAlign::BOTTOM_LEFT, "----"); it.graph(266, 108, id(power_graph)); // -- Footer --- //IP Adress if (id(ip_address).has_state()) { it.printf(25, 470, id(openSansBold_font), TextAlign::BASELINE_LEFT, "IP: %s", id(ip_address).state.c_str()); } // WiFi Signal Strength if(id(wifisignal).has_state()) { x = 235, y = 475; if (id(wifisignal).state >= -50) { it.print(x, y, id(materialdesign_icons_32), TextAlign::BOTTOM_RIGHT, "\U000F0928"); ESP_LOGI("WiFi", "Exellent"); } else if (id(wifisignal).state >= -60) { it.print(x, y, id(materialdesign_icons_32), TextAlign::BOTTOM_RIGHT, "\U000F0925"); ESP_LOGI("WiFi", "Good"); } else if (id(wifisignal).state >= -67) { it.print(x, y, id(materialdesign_icons_32), TextAlign::BOTTOM_RIGHT, "\U000F0922"); ESP_LOGI("WiFi", "Fair"); } else if (id(wifisignal).state >= -70) { it.print(x, y, id(materialdesign_icons_32), TextAlign::BOTTOM_RIGHT, "\U000F091F"); ESP_LOGI("WiFi", "Weak"); } else { it.print(x, y, id(materialdesign_icons_32), TextAlign::BOTTOM_RIGHT, "\U000F092B"); ESP_LOGI("WiFi", "Unlikely"); } } // ESP Home UpTime if (id(uptime_human).has_state()) { it.printf(570, 470, id(openSansBold_font), TextAlign::BASELINE_LEFT, "UpTime: %s", id(uptime_human).state.c_str()); } # --- Sensors ------------------------------------------------------------------ sensor: # ESP Home UpTime - platform: uptime id: uptime_sensor update_interval: 60s on_raw_value: then: - text_sensor.template.publish: id: uptime_human state: !lambda |- int seconds = round(id(uptime_sensor).raw_state); int days = seconds / (24 * 3600); seconds = seconds % (24 * 3600); int hours = seconds / 3600; seconds = seconds % 3600; int minutes = seconds / 60; seconds = seconds % 60; return ( (days ? String(days) + ":" : "000:") + (hours ? String(hours) + ":" : "00:") + (minutes ? String(minutes) + ":" : "00:") + (String(seconds) + "") ).c_str(); - platform: wifi_signal id: wifisignal update_interval: 60s - platform: aht10 temperature: id: "inside_temperatur" name: "Temperatur" humidity: id: "inside_humidity" name: "Luftfeuchte" update_interval: 30s - platform: homeassistant id: solar_forcast_now entity_id: sensor.power_production_now internal: true - platform: homeassistant id: sollar_power entity_id: sensor.shellyplus1pm_4855199bbb3c_switch_0_power internal: true - platform: homeassistant id: gesammtverbrauch entity_id: sensor.gesamtverbrauch internal: true text_sensor: # ESP WLAN IP Address - platform: wifi_info ip_address: name: "${name} IP Address" id: ip_address # ESP Home UpTime - platform: template id: uptime_human icon: mdi:clock-start # Weather forecast - platform: homeassistant id: epaper_weather_actual entity_id: sensor.epaper_weather_actual internal: true - platform: homeassistant id: epaper_sunrise entity_id: sensor.epaper_sunrise internal: true - platform: homeassistant id: epaper_sunset entity_id: sensor.epaper_sunset internal: true time: - platform: homeassistant id: time_homeassistant graph: - id: power_graph duration: 24h x_grid: 4h width: 515 height: 333 traces: - sensor: sollar_power line_type: SOLID line_thickness: 5 - sensor: solar_forcast_now line_type: DASHED line_thickness: 5