Nachdem wir im ersten Schritt erfolgreich ein erstes Device mit ESPHome geflasht und im zweiten Schritt Daten per MQTT eines ioBroker abonniert haben, können wir nun ein Display anschließen und die Daten auf dem Display anzeigen.

Für dieses kleine Projekt benötigen wir nicht viele Komponenten und müssen auch für einen ersten Testaufbau nicht den Lötkolben bemühen. Hierzu müssen wir lediglich sicherstellen, dass unser eingesetzter ESP32 und auch das Display Pinouts mit „Füßchen“ haben, um über female-female Jumper-Kabel die Verbindung der beiden Devices herstellen zu können. In unserem Fall setzen wir ein 1,77″ OLED-Display ein, ESPHome bietet eine breite Varianz an Display-Möglichkeiten an: https://esphome.io/#display-components


Unsere Empfehlungen


Für die Anzeige der Daten auf unserem Display gehen wir in zwei Schritten vor:

  1. Anschluss des Displays an den ESP32
  2. Erweiterung der YAML-Konfiguration unseres ESPHome Devices

Der Anschluss des Displays ist mit Hilfe von female-female-Jumper-Kabeln schnell erledigt. Für den dauerhaften Betrieb empfehlen wir allerdings die Verbindungen zu verlöten, die Jumper-Kabel sind eine wackelige Angelegenheit und häufig auch Fehlerquelle, wenn mal etwas nicht wie erwartet funktioniert.

Insgesamt benötigen wir acht Kabel und Verbindungen zwischen dem ESP32 und dem Display:

  1. GND für Display
  2. VCC für Display
  3. VCC für Displaybeleuchtung
  4. SCK-Anschluss am Display
  5. SDA-Anschluss am Display
  6. reset-Anschluss am Display
  7. RS-Anschluss am Display
  8. CS-Anschluss am Display

Die Pins sind am Display entsprechend beschriftet.

Wir nehmen also die Jumperkabel und erstellen folgende Verbindung (wichtig für die Konfiguration, die wir weiter unten im Artikel näher beschreiben):

ESP32 GND >> Display GND
ESP32 3.3V >> Display VCC
ESP32 GPIO22 >> Display SCK
ESP32 GPIO21 >> Display SDA
ESP32 GPIO4 >> Display RES
ESP32 GPIO18 >> Display CS
ESP32 GPIO19 >> Display RS
ESP32 GPIO23 >> Display LEDA

Wir können den Aufbau auch auf einem Breadbord vornehmen:

ST7735 mit ESP32 und ESPHOME

ST7735 mit ESP32 und ESPHOME

Für die Erweiterung unserer YAML-Konfiguration nutzen wir die Dokumentation, die ESPHome bietet. Für das eingesetzte Display finden wir hier alle Details.

Der Standard-Code für das Display lautet nach Dokumentation:

# Example configuration entry
display:
  - platform: st7735
    model: "INITR_18BLACKTAB"
    reset_pin: D4
    cs_pin: D1
    dc_pin: D2
    rotation: 0
    device_width: 128
    device_height: 160
    col_start: 0
    row_start: 0
    eight_bit_color: true
    update_interval: 5s

Die Ansteuerung erfolgt über die SPI-Schnittstelle:

# Example configuration entry
spi:
  clk_pin: GPIO14
  mosi_pin: GPIO13

Die Konfiguration ist mit etwas Erfahrung eigentlich sehr einfach. Wir benötigen neben VCC und GND (also + und – für die Stromversorgung) lediglich 5 Kabel und Zuordnungen zu den GPIOs des ESP32. Es gibt diverse Typen von unterschiedlichen ESP32, mit 30 oder 36 Pins und auch unterschiedlichen Beschriftungen. Theoretisch können alle GPIOs benutzt werden, manche sind aber nur für die Verarbeitung von Inputs und nicht von Output-Signalen, z.B. für ein Display.

In unserem Fall nutzen wir die PINs GPIO4, GPIO18, GPIO19, GPIO21, GPIO22. Unsere Konfiguration sieht also wie folgt aus:

# Example configuration for ST7735
spi:
  clk_pin: GPIO22 #SCK
  mosi_pin: GPIO21 # SDA


display:
  - platform: st7735
    model: "INITR_BLACKTAB"
    reset_pin: GPIO4 # RES
    cs_pin: GPIO18 # RS
    dc_pin: GPIO19 #CS
    rotation: 90
    device_width: 128
    device_height: 160
    col_start: 0
    row_start: 0
    eight_bit_color: true
    update_interval: 500ms
    id: WD1
    lambda: |-
      auto green = Color(0, 255, 0);
      it.filled_rectangle(0, 0, 97, 30, green);

Mit diesen Einstellungen konnten wir dem Display erstes Leben einhauchen und ein grünes Rechteck zeichnen.

Jetzt wird es nochmals spannend: Für die Einbindung von Schriften müssen wir wieder etwas Vorarbeit leisten. a) wir benötigen die gewünschten Schriften als TTF-Files auf dem Raspberry PI, auf dem das ioBroker zur Kompilierung von ESPHome liegt und b) müssen wir in der Konfiguration die Schriften „konfigurieren“ und definieren, also z.B. Schriftgröße.

Wir nutzen außerdem Materialdesignicons als Schrift, um Symbole nutzen zu können. Um Speicher zu sparen, laden wir nicht die vollständigen Schriften in die kompilierte Firmware, sondern nutzen nur die Zeichen, die wir auch benötigen.

Die Konfiguration sieht bei uns wie folgt aus:

font:
  - file: "Fonts/Verdana.ttf"
    id: Verdana10
    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','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']    
    size: 10


  - file: "Fonts/Verdana.ttf"
    id: Verdana12
    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','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']    
    size: 12


  - file: "Fonts/Verdana.ttf"
    id: Verdana16
    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','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']    
    size: 16


  - file: "Fonts/Verdana_Bold.ttf"
    id: VerdanaBold16
    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','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']    
    size: 16


  - file: "Fonts/materialdesignicons.ttf"
    id: Icons60
    size: 25
    glyphs:
    - "\U000F1A74" # Solar
    - "\U000F1904" # Haus
    - "\U000F1AAF" # Heizung
    - "\U000F058F" # Wasserhahn

Wir nutzen Verdana und materialdesignicons als Basisschriftarten. Die TTF-Dateien lassen sich einfach im Internet finden, diese müssen dann im Verzeichnis /opt/iobroker/iobroker-data/esphome.0/fonts abgelegt werden.

Fonts für ESPHome in ioBroker

Fonts für ESPHome in ioBroker

Um einen Text auf dem Display zu platzieren, wird die Platzierung über die Koordinaten aus dem linken oberen Eck definiert. 0,0 wäre als ganz oben links, 128,160 ganz unten rechts. Um es noch komplizierter zu machen: Welche Stelle des Textes genau den Punkt der Platzierung beschreibt, lässt sich angeben. Also z.B. bei normal ausgerichtetem Text bietet sich links oben an. Möchten wir Text in mehreren Zeilen mittig ausrichten, wäre die Mitte des Textes dafür besser geeignet. Der Code für die Texterstellung sieht wie folgt aus und enthält die notwendigen Infos zur Ausrichtung:

it.printf(47, 44, id(Verdana12), TextAlign::TOP_CENTER, „%s“, id(PV_Leistung_Heute).state.c_str());

Wir erkennen in den ersten Beiden Zahlen die Koordinaten, wo der Text auf dem Display dargestellt werden soll, danach folgt die Schriftart, die Ausrichtung und der eigentliche Text. Hier nur ein Platzhalter für die id „PV_Leistung_Heute“.

Etwas mühsam aber so können wir Text für Text, Zeile für Zeile erstellen. Linien und Kreise lassen sich auch definieren, eine Linie mit Definition des Start- und Endpunkts wird folgendermaßen erstellt:

it.line(0, 95, 160, 95);

Für unser Display haben wir außerdem noch zwei Kleinigkeiten eingebaut:

  1. Mehrere Seiten zur Darstellung (siehe Doku)
    Es können mehrere Seiten/Pages definiert werden, die einfach nacheinander eingeblendet werden. Die Doku ist recht umfangreich, am Ende reicht ein einfacher Konfigurations-Eintrag, die Seiten alle 5 Sekunden durchschalten zu lassen.

    interval:
      - interval: 5s
        then:
          - display.page.show_next: WD1
          - component.update: WD1

    Wichtig ist, dass bei der Konfiguration des Displays auch ein Name bzw. id vergeben wurde, hier WD1.

  2. Das Display-Licht wird nur angeschaltet, wenn wir über einen Bewegungsmelder eine Bewegung feststellen, nach 1min wird das Hintergrundlicht wieder ausgeschaltet. Das tolle an der Lösung ist, dass wir für die Stromversorgung des Display-Lichts auch ein Pinout des ESP32 nutzen können. Per MQTT steuern wir, ob der Pinout Strom liefert oder nicht. Dafür definieren wir zunächst einen Switch an einem GPIO des ESP32:
    switch:
      - platform: gpio
        id: Dis_power
        pin:
          number: 23

    Wir wählen GPIO23. Die Steuerung erfolgt über die bereits beschriebene MQTT-Schnittstelle, wenn ein Topic true liefert, dann soll Strom fließen und das Display beleuchtet sein, wenn false dann bitte kein Strom und Display-Beleuchtung aus (die Werte werden im Hintergrund dennoch aktualisiert, man sieht es eben nur nicht).
    Die Steuerung ist sehr einfach und erfolgt über die MQTT-Definition:

    # Enable MQTT
    mqtt:
    ...bestehende Konfiguration...
      topic_prefix: esphome
      on_message:
        - topic: esphome/Display_1/Display_off
          payload: "true"
          then:
            - switch.turn_off: Dis_power #definierten Switch an GIO23 ausschalten
            - logger.log: Power Off!
        - topic: esphome/Display_1/Display_off
          payload: "false"
          then:
            - switch.turn_on: Dis_power #definierten Switch an GIO23 einschalten
            - logger.log: Power on!

Zuletzt prüfen wir noch den Strombedarf des ESP32 und unseres Displays:

Stromverbrauch ST7735 Farbdisplay OLED mit ESPHome

Stromverbrauch ST7735 Farbdisplay OLED mit ESPHome

Durchschnittlich benötigt der ESP32 mit dem eingeschalteten Display als 5V*0,02A = 0,1 Watt.

Die vollständige YAML-Konfiguration:

esphome:
  name: display160128
  friendly_name: Display160x128


esp32:
  board: esp32dev
  framework:
    type: arduino


# Enable logging
logger:


# Enable Home Assistant API
api:
  encryption:
    key: "##KEY##"

ota:
  password: "##PWD##"


wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password


  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Display160X128 Fallback Hotspot"
    password: "Vz24OS4v6PGT"


captive_portal:


# Enable MQTT
mqtt:
  broker: 192.168.XXX.XXX
  username: ##USER##
  password: ##PWD##
  client_id: Display160
  topic_prefix: esphome
  on_message:
    - topic: esphome/Display_1/Display_off
      payload: "true"
      then:
        - switch.turn_off: Dis_power
        - logger.log: Power Off!
    - topic: esphome/Display_1/Display_off
      payload: "false"
      then:
        - switch.turn_on: Dis_power
        - logger.log: Power on!

