--- substitutions: device: tft name: TFT area: DEV comment: "${area} | Desk TFT Display" esphome: name: mcu-${device} friendly_name: ${name} area: ${area} comment: ${comment} on_boot: - priority: -100 then: - lvgl.page.show: status_page esp32: variant: esp32c3 framework: type: esp-idf packages: common: !include common/common.yaml ipv6_only: !include common/ipv6_only.yaml api: # status page until Home Assistant connects (log viewers don't subscribe to states) on_client_connected: - delay: 2s - if: condition: api.connected: state_subscription_only: true then: - lvgl.page.show: main_page on_client_disconnected: - if: condition: not: api.connected: state_subscription_only: true then: - lvgl.page.show: status_page spi: clk_pin: 4 mosi_pin: 5 miso_pin: 6 display: - platform: mipi_spi id: main_display model: ILI9341 cs_pin: 7 dc_pin: 8 reset_pin: 10 invert_colors: false data_rate: 40MHz update_interval: never auto_clear_enabled: false touchscreen: - platform: xpt2046 display: main_display cs_pin: 0 interrupt_pin: 1 transform: mirror_x: true calibration: x_min: 330 x_max: 3620 y_min: 230 y_max: 3680 script: - id: update_status then: - lambda: |- // same colors as the other status screens: ok green, waiting orange, details gray static const uint32_t OK = 0x4DD966, WAIT = 0xFFB300; auto set = [](lv_obj_t *label, const std::string &text, uint32_t color) { lv_label_set_text(label, text.c_str()); lv_obj_set_style_text_color(label, lv_color_hex(color), LV_PART_MAIN); }; const bool wifi_ok = wifi::global_wifi_component->is_connected(); set(id(status_wifi), wifi_ok ? str_sprintf("WiFi: connected (%d dBm)", wifi::global_wifi_component->wifi_rssi()) : std::string("WiFi: connecting..."), wifi_ok ? OK : WAIT); // IPv6 first (skip link-local), then IPv4 std::string ips; if (wifi_ok) { char buf[network::IP_ADDRESS_BUFFER_SIZE]; for (bool v6 : {true, false}) { for (auto &ip : wifi::global_wifi_component->get_ip_addresses()) { if (!ip.is_set() || ip.is_ip6() != v6) continue; ip.str_to(buf); if (v6 && strncmp(buf, "fe80", 4) == 0) continue; if (!ips.empty()) ips += "\n"; ips += buf; } } } lv_label_set_text(id(status_ips), ips.c_str()); if (ips.empty()) lv_obj_add_flag(id(status_ips), LV_OBJ_FLAG_HIDDEN); else lv_obj_remove_flag(id(status_ips), LV_OBJ_FLAG_HIDDEN); const bool api_ok = api::global_api_server->is_connected(); set(id(status_ha), api_ok ? "Home Assistant: connected" : "Home Assistant: waiting...", api_ok ? OK : WAIT); const uint32_t up = millis() / 1000; lv_label_set_text(id(status_footer), str_sprintf("ESPHome %s\nup %ud %02u:%02u:%02u", ESPHOME_VERSION, up / 86400, (up / 3600) % 24, (up / 60) % 60, up % 60).c_str()); interval: - interval: 1s then: - lvgl.label.update: id: clock_label text: !lambda |- auto now = id(ha_time).now(); if (!now.is_valid()) return std::string("--:--"); return now.strftime("%H:%M"); - if: condition: lvgl.page.is_showing: status_page then: - script.execute: update_status image: - platform: file file: assets/images/made-for-esphome-white-on-black.svg id: esphome_logo resize: 220x65 type: RGB565 transparency: alpha_channel font: - file: "gfonts://Roboto@500" id: font_clock size: 80 glyphs: "0123456789:-" - file: "gfonts://Roboto" id: font_title size: 24 - file: "gfonts://Roboto" id: font_status size: 14 lvgl: log_level: WARN color_depth: 16 bg_color: 0x000000 text_color: 0xFFFFFF theme: button: bg_color: 0x2B2F36 radius: 12 checked: bg_color: 0xE08A00 buttonmatrix: bg_opa: TRANSP border_width: 0 items: bg_color: 0x2B2F36 text_color: 0xFFFFFF radius: 12 checked: bg_color: 0xE08A00 top_layer: widgets: # same navigation bar as on the other LVGL displays - buttonmatrix: id: nav_bar align: bottom_mid width: 100% height: 48 pad_all: 4 pad_column: 6 items: text_font: montserrat_20 rows: - buttons: - id: page_prev text: "" on_press: then: lvgl.page.previous: - id: page_home text: "" on_press: then: lvgl.page.show: main_page - id: page_next text: "" on_press: then: lvgl.page.next: pages: # 1: clock - id: main_page widgets: - label: id: clock_label align: CENTER y: -24 text_font: font_clock text: "--:--" # 2: status (shown until Home Assistant connects) - id: status_page on_load: - script.execute: update_status widgets: - image: src: esphome_logo align: TOP_MID y: 8 - label: align: TOP_MID y: 78 text_font: font_title text: "${name}" - obj: x: 8 y: 116 width: 224 height: SIZE_CONTENT bg_opa: TRANSP border_width: 0 pad_all: 0 scrollbar_mode: "OFF" layout: type: flex flex_flow: column pad_row: 6 widgets: - label: id: status_wifi text_font: font_status text: "" - label: id: status_ips text_font: font_status text_color: 0x8C8C8C text: "" - label: id: status_ha text_font: font_status text: "" - label: id: status_footer text_font: font_status text_color: 0x8C8C8C text: ""