Refactor code structure for improved readability and maintainability

This commit is contained in:
Joshua King
2026-02-13 20:53:45 -05:00
parent ed0648866a
commit 8ebe0e29d6
4 changed files with 2551 additions and 1808 deletions

View File

@@ -0,0 +1,99 @@
psram:
mode: octal
speed: 80MHz
i2c:
sda: 8
scl: 9
# CH422G I/O expander (Waveshare uses it for LCD reset/backlight/touch reset)
ch422g:
- id: ch422g_hub
# --- Backlight control (CH422G IO2 is common for Waveshare LCD BL) ---
switch:
- platform: gpio
name: "LCD Backlight Raw"
id: lcd_backlight_raw
restore_mode: ALWAYS_ON
pin:
ch422g: ch422g_hub
number: 2
mode:
output: true
# A nicer HA-exposed control (so you can also automate it from HA)
light:
- platform: binary
name: "HA Remote Backlight"
output: lcd_backlight_out
id: ha_remote_backlight
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 (dim/off + 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();
# Turn off backlight ONCE at 2 minutes idle.
- 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 ---
display:
- platform: mipi_rgb
model: ESP32-S3-TOUCH-LCD-7-800X480
id: main_display
update_interval: never
auto_clear_enabled: false
reset_pin:
ch422g: ch422g_hub
number: 3
mode:
output: true
# --- Touch ---
touchscreen:
platform: gt911
id: touch_panel
update_interval: 120ms
reset_pin:
ch422g: ch422g_hub
number: 1
mode:
output: true
on_touch:
then:
- lambda: |-
id(last_activity_ms) = millis();
- light.turn_on: ha_remote_backlight
# --- LVGL UI ---
# Note: On ESP32-S3-Touch-LCD-7, GPIO14 is used by the RGB display bus,
# so it cannot be reused as ADC for battery telemetry in this display mode.

View File

@@ -0,0 +1,354 @@
text_sensor:
- platform: wifi_info
ip_address:
name: "HA Remote IP"
id: ip_addr
- platform: homeassistant
id: ts_family_room_tv_stand
entity_id: light.family_room_tv_stand
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_family_room_tv_stand
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_family_room_tv_stand);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_small_family_room_lamp
entity_id: light.small_family_room_lamp
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_small_family_room_lamp
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_small_family_room_lamp);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_living_room_lamp_1
entity_id: light.living_room_lamp_1
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_family_room_standing_lamp
state:
checked: !lambda return x == "on";
- lvgl.widget.update:
id: btn_living_room_standing_lamp
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn1 = id(btn_family_room_standing_lamp);
auto *btn2 = id(btn_living_room_standing_lamp);
lv_obj_set_style_text_color(btn1, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
lv_obj_set_style_text_color(btn2, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_living_room_light_2
entity_id: light.living_room_light_2
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_living_room_main_light
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_living_room_main_light);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_patio_light_1
entity_id: light.patio_light_1
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_living_room_patio_light
state:
checked: !lambda return x == "on";
- lvgl.widget.update:
id: btn_outside_patio_light
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn1 = id(btn_living_room_patio_light);
auto *btn2 = id(btn_outside_patio_light);
lv_obj_set_style_text_color(btn1, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
lv_obj_set_style_text_color(btn2, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_kitchen_sink_light
entity_id: light.kitchen_sink_light
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_kitchen_sink_light
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_kitchen_sink_light);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_office_lamp_2
entity_id: light.office_lamp_2
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_office_lamp
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_office_lamp);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_office_led_strip
entity_id: light.led_strip_controller_led_strip_controller
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_office_led_strip
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_office_led_strip);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_garage_cam_light
entity_id: light.esp32_saturn4_cam_esp32_saturn4_cam_light
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_garage_cam_light
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_garage_cam_light);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_family_room_standing_fan_outlet
entity_id: switch.standing_fan_socket_1
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_family_room_standing_fan_outlet
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_family_room_standing_fan_outlet);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_office_echo_plug
entity_id: switch.office_echo_plug
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_office_echo_plug
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_office_echo_plug);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_office_end_table_lamp_outlet
entity_id: switch.office_end_table_lamp_socket_1
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_office_end_table_lamp_outlet
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_office_end_table_lamp_outlet);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_office_wax_warmer_outlet
entity_id: switch.office_wax_warmer_socket_1
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_office_wax_warmer_outlet
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_office_wax_warmer_outlet);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_outside_lamppost_outlet_1
entity_id: switch.lamppost_outlets_socket_1
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_outside_lamppost_outlet_1
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_outside_lamppost_outlet_1);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_outside_lamppost_outlet_2
entity_id: switch.lamppost_outlets_socket_2
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_outside_lamppost_outlet_2
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_outside_lamppost_outlet_2);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_outside_porch_decor_outlet
entity_id: switch.washing_machine_socket_1
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_outside_porch_decor_outlet
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_outside_porch_decor_outlet);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_living_room_garland_switch
entity_id: switch.big_family_room_lamp
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_living_room_garland_switch
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_living_room_garland_switch);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_living_room_calendar_switch
entity_id: switch.digital_calendar
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_living_room_calendar_switch
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_living_room_calendar_switch);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_kitchen_dnd_switch
entity_id: switch.kitchen_do_not_disturb_switch
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_kitchen_dnd_switch
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_kitchen_dnd_switch);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_kitchen_camera_motion
entity_id: switch.kitchen_camera_motion_detection
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_kitchen_camera_motion
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_kitchen_camera_motion);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_upstairs_airquality_oled
entity_id: switch.airqualitysensor_3_oled_power
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_upstairs_airquality_oled
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_upstairs_airquality_oled);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_upstairs_camera_motion
entity_id: switch.upstairs_camera_motion_detection
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_upstairs_camera_motion
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_upstairs_camera_motion);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_garage_fume_exhaust_fan
entity_id: switch.fume_exhaust_fan
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_garage_fume_exhaust_fan
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_garage_fume_exhaust_fan);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
- platform: homeassistant
id: ts_garage_resin_printer_heater
entity_id: switch.resin_printer_heater
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_garage_resin_printer_heater
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x000000) : lv_color_hex(0xEAF2FF);
auto *btn = id(btn_garage_resin_printer_heater);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff