CYD/Habbit Device to control HA

Hi there!

A while ago i discovered the ESP32-2432S028R or CYD (“Cheap Yellow Display”), which you may already now because is a popular device, as it is very cheap and ready to use.

I made mi own version to control Home Assistant through this device. It shows you date and time, sensors information and it allows you to control devices. As you can see, the design is inspired by Rabbit R1, but you can customize it as you wish.



You can get the code in my blog:

Hope you like it!

If you find it usefull

You can help me to create more things like this if you:

:coffee: Consider to buy me a coffee
:email: Subscribe to my blog to get new ideas
:speech_balloon: Join our telegram community (we have an english room)
:avocado: Follow me in Facebook, Twitter, Youtube or Instagram

Thanks!! :smiley:

Other cool stuff i made

:ferris_wheel: ARC Reactor integration
:watch: Home Assistant companion for Zepp Devices
:label: Dynamic automations with NFC
:world_map: Airtag integration (user friendly)
:shopping_cart: Improved Shopping List + Bring! + Google Assistant
:muscle: Personal Trainer
:tv: Google Echo Show

3 Likes

Hallo first of all… Thank you very much for the tutorial… I like it very much, have followed the how to on your webpage and it works after integration in home assistant. My problem is the representation on the screen… i use a CYD like you and the code is working fine… I can controll some lights that i have setup in the code.

But it looks terrible. On the first page you can see the time repeated in four lines. On the second page you see the buttons, but the first row is offset and everything looks weird. No clean or clear representation. The Rotation of 90 degrees dont seem to work.

I cant upload photos at this time, because i am a new member. (found a way)

Have you any idea what i have to change to get clear view on the screen?

It looks bad. Is the screen working properly with other codes?

Hi, yes i had code from a other project uploaded on the cyd and works fine. No flickering or strange looking.
Before i could compiling the code i must attach the following line in the code: invert_colors: false at line 403 for the diplay settings… if i dont do that, i get error at compiling that say i have to insert the code line “invert_colors”

Here is my code, dont have changed much for testing, inserted the two keys, my wifi connection and two lights for testing. Maybe that helps:

esphome:
  name: cyd
  friendly_name: CYD Schlafzimmer

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

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

ota:
  - platform: esphome
    password: "XXXXXXXXXXXXXXXX"

wifi:
  ssid: "secret"
  password: "secret"

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

captive_portal:

globals:
  - id: show_return_page
    type: bool
    restore_value: yes
    initial_value: "false"

# Setup a pin to control the backlight and the LED
output:
  - platform: ledc
    pin: GPIO21
    id: backlight_pwm
  - platform: ledc
    id: output_red
    pin: GPIO4
    inverted: true
  - platform: ledc
    id: output_green
    pin: GPIO16
    inverted: true
  - platform: ledc
    id: output_blue
    pin: GPIO17
    inverted: true

light:
  - platform: monochromatic
    output: backlight_pwm
    name: Display Backlight
    id: backlight
    restore_mode: ALWAYS_ON
  - platform: rgb
    name: LED
    red: output_red
    id: led
    green: output_green
    blue: output_blue
    restore_mode: ALWAYS_OFF

# Setup SPI for the display. The ESP32-2432S028R uses separate SPI buses for display and touch
spi:
  - id: tft
    clk_pin: GPIO14
    mosi_pin: GPIO13
    miso_pin: GPIO12
  - id: touch
    clk_pin: GPIO25
    mosi_pin: GPIO32
    miso_pin: GPIO39

touchscreen:
  platform: xpt2046
  spi_id: touch
  cs_pin: GPIO33
  interrupt_pin: GPIO36
  update_interval: 50ms
  threshold: 400
  calibration:
    x_min: 3860
    x_max: 280
    y_min: 340
    y_max: 3860
  transform:
    swap_xy: false   

# Create a font to use, add and remove glyphs as needed. 
# Crea las fuente que quieres utilizar, añade o quita los caracteres que necesites.

font:
  - file: "gfonts://Space Grotesk"
    id: fecha
    size: 15
  - file: "gfonts://Space Grotesk"
    id: hora
    size: 60
  - file: "gfonts://Roboto"
    id: info
    size: 15
  - file: "gfonts://Roboto"
    id: botones
    size: 11

