AZ-Delivery Touch in Home Assistant nutzen

Mit dem AZ-Delivery Touch bietet AZ-Delivery ein 2,8 Zoll TFT mit Touch-Funktion in einem fertigen Gehäuse der bspw. für ESP32-Mikrocontroller genutzt werden kann um das Ganze dann über ESPHome nutzbar zu machen. Definitiv keine Lösung, die für jeden perfekt ist, aber aufgrund der genannten Specs vielleicht für manche dennoch interessant. Da ich nichts brauchbares zum AZ-Delivery Touch in Kombination mit ESPHome finden konnte, das halbwegs generisch ist, habe ich ein klein wenig Code hierfür zusammelngeklöppelt (ggf. haben mir Claude und Gemini ein wenig geholfen ;)).

AZ-Delivery scheint ja den Betrieb einzustellen, aber vielleicht hast du ja dennoch Bedarf an meinem Code.

Mit diesem ESPHome-Code verwandelst du ein AZ-Touch-Display (ein ESP32 mit ILI9341-Farbdisplay und kapazitivem XPT2046-Touchscreen) in ein vollwertiges Bedienpanel für dein Smart Home, das nahtlos mit Home Assistant zusammenarbeitet.

Auf dem Bildschirm hast du drei Seiten, zwischen denen du über eine Reiterleiste am unteren Rand wechselst, ganz ähnlich wie bei Tabs in einer App. Jede Seite zeigt sechs Kacheln in einem ordentlichen 3×2-Raster, jede mit einem passenden Material-Design-Icon (zum Beispiel eine Lampe, ein Lichtschalter, ein Stecker, eine Klimaanlage, ein Thermometer oder eine Kamera) und einer kurzen Beschriftung darunter. Insgesamt stehen dir damit 18 Schaltflächen zur Verfügung, mit denen du Lampen, Steckdosen oder andere schaltbare Geräte in Home Assistant steuerst.

Du magst Home Assistant? Dann abonniere kostenlos meine Beiträge mit Tipps, Tricks und Anleitungen rund um Home Assistant:

Follow Home Assistant
( 1039 Followers )
X

Follow Home Assistant

E-mail : *
* Ich stimme der Datenschutzerklärung zu!

Garantiert kein Spam, keine Werbung und immer mit Abmelde-Link, solltest du es dir anders überlegen!

Das Besondere daran: Die Kacheln zeigen nicht nur ein Symbol, sondern auch den tatsächlichen Live-Status des jeweiligen Geräts an. Ist eine Lampe an, färbt sich ihre Kachel blau; ist sie aus, bleibt sie schwarz mit einem feinen blauen Rahmen. Das funktioniert in beide Richtungen, schaltest du das Licht über die Home-Assistant-App, per Sprachassistent oder über eine Automatisierung, zieht das Display den neuen Status innerhalb von etwa einer Sekunde automatisch nach. Tippst du dagegen direkt auf die Kachel, schickt der ESP32 sofort einen Schaltbefehl an Home Assistant, und das Gerät reagiert ebenso prompt.

6,60 EUR € Rabatt
AZDelivery AZ-Touch MOD Smart Home Wandgehäuseset mit...*
  • ✅ Das AZ-Touch Smarthome Wandgehäuse Set mit den Dimensionen 120mm...
  • ✅ Das Wandgehäuse Set lässt sich einfach mit einem D1 Mini oder...

Damit du bei der Pflege nicht den Überblick verlierst, sind alle 18 Zuordnungen, also welches Gerät hinter welcher Kachel steckt, welches Icon sie zeigt und wie sie beschriftet ist, ganz oben im Code an einer einzigen, übersichtlichen Stelle gesammelt. Willst du eine Schaltfläche später auf ein anderes Gerät umlegen, änderst du nur diese eine Zeile und spielst die Firmware neu auf, der Rest des Codes bleibt unberührt. Die Namen der drei Reiter dagegen lassen sich sogar ganz ohne neues Flashen anpassen: Sie tauchen als normale Texteingabefelder direkt in den Geräteeinstellungen von Home Assistant auf, sodass du „Seite 2“ jederzeit spontan in „Küche“ oder „Schlafzimmer“ umbenennen kannst.

Über den Kacheln ist außerdem schon eine schmale Kopfzeile vorgesehen, die später Sensordaten wie eine Raumtemperatur anzeigen kann, aktuell steht dort noch ein Platzhaltertext. Im Hintergrund sorgt der Code dafür, dass die Bildschirmbeleuchtung zuverlässig leuchtet und nicht versehentlich von Home Assistant ausgeschaltet wird, dass Touch-Eingabe und Anzeige exakt übereinstimmen (Kalibrierung und Achsenausrichtung sind bereits fein eingestellt) und dass dieselben physischen Touch-Felder je nach aktiver Seite das richtige Gerät schalten, ohne dass du das beim Antippen merkst.

Kurz gesagt: Du bekommst aus einem kleinen, günstigen Touch-Display ein anpassbares, optisch ansprechendes Bedienpanel für bis zu 18 Smart-Home-Geräte, das den aktuellen Zustand zuverlässig anzeigt, sich per Fingertipp steuern lässt und dessen Inhalte sich über einen zentralen Konfigurationsblock im Code leicht erweitern oder umbelegen lassen.

6,60 EUR € Rabatt
AZDelivery AZ-Touch MOD Smart Home Wandgehäuseset mit...*
  • ✅ Das AZ-Touch Smarthome Wandgehäuse Set mit den Dimensionen 120mm...
  • ✅ Das Wandgehäuse Set lässt sich einfach mit einem D1 Mini oder...

Und hier natürlich noch der etwas längere Code für die ganze Magie etc.:

esphome:
  name: aztouch-hello-world

esp32:
  board: esp32dev 
  framework:
    type: arduino

logger:

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

# ====================================
# Deine Standard-Sicherheitsblöcke
# ====================================
api:
  encryption:
    key: !secret api_key

ota:
  - platform: esphome
    password: !secret ota_password

# ==============================================================================
# DEINE STEUERZENTRALE: ALLE 18 BUTTONS
# ==============================================================================
substitutions:
  # === SEITE 1 (Home) ===
  s1_b1_name: '"Sessel"'
  s1_b1_icon: '"\U0000E0F0"'
  s1_b1_ent: "light.sessel_z2m"

  s1_b2_name: '"Kamin"'
  s1_b2_icon: '"\U0000E9F6"'
  s1_b2_ent: "light.kamin_z2m"

  s1_b3_name: '"Couch"'
  s1_b3_icon: '"\U0000E63C"'
  s1_b3_ent: "light.deckenfluter_wohnzimmer"

  s1_b4_name: '"TV-Licht"'
  s1_b4_icon: '"\U0000EB3B"'
  s1_b4_ent: "light.led_wohnzimmer_aqara"

  s1_b5_name: '"Sessel 2"'
  s1_b5_icon: '"\U0000E1FF"'
  s1_b5_ent: "light.sessel_z2m"

  s1_b6_name: '"Kamin 2"'
  s1_b6_icon: '"\U0000E04B"'
  s1_b6_ent: "light.kamin_z2m"

  # === SEITE 2 ===
  s2_b1_name: '"P2 Lampe"'
  s2_b1_icon: '"\U0000E0F0"'
  s2_b1_ent: "light.sessel_z2m"

  s2_b2_name: '"P2 Schalter"'
  s2_b2_icon: '"\U0000E9F6"'
  s2_b2_ent: "light.kamin_z2m"

  s2_b3_name: '"P2 Stecker"'
  s2_b3_icon: '"\U0000E63C"'
  s2_b3_ent: "light.deckenfluter_wohnzimmer"

  s2_b4_name: '"P2 Lüfter"'
  s2_b4_icon: '"\U0000EB3B"'
  s2_b4_ent: "light.led_wohnzimmer_aqara"

  s2_b5_name: '"P2 Klima"'
  s2_b5_icon: '"\U0000E1FF"'
  s2_b5_ent: "light.sessel_z2m"

  s2_b6_name: '"P2 Kamera"'
  s2_b6_icon: '"\U0000E04B"'
  s2_b6_ent: "light.kamin_z2m"

  # === SEITE 3 ===
  s3_b1_name: '"P3 Lampe"'
  s3_b1_icon: '"\U0000E0F0"'
  s3_b1_ent: "light.sessel_z2m"

  s3_b2_name: '"P3 Schalter"'
  s3_b2_icon: '"\U0000E9F6"'
  s3_b2_ent: "light.kamin_z2m"

  s3_b3_name: '"P3 Stecker"'
  s3_b3_icon: '"\U0000E63C"'
  s3_b3_ent: "light.deckenfluter_wohnzimmer"

  s3_b4_name: '"P3 Lüfter"'
  s3_b4_icon: '"\U0000EB3B"'
  s3_b4_ent: "light.led_wohnzimmer_aqara"

  s3_b5_name: '"P3 Klima"'
  s3_b5_icon: '"\U0000E1FF"'
  s3_b5_ent: "light.sessel_z2m"

  s3_b6_name: '"P3 Kamera"'
  s3_b6_icon: '"\U0000E04B"'
  s3_b6_ent: "light.kamin_z2m"

# ====================================
# Globale Variablen (Merkt sich die Seite)
# ====================================
globals:
  - id: current_page
    type: int
    restore_value: no
    initial_value: '1'

# ====================================
# Farben definieren
# ====================================
color:
  - id: color_black
    red: 0%
    green: 0%
    blue: 0%
  - id: color_white
    red: 100%
    green: 100%
    blue: 100%
  - id: color_blue
    red: 0%
    green: 0%
    blue: 100%
  - id: color_grey
    red: 40%
    green: 40%
    blue: 40%
  - id: color_dark_grey
    red: 20%
    green: 20%
    blue: 20%

# ====================================
# Schriftarten & Icons
# ====================================
font:
  - file:
      type: gfonts
      family: Roboto
      weight: 700
    id: font_hello
    size: 15   
    glyphs: ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~'

  - file:
      type: gfonts
      family: Material Icons
      weight: 400
    id: font_icon
    size: 28   
    glyphs:
      - "\U0000E0F0" 
      - "\U0000E9F6" 
      - "\U0000E63C" 
      - "\U0000EB3B" 
      - "\U0000E1FF" 
      - "\U0000E04B" 

# ====================================
# Hintergrundbeleuchtung 
# ====================================
output:
  - platform: ledc
    pin: 15
    id: gpio_15_backlight_pwm

light:
  - platform: monochromatic
    output: gpio_15_backlight_pwm
    name: "Display Backlight"
    id: back_light
    restore_mode: ALWAYS_OFF

# ====================================
# Text-Eingabefelder für Home Assistant
# ====================================
text:
  - platform: template
    name: "Name Tab 1"
    id: tab_1_label
    mode: text
    optimistic: true
    initial_value: "Home"
    restore_value: true
    max_length: 15

  - platform: template
    name: "Name Tab 2"
    id: tab_2_label
    mode: text
    optimistic: true
    initial_value: "Seite 2"
    restore_value: true
    max_length: 15

  - platform: template
    name: "Name Tab 3"
    id: tab_3_label
    mode: text
    optimistic: true
    initial_value: "Seite 3"
    restore_value: true
    max_length: 15

# ====================================
# Status der 18 Entitäten abrufen
# ====================================
binary_sensor:
  - platform: homeassistant
    id: state_s1_b1
    entity_id: ${s1_b1_ent}
  - platform: homeassistant
    id: state_s1_b2
    entity_id: ${s1_b2_ent}
  - platform: homeassistant
    id: state_s1_b3
    entity_id: ${s1_b3_ent}
  - platform: homeassistant
    id: state_s1_b4
    entity_id: ${s1_b4_ent}
  - platform: homeassistant
    id: state_s1_b5
    entity_id: ${s1_b5_ent}
  - platform: homeassistant
    id: state_s1_b6
    entity_id: ${s1_b6_ent}

  - platform: homeassistant
    id: state_s2_b1
    entity_id: ${s2_b1_ent}
  - platform: homeassistant
    id: state_s2_b2
    entity_id: ${s2_b2_ent}
  - platform: homeassistant
    id: state_s2_b3
    entity_id: ${s2_b3_ent}
  - platform: homeassistant
    id: state_s2_b4
    entity_id: ${s2_b4_ent}
  - platform: homeassistant
    id: state_s2_b5
    entity_id: ${s2_b5_ent}
  - platform: homeassistant
    id: state_s2_b6
    entity_id: ${s2_b6_ent}

  - platform: homeassistant
    id: state_s3_b1
    entity_id: ${s3_b1_ent}
  - platform: homeassistant
    id: state_s3_b2
    entity_id: ${s3_b2_ent}
  - platform: homeassistant
    id: state_s3_b3
    entity_id: ${s3_b3_ent}
  - platform: homeassistant
    id: state_s3_b4
    entity_id: ${s3_b4_ent}
  - platform: homeassistant
    id: state_s3_b5
    entity_id: ${s3_b5_ent}
  - platform: homeassistant
    id: state_s3_b6
    entity_id: ${s3_b6_ent}

  # ==============================================
  # DYNAMISCHE TOUCH-ZONEN (Ohne fehleranfällige Inline-Klammern)
  # ==============================================
  - platform: touchscreen
    id: touch_button_1
    x_min: 10
    x_max: 100
    y_min: 40
    y_max: 110
    on_press:
      - if:
          condition:
            lambda: 'return id(current_page) == 1;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s1_b1_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 2;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s2_b1_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 3;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s3_b1_ent}

  - platform: touchscreen
    id: touch_button_2
    x_min: 115
    x_max: 205
    y_min: 40
    y_max: 110
    on_press:
      - if:
          condition:
            lambda: 'return id(current_page) == 1;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s1_b2_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 2;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s2_b2_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 3;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s3_b2_ent}

  - platform: touchscreen
    id: touch_button_3
    x_min: 220
    x_max: 310
    y_min: 40
    y_max: 110
    on_press:
      - if:
          condition:
            lambda: 'return id(current_page) == 1;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s1_b3_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 2;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s2_b3_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 3;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s3_b3_ent}

  - platform: touchscreen
    id: touch_button_4
    x_min: 10
    x_max: 100
    y_min: 120
    y_max: 190
    on_press:
      - if:
          condition:
            lambda: 'return id(current_page) == 1;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s1_b4_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 2;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s2_b4_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 3;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s3_b4_ent}

  - platform: touchscreen
    id: touch_button_5
    x_min: 115
    x_max: 205
    y_min: 120
    y_max: 190
    on_press:
      - if:
          condition:
            lambda: 'return id(current_page) == 1;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s1_b5_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 2;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s2_b5_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 3;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s3_b5_ent}

  - platform: touchscreen
    id: touch_button_6
    x_min: 220
    x_max: 310
    y_min: 120
    y_max: 190
    on_press:
      - if:
          condition:
            lambda: 'return id(current_page) == 1;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s1_b6_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 2;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s2_b6_ent}
      - if:
          condition:
            lambda: 'return id(current_page) == 3;'
          then:
            - homeassistant.service:
                service: light.toggle
                data:
                  entity_id: ${s3_b6_ent}

  # --- TOUCH-ZONEN FÜR DIE NAVIGATION (Aktualisiert die Seite & Variable) ---
  - platform: touchscreen
    id: touch_tab_home
    x_min: 0
    x_max: 106
    y_min: 200
    y_max: 240
    on_press:
      - globals.set:
          id: current_page
          value: '1'
      - display.page.show: page_home

  - platform: touchscreen
    id: touch_tab_page2
    x_min: 107
    x_max: 213
    y_min: 200
    y_max: 240
    on_press:
      - globals.set:
          id: current_page
          value: '2'
      - display.page.show: page_2

  - platform: touchscreen
    id: touch_tab_page3
    x_min: 214
    x_max: 320
    y_min: 200
    y_max: 240
    on_press:
      - globals.set:
          id: current_page
          value: '3'
      - display.page.show: page_3

# ====================================
# SPI-Bus
# ====================================
spi:
  clk_pin: 18 
  mosi_pin: 23
  miso_pin: 19
  id: ili9341_spi

# ====================================
# Das Display
# ====================================
display:
  - platform: ili9xxx
    id: ili9341_spi_display
    model: ILI9341
    spi_id: ili9341_spi
    cs_pin: 5
    dc_pin: 4
    reset_pin: 22 
    rotation: 90
    invert_colors: false 
    color_order: BGR     
    color_palette: 8BIT
    update_interval: 1s
    pages:
      # ==========================================
      # SEITE 1: HOME
      # ==========================================
      - id: page_home
        lambda: |-
          it.fill(id(color_black));
          it.printf(160, 20, id(font_hello), id(color_white), TextAlign::CENTER, "SENSOR-PLATZHALTER");
          it.line(0, 30, 320, 30, id(color_grey)); 

          if (id(state_s1_b1).state) { it.filled_rectangle(10, 40, 90, 70, id(color_blue)); } else { it.filled_rectangle(10, 40, 90, 70, id(color_black)); it.rectangle(10, 40, 90, 70, id(color_blue)); }
          it.printf(55, 60, id(font_icon), id(color_white), TextAlign::CENTER, ${s1_b1_icon});
          it.printf(55, 95, id(font_hello), id(color_white), TextAlign::CENTER, ${s1_b1_name});

          if (id(state_s1_b2).state) { it.filled_rectangle(115, 40, 90, 70, id(color_blue)); } else { it.filled_rectangle(115, 40, 90, 70, id(color_black)); it.rectangle(115, 40, 90, 70, id(color_blue)); }
          it.printf(160, 60, id(font_icon), id(color_white), TextAlign::CENTER, ${s1_b2_icon});
          it.printf(160, 95, id(font_hello), id(color_white), TextAlign::CENTER, ${s1_b2_name});

          if (id(state_s1_b3).state) { it.filled_rectangle(220, 40, 90, 70, id(color_blue)); } else { it.filled_rectangle(220, 40, 90, 70, id(color_black)); it.rectangle(220, 40, 90, 70, id(color_blue)); }
          it.printf(265, 60, id(font_icon), id(color_white), TextAlign::CENTER, ${s1_b3_icon});
          it.printf(265, 95, id(font_hello), id(color_white), TextAlign::CENTER, ${s1_b3_name});

          if (id(state_s1_b4).state) { it.filled_rectangle(10, 120, 90, 70, id(color_blue)); } else { it.filled_rectangle(10, 120, 90, 70, id(color_black)); it.rectangle(10, 120, 90, 70, id(color_blue)); }
          it.printf(55, 140, id(font_icon), id(color_white), TextAlign::CENTER, ${s1_b4_icon});
          it.printf(55, 175, id(font_hello), id(color_white), TextAlign::CENTER, ${s1_b4_name});

          if (id(state_s1_b5).state) { it.filled_rectangle(115, 120, 90, 70, id(color_blue)); } else { it.filled_rectangle(115, 120, 90, 70, id(color_black)); it.rectangle(115, 120, 90, 70, id(color_blue)); }
          it.printf(160, 140, id(font_icon), id(color_white), TextAlign::CENTER, ${s1_b5_icon});
          it.printf(160, 175, id(font_hello), id(color_white), TextAlign::CENTER, ${s1_b5_name});

          if (id(state_s1_b6).state) { it.filled_rectangle(220, 120, 90, 70, id(color_blue)); } else { it.filled_rectangle(220, 120, 90, 70, id(color_black)); it.rectangle(220, 120, 90, 70, id(color_blue)); }
          it.printf(265, 140, id(font_icon), id(color_white), TextAlign::CENTER, ${s1_b6_icon});
          it.printf(265, 175, id(font_hello), id(color_white), TextAlign::CENTER, ${s1_b6_name});

          // Tabs
          it.line(0, 199, 320, 199, id(color_grey)); 
          it.filled_rectangle(0, 200, 106, 40, id(color_dark_grey));
          it.printf(53, 225, id(font_hello), id(color_white), TextAlign::CENTER, "%s", id(tab_1_label).state.c_str());
          it.rectangle(107, 200, 106, 40, id(color_grey));
          it.printf(160, 225, id(font_hello), id(color_grey), TextAlign::CENTER, "%s", id(tab_2_label).state.c_str());
          it.rectangle(214, 200, 106, 40, id(color_grey));
          it.printf(267, 225, id(font_hello), id(color_grey), TextAlign::CENTER, "%s", id(tab_3_label).state.c_str());

      # ==========================================
      # SEITE 2 
      # ==========================================
      - id: page_2
        lambda: |-
          it.fill(id(color_black));
          it.printf(160, 20, id(font_hello), id(color_white), TextAlign::CENTER, "SENSOR-PLATZHALTER");
          it.line(0, 30, 320, 30, id(color_grey)); 

          if (id(state_s2_b1).state) { it.filled_rectangle(10, 40, 90, 70, id(color_blue)); } else { it.filled_rectangle(10, 40, 90, 70, id(color_black)); it.rectangle(10, 40, 90, 70, id(color_blue)); }
          it.printf(55, 60, id(font_icon), id(color_white), TextAlign::CENTER, ${s2_b1_icon});
          it.printf(55, 95, id(font_hello), id(color_white), TextAlign::CENTER, ${s2_b1_name});

          if (id(state_s2_b2).state) { it.filled_rectangle(115, 40, 90, 70, id(color_blue)); } else { it.filled_rectangle(115, 40, 90, 70, id(color_black)); it.rectangle(115, 40, 90, 70, id(color_blue)); }
          it.printf(160, 60, id(font_icon), id(color_white), TextAlign::CENTER, ${s2_b2_icon});
          it.printf(160, 95, id(font_hello), id(color_white), TextAlign::CENTER, ${s2_b2_name});

          if (id(state_s2_b3).state) { it.filled_rectangle(220, 40, 90, 70, id(color_blue)); } else { it.filled_rectangle(220, 40, 90, 70, id(color_black)); it.rectangle(220, 40, 90, 70, id(color_blue)); }
          it.printf(265, 60, id(font_icon), id(color_white), TextAlign::CENTER, ${s2_b3_icon});
          it.printf(265, 95, id(font_hello), id(color_white), TextAlign::CENTER, ${s2_b3_name});

          if (id(state_s2_b4).state) { it.filled_rectangle(10, 120, 90, 70, id(color_blue)); } else { it.filled_rectangle(10, 120, 90, 70, id(color_black)); it.rectangle(10, 120, 90, 70, id(color_blue)); }
          it.printf(55, 140, id(font_icon), id(color_white), TextAlign::CENTER, ${s2_b4_icon});
          it.printf(55, 175, id(font_hello), id(color_white), TextAlign::CENTER, ${s2_b4_name});

          if (id(state_s2_b5).state) { it.filled_rectangle(115, 120, 90, 70, id(color_blue)); } else { it.filled_rectangle(115, 120, 90, 70, id(color_black)); it.rectangle(115, 120, 90, 70, id(color_blue)); }
          it.printf(160, 140, id(font_icon), id(color_white), TextAlign::CENTER, ${s2_b5_icon});
          it.printf(160, 175, id(font_hello), id(color_white), TextAlign::CENTER, ${s2_b5_name});

          if (id(state_s2_b6).state) { it.filled_rectangle(220, 120, 90, 70, id(color_blue)); } else { it.filled_rectangle(220, 120, 90, 70, id(color_black)); it.rectangle(220, 120, 90, 70, id(color_blue)); }
          it.printf(265, 140, id(font_icon), id(color_white), TextAlign::CENTER, ${s2_b6_icon});
          it.printf(265, 175, id(font_hello), id(color_white), TextAlign::CENTER, ${s2_b6_name});

          // Tabs
          it.line(0, 199, 320, 199, id(color_grey)); 
          it.rectangle(0, 200, 106, 40, id(color_grey));
          it.printf(53, 225, id(font_hello), id(color_grey), TextAlign::CENTER, "%s", id(tab_1_label).state.c_str());
          it.filled_rectangle(107, 200, 106, 40, id(color_dark_grey));
          it.printf(160, 225, id(font_hello), id(color_white), TextAlign::CENTER, "%s", id(tab_2_label).state.c_str());
          it.rectangle(214, 200, 106, 40, id(color_grey));
          it.printf(267, 225, id(font_hello), id(color_grey), TextAlign::CENTER, "%s", id(tab_3_label).state.c_str());

      # ==========================================
      # SEITE 3 
      # ==========================================
      - id: page_3
        lambda: |-
          it.fill(id(color_black));
          it.printf(160, 20, id(font_hello), id(color_white), TextAlign::CENTER, "SENSOR-PLATZHALTER");
          it.line(0, 30, 320, 30, id(color_grey)); 

          if (id(state_s3_b1).state) { it.filled_rectangle(10, 40, 90, 70, id(color_blue)); } else { it.filled_rectangle(10, 40, 90, 70, id(color_black)); it.rectangle(10, 40, 90, 70, id(color_blue)); }
          it.printf(55, 60, id(font_icon), id(color_white), TextAlign::CENTER, ${s3_b1_icon});
          it.printf(55, 95, id(font_hello), id(color_white), TextAlign::CENTER, ${s3_b1_name});

          if (id(state_s3_b2).state) { it.filled_rectangle(115, 40, 90, 70, id(color_blue)); } else { it.filled_rectangle(115, 40, 90, 70, id(color_black)); it.rectangle(115, 40, 90, 70, id(color_blue)); }
          it.printf(160, 60, id(font_icon), id(color_white), TextAlign::CENTER, ${s3_b2_icon});
          it.printf(160, 95, id(font_hello), id(color_white), TextAlign::CENTER, ${s3_b2_name});

          if (id(state_s3_b3).state) { it.filled_rectangle(220, 40, 90, 70, id(color_blue)); } else { it.filled_rectangle(220, 40, 90, 70, id(color_black)); it.rectangle(220, 40, 90, 70, id(color_blue)); }
          it.printf(265, 60, id(font_icon), id(color_white), TextAlign::CENTER, ${s3_b3_icon});
          it.printf(265, 95, id(font_hello), id(color_white), TextAlign::CENTER, ${s3_b3_name});

          if (id(state_s3_b4).state) { it.filled_rectangle(10, 120, 90, 70, id(color_blue)); } else { it.filled_rectangle(10, 120, 90, 70, id(color_black)); it.rectangle(10, 120, 90, 70, id(color_blue)); }
          it.printf(55, 140, id(font_icon), id(color_white), TextAlign::CENTER, ${s3_b4_icon});
          it.printf(55, 175, id(font_hello), id(color_white), TextAlign::CENTER, ${s3_b4_name});

          if (id(state_s3_b5).state) { it.filled_rectangle(115, 120, 90, 70, id(color_blue)); } else { it.filled_rectangle(115, 120, 90, 70, id(color_black)); it.rectangle(115, 120, 90, 70, id(color_blue)); }
          it.printf(160, 140, id(font_icon), id(color_white), TextAlign::CENTER, ${s3_b5_icon});
          it.printf(160, 175, id(font_hello), id(color_white), TextAlign::CENTER, ${s3_b5_name});

          if (id(state_s3_b6).state) { it.filled_rectangle(220, 120, 90, 70, id(color_blue)); } else { it.filled_rectangle(220, 120, 90, 70, id(color_black)); it.rectangle(220, 120, 90, 70, id(color_blue)); }
          it.printf(265, 140, id(font_icon), id(color_white), TextAlign::CENTER, ${s3_b6_icon});
          it.printf(265, 175, id(font_hello), id(color_white), TextAlign::CENTER, ${s3_b6_name});

          // Tabs
          it.line(0, 199, 320, 199, id(color_grey)); 
          it.rectangle(0, 200, 106, 40, id(color_grey));
          it.printf(53, 225, id(font_hello), id(color_grey), TextAlign::CENTER, "%s", id(tab_1_label).state.c_str());
          it.rectangle(107, 200, 106, 40, id(color_grey));
          it.printf(160, 225, id(font_hello), id(color_grey), TextAlign::CENTER, "%s", id(tab_2_label).state.c_str());
          it.filled_rectangle(214, 200, 106, 40, id(color_dark_grey));
          it.printf(267, 225, id(font_hello), id(color_white), TextAlign::CENTER, "%s", id(tab_3_label).state.c_str());

# ====================================
# Touchscreen
# ====================================
touchscreen:
  - id: my_touchscreen
    platform: xpt2046
    display: ili9341_spi_display
    spi_id: ili9341_spi
    cs_pin: 14
    calibration:
      x_min: 256
      x_max: 3839
      y_min: 180
      y_max: 3640
    transform:
      swap_xy: true
      mirror_x: true   
      mirror_y: true

Produktempfehlungen

1,49 EUR € Rabatt SONOFF S60ZBTPF Zigbee Steckdose – Fernsteuerung...