text_sensor:
  - platform: mqtt_subscribe
    id: PV_Leistung_Vortag
    topic: esphome/Display_1/PV/Leistung_Vortag
  - platform: mqtt_subscribe
    id: PV_Leistung_Heute
    topic: esphome/Display_1/PV/Leistung_Heute
  - platform: mqtt_subscribe
    id: PV_Leistung_Woche
    topic: esphome/Display_1/PV/Leistung_Woche
  - platform: mqtt_subscribe
    id: PV_Leistung_Peak
    topic: esphome/Display_1/PV/Leistung_Peak
  - platform: mqtt_subscribe
    id: PV_Leistung_actual
    topic: esphome/Display_1/PV/Leistung_actual
  - platform: mqtt_subscribe
    id: Leistung_heute
    topic: esphome/Display_1/PV/Leistung_heute
  - platform: mqtt_subscribe
    id: Leistung_gestern
    topic: esphome/Display_1/PV/Leistung_gestern
  - platform: mqtt_subscribe
    id: Leistung_Woche
    topic: esphome/Display_1/PV/Leistung_Woche
  - platform: mqtt_subscribe
    id: Display_off
    topic: esphome/Display_1/Display_off
  - platform: mqtt_subscribe
    id: PV_Leistung_Peak_day
    topic: esphome/Display_1/PV/Leistung_Peak_day
  - platform: mqtt_subscribe
    id: Wasserverbrauch_Woche
    topic: esphome/Display_1/Wasserverbrauch_Woche
  - platform: mqtt_subscribe
    id: Wasserverbrauch_Vortag
    topic: esphome/Display_1/Wasserverbrauch_Vortag
  - platform: mqtt_subscribe
    id: Wasserverbrauch_Heute
    topic: esphome/Display_1/Wasserverbrauch_Heute    
  - platform: mqtt_subscribe
    id: Gasverbrauch_Vortag
    topic: esphome/Display_1/Gasverbrauch_Vortag
  - platform: mqtt_subscribe
    id: KW_Heizung_Vortag
    topic: esphome/Display_1/KW_Heizung_Vortag
  - platform: mqtt_subscribe
    id: SolarYield_Gestern
    topic: esphome/Display_1/SolarYield_Gestern
  - platform: mqtt_subscribe
    id: KWWW_Gestern
    topic: esphome/Display_1/KWWW_Gestern


font:
  - file: "Fonts/Verdana.ttf"
    id: Verdana10
    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','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']    
    size: 10


  - file: "Fonts/Verdana.ttf"
    id: Verdana12
    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','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']    
    size: 12


  - file: "Fonts/Verdana.ttf"
    id: Verdana16
    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','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']    
    size: 16


  - file: "Fonts/Verdana_Bold.ttf"
    id: VerdanaBold16
    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','å', 'Ä', 'ä', 'Ö', 'ö', 'Ü', 'ü', '/']    
    size: 16


  - file: "Fonts/materialdesignicons.ttf"
    id: Icons60
    size: 25
    glyphs:
    - "\U000F1A74" # Solar
    - "\U000F1904" # Haus
    - "\U000F1AAF" # Heizung
    - "\U000F058F" # Wasserhahn


switch:
  - platform: gpio
    id: Dis_power
    pin:
      number: 23


# Example configuration for ST7735
spi:
  clk_pin: GPIO22 #SCK
  mosi_pin: GPIO21 # SDA


display:
  - platform: st7735
    model: "INITR_BLACKTAB"
    reset_pin: GPIO4 # RES
    cs_pin: GPIO18 # RS
    dc_pin: GPIO19 #CS
    rotation: 90
    device_width: 128
    device_height: 160
    col_start: 0
    row_start: 0
    eight_bit_color: true
    update_interval: 500ms
    id: WD1
    pages:
      - id: page1
        lambda: |-
          auto red = Color(255, 0, 0);
          auto green = Color(0, 255, 0);
          auto blue = Color(0, 0, 255);
          auto white = Color(255, 255, 255);
          it.filled_rectangle(0, 0, 97, 30, green);
          it.printf(50, 5, id(VerdanaBold16), TextAlign::TOP_CENTER, "%s Watt", id(PV_Leistung_actual).state.c_str());
          it.printf(160, 3, id(Verdana10), TextAlign::TOP_RIGHT, "M: %s W", id(PV_Leistung_Peak).state.c_str());
          it.printf(160, 15, id(Verdana10), TextAlign::TOP_RIGHT, "DM: %s W", id(PV_Leistung_Peak_day).state.c_str());

          it.print(10, 35, id(Icons60), TextAlign::TOP_CENTER, "\U000F1A74");
          it.print(47, 32, id(Verdana10), TextAlign::TOP_CENTER, "Heute");
          it.print(91, 32, id(Verdana10), TextAlign::TOP_CENTER, "Gestern");
          it.print(135, 32, id(Verdana10), TextAlign::TOP_CENTER, "Woche");

          it.printf(47, 44, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(PV_Leistung_Heute).state.c_str());
          it.printf(91, 44, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(PV_Leistung_Vortag).state.c_str());
          it.printf(135, 44, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(PV_Leistung_Woche).state.c_str());

          it.line(0, 63, 160, 63);
         
          it.print(10, 66, id(Icons60), TextAlign::TOP_CENTER, "\U000F1904");
          it.print(47, 64, id(Verdana10), TextAlign::TOP_CENTER, "Heute");
          it.print(91, 64, id(Verdana10), TextAlign::TOP_CENTER, "Gestern");
          it.print(135, 64, id(Verdana10), TextAlign::TOP_CENTER, "Woche");

          it.printf(47, 76, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(Leistung_heute).state.c_str());
          it.printf(91, 76, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(Leistung_gestern).state.c_str());
          it.printf(135, 76, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(Leistung_Woche).state.c_str());
         
          it.line(0, 95, 160, 95);
         
          it.print(10, 98, id(Icons60), TextAlign::TOP_CENTER, "\U000F1AAF");
          it.print(47, 98, id(Verdana10), TextAlign::TOP_CENTER, "KW");
          it.print(91, 98, id(Verdana10), TextAlign::TOP_CENTER, "Wasser");
          it.print(135, 98, id(Verdana10), TextAlign::TOP_CENTER, "Solar");

          it.printf(47, 110, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(KW_Heizung_Vortag).state.c_str());
          it.printf(91, 110, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(KWWW_Gestern).state.c_str());
          it.printf(135, 110, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(SolarYield_Gestern).state.c_str());


      - id: page2
        lambda: |-
          auto red = Color(255, 0, 0);
          auto green = Color(0, 255, 0);
          auto blue = Color(0, 0, 255);
          auto white = Color(255, 255, 255);
          it.filled_rectangle(0, 0, 97, 30, green);
          it.printf(50, 5, id(VerdanaBold16), TextAlign::TOP_CENTER, "%s Watt", id(PV_Leistung_actual).state.c_str());
          it.printf(160, 3, id(Verdana10), TextAlign::TOP_RIGHT, "M: %s W", id(PV_Leistung_Peak).state.c_str());
          it.printf(160, 15, id(Verdana10), TextAlign::TOP_RIGHT, "DM: %s W", id(PV_Leistung_Peak_day).state.c_str());

          it.print(10, 35, id(Icons60), TextAlign::TOP_CENTER, "\U000F1A74");
          it.print(47, 32, id(Verdana10), TextAlign::TOP_CENTER, "Heute");
          it.print(91, 32, id(Verdana10), TextAlign::TOP_CENTER, "Gestern");
          it.print(135, 32, id(Verdana10), TextAlign::TOP_CENTER, "Woche");

          it.printf(47, 44, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(PV_Leistung_Heute).state.c_str());
          it.printf(91, 44, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(PV_Leistung_Vortag).state.c_str());
          it.printf(135, 44, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(PV_Leistung_Woche).state.c_str());

          it.line(0, 63, 160, 63);
         
          it.print(10, 66, id(Icons60), TextAlign::TOP_CENTER, "\U000F1904");
          it.print(47, 64, id(Verdana10), TextAlign::TOP_CENTER, "Heute");
          it.print(91, 64, id(Verdana10), TextAlign::TOP_CENTER, "Gestern");
          it.print(135, 64, id(Verdana10), TextAlign::TOP_CENTER, "Woche");

          it.printf(47, 76, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(Leistung_heute).state.c_str());
          it.printf(91, 76, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(Leistung_gestern).state.c_str());
          it.printf(135, 76, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(Leistung_Woche).state.c_str());
         
          it.line(0, 95, 160, 95);
         
          it.print(10, 98, id(Icons60), TextAlign::TOP_CENTER, "\U000F058F");
          it.print(47, 98, id(Verdana10), TextAlign::TOP_CENTER, "Heute");
          it.print(91, 98, id(Verdana10), TextAlign::TOP_CENTER, "Gestern");
          it.print(135, 98, id(Verdana10), TextAlign::TOP_CENTER, "Woche");

          it.printf(47, 110, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(Wasserverbrauch_Heute).state.c_str());
          it.printf(91, 110, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(Wasserverbrauch_Vortag).state.c_str());
          it.printf(135, 110, id(Verdana12), TextAlign::TOP_CENTER, "%s", id(Wasserverbrauch_Woche).state.c_str());


# For example cycle through pages on a timer
interval:
  - interval: 5s
    then:
      - display.page.show_next: WD1
      - component.update: WD1