Merge branch 'feat/phase2-lvgl-ui'

This commit is contained in:
pyr0ball 2026-07-11 23:08:12 -07:00
commit 976410e0b0
5 changed files with 335 additions and 7 deletions

View file

@ -42,3 +42,14 @@ climate:
- switch.turn_off: relay_heat2
- switch.turn_off: relay_cool1
- switch.turn_off: relay_cool2
on_state:
then:
- lvgl.label.update:
id: home_mode_label
text: !lambda |-
switch (id(main_thermostat).mode) {
case climate::CLIMATE_MODE_HEAT: return "Mode: Heat";
case climate::CLIMATE_MODE_COOL: return "Mode: Cool";
case climate::CLIMATE_MODE_OFF: return "Mode: Off";
default: return "Mode: Idle";
}

View file

@ -0,0 +1,25 @@
text_sensor:
- platform: wifi_info
ip_address:
name: "IP Address"
id: wifi_ip_text
on_value:
then:
- lvgl.label.update:
id: settings_ip_label
text:
format: "IP: %s"
args: ["x.c_str()"]
sensor:
- platform: uptime
name: "Uptime"
id: uptime_sensor
update_interval: 60s
on_value:
then:
- lvgl.label.update:
id: settings_uptime_label
text:
format: "Uptime: %.0f min"
args: ["x / 60.0f"]

View file

@ -37,11 +37,276 @@ display:
number: 6 # EXIO6 = LCD_VDD_EN (VCOM enable) — the built-in preset doesn't set
# this, but the Waveshare wiki confirms VCOM must be driven high on
# this board or the panel won't display correctly. Added explicitly.
lambda: |-
it.fill(Color::BLACK);
it.print(512, 300, id(font_label), TextAlign::CENTER, "Thermostat — Phase 1 OK");
font:
- file: "gfonts://Roboto"
id: font_label
size: 32
lvgl:
id: lvgl_comp
displays:
- lcd_display
touchscreens:
- touch_gt911
pages:
- id: page_home
widgets:
- obj:
width: 100%
height: 510px
pad_all: 16
border_width: 0
outline_width: 0
scrollable: false
layout:
type: flex
flex_flow: column
flex_align_cross: center
flex_align_track: center
flex_align_main: space_evenly
widgets:
- label:
id: home_temp_label
text: "-- °C"
text_font: montserrat_48
- label:
id: home_mode_label
text: "Mode: --"
text_font: montserrat_28
- obj:
width: 100%
height: size_content
border_width: 0
outline_width: 0
scrollable: false
layout:
type: flex
flex_flow: row
flex_align_cross: center
flex_align_track: center
flex_align_main: space_evenly
widgets:
- button:
width: 140px
height: 100px
on_click:
climate.control:
id: main_thermostat
target_temperature_low: !lambda "return id(main_thermostat).target_temperature_low - 0.5f;"
target_temperature_high: !lambda "return id(main_thermostat).target_temperature_high - 0.5f;"
widgets:
- label:
text: "-"
text_font: montserrat_40
- button:
width: 140px
height: 100px
on_click:
climate.control:
id: main_thermostat
target_temperature_low: !lambda "return id(main_thermostat).target_temperature_low + 0.5f;"
target_temperature_high: !lambda "return id(main_thermostat).target_temperature_high + 0.5f;"
widgets:
- label:
text: "+"
text_font: montserrat_40
- id: page_sensors
widgets:
- obj:
width: 100%
height: 510px
pad_all: 16
border_width: 0
outline_width: 0
scrollable: false
layout:
type: flex
flex_flow: column
flex_align_cross: center
flex_align_track: center
flex_align_main: space_evenly
widgets:
- label:
id: sensors_temp_label
text: "Temperature: -- °C"
text_font: montserrat_28
- label:
id: sensors_humidity_label
text: "Humidity: -- %"
text_font: montserrat_28
- label:
id: sensors_pressure_label
text: "Pressure: -- hPa"
text_font: montserrat_28
- id: page_settings
widgets:
- obj:
width: 100%
height: 510px
pad_all: 16
border_width: 0
outline_width: 0
scrollable: false
layout:
type: flex
flex_flow: column
flex_align_cross: center
flex_align_track: start
flex_align_main: start
widgets:
- label:
id: settings_ip_label
text: "IP: --"
text_font: montserrat_20
- label:
id: settings_uptime_label
text: "Uptime: -- min"
text_font: montserrat_20
- label:
text: "Manual relay override (bypasses thermostat):"
text_font: montserrat_16
- obj:
width: 100%
height: size_content
border_width: 0
outline_width: 0
scrollable: false
layout:
type: flex
flex_flow: row_wrap
flex_align_cross: start
flex_align_track: start
flex_align_main: start
widgets:
- checkbox:
text: "Fan"
on_click:
switch.toggle: relay_fan
- checkbox:
text: "Cool 1"
on_click:
switch.toggle: relay_cool1
- checkbox:
text: "Cool 2"
on_click:
switch.toggle: relay_cool2
- checkbox:
text: "Heat 1"
on_click:
switch.toggle: relay_heat1
- checkbox:
text: "Heat 2"
on_click:
switch.toggle: relay_heat2
- id: page_schedule
widgets:
- obj:
width: 100%
height: 510px
pad_all: 16
border_width: 0
outline_width: 0
scrollable: false
layout:
type: flex
flex_flow: column
flex_align_cross: center
flex_align_track: center
flex_align_main: space_evenly
widgets:
- label:
text: "Preset"
text_font: montserrat_28
- obj:
width: 100%
height: size_content
border_width: 0
outline_width: 0
scrollable: false
layout:
type: flex
flex_flow: row
flex_align_cross: center
flex_align_track: center
flex_align_main: space_evenly
widgets:
- button:
width: 300px
height: 100px
on_click:
climate.control:
id: main_thermostat
preset: home
widgets:
- label:
text: "Home"
text_font: montserrat_28
- button:
width: 300px
height: 100px
on_click:
climate.control:
id: main_thermostat
preset: away
widgets:
- label:
text: "Away"
text_font: montserrat_28
- label:
text: "Time-based scheduling runs in Home Assistant, not on this device."
text_font: montserrat_16
top_layer:
widgets:
- obj:
id: nav_bar
align: bottom_mid
width: 100%
height: 90px
pad_all: 4
radius: 0
border_width: 0
outline_width: 0
scrollable: false
layout:
type: flex
flex_flow: row
flex_align_cross: center
flex_align_track: center
flex_align_main: space_evenly
widgets:
- button:
id: nav_btn_home
width: 220px
height: 78px
on_click:
lvgl.page.show: page_home
widgets:
- label:
text: "Home"
text_font: montserrat_20
- button:
id: nav_btn_sensors
width: 220px
height: 78px
on_click:
lvgl.page.show: page_sensors
widgets:
- label:
text: "Sensors"
text_font: montserrat_20
- button:
id: nav_btn_settings
width: 220px
height: 78px
on_click:
lvgl.page.show: page_settings
widgets:
- label:
text: "Settings"
text_font: montserrat_20
- button:
id: nav_btn_schedule
width: 220px
height: 78px
on_click:
lvgl.page.show: page_schedule
widgets:
- label:
text: "Schedule"
text_font: montserrat_20

View file

@ -6,9 +6,35 @@ sensor:
temperature:
name: "Ambient Temperature"
id: bme280_temperature
on_value:
then:
- lvgl.label.update:
id: home_temp_label
text:
format: "%.1f °C"
args: ["x"]
- lvgl.label.update:
id: sensors_temp_label
text:
format: "Temperature: %.1f °C"
args: ["x"]
humidity:
name: "Ambient Humidity"
id: bme280_humidity
on_value:
then:
- lvgl.label.update:
id: sensors_humidity_label
text:
format: "Humidity: %.1f %%"
args: ["x"]
pressure:
name: "Ambient Pressure"
id: bme280_pressure
on_value:
then:
- lvgl.label.update:
id: sensors_pressure_label
text:
format: "Pressure: %.1f hPa"
args: ["x"]

View file

@ -48,3 +48,4 @@ packages:
sensors: !include components/sensors.yaml
relays: !include components/relays.yaml
climate: !include components/climate.yaml
diagnostics: !include components/diagnostics.yaml