Home Assistant – 7,5″ E-Paper Display (Waveshare) mit ESPHome ansteuern – Wetterstation

In diesem Tutorial beschreibe ich wie ein Waveshare e-Paper Display über ESPHome mit Home Assistant verbunden wird und als Wetterstation und zum Anzeigen weiterer Sensor Daten verwendet werden kann.

Hardware

  • E-Paper Display: Waveshare 7.5 Inch E-Paper Display HAT Module V2 Kit 800×480 Resolution. Das Display führt einen SPI Anschluss über ein Flachbandkabel heraus und kann ohne Lötarbeiten mit dem unten genannten ESP32 Driver Board verbunden werden.

  • ESP32 Driver Board: Waveshare Universal e-Paper Driver Board mit Wifi und Bluetooth. Das Board erlaubt den direkten Anschluss des Display über SPI. Wichtig ist hier die ESP32 Version zu kaufen. Es gibt auch ein ESP8266 Driver Board das ich zuerst gekauft habe. Dieses hat aber für das 7,5″ E-Paper Display nicht genug Leistung.
  • Gehäuse: Waveshare 7.5inch e-Paper Raw Panel Case. Das Gehäuse ist perfekt auf das Display abgestimmt.

  • Es wird mit Magneten zusammengehalten, so das das Display sehr schnell ein- und ausgebaut werden kann. Ich habe den ESP32 einfach auf der Rückseite montiert und mit Holz und etwas Farbe einen Ständer dran gebaut. Siehe obige Bilder. Sehr Flache Kontroller finden ggf. auch im Gehäuse Platz.

Software Konfiguration

Datenquelle – Home Assistant Weather Integration

Als Datenquelle für die Wetterinformationen nutze ich die Home Assistant Weather Integration. Diese ist in der Regel standardmäßig in Home Assitant integriert. Dabei handelt es sich um folgende Kachel im UI:

Gespeist wird die Kachel über den Sensor „weather.home“ den du in den „Entwicklerwerkzeuge -> Zustände“ finden solltest:

Um die Wetterdaten an das Display zu senden habe ich zwei neue Template Sensoren angelegt die die Werte als CSV (Comma Separated Values) dem Display zu Verfügung stellen. Die Sensoren müssen in der „config/configuration.yaml“ Datei eingetragen werden.

sensor:
 - platform: template
    sensors:
      epaper_weather_actual:
        #weahtericon;temperature;humidity,pressure;wind_speed
        value_template: "{{states('weather.home')}};{{state_attr('weather.home', 'temperature') | replace('.',',') }};{{state_attr('weather.home', 'humidity') | replace('.',',') }};{{state_attr('weather.home', 'pressure') | replace('.',',') }};{{state_attr('weather.home', 'wind_speed') | replace('.',',') }}"
      epaper_weather_forecast:
        value_template: "{{as_timestamp(state_attr('weather.home', 'forecast')[0]['datetime']) | timestamp_custom('%a') }};{{state_attr('weather.home', 'forecast')[0]['condition']}};{{state_attr('weather.home', 'forecast')[0]['temperature']| replace('.',',') }};{{state_attr('weather.home', 'forecast')[0]['templow']| replace('.',',') }};{{as_timestamp(state_attr('weather.home', 'forecast')[1]['datetime']) | timestamp_custom('%a') }};{{state_attr('weather.home', 'forecast')[1]['condition']}};{{state_attr('weather.home', 'forecast')[1]['temperature']| replace('.',',') }};{{state_attr('weather.home', 'forecast')[1]['templow']| replace('.',',') }};{{as_timestamp(state_attr('weather.home', 'forecast')[2]['datetime']) | timestamp_custom('%a') }};{{state_attr('weather.home', 'forecast')[2]['condition']}};{{state_attr('weather.home', 'forecast')[2]['temperature']| replace('.',',') }};{{state_attr('weather.home', 'forecast')[2]['templow']| replace('.',',') }};{{as_timestamp(state_attr('weather.home', 'forecast')[3]['datetime']) | timestamp_custom('%a') }};{{state_attr('weather.home', 'forecast')[3]['condition']}};{{state_attr('weather.home', 'forecast')[3]['temperature']| replace('.',',') }};{{state_attr('weather.home', 'forecast')[3]['templow']| replace('.',',') }};{{as_timestamp(state_attr('weather.home', 'forecast')[4]['datetime']) | timestamp_custom('%a') }};{{state_attr('weather.home', 'forecast')[4]['condition']}};{{state_attr('weather.home', 'forecast')[4]['temperature']| replace('.',',') }};{{state_attr('weather.home', 'forecast')[4]['templow']| replace('.',',') }}"
      epaper_sunrise:
        value_template: "{{ as_timestamp(state_attr('sun.sun', 'next_dawn')) | timestamp_custom('%H:%M') }}"
      epaper_sunset:
        value_template: "{{ as_timestamp(state_attr('sun.sun', 'next_dusk')) | timestamp_custom('%H:%M') }}"

ESP32 mit ESPHome einrichten

Das Display habe ich mit ESPHome eingerichtet. D.h. du must die ESPHome Integration in Home Assistant installieren und den ESP32 Mikrokontroller hinzufügen. Dazu verbindest du diesen mittels USB mit Home Assistant und gehst in die ESPHome Oberfläche:

Einstellungen -> Add-ons, Backups & Supervisor -> ESPHome -> Benutzeroberfläche öffnen

Hier kannst du dann mit mit „New Device“ den Mikrokontroller als ESP32 hinzufügen und diesem einen Namen geben. Siehe nachfolgende Screenshots:



Sobald der ESP32 in ESPHome integriert ist, sollte Home Assistant diesen als neue Integration finden. „Einstellungen -> Geräte & Dienste -> Integrationen“. Hier muss die Integration hinzugefügt werden, damit das Display auf die Wetterdaten von Home Assistant zugreifen kann.

ESPHome Display Konfiguration

Das Display nutzt Google Open Sans Font für die Schriften und Material Design Icon Font um z.B. die Wetter Bilder zu zeigen. Diese müsst ihr herunterladen und in den Order „config\esphome\fonts“ legen. Am einfachsten geht dies wenn ihr Samba auf dem Home Assistant einrichtet und dann über das Netzwerk auf die Verzeichnisse zugreift.
\\HOMEASSISTANT_IP\config\esphome\fonts

In der Konfiguration nutze ich die UniCodes der Bilder. Dies ist etwas robuster ein falsch eingestelltes Encoding der Konfigurationsdatei so keine Probleme bereitet. Die Unicodes der Material Design Icons kannst du hier finden.
Nachfolgend findest du meine ESPHome Konfiguration die eine Uhrzeit, Sonnen Auf- und Untergangzeiten, UpTime, WLAN Signalstärke und natürlich die Wetterdaten anzeigt:

esphome:
  name: epaper75

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

# Enable Home Assistant API
api:

ota:
  password: "OTAPW"

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

# --- 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
      ]
      
  - 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
     it.line(532, 108, 532, 440); // Vertical second line
     
    
     // Sunrise / Sunset
     it.printf(5, 40, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F059C");
     it.printf(35, 40, id(openSansBold_font), TextAlign::BOTTOM_LEFT, id(epaper_sunrise).state.c_str());
      
     it.printf(5, 70, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F059B");
     it.printf(35, 70, id(openSansBold_font), TextAlign::BOTTOM_LEFT, id(epaper_sunset).state.c_str());
     
     // Temperature inside / outside
     it.printf(100, 35, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F0F54"); 
     //it.printf(130, 40, id(openSansBold_font), TextAlign::BOTTOM_LEFT, "%s °C", id(temperature_inside).state.c_str()); // use your own temp sensor
     
     it.printf(100, 65, id(materialdesign_icons_25), TextAlign::BASELINE_LEFT, "\U000F0F55"); 
     //it.printf(130, 70, id(openSansBold_font), TextAlign::BOTTOM_LEFT, "%s °C", id(temperature_outside).state.c_str());// use your own temp sensor
     
     //Time
     it.strftime(540, 100, id(watch_font),TextAlign::BOTTOM_LEFT, "%H:%M", id(time_homeassistant).now());
     it.strftime(540, 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 <std::string, std::string> 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 = 5; 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 PA", value);
           } else if (i == 4) { // windpeed
              it.printf(x, y, id(openSansBold_font), TextAlign::BASELINE_LEFT,"%s m/s", value);
           }
           y += 25;
           previous = current + 1;
           current = actualWeatherCSV.find(delim, previous);
       }
     }
     
     // Weather Forecast
     if(id(epaper_weather_forecast).has_state()) {
       std::string forecastWeatherCSV = id(epaper_weather_forecast).state; // Mon;sunny;16,5;5,1;Tue;sunny;17,2;6,8;Wed;sunny;15,4;2,7;Thu;sunny;15,3;4,6;Fri;partlycloudy;16,0;3,5
       ESP_LOGI("Weather forecast", "%s", forecastWeatherCSV.c_str());
       std::size_t current, previous = 0;
       char delim = ';';
       current = forecastWeatherCSV.find(delim);
       x = 5; y = 270;
       int nextRow =0;
       for (int i=0; i<20; i++) {
           const char * value = forecastWeatherCSV.substr(previous, current - previous).c_str();
           if(i == 0 || i == 4 || i == 8 || i == 12 || i == 16) { // Weekday
              it.printf(x, y, id(openSansBold_font), TextAlign::BASELINE_LEFT,"%s", value);
           } else if (i == 1 || i == 5 || i == 9 || i == 13 || i == 17) { // icon
             it.printf(x + 50  , y, id(materialdesign_icons_32), TextAlign::BASELINE_LEFT, weatherMap.at(value).c_str()); 
           } else if (i == 2 || i == 6 || i == 10 || i == 14 || i == 18) { // Temp high
              it.printf(x + 100 , y, id(openSansBold_font), TextAlign::BASELINE_LEFT,"%s°C", value);
           } else if (i == 3 || i == 7 || i == 11 || i == 15 || i == 19) { // Temp low
              it.printf(x + 170, y, id(openSansBold_font), TextAlign::BASELINE_LEFT,"%s °C", value);
           }
           nextRow = nextRow + 1;
           if (nextRow == 4) {
             y += 28;
             nextRow = 0;
           }
           previous = current + 1;
           current = forecastWeatherCSV.find(delim, previous);
       }
     }
      
     // -- Footer ---
     //IP Adress
     if (id(ip_address).has_state()) {
         it.printf(5, 470, id(openSansBold_font), TextAlign::BASELINE_LEFT, "IP: %s", id(ip_address).state.c_str());
     }
      
     // WiFi Signal Strength
     if(id(wifisignal).has_state()) {
       x = 210, 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(520, 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

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_weather_forecast
    entity_id: sensor.epaper_weather_forecast
    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
Veröffentlicht in Home Assistant, Smarthome.

14 Kommentare

  1. Ein toller Artikel, der mich sofort inspiriert hat, mir das Display zuzulegen. Nun funktioniert es auch fast – aber bei den Wetterdaten bin ich am verzweifeln: Im oberen Teil werden die Symbole für Sonnenauf- und untergang, sowie Innen- und Außentemperatur werden angezeigt, aber keine Werte. Ebenso bleibt die „Wetter“-Spalte total leer. Die Sensoren scheinen nicht zu funktionieren, obwohl ich das Skript in der „Config“ entsprechend eingetragen habe. Was habe ich vielleicht falsch gemacht?

    • Danke! Ich habe das Skript für die Sensoren noch einmal aktualisiert (Datumsformatierung). Am besten einmal ausprobieren und Neustart nicht vergessen. Unter „Entwicklerwerkzeuge“ -> „Zustände“ müssten dann für die vier Sensoren die Werte kommasepariert stehen. Ansonsten mal schauen ob etwas für die Sensoren in den Logfiles steht: „Einstellungen“ -> „System“ -> „Protokolle“

  2. Hallo Marcus,

    ganz toll – es funktioniert jetzt!!!
    Bei der Außen- Innentemperaturanzeige kann es nicht funktionieren, weil ich da keinen eigenen temp-sensor definiert habe – das werde ich noch ausprobieren müssen. Aber der „dicke Brocken“ ist gelöst und das hilft mir sehr.

    Vielen Dank !!!

  3. Ach ja – oben werden bei Sonnenauf- und untergang weiterhin keine Werte gezeigt.
    Und im Skript ist „sensors“ unter „- platform: template“ eine Stelle zu weit nach rechts verschoben…

  4. Hallo nochmal,

    bei dem ESP-Skript habe ich in Zeile 367 und 371 „sensor.epaper_sunrise“ und „sensor.epaper_sunset“ (die bei meinen „Zuständen“ nicht vorhanden sind, mit „sensor.sun_next_rising“ und „sensor.sun_next_setting“ ersetzt – nun steht hinter den entsprechenden Symbolen auf meinem Display jeweils eine lange Zeichenkette mit Jahreszahl, Datum und Uhrzeit. Wo, im Skript muss ich es ändern, um nur die Uhrzeit angezeigt zu bekommen?

    • Hallo, eigentlich sollte es die Sensoren (epaper_sunrise / sunset) geben, die oben in dem Template definiert wurden. Dort ist auch die Formatierung des Werte auf die Uhrzeit drin. timestamp_custom(‚%H:%M‘)

  5. Vielen Dank,
    ich muss wohl irgendwie versäumt haben, die unteren Zeilen des Configurations-Skriptes zu kopieren. 🙄
    Ich habe die Zeilen nun nachträglich eingefügt und nach dem Neustart waren dann auch die Sensoren vorhanden. Also die Zeilen 367 und 371 wieder korrigiert und voila – es sieht perfekt aus.
    Vielen Dank für diesen tollen Blog-Beitrag und ganz besonders für den persönlichen Support!!! 🤗

  6. Hallo Marcus!

    Vielen Dank für die Anleitung! Dein Artikel war mein Start in die E-Paper Welt!
    Nach langem basteln und probieren habe ich es endlich geschafft mein 4,2″ Waveshare E-Paper ähnlich deiner Vorlage zu programmieren.
    Ich nutze allerdings OpenWeatherMap. Bei dem aktuellen Wetter funktioniert alles, aber bei der Vorhersage hängt es. In den Entwicklerwerkzeugen zeigt mir HomeAssistant den Forecast-Status als unavailable an. Hast du einen Tipp?

    • Hi Basti,
      sorry für die späte Antwort. Sind super viele Termine vor Weihnachten. Schön das mein Artikel dir weitergeholfen hat. OpenWeatherMap nutze ich nicht, daher kann ich dir leider nicht wirklich helfen. Im Prinzip müsstest du schauen wie die Sensoren heißen, die das Plugin zu Verfügung stellt und diese dann auslesen und in das Format „Mon;cloudy;7,9;7,2;“ überführen (Tag, wetter-icon, max-temp, min-temp). Das kann der ePaper Code dann anzeigen wenn der Sensor epaper_weather_forecast heißt. Die möglichen Icons sind die ab Zeile 116 im Code.

  7. Hallo Marcus,

    ich habe das Skript (mit individuellen Anpassungen) nun einige Zeit am Laufen. Nach ein paar Wochen habe ich feststellen müssen, dass das Display immer mehr an Kontrast verlor. Nach langer Recherche habe ich nun eine Lösung gefunden: in dem o.a. Skript habe ich die Zeilen 161 – 165 gelöscht – und siehe da: schwarz ist wieder schwarz und nicht hellgrau!
    Offensichtlich gibt es einen Bug mit der Darstellung von „Umrandungslinien“ beim ESP-Driver und dem ePaper. Falls Du das Problem mit dem „ausgeblichenen Display“ evtl. auch schon bemerkt hast, vielleicht hilft ja dieser „Workaround“…

  8. ein kleiner Hinweis: seit dem Update 2024.4.x von Home Assistant wurde die „Weather Forecast“ Funktion geändert. Dies hat zur Folge, dass die Anzeige in der beschriebenen Form nicht mehr funktioniert …

  9. Ja leider..

    fix!
    add

    template:
    – trigger:
    – platform: time_pattern
    minutes: /5
    action:
    – service: weather.get_forecasts
    data:
    type: daily
    target:
    entity_id: weather.forecast_home
    response_variable: daily
    sensor:
    – name: Forecast next days
    unique_id: Forecast_next_days
    state: „{{ daily[‚weather.forecast_home‘].forecast[0].condition }}“
    attributes:
    forecast: „{{ daily[‚weather.forecast_home‘].forecast }}“

    in die configuration.yaml

    helpers template mit:

    {{as_timestamp(state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[0].datetime) | timestamp_custom(‚%a‘) }};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[0].condition}};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[0].temperature| replace(‚.‘,‘,‘) }};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[0].templow| replace(‚.‘,‘,‘) }};{{as_timestamp(state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[1].datetime) | timestamp_custom(‚%a‘) }};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[1].condition}};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[1].temperature| replace(‚.‘,‘,‘) }};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[1].templow| replace(‚.‘,‘,‘) }};{{as_timestamp(state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[2].datetime) | timestamp_custom(‚%a‘) }};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[2].condition}};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[2].temperature| replace(‚.‘,‘,‘) }};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[2].templow| replace(‚.‘,‘,‘) }};{{as_timestamp(state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[3].datetime) | timestamp_custom(‚%a‘) }};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[3].condition}};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[3].temperature| replace(‚.‘,‘,‘) }};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[3].templow| replace(‚.‘,‘,‘) }};{{as_timestamp(state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[4].datetime) | timestamp_custom(‚%a‘) }};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[4].condition}};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[4].temperature| replace(‚.‘,‘,‘) }};{{state_attr(’sensor.forecast_next_days‘, ‚forecast‘)[4].templow| replace(‚.‘,‘,‘) }};

    ersetzen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert