GUITION 4" 480x480 ESP32-S3-4848S040 Smart Display with LVGL

Im not finished yet by a long shot, but here is what Im doing and where Ive got to:

For clarification - this is not tidy or efficient coding (YET) - but its the way I do things: proof of concept and then clean up. Hopefully there are parts here that may help others.

Am creating a fermenter controller for my brewery.

substitutions:
  name: "display"
  friendly_name: "display"
  text_font: barlow24

esphome:
  name: "${name}"
  friendly_name: "${friendly_name}"
  min_version: 2024.7.0
  platformio_options:
    board_build.flash_mode: dio
  on_boot: 
    - delay: 5s  # 5s for speed
    - lvgl.label.update:
        id: ssid_label_top_layer
        text:
          format: "SSID: %s"
          args: [ 'id(ssid_address_text).state.c_str()' ]
    - lvgl.label.update:
        id: ip_label_top_layer
        text:
          format: "IP: %s"
          args: [ 'id(ip_address_text).state.c_str()' ]          
    - delay: 1s #1s for speed
    - lvgl.widget.hide: boot_screen
esp32:
  board: esp32-s3-devkitc-1
  variant: esp32s3
  flash_size: 16MB
  framework:
    type: esp-idf
    sdkconfig_options:
      COMPILER_OPTIMIZATION_SIZE: y
      CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y"
      CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
      CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
      CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
      CONFIG_SPIRAM_RODATA: y
psram:
  mode: octal
  speed: 80MHz
logger:
  level: DEBUG
  logs:
    i2c.idf: info
    touchscreen: info
    scheduler: none
    api: debug
api:
  on_client_connected:
    - logger.log:
        format: "Client %s connected to API with IP %s"
        args: ["client_info.c_str()", "client_address.c_str()"]
    - if:
        condition:
          lambda: 'return (0 == client_info.find("Home Assistant"));' 
        then:
          - lvgl.led.update:
              id: api_led
              color: 0x32CD32
              brightness: 100%      
          - lvgl.led.update:
              id: api_led6
              color: 0x32CD32
              brightness: 100%                
          - lvgl.led.update:
              id: api_led_settings_page
              color: 0x32CD32
              brightness: 100%     
          - lvgl.led.update:
              id: api_led_screensaver
              color: 0x32CD32
              brightness: 100%                                              
        else:
          - lvgl.led.update:
              id: api_led
              color: 0xFF0000
              brightness: 100%        
          - lvgl.led.update:
              id: api_led6
              color: 0xFF0000
              brightness: 100%   
          - lvgl.led.update:
              id: api_led_settings_page
              color: 0xFF0000
              brightness: 100%        
          - lvgl.led.update:
              id: api_led_screensaver
              color: 0xFF0000
              brightness: 100%                                                          
captive_portal:
safe_mode:  
ota:
  platform: esphome
web_server:
  port: 80
  version: 3  
  auth:
    username: "admin"
    password: "tYcho1-2264"
wifi:
  networks:
  - ssid: xxxxx
    password: xxxxxx
  - ssid: xxxxx
    password: xxxxx
  on_connect:
    then:
      - lvgl.label.update:
          id: ssid_label_p6
          text:
            format: "SSID: %s"
            args: [ 'id(ssid_address_text).state.c_str()' ]  
      - lvgl.label.update:
          id: ipaddr_label_p6
          text:
            format: "IP: %s"
            args: [ 'id(ip_address_text).state.c_str()' ]                   
      - lvgl.led.update:
          id: wfi_led
          color: 0x32CD32
          brightness: 100%
      - lvgl.led.update:
          id: wfi_led6
          color: 0x32CD32
          brightness: 100%          
      - lvgl.led.update:
          id: wfi_led_settings_page
          color: 0x32CD32
          brightness: 100% 
      - lvgl.led.update:
          id: wfi_led_screensaver
          color: 0x32CD32
          brightness: 100%                               
  on_disconnect:
    then:
      - lvgl.label.update:
          id: ssid_label_p6
          text: "SSID: NOT CONNECTED"
      - lvgl.label.update:
          id: ipaddr_label_p6
          text: "IP: NOT CONNECTED"
      - lvgl.led.update:
          id: wfi_led
          color: 0xFF0000
          brightness: 100%
      - lvgl.led.update:
          id: wfi_led6
          color: 0xFF0000
          brightness: 100%
      - lvgl.led.update:
          id: wfi_led_settings_page
          color: 0xFF0000
          brightness: 100%          
      - lvgl.led.update:
          id: wfi_led_screensaver
          color: 0xFF0000
          brightness: 100%    
external_components:
  - source: github://pr#6363 # Previous commit - wont be needed once this code is relaased
    refresh: 10min
    components: [lvgl]


# LVGL DASHBOARDS
lvgl:
  displays:
    - display_id: my_display
  touchscreens:
    - touchscreen_id: my_touchscreen
  on_idle:
    - timeout: 300s
      then:
        - logger.log: idle timeout
        - lvgl.page.show: screensaver

  style_definitions:
    - id: style_line
      line_color: 0x0000FF
      line_width: 8
      line_rounded: true
    - id: date_style
      text_font: barlow24
      align: center
      text_color: 0x333333
      bg_opa: cover
      radius: 4
      pad_all: 2

  theme:
    button:
      text_font: barlow24
      scroll_on_focus: true
      group: general
      radius: 5
      width: 133
      height: 50
      bg_opa: COVER
      border_color: 0x0077b3
      border_width: 1      
      text_color: 0xB6B6B6
      # checked:
      #   bg_color: 0xCC5E14
      #   text_color: 0xB6B6B6
    label:
        text_color: 0xB6B6B6
    image:
      border_width: 0
      border_side: none


  top_layer:
    widgets:
      - obj:
          id: boot_screen
          x: 0
          y: 0
          width: 100%
          height: 100%
          bg_color: 0x000000
          bg_opa: COVER
          radius: 0
          pad_all: 0
          border_width: 0
          widgets:
            - image:
                align: CENTER
                src: boot_logo_1
                y: -40
            - spinner:
                align: CENTER
                y: 95
                height: 70
                width: 70
                spin_time: 1.5s
                arc_length: 60deg
                arc_width: 8
                indicator:
                  arc_color: 0x18bcf2
                  arc_width: 8
            - label:
                id: ssid_label_top_layer
                text_font: barlow24
                text: "SSID: NOT CONNECTED"
                x: 150
                y: 385        
            - label:
                id: ip_label_top_layer
                text_font: barlow24
                text: "IP: NOT CONNECTED"
                x: 150
                y: 420       
          on_press:
            - lvgl.widget.hide: boot_screen

  page_wrap: true
  pages:
    - id: page1
      skip: false
      pad_all: 0
      widgets:
        - image:
            id: page1_background
            src: display_not_cooling
        - image:
            id: page1_sidebar
            src: display_sidebar
            opa: 50%
            x: 310

      #       LEDS
        - led:
            id: wfi_led
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 10
        - label:
            id: wfi_led_label
            text_font: barlow24
            text: "WIFI"
            x: 50
            y: 5
        - led:
            id: api_led
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 50
        - label:
            id: api_led_label
            text_font: barlow24
            text: "API"
            x: 50
            y: 45          
        - led:
            id: sensor_led
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 90
        - label:
            id: sensor_led_label
            text_font: barlow24
            text: "SENSOR"
            x: 50
            y: 85        

        - label:
            id: tank_temp_label
            text_font: barlow24
            text: "TANK TEMP"
            text_color: 0xFFFFFF            
            x: 190
            y: 80
        - label:
            id: tank_acttemp_label
            text_font: barlow120
            text_color: 0xFFFFFF
            x: 140
            y: 110
            hidden: true
            text:
              format: "%.1f"
              args: [ 'id(sim_temp1).state' ]   # < - CHANGE THIS WHEN READY
        - label:
            id: tank_error_label
            text_font: barlow120
            text_color: 0xFFFFFF
            x: 140
            y: 110
            text: "ERROR"
            hidden: false
   
        - label:
            id: set_temp_label
            text_font: barlow24
            text: "SET TEMP"
            text_color: 0xFFFFFF
            x: 191
            y: 321           
        - label:
            id: set_act_temp_label
            text_font: barlow40
            text_color: 0xFFFFFF
            text: "17.6"
            x: 210
            y: 355        


        - button:
            id: lv_button_1
            x: 332
            y: 35
            widgets:
              - label:
                  text_font: barlow24
                  text: "AUTO"
                  align: center
                  text_color: 0xFFFFFF
            on_click:
              - climate.control:
                  id: controller
                  mode: "COOL"         

        - button:
            id: lv_button_2
            x: 332
            y: 109
            bg_color: 0x868686
            bg_grad_color: 0x2c2d2f
            bg_grad_dir: VER            
            widgets:
              - label:
                  text_font: barlow24
                  text: "OFF"
                  align: center
            on_click:
              - lvgl.widget.update:
                  id: lv_button_1
              - climate.control:
                  id: controller
                  mode: "OFF"        


        - button:
            id: lv_button_3
            x: 332
            y: 204
            bg_color: 0x5fadd6
            bg_grad_color: 0x2c2d2f
            bg_grad_dir: VER                  
            widgets:
              - label:
                  text_font: barlow24
                  text: "COOLING"
                  align: center
                  bg_color: 0x5DA8CE
                  bg_grad_color: 0x2D2E30
                  bg_grad_dir: VER
            on_click:
              - lvgl.widget.update:
                  id: lv_button_1
                                      
                  align: center
                  bg_color: 0x808182
                  bg_grad_color: 0x2d2e30
                  bg_grad_dir: VER

        - button:
            id: lv_button_4
            x: 332
            y: 338
            bg_color: 0x962B2B
            widgets:
              - label:
                  text_font: barlow24
                  text: "SETTINGS"
                  align: center
            on_press:
              then:
                lvgl.page.show: settings_page

        - button:
            id: lv_button_5
            x: 332
            y: 403
            bg_color: 0x622D93
            widgets:
              - label:
                  text_font: barlow24
                  text: "EXTRAS"
                  align: center
            on_press:
              then:
                lvgl.page.show: extras_page


    - id: settings_page
      skip: true
      bg_image_src: display_cooling
      bg_opa: cover
      pad_all: 0
      widgets:

        #       LEDS
        - led:
            id: wfi_led_settings_page
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 10
        - label:
            id: wfi_led_label_settings_page
            text_font: barlow24
            text: "WIFI"
            x: 50
            y: 5
        - led:
            id: api_led_settings_page
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 50
        - label:
            id: api_led_label_settings_page
            text_font: barlow24
            text: "API"
            x: 50
            y: 45          
        - led:
            id: sensor_led_settings_page
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 90
        - label:
            id: sensor_led_label_settings_page
            text_font: barlow24
            text: "SENSOR"
            x: 50
            y: 85        

        - label:
            id: tank_temp_label_settings_page
            text_font: barlow24
            text: "SET TEMP"
            text_color: 0xFFFFFF            
            x: 190
            y: 80
        - label:
            id: tank_settemp_label_settingspage
            text_font: barlow120
            text_color: 0xFFFFFF
            x: 140
            y: 110
            text:
              format: "%.1f"
              args: [ 'id(controller).target_temperature' ] 

        - button:
            id: lv_button_1_settings_page
            x: 332
            y: 35
            widgets:
              - label:
                  text_font: barlow24
                  text: "+"
                  align: center
            on_release:
              then:
                - climate.control:
                    id: controller
                    target_temperature: !lambda "return id(controller).target_temperature + 0.1;"
                - lvgl.widget.update:
                    id: tank_settemp_label_settingspage


        - button:
            id: lv_button_2_settings_page
            x: 332
            y: 109
            bg_color: 0x1E1E1E
            widgets:
              - label:
                  text_font: barlow24
                  text: "-"
                  align: center
            on_release:
              then:
                - climate.control:
                    id: controller
                    target_temperature: !lambda "return id(controller).target_temperature - 0.1;"
                - lvgl.label.update:
                    id: tank_settemp_label_settingspage


        - button:
            id: lv_button_5_settings_page
            x: 332
            y: 403
            bg_color: 0x622D93
            widgets:
              - label:
                  text_font: barlow24
                  text: "RETURN"
                  align: center
            on_press:
              then:
                lvgl.page.show: page1


    - id: extras_page
      skip: true
      bg_image_src: display_error
      bg_opa: cover
      pad_all: 0
      widgets:

        #       LEDS


        - led:
            id: wfi_led6
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 10
        - label:
            id: wfi_led_label6
            text_font: barlow24
            text: "WIFI"
            x: 50
            y: 5
        - led:
            id: api_led6
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 50
        - label:
            id: api_led_label6
            text_font: barlow24
            text: "API"
            x: 50
            y: 45          
        - led:
            id: sensor_led6
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 90
        - label:
            id: sensor_led_label6
            text_font: barlow24
            text: "SENSOR"
            x: 50
            y: 85        

        - button:
            id: lv_button_6
            x: 332
            y: 403
            bg_color: 0x622D93
            widgets:
              - label:
                  text_font: barlow24
                  text: "RETURN"
                  align: center
            # on_press:
            #   then:
            #     lvgl.page.previous:
            on_press:
              then:
                lvgl.page.show: page1

        - label:
            id: ssid_label_p6
            text_font: barlow24
            text: "SSID: NOT CONNECTED"
            x: 150
            y: 285        
        - label:
            id: ipaddr_label_p6
            text_font: barlow24
            text: "IP: NOT CONNECTED"
            x: 150
            y: 320       




        - button:
            id: lv_button_7
            x: 150
            y: 150
            bg_color: 0x622D93
            widgets:
              - label:
                  text_font: barlow24
                  text: "RESTART"
                  align: center
            on_click:
              - switch.turn_on: restart_node
                


    - id: screensaver
      skip: true
      bg_opa: cover
      pad_all: 0
      widgets:
        - image:
            id: ss_background
            src: display_off

        #       LEDS

        - led:
            id: wfi_led_screensaver
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 10
        - label:
            id: wfi_led_label_screensaver
            text_font: barlow24
            text: "WIFI"
            x: 50
            y: 5
        - led:
            id: api_led_screensaver
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 50
        - label:
            id: api_led_label_screensaver
            text_font: barlow24
            text: "API"
            x: 50
            y: 45          
        - led:
            id: sensor_led_screensaver
            color: 0xFF0000
            brightness: 100%
            x: 10
            y: 90
        - label:
            id: sensor_led_label_screensaver
            text_font: barlow24
            text: "SENSOR"
            x: 50
            y: 85        

        - label:
            id: tank_error_label_screensaver
            text_font: barlow120
            text_color: 0xFFFFFF
            x: 140
            y: 110
            text: "ERROR"
            hidden: false

        - button:
            id: lv_button_screensaver
            x: 332
            y: 403
            bg_color: 0x622D93
            widgets:
              - label:
                  text_font: barlow24
                  text: "RETURN"
                  align: center
            # on_press:
            #   then:
            #     lvgl.page.previous:
            on_press:
              then:
                lvgl.page.show: page1


# ESPHome sensors switches GPIOs and bits   
text_sensor:
  - platform: wifi_info
    ip_address:
      id: ip_address_text
      name: "IP Address"
      entity_category: diagnostic
    ssid:
      id: ssid_address_text
      name: "Connected SSID"
      entity_category: diagnostic
    mac_address:
      name: "Mac Address"
      entity_category: diagnostic
 
one_wire:
  - platform: gpio
    pin: GPIO1

sensor:
  - platform: wifi_signal
    name: "WiFi Signal"
    id: wifi_signal_db
    update_interval: 60s
    entity_category: diagnostic
    internal: true

  # Reports the WiFi signal strength in %
  - platform: copy
    source_id: wifi_signal_db
    name: "WiFi Strength"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"
    entity_category: diagnostic

  - platform: dallas_temp
    name: "temp1 raw value"
    update_interval: 1s
    id: temp1_raw

  - platform: dallas_temp
    name: temp_probe
    update_interval: 1s
    id: temp1
    filters:
      - skip_initial: 5
      - clamp:
          min_value: 2
          max_value: 90
          ignore_out_of_range: true
      - median:
          window_size: 7
          send_every: 4
          send_first_at: 3       
    # on_value:
    #   then:
    #     - lvgl.label.update:
    #         id: tank_acttemp_label
    #         text:
    #           format: "%.1f"
    #           args: [ 'x' ]
        
    
  - platform: dallas_temp
    name: demo-probe-error
    update_interval: 10s
    id: temp_probe_error

  - platform: template
    name: "Simulated Temperature"
    id: sim_temp1
    update_interval: 5s  # Update interval for the temperature change
    lambda: |-
      static float temperature = 20.0;  
      int rand_val = esp_random(); 
      float change = ((rand_val % 1000) / 1000.0 - 0.5) * 0.4; // Scale to -0.2 to +0.2
      temperature += change;
      if (temperature < 0.0) {
        temperature = 0.0;
      } else if (temperature > 40.0) {
        temperature = 40.0;
      }
      return temperature;
    on_value:
      then:
        - lvgl.label.update:
            id: tank_acttemp_label
            text:
              format: "%.1f" 
              args: [ 'x' ]

binary_sensor:
  - platform: template
    name: "ds18b20 state"
    id: ds18_state
    lambda: |-
      if (id(temp_probe_error).state > 0) {
        return true;
      } else {
        return false;
      }
    on_state: 
      then:
        if:
          condition:
            binary_sensor.is_on: ds18_state
          then:
            - lvgl.led.update:
                id: sensor_led
                color: 0x32CD32
                brightness: 100%
            - lvgl.led.update:
                id: sensor_led6
                color: 0x32CD32
                brightness: 100%    
            - lvgl.led.update:
                id: sensor_led_settings_page
                color: 0x32CD32
                brightness: 100%                             
          else:
            - lvgl.led.update:
                id: sensor_led
                color: 0xFF0000
                brightness: 100%
            - lvgl.led.update:
                id: sensor_led6
                color: 0xFF0000
                brightness: 100%
            - lvgl.led.update:
                id: sensor_led_settings_page
                color: 0xFF0000
                brightness: 100%
            - lvgl.image.update:
                id: page1_background
                src: display_error
                bg_image_recolor: 0xff0000
            - lvgl.image.update:
                id: ss_background
                src: display_error
                

number:
  - platform: template
    name: "Sensor Offset"
    id: sensor_offset
    optimistic: true
    min_value: -2.0
    max_value: 2.0
    restore_value: True
    step: 0.1
    unit_of_measurement: "Ā°C" 
    # on_value:
    #   - lvgl.label.update:
    #       id: tank_acttemp_label
    #       text:
    #         format: "%.1f"
    #         args: [ 'x' ]


output:
    # Backlight LED
  - platform: ledc
    pin: GPIO38
    id: GPIO38
    frequency: 100Hz
    
    # Built in 240v relay
  # - id: relay_1a
  #   platform: gpio
  #   pin: 40

switch:
  - platform: gpio
    pin: 40
    id: relay_1
    name: relay1

  - platform: restart
    id: restart_node
    name: Restart Node  
    restore_mode: ALWAYS_OFF  
    on_turn_on:
      - delay: 2s 
      - switch.turn_off: restart_node

light:
  - platform: monochromatic
    output: GPIO38
    name: Backlight
    id: backlight
    restore_mode: ALWAYS_ON


climate:
  - platform: thermostat
    name: demo-controller
    id: controller
    sensor: sim_temp1
    on_boot_restore_from: memory
    setup_priority: -100
    startup_delay: True    
    visual:
      min_temperature: 0
      max_temperature: 40
      temperature_step: 0.1    
    min_cooling_off_time: 20s
    min_cooling_run_time: 1s
    cool_deadband: 0.01
    cool_overrun: 0.1
    min_idle_time: 1s
    cool_action:
      - switch.turn_on: relay_1
      - light.turn_on:
          id: backlight
          # Solenoid button blue
      - lvgl.widget.update:
          id: lv_button_3
          bg_color: 0x5DA8CE
          bg_grad_color: 0x2D2E30
          bg_grad_dir: VER


    idle_action:
      - switch.turn_off: relay_1    
      # solenoid button grey  
      - lvgl.widget.update:
          id: lv_button_3
          bg_color: 0x808182
          bg_grad_color: 0x2d2e2f
          bg_grad_dir: VER          
    cool_mode:
      - light.turn_on:
          id: backlight
          # auto mode green
      - lvgl.widget.update:
          id: lv_button_1
          bg_color: 0x6fd5b4
          bg_grad_color: 0x2d2e2f
          bg_grad_dir: VER                    

    off_mode:
      - switch.turn_off: relay_1          
      - lvgl.widget.update:
          id: lv_button_2
          bg_color: 0xb4b5b5
          bg_grad_color: 0x2d2e2f
          bg_grad_dir: VER          
      - lvgl.widget.update:
          id: lv_button_1
          bg_color: 0x364B47
          bg_grad_color: 0x090B0A
          bg_grad_dir: VER              
      - lvgl.widget.update:
          id: lv_button_3
          bg_color: 0x808182
          bg_grad_color: 0x2d2e2f
          bg_grad_dir: VER     

# ==========================================================================================================================================================================================================
# Stuff that doesnt need to be modified

# Graphics, Images and Fonts
font:
  - file: "BarlowCondensed-Regular.ttf"
    id: barlow24
    size: 24
    bpp: 4
  - file: "BarlowCondensed-Regular.ttf"
    id: barlow120
    size: 120
    bpp: 4
  - file: "BarlowCondensed-Regular.ttf"
    id: barlow40
    size: 40
    bpp: 4


image:

  - file: tank_sidebar.png
    id: display_sidebar
    resize: 480x480
    type: RGB565
  - file: tank_cooling.png
    id: display_cooling
    resize: 480x480
    type: RGB565
  - file: tank_error.png
    id: display_error
    resize: 480x480
    type: RGB565
  - file: tank_error.png
    id: display_disconn
    resize: 480x480
    type: RGB565
  - file: tank_not_cooling.png
    id: display_not_cooling
    resize: 480x480
    type: RGB565
  - file: tank_off.png
    id: display_off
    resize: 480x480
    type: RGB565
  - file: opba.jpg
    id: boot_logo_1
    resize: 200x200
    type: RGB565

i2c:
  - id: bus_a
    sda: GPIO19
    scl: GPIO45
    #frequency: 100kHz
    
touchscreen:
  platform: gt911
  transform:
    mirror_x: false
    mirror_y: false
  id: my_touchscreen
  display: my_display

  on_touch:
    - logger.log:
          format: Touch at (%d, %d)
          args: [touch.x, touch.y]
    - lambda: |-
          ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
              touch.x,
              touch.y,
              touch.x_raw,
              touch.y_raw
              );

spi:
  - id: lcd_spi
    clk_pin: GPIO48
    mosi_pin: GPIO47
    
display:
  - platform: st7701s
    id: my_display
    update_interval: never
    auto_clear_enabled: False
    spi_mode: MODE3
    data_rate: 2MHz
    color_order: RGB
    invert_colors: False
    dimensions:
      width: 480
      height: 480
    cs_pin: 39
    de_pin: 18
    hsync_pin: 16
    vsync_pin: 17
    pclk_pin: 21
    pclk_frequency: 12MHz
    pclk_inverted: False
    hsync_pulse_width: 8
    hsync_front_porch: 10
    hsync_back_porch: 20
    vsync_pulse_width: 8
    vsync_front_porch: 10
    vsync_back_porch: 10
    init_sequence:
      - 1
      # Custom sequences are an array, first byte is command, the rest are data.
      - [ 0xFF, 0x77, 0x01, 0x00, 0x00, 0x10 ] # CMD2_BKSEL_BK0
      - [ 0xCD, 0x00 ] # disable MDT flag
    data_pins:
      red:
        - 11        #r1
        - 12        #r2
        - 13        #r3
        - 14        #r4
        - 0         #r5
      green:
        - 8         #g0
        - 20        #g1
        - 3         #g2
        - 46        #g3
        - 9         #g4
        - 10        #g5
      blue:
        - 4         #b1
        - 5         #b2
        - 6         #b3
        - 7         #b4
        - 15        #b5        

Iā€™m on the phone, so itā€™s hard to edit and post the codes.

The initial state is working correctly, right?
In the automation, use text update instead of widget and pass the same arguments as the initial state.

Hey guysā€¦

Are we still using

external_components:
  - source: github://pr#7184

or has it been baked into 2024.8.X already

No you donā€™t need that git link anymore. Itā€™s much better to use the release code. You will have to change a few things like btn is now button. But a search and replace will get it working fast.

Iā€™m programming a few of these displays for my diy campervan and Iā€™m struggling with one (minor) thing. I want to use substitutions for the colors of the buttons in lvgl, but I canā€™t figure it out how to use the correct syntax. I can use numbers for the height and width, but when I use it for p.e. bg_color I keep getting errors. Anyone with the correct way to do this?

  • edit: found another solution by working with the ā€˜colorā€™ option.

@walberjunior

I want to use images instead of icons for weather state I see this example, but how this de id look like? I know only files and than I have this

  - file: 'images/cloudy.png'
    id: weather_weather_image
    type: RGB565

But you have like this, how should the file/id look like than?

              - lvgl.image.update:
                  id: display_weather_image
                  src: cloudy

Take a look at my latest example file. Iā€™m pulling colors from an external file.

I have been working hard a getting this screen to do more. I just added a big example file with a boot screen, auto dimming the backlight at night and basic examples for local and Home Assistant control buttons. Also pulling in almost 200 colors that can be called by name!

1 Like

Something like this:

image:

  - file: 'images/cloudy.png'
    id: cloudy
    type: RGB565

  - file: 'images/rainy.png'
    id: rainy
    type: RGB565


  - lvgl.image.update:
      id: display_weather_image 
      src: cloudy
  page_wrap: true
  pages:  
    - id: page_floorplan 
      widgets:
        - image:
            align: TOP_LEFT
            x: 0
            y: 0
            src: rainy
            id: display_weather_image 

1 Like

You need to start reading the esphome release notes :slight_smile:

However the tips and tricks page has not yet been migrated, so you have to look here. LVGL: Tips and Tricks ā€” ESPHome

Nobody knows?
Iā€™m completely stuck here =(

I donā€™t think you did.

lv_font_montserrat is not in the first post. Please post your full yaml.

Without the code we are only guessing.

If you post your yaml Iā€™m sure that someone here will be willing to help.

Everyone here has been most helpful to date.

Yepā€¦ Been a bit of a lag in catching up.to whatā€™s relevant NOW compared to ā€œup and runningā€ at the top of this post.

Just ran thru the 2024.9.b GitHub this morn and the 2024.8.3 stuff yesterday.

Look like you are trying to use a font that doesnā€™t exist. Try building this code first. Then edit from there.

That can be useful indeed, Iā€™m gonna check this out. Learning a lot from your other yaml as well, thanks! :smiley:

Hi Andrew - Ive looked at your ā€˜more buttonsā€™ file and will give it a go when i get home.
what im trying to work out is - how do i define a thing in ESP home to do a thing in HA.

ie:
under the buttons bit of LVGL you can put : ā€œshort_pressā€, then something about -platform: homeassistant, then something about 'call_service, then something about ā€˜light.toggleā€™ then entity_id

is that how it works?

or do you need to ā€˜defineā€™ it somewhere in the yaml file first, to be able to access it?
i cant make head nor tail of the lvgl documentation.

It works like the docs say

The second button on the page does this. I have a very nice Athom Smart Plug connected to a lamp next to my couch. This shows up in Home Assistant and automatically creates a switch called switch.athom_smart_plug_v3_50ebc0_switch

I am trying to make all my buttons generic and then configure them using a substitutions:

So step 1 is to create the substitutions. This creates the buttons name, ID, Icon, and Home Assistant device to be controlled.

  button_2_name: "Couch Lamp"
  button_2_id: couch_lamp
  button_2_icon: $lightbulb
  button_2_HAdevice: "switch.athom_smart_plug_v3_50ebc0_switch"

Next I create the button itself in the LVGL section

        - button:
            height: $button_height_single        
            checkable: true
            id: lv_button_2
            widgets:
              - label:
                  text_font: $icon_font
                  align: top_left
                  text: $button_2_icon
                  id: lv_button_2_icon
              - label:
                  align: bottom_left
                  text: $button_2_name
 
            on_click:
                - homeassistant.service:
                    service: switch.toggle
                    data:
                      entity_id: $button_2_HAdevice

And last I create a Home Assistant object that changes the color of the button and icon to match the state in Home Assistant. That way if another device turns on the my Couch Light it will update correctly on the screen.

  - platform: homeassistant
    name: "$button_2_name"
    entity_id: $button_2_HAdevice
    on_value:
      then:
        - lvgl.widget.update:
            id: lv_button_2
            state:
              checked: !lambda return (0 == x.compare(std::string{"on"}));
              disabled: !lambda return ((0 == x.compare(std::string{"unavailable"})) or (0 == x.compare(std::string{"unknown"})));
        - if:
            condition:
              lambda: return (0 == x.compare(std::string{"on"}));
            then:
              - lvgl.widget.update:
                  id: lv_button_2_icon
                  text_color: Yellow
            else:
              - lvgl.widget.update:
                  id: lv_button_2_icon
                  text_color: Gray

At some point Iā€™ll create more ā€œgenericā€ types of buttons like for dimmable lights and color changing light (once the color picker is added to ESPHome). But for now just copy this one and add 1 to the numbers.

1 Like

Thats amazing!

can i Just ask - the 3rd bit of programming - where does that go exactly? should there be a ā€˜object:ā€™ thing or does it sit randomly?