# Create the colors you want to use.
# Crea los colores que quieres utilizar.

color:
  - id: black
    hex: '000000'
  - id: orange
    hex: '16afd9'
  - id: grey
    hex: '464646'
    
# Create the icons you want to use.
# Crea los iconos que quieres utilizar.

image:
  - file: mdi:home-thermometer
    id: hometemperature
    resize: 40x40
  - file: mdi:weather-partly-cloudy
    id: weather
    resize: 40x40
  - file: mdi:finance
    id: finance
    resize: 40x40
  - file: mdi:heart-pulse
    id: health
    resize: 40x40
  - file: mdi:page-previous
    id: back
    resize: 40x40
  - file: mdi:fan
    id: fan
    resize: 40x40
  - file: mdi:thermostat
    id: thermostat
    resize: 40x40
  - file: mdi:robot-vacuum
    id: vacuum
    resize: 40x40
  - file: mdi:desk-lamp
    id: desk
    resize: 40x40
  - file: mdi:printer
    id: printer
    resize: 40x40
  - file: mdi:printer-3d-nozzle
    id: printer3d
    resize: 40x40
  - file: mdi:home-assistant
    id: habbit
    resize: 40x40

# Replace the home gif as you want.
# Reemplaza el gif the inicio como quieras.

animation:
  - file: "habbit.gif"
    id: ha
    resize: 70x70
    type: TRANSPARENT_BINARY

# This will fetch time from Home Assistant
time:
  - platform: homeassistant
    id: esptime

# Create sensors from HA you want to use and show.
# Crea los sensores de HA que quieres utilizar y mostrar.

sensor:
  - platform: homeassistant
    id: temperatura
    entity_id: sensor.wandthermostat_jan_temperatur
    internal: true
  - platform: homeassistant
    id: humedad
    entity_id: sensor.wandthermostat_jan_luftfeuchtigkeit
    internal: true
  - platform: homeassistant
    id: tempexterior
    entity_id: sensor.aussentemperatur_temperatur
    internal: true
  - platform: homeassistant
    id: problluvia
    entity_id: sensor.aussentemperatur_luftfeuchtigkeit
    internal: true
  - platform: homeassistant
    id: brickken
    entity_id: sensor.brickken_price
    internal: true
  - platform: homeassistant
    id: weight
    entity_id: sensor.tito_weight
    internal: true
  - platform: homeassistant
    id: distancia
    entity_id: input_number.distancia_acumulada_tito
    internal: true

text_sensor:
  - platform: homeassistant
    id: aireacondicionado
    entity_id: switch.aire_acondicionado
    internal: true
  - platform: homeassistant
    id: calefaccion
    entity_id: climate.salon
    internal: true
  - platform: homeassistant
    id: aspirador
    entity_id: vacuum.aspirador
    internal: true
  - platform: homeassistant
    id: escritorio
    entity_id: light.escritorio
    internal: true
  - platform: homeassistant
    id: impresora
    entity_id: switch.impresora
    internal: true
  - platform: homeassistant
    id: impresora3d
    entity_id: switch.impresora_3d
    internal: true

# Assigns a function to each button, by calling the corresponding service in HA.
# Asigna una función a cada botón, llamando al servicio correspondiente en HA.

binary_sensor:
  - platform: touchscreen
    name: Button 1
    x_min: 0
    x_max: 140
    y_min: 0
    y_max: 65
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: switch.toggle
                  data:
                    entity_id: switch.aire_acondicionado
  - platform: touchscreen
    name: Button 2
    x_min: 140
    x_max: 280
    y_min: 0
    y_max: 65
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: climate.toggle
                  data:
                    entity_id: climate.salon
  - platform: touchscreen
    name: Button 3
    x_min: 0
    x_max: 140
    y_min: 65
    y_max: 130
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
            - if:
                condition:
                  lambda: 'return id(aspirador).state == "docked";'
                then:
                  - homeassistant.service:
                      service: vacuum.start
                      data:
                        entity_id: vacuum.aspirador
                else:
                  - homeassistant.service:
                      service: vacuum.return_to_base
                      data:
                        entity_id: vacuum.aspirador
  - platform: touchscreen
    name: Button 4
    x_min: 140
    x_max: 280
    y_min: 65
    y_max: 130
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: light.toggle
                  data:
                    entity_id: light.wandlicht
  - platform: touchscreen
    name: Button 5
    x_min: 0
    x_max: 140
    y_min: 130
    y_max: 170
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: switch.toggle
                  data:
                    entity_id: switch.pc_led_pv_led
  - platform: touchscreen
    name: Button 6
    x_min: 140
    x_max: 280
    y_min: 130
    y_max: 170
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: switch.toggle
                  data:
                    entity_id: switch.impresora_3d
  - platform: touchscreen
    name: Button 7
    x_min: 0
    x_max: 140
    y_min: 180
    y_max: 260
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
  - platform: touchscreen
    name: Button 8
    x_min: 140
    x_max: 280
    y_min: 180
    y_max: 260
    on_press:
      then:
        - globals.set:
            id: show_return_page
            value: !lambda "return !id(show_return_page);"

# Setup the ili9xxx platform
# Display is used as 240x320 by default so we rotate it to 90°

display:
  - platform: ili9xxx
    id: esp_display
    model: ili9342
    spi_id: tft
    cs_pin: GPIO15
    dc_pin: GPIO2
    rotation: 90
    invert_colors: false
    lambda: |-
      if (id(show_return_page)) {
        int button_width = 100;
        int button_height = 65;
        int x_start = 15;
        int y_start = 15;
        int x_padding = 10;
        int y_padding = 10;

        // Define los textos para los botones
        const char* button_texts[] = {
          "Aire Ac",
          "Calefaccion",
          "Wandlicht",
          "PC-Licht",
          "Impresora",
          "Impr 3D",
          "Habbit",
          "Zurück"
        };

        for (int row = 0; row < 4; row++) {
          for (int col = 0; col < 2; col++) {
            int button_index = row * 2 + col;
            int x = x_start + col * (button_width + x_padding);
            int y = y_start + row * (button_height + y_padding);
            it.rectangle(x, y, button_width, button_height, id(grey));
            int text_width = strlen(button_texts[button_index]) * 5.5; 
            int text_height = 16; 
            it.print(x + (button_width - text_width) / 2, y + (button_height - text_height) / 2 + 20, id(botones), button_texts[button_index]);
          }
        }
        if (id(aireacondicionado).state == "on") {
          it.image(45, 20, id(fan), id(orange));
        } else {
          it.image(45, 20, id(fan), id(grey));
        }
        if (id(calefaccion).state == "off") {
          it.image(155, 20, id(thermostat), id(grey));
        } else {
          it.image(155, 20, id(thermostat), id(orange));
        }
        if (id(aspirador).state == "docked") {
          it.image(45, 95, id(vacuum), id(grey));
        } else {
          it.image(45, 95, id(vacuum), id(orange));
        }
        if (id(escritorio).state == "on") {
          it.image(155, 95, id(desk), id(orange));
        } else {
          it.image(155, 95, id(desk), id(grey));
        }
        if (id(impresora).state == "on") {
          it.image(45, 170, id(printer), id(orange));
        } else {
          it.image(45, 170, id(printer), id(grey));
        }
        if (id(impresora3d).state == "on") {
          it.image(155, 170, id(printer3d), id(orange));
        } else {
          it.image(155, 170, id(printer3d), id(grey));
        }
        it.image(45, 245, id(habbit), id(grey));
        it.image(155, 245, id(back), id(grey));

      } else {
        static int y = 150;
        static int y_direction = 4;  // Velocidad del movimiento
        const int y_min = 145;       
        const int y_max = 155;       

        it.fill(id(black));
        it.strftime(120, 60, id(fecha), TextAlign::CENTER, "%d/%m/%Y", id(esptime).now());
        it.strftime(120, 92, id(hora), TextAlign::CENTER, "%H:%M", id(esptime).now());
        it.image(120, y, id(ha), ImageAlign::CENTER);
        y += y_direction;
        if (y <= y_min || y >= y_max) {
          y_direction = -y_direction;
        }

        static int current_text_index = 0;
        static float text_timer = 0;
        const float text_interval = 5.0;  // Intervalo para cambiar el texto en segundos

        text_timer += 1.0;  
        if (text_timer >= text_interval) {
          text_timer = 0;
          current_text_index = (current_text_index + 1) % 4;  // Alternar entre cuatro textos
        }

        if (current_text_index == 0) {
          it.image(15, 260, id(hometemperature), id(orange));
          it.print(70, 260, id(info), "Temperatura");
          it.printf(175, 260, id(info), "%.1f C", id(temperatura).state);
          it.print(70, 280, id(info), "Humedad");
          it.printf(175, 280, id(info), "%.1f %%", id(humedad).state);
        } else if (current_text_index == 1) {
          it.image(15, 260, id(weather), id(orange));
          it.print(70, 260, id(info), "Temperatura");
          it.printf(175, 260, id(info), "%.1f C", id(tempexterior).state);
          it.print(70, 280, id(info), "Prob. Lluvia");
          it.printf(175, 280, id(info), "%.1f %%", id(problluvia).state);
        } else if (current_text_index == 2) {
          it.image(15, 260, id(finance), id(orange));
          it.print(70, 260, id(info), "Brickken");
          it.printf(165, 260, id(info), "%.2f USD", id(brickken).state);
        } else if (current_text_index == 3) {
          it.image(15, 260, id(health), id(orange));
          it.print(70, 260, id(info), "Peso");
          it.printf(175, 260, id(info), "%.1f Kg", id(weight).state);
          it.print(70, 280, id(info), "Distancia");
          it.printf(175, 280, id(info), "%.1f Km%", id(distancia).state);
        }
      }

interval:
  - interval: 1s
    then:
      animation.next_frame: ha

Have you checked what is the model of your board? I am aware that It may be differences across models

Hi, i have a ESP32-2432S028, that is written on the backside.
In your code i find this notice:

# Setup SPI for the display. The ESP32-2432S028R uses separate SPI buses for display and touch

Can you tell me, how to do that? I think, i have to change some pins for spi?

EDIT: I found a way to see it right. I have changed the model to ili9341 and display rotation to 0 under the display settings and now i get a right view. But still one problem, i cant touch the buttons right on the second site, they are only touchable over very little points in the corners. Any help is appreciated. I would love to use it.
Maybe it had something to do with the rotation, but the button still are configurated for the rotation 90 degrees? or something else?

display:
  - platform: ili9xxx
    id: esp_display
    model: ili9341
    spi_id: tft
    cs_pin: GPIO15
    dc_pin: GPIO2
    rotation: 0
    invert_colors: false
    lambda: |-

Due to the changes you made, you may need to adapt the coordinares or each in button. I would try with that

1 Like

Yes, i was thinking about that too. The last 4 buttons i have setup with little other coordinates and now its working like it should be. Also i have changed some specs for the first site. I will upload my code and some example pictures later.

Are you sure you have setup the button coordinates right in your code? the last four buttons didnt have the right dimension i think. The buttons are defined by 140x65 pixel, but in the code button 5 and 6 are setup with a height of 40 pixel and button 7 and 8 with 80 pixel.

1 Like

Maybe! To be honest, i am working in a new and improved version. Stay tunned!

Nice, i am looking forward to it… :slight_smile:

Here is my current layout. i removed the gif on the first page and show there some other useful stuff. The bottom section i have setup to my preferences.

I really like it and use it on my night desk. With HA i set the background light from the display to 30% in the night and 70% at day.

To have a nice view i printed the following:

The stand i have designed

That is my latest code for the ESP32-2432S028:

esphome:
  name: cyd
  friendly_name: CYD Schlafzimmer

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:

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

ota:
  - platform: esphome
    password: "secret"

wifi:
  ssid: "secret"
  password: "secret"

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

captive_portal:

globals:
  - id: show_return_page
    type: bool
    restore_value: yes
    initial_value: "false"

# Setup a pin to control the backlight and the LED
output:
  - platform: ledc
    pin: GPIO21
    id: backlight_pwm
  - platform: ledc
    id: output_red
    pin: GPIO4
    inverted: true
  - platform: ledc
    id: output_green
    pin: GPIO16
    inverted: true
  - platform: ledc
    id: output_blue
    pin: GPIO17
    inverted: true

light:
  - platform: monochromatic
    output: backlight_pwm
    name: Display Backlight
    id: backlight
    restore_mode: ALWAYS_ON
  - platform: rgb
    name: LED
    red: output_red
    id: led
    green: output_green
    blue: output_blue
    restore_mode: ALWAYS_OFF

# Setup SPI for the display. The ESP32-2432S028R uses separate SPI buses for display and touch
spi:
  - id: tft
    clk_pin: GPIO14
    mosi_pin: GPIO13
    miso_pin: GPIO12
  - id: touch
    clk_pin: GPIO25
    mosi_pin: GPIO32
    miso_pin: GPIO39

touchscreen:
  platform: xpt2046
  spi_id: touch
  cs_pin: GPIO33
  interrupt_pin: GPIO36
  update_interval: 50ms
  threshold: 400
  calibration:
    x_min: 3860
    x_max: 280
    y_min: 340
    y_max: 3860
  transform:
    swap_xy: false   

# Create a font to use, add and remove glyphs as needed. 
# Crea las fuente que quieres utilizar, añade o quita los caracteres que necesites.

font:
  - file: "gfonts://Itim"
    id: fecha
    size: 15
  - file: "gfonts://Itim"
    id: fetcha
    size: 17  
  - file: "gfonts://Kanit"
    id: hora
    size: 60
  - file: "gfonts://Roboto"
    id: info
    size: 15
  - file: "gfonts://Roboto"
    id: botones
    size: 11

# Create the colors you want to use.
# Crea los colores que quieres utilizar.

color:
  - id: black
    hex: '000000'
  - id: orange
    hex: 'eb9c17'
  - id: red
    hex: 'b20b23'
  - id: green
    hex: '148e23'  
  - id: grey
    hex: '464646'
    
# Create the icons you want to use.
# Crea los iconos que quieres utilizar.

image:
  - file: mdi:home-thermometer
    id: hometemperature
    resize: 40x40
  - file: mdi:weather-partly-cloudy
    id: weather
    resize: 40x40
  - file: mdi:solar-power-variant
    id: finance
    resize: 40x40
  - file: mdi:transmission-tower
    id: health
    resize: 40x40
  - file: mdi:page-previous
    id: back
    resize: 40x40
  - file: mdi:lightbulb-group-off-outline
    id: fan
    resize: 40x40
  - file: mdi:floor-lamp-torchiere
    id: thermostat
    resize: 40x40
  - file: mdi:mirror-rectangle
    id: vacuum
    resize: 40x40
  - file: mdi:led-strip-variant
    id: desk
    resize: 40x40
  - file: mdi:desk-lamp
    id: printer
    resize: 40x40
  - file: mdi:lightbulb
    id: printer3d
    resize: 40x40
  - file: mdi:home-assistant
    id: habbit
    resize: 40x40

# Replace the home gif as you want.
# Reemplaza el gif the inicio como quieras.

#animation:
#  - file: "habbit.gif"
#    id: ha
#    resize: 70x70
#    type: TRANSPARENT_BINARY

# This will fetch time from Home Assistant
time:
  - platform: homeassistant
    id: esptime

# Create sensors from HA you want to use and show.
# Crea los sensores de HA que quieres utilizar y mostrar.

sensor:
  - platform: homeassistant
    id: temperatura
    entity_id: sensor.wandthermostat_jan_temperatur
    internal: true
  - platform: homeassistant
    id: humedad
    entity_id: sensor.wandthermostat_jan_luftfeuchtigkeit
    internal: true
  - platform: homeassistant
    id: tempexterior
    entity_id: sensor.aussentemperatur_temperatur
    internal: true
  - platform: homeassistant
    id: problluvia
    entity_id: sensor.aussentemperatur_luftfeuchtigkeit
    internal: true
  - platform: homeassistant
    id: solarkwh
    entity_id: sensor.homestation_solar_total_energie_heute
    internal: true
  - platform: homeassistant
    id: netzeinsp
    entity_id: sensor.solar_netzeinspeisung_kwh_taglich
    internal: true
  - platform: homeassistant
    id: weight
    entity_id: sensor.stromverbrauch_taglich
    internal: true
  - platform: homeassistant
    id: distancia
    entity_id: sensor.stromverbrauch_gesamt_kwh
    internal: true
  - platform: homeassistant
    id: totalstrom
    entity_id: sensor.total_power_nur_verbrauch
    internal: true

text_sensor:
  - platform: homeassistant
    id: aireacondicionado
    entity_id: scene.lichtgruppe_wohnzimmer_aus
    internal: true
  - platform: homeassistant
    id: calefaccion
    entity_id: light.schlafzimmerlicht
    internal: true
  - platform: homeassistant
    id: aspirador
    entity_id: switch.bad_spiegellicht
    internal: true
  - platform: homeassistant
    id: escritorio
    entity_id: light.wandlicht
    internal: true
  - platform: homeassistant
    id: impresora
    entity_id: switch.pc_led_pv_led
    internal: true
  - platform: homeassistant
    id: impresora3d
    entity_id: light.couchlicht
    internal: true

# Assigns a function to each button, by calling the corresponding service in HA.
# Asigna una función a cada botón, llamando al servicio correspondiente en HA.

binary_sensor:
  - platform: touchscreen
    name: Button 1
    x_min: 0
    x_max: 140
    y_min: 0
    y_max: 65
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: scene.toggle
                  data:
                    entity_id: scene.lichtgruppe_wohnzimmer_aus
  - platform: touchscreen
    name: Button 2
    x_min: 140
    x_max: 280
    y_min: 0
    y_max: 65
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: light.toggle
                  data:
                    entity_id: light.schlafzimmerlicht
  - platform: touchscreen
    name: Button 3
    x_min: 0
    x_max: 140
    y_min: 65
    y_max: 130
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: switch.toggle
                  data:
                    entity_id: switch.bad_spiegellicht
  - platform: touchscreen
    name: Button 4
    x_min: 140
    x_max: 280
    y_min: 65
    y_max: 130
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: light.toggle
                  data:
                    entity_id: light.wandlicht
  - platform: touchscreen
    name: Button 5
    x_min: 0
    x_max: 140
    y_min: 130
    y_max: 195
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: switch.toggle
                  data:
                    entity_id: switch.pc_led_pv_led
  - platform: touchscreen
    name: Button 6
    x_min: 140
    x_max: 280
    y_min: 130
    y_max: 195
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
            else:
              - homeassistant.service:
                  service: light.toggle
                  data:
                    entity_id: light.couchlicht
  - platform: touchscreen
    name: Button 7
    x_min: 0
    x_max: 140
    y_min: 195
    y_max: 260
    on_press:
      then:
        - if:
            condition:
              lambda: 'return !id(show_return_page);'
            then:
              - globals.set:
                  id: show_return_page
                  value: !lambda "return !id(show_return_page);"
  - platform: touchscreen
    name: Button 8
    x_min: 140
    x_max: 280
    y_min: 195
    y_max: 260
    on_press:
      then:
        - globals.set:
            id: show_return_page
            value: !lambda "return !id(show_return_page);"

# Setup the ili9xxx platform
# Display is used as 240x320 by default so we rotate it to 90°     model: ili9342 changed to model: ili9341

display:
  - platform: ili9xxx
    id: esp_display
    model: ili9341
    spi_id: tft
    cs_pin: GPIO15
    dc_pin: GPIO2
    rotation: 0
    invert_colors: false
    lambda: |-
      if (id(show_return_page)) {
        int button_width = 100;
        int button_height = 65;
        int x_start = 15;
        int y_start = 15;
        int x_padding = 10;
        int y_padding = 10;

        // Define los textos para los botones
        const char* button_texts[] = {
          "Wohnzimmer",
          "Schlafzimmer",
          "Badlicht",
          "Wandlicht",
          "PC-Licht",
          "Couchlicht",
          "Free",
          "Start"
        };

        for (int row = 0; row < 4; row++) {
          for (int col = 0; col < 2; col++) {
            int button_index = row * 2 + col;
            int x = x_start + col * (button_width + x_padding);
            int y = y_start + row * (button_height + y_padding);
            it.rectangle(x, y, button_width, button_height, id(grey));
            int text_width = strlen(button_texts[button_index]) * 5.5; 
            int text_height = 16; 
            it.print(x + (button_width - text_width) / 2, y + (button_height - text_height) / 2 + 20, id(botones), button_texts[button_index]);
          }
        }
        if (id(aireacondicionado).state == "on") {
          it.image(45, 20, id(fan), id(orange));
        } else {
          it.image(45, 20, id(fan), id(grey));
        }
        if (id(calefaccion).state == "on") {
          it.image(155, 20, id(thermostat), id(orange));
        } else {
          it.image(155, 20, id(thermostat), id(grey));
        }
        if (id(aspirador).state == "on") {
          it.image(45, 95, id(vacuum), id(orange));
        } else {
          it.image(45, 95, id(vacuum), id(grey));
        }
        if (id(escritorio).state == "on") {
          it.image(155, 95, id(desk), id(orange));
        } else {
          it.image(155, 95, id(desk), id(grey));
        }
        if (id(impresora).state == "on") {
          it.image(45, 170, id(printer), id(orange));
        } else {
          it.image(45, 170, id(printer), id(grey));
        }
        if (id(impresora3d).state == "on") {
          it.image(155, 170, id(printer3d), id(orange));
        } else {
          it.image(155, 170, id(printer3d), id(grey));
        }
        it.image(45, 245, id(habbit), id(grey));
        it.image(155, 245, id(back), id(green));

      } else {
        static int y = 182;
        static int y_direction = 4;  // Velocidad del movimiento
        const int y_min = 180;       
        const int y_max = 187;       

        it.fill(id(black));
        it.strftime(120, 55, id(fecha), TextAlign::CENTER, "%d/%m/%Y", id(esptime).now());
        it.strftime(120, 92, id(hora), TextAlign::CENTER, "%H:%M", id(esptime).now());
        it.printf(120, 135, id(fetcha), TextAlign::CENTER, "Aussentemp %.1f C", id(tempexterior).state);
        it.line(50, 150, 190, 150);
        it.printf(120, 163, id(fetcha), TextAlign::CENTER, "Hausstr %.1f W", id(totalstrom).state);
        
        static int current_text_index = 0;
        static float text_timer = 0;
        const float text_interval = 4.0;  // Intervalo para cambiar el texto en segundos

        text_timer += 1.0;  
        if (text_timer >= text_interval) {
          text_timer = 0;
          current_text_index = (current_text_index + 1) % 4;  // Alternar entre cuatro textos
        }

        if (current_text_index == 0) {
          it.image(15, 260, id(hometemperature), id(orange));
          it.print(70, 260, id(info), "Temperatur");
          it.printf(175, 260, id(info), "%.1f C", id(temperatura).state);
          it.print(70, 280, id(info), "Luftfeuchte");
          it.printf(175, 280, id(info), "%.1f %%", id(humedad).state);
        } else if (current_text_index == 1) {
          it.image(15, 260, id(weather), id(orange));
          it.print(70, 260, id(info), "Temperatur");
          it.printf(175, 260, id(info), "%.1f C", id(tempexterior).state);
          it.print(70, 280, id(info), "Au Luftfeuchte");
          it.printf(175, 280, id(info), "%.1f %%", id(problluvia).state);
        } else if (current_text_index == 2) {
          it.image(15, 260, id(finance), id(green));
          it.print(70, 260, id(info), "Solarertrag");
          it.printf(175, 260, id(info), "%.1f kWh", id(solarkwh).state);
          it.print(70, 280, id(info), "Einspeisung");
          it.printf(175, 280, id(info), "%.1f kWh", id(netzeinsp).state);
        } else if (current_text_index == 3) {
          it.image(15, 260, id(health), id(red));
          it.print(70, 260, id(info), "Strom heute");
          it.printf(175, 260, id(info), "%.1f kWh", id(weight).state);
          it.print(70, 280, id(info), "Strom total");
          it.printf(175, 280, id(info), "%.1f kWh", id(distancia).state);
        }
      }


2 Likes

That’s pretty cool!! I’ll share your design with my community :blush: