psram: mode: octal speed: 80MHz i2c: id: i2c_main sda: GPIO19 scl: GPIO20 frequency: 400kHz scan: false # --- Backlight control (GPIO2 direct) --- switch: - platform: gpio name: "LCD Backlight Raw" id: lcd_backlight_raw restore_mode: ALWAYS_ON pin: number: GPIO2 mode: output: true light: - platform: binary name: "Family Room Remote Backlight" output: lcd_backlight_out id: ha_remote_backlight restore_mode: ALWAYS_ON output: - platform: template id: lcd_backlight_out type: binary write_action: - if: condition: lambda: return state; then: - switch.turn_on: lcd_backlight_raw else: - switch.turn_off: lcd_backlight_raw # --- Inactivity tracking (off after 2 minutes, wake on touch) --- globals: - id: last_activity_ms type: uint32_t restore_value: no initial_value: '0' interval: - interval: 1s then: - lambda: |- if (id(last_activity_ms) == 0) id(last_activity_ms) = millis(); - if: condition: lambda: |- const uint32_t idle_s = (millis() - id(last_activity_ms)) / 1000; return idle_s == 120; then: - light.turn_off: ha_remote_backlight # --- Display (ST7262 parallel RGB, 800x480) --- display: - platform: rpi_dpi_rgb id: main_display dimensions: width: 800 height: 480 de_pin: GPIO40 hsync_pin: GPIO39 vsync_pin: GPIO41 pclk_pin: GPIO42 pclk_frequency: 16MHz color_order: BGR data_pins: red: - GPIO45 - GPIO48 - GPIO47 - GPIO21 - GPIO14 green: - GPIO5 - GPIO6 - GPIO7 - GPIO15 - GPIO16 - GPIO4 blue: - GPIO8 - GPIO3 - GPIO46 - GPIO9 - GPIO1 hsync_back_porch: 48 hsync_front_porch: 40 hsync_pulse_width: 48 vsync_back_porch: 32 vsync_front_porch: 13 vsync_pulse_width: 3 update_interval: never auto_clear_enabled: false # --- Touch (GT911 capacitive) --- # NOTE: interrupt_pin GPIO18 requires soldering the R17 bridge on the board. # If not soldered, remove the interrupt_pin line (falls back to polling). touchscreen: platform: gt911 id: touch_panel i2c_id: i2c_main reset_pin: GPIO38 on_touch: then: - lambda: |- id(last_activity_ms) = millis(); - light.turn_on: ha_remote_backlight # --- MDI Icon Font --- font: - file: "https://raw.githubusercontent.com/Templarian/MaterialDesign-Webfont/master/fonts/materialdesignicons-webfont.ttf" id: mdi_icons size: 24 bpp: 4 glyphs: - "\U000F0335" # mdi:lightbulb - "\U000F0425" # mdi:power - "\U000F0079" # mdi:battery - "\U000F12A1" # mdi:battery-low - "\U000F12A2" # mdi:battery-medium - "\U000F12A3" # mdi:battery-high - "\U000F12A4" # mdi:battery-charging-low - "\U000F12A5" # mdi:battery-charging-medium - "\U000F12A6" # mdi:battery-charging-high - "\U000F0091" # mdi:battery-unknown - "\U000F10CD" # mdi:battery-alert-variant-outline # --- Battery fuel gauge (MAX17048 via I2C) --- # DISABLED for testing - suspected display interference # sensor: # - platform: max17043 # id: max17048_battery # i2c_id: i2c_main # update_interval: 120s # battery_voltage: # name: "Remote Battery Voltage" # id: remote_battery_voltage # entity_category: diagnostic # device_class: voltage # state_class: measurement # accuracy_decimals: 3 # battery_level: # name: "Remote Battery Level" # id: remote_battery_level # entity_category: diagnostic # device_class: battery # state_class: measurement # accuracy_decimals: 0 # on_value: # then: # - lambda: |- # ESP_LOGI("battery", "Level: %.0f%%", x); # // Update the LVGL battery icon based on level # lv_obj_t *lbl = id(battery_icon); # if (x < 10) # lv_label_set_text(lbl, "\U000F10CD"); // battery-alert-variant-outline # else if (x < 30) # lv_label_set_text(lbl, "\U000F12A1"); // battery-low # else if (x < 70) # lv_label_set_text(lbl, "\U000F12A2"); // battery-medium # else # lv_label_set_text(lbl, "\U000F12A3"); // battery-high