initial commit

This commit is contained in:
root
2026-06-28 14:27:20 -04:00
commit ae0f1f559e
115 changed files with 30411 additions and 0 deletions
@@ -0,0 +1,173 @@
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
@@ -0,0 +1,59 @@
text_sensor:
- platform: wifi_info
ip_address:
name: "Family Room 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(0x001A33) : lv_color_hex(0xE3E2E6);
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));
for (uint32_t i = 0; i < lv_obj_get_child_cnt(btn); i++) {
lv_obj_set_style_text_color(lv_obj_get_child(btn, i), 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(0x22001F) : lv_color_hex(0xE3E2E6);
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));
for (uint32_t i = 0; i < lv_obj_get_child_cnt(btn); i++) {
lv_obj_set_style_text_color(lv_obj_get_child(btn, i), text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
}
- platform: homeassistant
id: ts_big_family_room_lamp
entity_id: switch.big_family_room_lamp
internal: true
on_value:
then:
- lvgl.widget.update:
id: btn_big_family_room_lamp
state:
checked: !lambda return x == "on";
- lambda: |-
const lv_color_t text_color = (x == "on") ? lv_color_hex(0x001F15) : lv_color_hex(0xE3E2E6);
auto *btn = id(btn_big_family_room_lamp);
lv_obj_set_style_text_color(btn, text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
for (uint32_t i = 0; i < lv_obj_get_child_cnt(btn); i++) {
lv_obj_set_style_text_color(lv_obj_get_child(btn, i), text_color, static_cast<lv_style_selector_t>(LV_PART_MAIN | LV_STATE_DEFAULT));
}
@@ -0,0 +1,231 @@
lvgl:
displays:
- main_display
touchscreens:
- touch_panel
disp_bg_color: 0x141218
style_definitions:
# ── Top App Bar ──
- id: md3_header
bg_color: 0x1D1B20
bg_opa: 100%
border_width: 0
radius: 0
pad_all: 0
shadow_width: 0
# ── Status Chip ──
- id: md3_chip
bg_color: 0x2B2930
bg_opa: 100%
border_color: 0x49454F
border_width: 1
border_opa: 100%
radius: 8
pad_all: 0
# ── Text Styles ──
- id: md3_title
text_color: 0xE3E2E6
text_opa: 100%
- id: md3_meta
text_color: 0xC4C6CF
text_opa: 100%
- id: md3_icon
text_color: 0xC4C6CF
text_opa: 100%
# ── Card Variants ──
- id: md3_card_blue
bg_color: 0x2B2930
bg_opa: 100%
border_color: 0x49454F
border_width: 1
border_opa: 100%
radius: 16
shadow_width: 0
- id: md3_card_pink
bg_color: 0x2B2930
bg_opa: 100%
border_color: 0x49454F
border_width: 1
border_opa: 100%
radius: 16
shadow_width: 0
- id: md3_card_green
bg_color: 0x2B2930
bg_opa: 100%
border_color: 0x49454F
border_width: 1
border_opa: 100%
radius: 16
shadow_width: 0
theme:
label:
text_color: 0xE3E2E6
button:
text_color: 0xE3E2E6
pages:
- id: home
widgets:
# ── Header ──
- obj:
x: 0
y: 0
width: 800
height: 64
styles: md3_header
widgets:
- label:
x: 24
y: 20
text_color: 0xE3E2E6
text: "Family Room"
# ── TV Stand ──
- button:
id: btn_family_room_tv_stand
x: 24
y: 80
width: 234
height: 300
checkable: true
styles: md3_card_blue
checked:
bg_color: 0xA8C7FA
bg_opa: 100%
border_color: 0xA8C7FA
border_opa: 100%
text_color: 0x001A33
on_click:
- homeassistant.service:
service: light.toggle
data:
entity_id: light.family_room_tv_stand
widgets:
- label:
x: 194
y: 16
styles: md3_icon
text_font: mdi_icons
text: "\U000F0335" # mdi:lightbulb
- label:
x: 18
y: 16
styles: md3_meta
text: "LIGHT"
- label:
x: 18
y: 56
styles: md3_title
text: "TV Stand"
- label:
x: 18
y: 90
styles: md3_meta
text: "Tap to toggle"
# ── Small Lamp ──
- button:
id: btn_small_family_room_lamp
x: 282
y: 80
width: 234
height: 300
checkable: true
styles: md3_card_pink
checked:
bg_color: 0xFFD7F1
bg_opa: 100%
border_color: 0xFFD7F1
border_opa: 100%
text_color: 0x22001F
on_click:
- homeassistant.service:
service: light.toggle
data:
entity_id: light.small_family_room_lamp
widgets:
- label:
x: 194
y: 16
styles: md3_icon
text_font: mdi_icons
text: "\U000F0335" # mdi:lightbulb
- label:
x: 18
y: 16
styles: md3_meta
text: "LIGHT"
- label:
x: 18
y: 56
styles: md3_title
text: "Small Lamp"
- label:
x: 18
y: 90
styles: md3_meta
text: "Tap to toggle"
# ── Standing Lamp ──
- button:
id: btn_big_family_room_lamp
x: 540
y: 80
width: 236
height: 300
checkable: true
styles: md3_card_green
checked:
bg_color: 0xB5CCBA
bg_opa: 100%
border_color: 0xB5CCBA
border_opa: 100%
text_color: 0x001F15
on_click:
- homeassistant.service:
service: light.toggle
data:
entity_id: light.living_room_lamp_1
widgets:
- label:
x: 196
y: 16
styles: md3_icon
text_font: mdi_icons
text: "\U000F0335" # mdi:lightbulb
- label:
x: 18
y: 16
styles: md3_meta
text: "LIGHT"
- label:
x: 18
y: 56
styles: md3_title
text: "Standing Lamp"
- label:
x: 18
y: 90
styles: md3_meta
text: "Tap to toggle"
# ── Status Bar ──
- obj:
x: 0
y: 400
width: 800
height: 80
styles: md3_header
widgets:
- obj:
x: 8
y: 20
width: 84
height: 40
styles: md3_chip
widgets:
- label:
id: battery_icon
align: center
text_font: mdi_icons
text_color: 0xC4C6CF
text: "\U000F10CD" # mdi:battery-alert-variant-outline