substitutions: device: lvgl name: LVGL area: DEV comment: "${area} | LVGL" esphome: name: mcu-${device} area: ${area} comment: ${comment} platformio_options: board_build.flash_mode: dio includes: ota.h esp32: board: esp32-s3-devkitc-1 variant: esp32s3 flash_size: 16MB framework: type: esp-idf version: 5.3.2 platform_version: 53.03.11 # Required to achieve sufficient PSRAM bandwidth sdkconfig_options: CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: y CONFIG_ESP32S3_DATA_CACHE_64KB: y CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y CONFIG_SPIRAM_RODATA: y psram: mode: octal speed: 80MHz packages: common: !include common/common.yaml # PINOUTS: ESP32 Cheap Yellow Display, 4.3", IPS, Capacitive ## Display # R0 GND # R1 GND # R2 GND # R3 45 # R4 48 # R5 47 # R6 21 # R7 14 # G0 GND # G1 GND # G2 5 # G3 6 # G4 7 # G5 15 # G6 16 # G7 4 # B0 GND # B1 GND # B2 GND # B3 8 # B4 3 # B5 46 # B6 9 # B7 1 # DCLK 42 # HSYNC 39 # VSYNC 41 # DE 40 ## Capacitive Touch # TP_INT # TP_RST 38 # TP_SDA 19 # TP_SCL 20 ## SDCARD # TF_CS 10 # SPI_MOSI 11 # SPI_CLK 12 # SPI_MISO 13 ## SPI Conector (HC1.25-4) # SPI_CS 19 # SPI_MOSI 11 # SPI_CLK 12 # SPI_MISO 13 ## UART1 (SH1.0-4) # 1 GND # 2 3V3-ESP # 3 17 # 4 18 ## UART1, USB Connector (Resistive) / I2C (Capacitive) (HC1.25-4) # 1 17 # 2 18 # 3 19 TP_SDA # 4 20 TP_SCL i2c: - id: i2c_main sda: 19 scl: 20 scan: true display: - platform: rpi_dpi_rgb id: main_display color_order: RGB invert_colors: true update_interval: never auto_clear_enabled: false # takes 2.8 seconds to clear the display dimensions: width: 800 height: 480 de_pin: 40 hsync_pin: 39 vsync_pin: 41 pclk_pin: 42 pclk_frequency: 12.5MHz hsync_pulse_width: 4 hsync_front_porch: 8 hsync_back_porch: 8 vsync_pulse_width: 4 vsync_front_porch: 8 vsync_back_porch: 8 data_pins: red: - 45 # R1 - 48 # R2 - 47 # R3 - 21 # R4 - 14 # R5 green: - 5 # G0 - 6 # G1 - 7 # G2 - 15 # G3 - 16 # G4 - 4 # G5 blue: - 8 # B1 - 3 # B2 - 46 # B3 - 9 # B4 - 1 # B5 # Define a PWM output on the ESP32 output: - platform: ledc pin: 2 frequency: 1220 id: gpio_backlight_pwm light: - platform: monochromatic output: gpio_backlight_pwm id: back_light restore_mode: ALWAYS_ON text_sensor: - platform: template # name: Uptime Human Readable id: uptime_human icon: mdi:clock-start internal: True time: - platform: homeassistant id: time_comp number: - platform: template initial_value: 0 id: counting_number internal: True min_value: -10 max_value: 10 step: 1 optimistic: True # debug: # update_interval: 5s sensor: - platform: uptime id: uptime_counter update_interval: 1s accuracy_decimals: 0 on_raw_value: then: - light.turn_on: id: back_light brightness: 90% - number.increment: id: counting_number cycle: True - script.execute: update_display # - platform: debug # free: # name: "${name} Heap Free" # block: # name: "${name} Heap Max Block" # loop_time: # name: "${name} Loop Time" # psram: # name: "${name} Free PSRAM" - platform: uptime # name: Uptime Sensor internal: True id: uptime_sensor update_interval: 1s on_raw_value: then: - text_sensor.template.publish: id: uptime_human state: !lambda |- int seconds = round(id(uptime_sensor).raw_state); int days = seconds / (24 * 3600); seconds = seconds % (24 * 3600); int hours = seconds / 3600; seconds = seconds % 3600; int minutes = seconds / 60; seconds = seconds % 60; return ( ("Uptime ") + (days ? to_string(days) + "d " : "") + (hours ? to_string(hours) + "h " : "") + (minutes ? to_string(minutes) + "m " : "") + (to_string(seconds) + "s") ).c_str(); script: - id: update_display then: # - lvgl.indicator.line.update: # id: power_meter_input # value: !lambda return id(counting_number).state; - lvgl.label.update: id: battery_kw text: !lambda |- static char buf[8]; snprintf(buf, sizeof(buf), "%.1fkW", id(counting_number).state); return buf; - lvgl.label.update: id: battery_status text_color: 0xFF0000 #text: "charging" text: "discharging" - lvgl.label.update: id: battery_soc text: !lambda |- static char buf[8]; snprintf(buf, sizeof(buf), "%.1f%%", id(counting_number).state); return buf; - lvgl.label.update: id: solar_kw text: !lambda |- static char buf[8]; snprintf(buf, sizeof(buf), "%.1fkW", id(counting_number).state); return buf; # - lvgl.img.update: # id: img_solar_power # src: solar_power_icon # img_recolor: 0xFFF000 #mixes this color with the base image # #img_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect # #bg_color: 0xFFFFFF # # - lvgl.indicator.line.update: # # id: power_meter_input2 # # value: !lambda return id(counting_number).state; - lvgl.label.update: id: battery_kw2 text: !lambda |- static char buf[8]; snprintf(buf, sizeof(buf), "%.1fkW", id(counting_number).state); return buf; - lvgl.label.update: id: battery_status2 text_color: 0xFF0000 #text: "charging" text: "discharging" - lvgl.label.update: id: battery_soc2 text: !lambda |- static char buf[8]; snprintf(buf, sizeof(buf), "%.1f%%", id(counting_number).state); return buf; - lvgl.label.update: id: solar_kw2 text: !lambda |- static char buf[8]; snprintf(buf, sizeof(buf), "%.1fkW", id(counting_number).state); return buf; # - lvgl.img.update: # id: img_solar_power2 # src: solar_power_icon # img_recolor: 0xFFF000 #mixes this color with the base image # #img_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect # #bg_color: 0xFFFFFF image: - file: mdi:sun-wireless-outline #"solar-power-invert.png" # mdi:solar-power # mdi:battery-charging-outline # mdi:battery-arrow-up-outline # mdi:battery-arrow-down-outline id: solar_power_icon resize: 50x50 type: BINARY - file: mdi:battery-arrow-down-outline id: home_battery_icon resize: 30x30 type: BINARY lvgl: log_level: INFO color_depth: 16 #buffer_size: 25% bg_color: 0 border_width: 0 outline_width: 0 shadow_width: 0 text_font: unscii_16 align: center style_definitions: - id: meter_style text_font: unscii_8 #state_default: null - id: font_style text_font: MONTSERRAT_24 #text_font: unscii_16 align: center text_color: 0xFFFFFF #bg_opa: cover bg_opa: TRANSP bg_color: 0 radius: 4 pad_all: 2 - id: details_style text_font: MONTSERRAT_18 align: center text_color: 0xFFFFFF #bg_opa: cover bg_opa: TRANSP bg_color: 0 radius: 4 pad_all: 2 widgets: - obj: # Meter height: 240 width: 240 #bg_opa: TRANSP bg_color: 0 border_width: 0 outline_width: 0 shadow_width: 0 pad_all: 4 align: TOP_LEFT #scrollbar_mode: "off" widgets: - meter: # Gradient color arc height: 100% width: 100% border_width: 0 outline_width: 0 align: center bg_color: 0 styles: meter_style #bg_opa: TRANSP scales: angle_range: 180 # sets the total angle to 180 = starts mid left and ends mid right range_to: 10 range_from: -10 ticks: count: 0 indicators: - line: id: power_meter_input width: 8 color: 0xFFFFFF r_mod: 12 #sets line length by this much difference from the scale default radius value: 50 # - image: # id: power_meter_input_img - arc: color: 0xFF3000 r_mod: 10 #radius difference from the scale default radius width: 20 start_value: -10 end_value: 0 - arc: color: 0x00FF00 r_mod: 10 #radius difference from the scale default radius width: 20 start_value: 0 end_value: 10 #- canvas: - arc: # black arc to erase middle part of meter indicator line height: 160 width: 160 align: center arc_color: 0x000000 # background color arc_width: 150 start_angle: 0 end_angle: 360 indicator: arc_width: 150 arc_color: 0x000000 - label: # gauge lower and higher range indicators styles: font_style text_font: MONTSERRAT_18 # override font size y: 8 #negative = higher x: -99 text: "-10" - label: styles: font_style text_font: MONTSERRAT_18 # override font size y: 8 #negative = higher x: 99 text: "+10" - label: styles: font_style id: battery_status y: -35 #negative = higher - label: styles: font_style id: battery_kw y: -60 - label: styles: font_style text_font: MONTSERRAT_40 # override font size id: battery_soc y: 0 - label: styles: font_style id: solar_kw text_color: 0xFFFF00 y: 90 #- img: # src: home_battery_icon #id: img_solar_power #align: center #img_recolor: 0xFFFFFF #img_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect #bg_color: 0xFFFFFF #y: -35 #x: -60 - image: src: solar_power_icon id: img_solar_power align: center image_recolor: 0xFFFF00 image_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect #bg_color: 0xFFFFFF y: 50 #x: -60 - obj: # Meter height: 240 width: 240 #bg_opa: TRANSP bg_color: 0 border_width: 0 outline_width: 0 shadow_width: 0 pad_all: 4 align: TOP_MID #scrollbar_mode: "off" widgets: - meter: # Gradient color arc height: 100% width: 100% border_width: 0 outline_width: 0 align: center bg_color: 0 styles: meter_style #bg_opa: TRANSP scales: angle_range: 180 # sets the total angle to 180 = starts mid left and ends mid right range_to: 10 range_from: -10 ticks: count: 0 indicators: - line: id: power_meter_input2 width: 8 color: 0xFFFFFF r_mod: 12 #sets line length by this much difference from the scale default radius value: 50 # - image: # id: power_meter_input_img2 - arc: color: 0xFF3000 r_mod: 10 #radius difference from the scale default radius width: 20 start_value: -10 end_value: 0 - arc: color: 0x00FF00 r_mod: 10 #radius difference from the scale default radius width: 20 start_value: 0 end_value: 10 #- canvas: - arc: # black arc to erase middle part of meter indicator line height: 160 width: 160 align: center arc_color: 0x000000 # background color arc_width: 150 start_angle: 0 end_angle: 360 indicator: arc_width: 150 arc_color: 0x000000 - label: # gauge lower and higher range indicators styles: font_style text_font: MONTSERRAT_18 # override font size y: 8 #negative = higher x: -99 text: "-10" - label: styles: font_style text_font: MONTSERRAT_18 # override font size y: 8 #negative = higher x: 99 text: "+10" - label: styles: font_style id: battery_status2 y: -35 #negative = higher - label: styles: font_style id: battery_kw2 y: -60 - label: styles: font_style text_font: MONTSERRAT_40 # override font size id: battery_soc2 y: 0 - label: styles: font_style id: solar_kw2 text_color: 0xFFFF00 y: 90 #- img: # src: home_battery_icon #id: img_solar_power #align: center #img_recolor: 0xFFFFFF #img_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect #bg_color: 0xFFFFFF #y: -35 #x: -60 - image: src: solar_power_icon id: img_solar_power2 align: center image_recolor: 0xFFFF00 image_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect #bg_color: 0xFFFFFF y: 50 #x: -60 - obj: # Meter height: 240 width: 240 #bg_opa: TRANSP bg_color: 0 border_width: 0 outline_width: 0 shadow_width: 0 pad_all: 4 align: BOTTOM_LEFT #scrollbar_mode: "off" widgets: - meter: # Gradient color arc height: 100% width: 100% border_width: 0 outline_width: 0 align: center bg_color: 0 styles: meter_style #bg_opa: TRANSP scales: angle_range: 180 # sets the total angle to 180 = starts mid left and ends mid right range_to: 10 range_from: -10 ticks: count: 0 indicators: - line: id: power_meter_input3 width: 8 color: 0xFFFFFF r_mod: 12 #sets line length by this much difference from the scale default radius value: 50 # - image: # id: power_meter_input_img3 - arc: color: 0xFF3000 r_mod: 10 #radius difference from the scale default radius width: 20 start_value: -10 end_value: 0 - arc: color: 0x00FF00 r_mod: 10 #radius difference from the scale default radius width: 20 start_value: 0 end_value: 10 #- canvas: - arc: # black arc to erase middle part of meter indicator line height: 160 width: 160 align: center arc_color: 0x000000 # background color arc_width: 150 start_angle: 0 end_angle: 360 indicator: arc_width: 150 arc_color: 0x000000 - label: # gauge lower and higher range indicators styles: font_style text_font: MONTSERRAT_18 # override font size y: 8 #negative = higher x: -99 text: "-10" - label: styles: font_style text_font: MONTSERRAT_18 # override font size y: 8 #negative = higher x: 99 text: "+10" - label: styles: font_style id: battery_status3 y: -35 #negative = higher - label: styles: font_style id: battery_kw3 y: -60 - label: styles: font_style text_font: MONTSERRAT_40 # override font size id: battery_soc3 y: 0 - label: styles: font_style id: solar_kw3 text_color: 0xFFFF00 y: 90 #- img: # src: home_battery_icon #id: img_solar_power #align: center #img_recolor: 0xFFFFFF #img_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect #bg_color: 0xFFFFFF #y: -35 #x: -60 - image: src: solar_power_icon id: img_solar_power3 align: center image_recolor: 0xFFFF00 image_recolor_opa: 100% #opacity defaults to 0% = must set this for recolor to take effect #bg_color: 0xFFFFFF y: 50 #x: -60