From ea7eedff931e2377d0098b3482d768e5984eada4 Mon Sep 17 00:00:00 2001 From: ESPHome Device Builder Date: Wed, 15 Jul 2026 20:16:38 +1200 Subject: [PATCH] Edit esp-bedside-panel.yaml --- esphome/esp-bedside-panel.yaml | 487 +++++++++++++++------------------ 1 file changed, 225 insertions(+), 262 deletions(-) diff --git a/esphome/esp-bedside-panel.yaml b/esphome/esp-bedside-panel.yaml index 7b28254..3866655 100644 --- a/esphome/esp-bedside-panel.yaml +++ b/esphome/esp-bedside-panel.yaml @@ -6,10 +6,9 @@ # https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-bedside-panel.yaml #:########################################################################################:# # VERSIONS: -# V0.9 2026-07-15 Added four environmental/status readings to Bedroom and Clock pages -# Changed clock to 24-hour format and increased clock font to 220px +# V0.9a 2026-07-15 Reduced clock font to 190px and delayed LVGL sensor updates until startup +# V0.9 2026-07-15 Added four status readings and enlarged 24-hour clock # V0.8a 2026-07-14 Reduced LVGL memory load after V0.8 OTA rollback -# Added lean large-clock idle page and Bedroom controls # V0.8 2026-07-14 Added large bedside clock, idle dimming and first bedroom control page # V0.7 2026-07-14 Added first landscape LVGL page and Home Assistant test button # V0.6 2026-07-14 Added GT911 touchscreen and touch-coordinate logging @@ -42,27 +41,19 @@ # - Touch I2C address: 0x5D #:########################################################################################:# # OPERATION NOTES: -# - The display remains in its native 1024x600 landscape orientation. -# - The default page contains nine Bedroom / nearby controls. -# - The Bedroom and Clock pages display: -# - Moon phase percentage -# - Outdoor temperature -# - Indoor temperature -# - Indoor humidity -# - The clock uses 24-hour HH:MM format. -# - After the configured idle period: -# - The large clock page is displayed. -# - Backlight brightness is reduced. -# - Touching the clock: -# - Returns to the Bedroom controls. -# - Restores normal brightness. -# - Climate and Downstairs pages remain omitted from this version. +# - Native 1024x600 landscape orientation. +# - Bedroom page contains nine nearby controls. +# - Bedroom and Clock pages show Moon, Outdoor, Indoor and Humidity readings. +# - Clock uses a 24-hour HH:MM format. +# - Clock font reduced to 190px after V0.9 startup rollback. +# - Imported Home Assistant readings are refreshed only after LVGL startup is complete. +# - After the idle timeout, the Clock page is shown and the backlight is dimmed. +# - Touching the Clock page returns to Bedroom controls and restores normal brightness. #:########################################################################################:# # OFFLINE NOTES: -# - LVGL, the clock, touch and backlight operate locally. +# - LVGL, clock, touch and backlight operate locally. # - Home Assistant control buttons require an API connection. # - The clock continues using the most recently synchronised time. -# - Imported readings may display their most recently received values while HA is offline. #:########################################################################################:# #:########################################################################################:# @@ -74,12 +65,12 @@ substitutions: # Device Naming device_name: "esp-bedside-panel" friendly_name: "ESP Bedside Panel" - description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside clock and Home Assistant control panel. Four status readings and 24-hour clock. (Layout V1.1)" + description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside clock and Home Assistant control panel. Delayed LVGL sensor updates. (Layout V1.1)" device_area: "Bedroom" # Project Naming project_name: "Guition.JC1060P470C_I_W_Y" - project_version: "v0.9" + project_version: "v0.9a" # Passwords & Secrets api_key: !secret esp-api_key @@ -144,28 +135,9 @@ packages: #### HOME ASSISTANT API #### common_api: !include file: common/api_common.yaml - #file: common/api_common_noencryption.yaml vars: local_api_key: "${api_key}" - #### MQTT #### - #common_mqtt: !include - # file: common/mqtt_common.yaml - # vars: - # local_device_name: "${device_name}" - - #### WEB PORTAL #### - #common_webportal: !include common/webportal_common_nopass.yaml - - #### SNTP #### - #common_sntp: !include common/sntp_common.yaml - - #### DIAGNOSTICS Sensors #### - #diag_basic: !include common/include_basic_diag_sensors.yaml - #diag_more: !include common/include_more_diag_sensors.yaml - #diag_debug: !include common/include_debug_diag_sensors.yaml - #diag_resetcount: !include common/include_resetcount_diag_sensors.yaml - #:########################################################################################:# # ESPHOME: # https://esphome.io/components/esphome.html @@ -179,6 +151,16 @@ esphome: name: "${project_name}" version: "${project_version}" + on_boot: + priority: -100 + then: + - delay: 12s + - lambda: |- + id(lvgl_ready) = true; + - logger.log: + level: INFO + format: "LVGL startup delay complete; sensor label updates enabled" + #:########################################################################################:# # ESP PLATFORM AND FRAMEWORK: # https://esphome.io/components/esp32.html @@ -232,6 +214,15 @@ esp_ldo: voltage: 2.5V adjustable: true +#:########################################################################################:# +# GLOBALS: +#:########################################################################################:# +globals: + - id: lvgl_ready + type: bool + restore_value: false + initial_value: "false" + #:########################################################################################:# # LOGGER: # https://esphome.io/components/logger.html @@ -250,22 +241,28 @@ api: - logger.log: level: INFO format: "API connected: ESP Bedside Panel is online" - - - lvgl.label.update: - id: bedroom_connection_label - text: "HA connected" - text_color: 0x65D483 + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.label.update: + id: bedroom_connection_label + text: "HA connected" + text_color: 0x65D483 on_client_disconnected: then: - logger.log: level: WARN format: "API disconnected: ESP Bedside Panel is offline from Home Assistant" - - - lvgl.label.update: - id: bedroom_connection_label - text: "HA offline" - text_color: 0xF06A6A + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.label.update: + id: bedroom_connection_label + text: "HA offline" + text_color: 0xF06A6A #:########################################################################################:# # OTA: @@ -343,12 +340,10 @@ touchscreen: display: main_display i2c_id: touch_i2c address: 0x5D - interrupt_pin: number: "${touch_interrupt_pin}" mode: input: true - reset_pin: number: "${touch_reset_pin}" mode: @@ -362,7 +357,7 @@ touchscreen: font: - file: "gfonts://Roboto" id: font_clock - size: 220 + size: 190 glyphs: - "0123456789:" @@ -409,73 +404,21 @@ sensor: id: moon_phase entity_id: "${moon_phase_entity}" internal: true - on_value: - then: - - lvgl.label.update: - id: bedroom_moon_value_label - text: - format: "%.1f%%" - args: [x] - - - lvgl.label.update: - id: clock_moon_value_label - text: - format: "%.1f%%" - args: [x] - platform: homeassistant id: outdoor_temperature entity_id: "${outdoor_temperature_entity}" internal: true - on_value: - then: - - lvgl.label.update: - id: bedroom_outdoor_value_label - text: - format: "%.1f°C" - args: [x] - - - lvgl.label.update: - id: clock_outdoor_value_label - text: - format: "%.1f°C" - args: [x] - platform: homeassistant id: indoor_temperature entity_id: "${indoor_temperature_entity}" internal: true - on_value: - then: - - lvgl.label.update: - id: bedroom_indoor_value_label - text: - format: "%.1f°C" - args: [x] - - - lvgl.label.update: - id: clock_indoor_value_label - text: - format: "%.1f°C" - args: [x] - platform: homeassistant id: indoor_humidity entity_id: "${indoor_humidity_entity}" internal: true - on_value: - then: - - lvgl.label.update: - id: bedroom_humidity_value_label - text: - format: "%.0f%%" - args: [x] - - - lvgl.label.update: - id: clock_humidity_value_label - text: - format: "%.0f%%" - args: [x] #:########################################################################################:# # HOME ASSISTANT BINARY SENSORS: @@ -488,12 +431,14 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: north_lights_button - bg_color: !lambda |- - return x - ? lv_color_hex(0xB88918) - : lv_color_hex(0x28313D); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: north_lights_button + bg_color: !lambda |- + return x ? lv_color_hex(0xB88918) : lv_color_hex(0x28313D); - platform: homeassistant id: ha_south_lights @@ -501,12 +446,14 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: south_lights_button - bg_color: !lambda |- - return x - ? lv_color_hex(0xB88918) - : lv_color_hex(0x28313D); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: south_lights_button + bg_color: !lambda |- + return x ? lv_color_hex(0xB88918) : lv_color_hex(0x28313D); - platform: homeassistant id: ha_bedside_lamp @@ -514,12 +461,14 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: bedside_lamp_button - bg_color: !lambda |- - return x - ? lv_color_hex(0xB88918) - : lv_color_hex(0x28313D); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: bedside_lamp_button + bg_color: !lambda |- + return x ? lv_color_hex(0xB88918) : lv_color_hex(0x28313D); - platform: homeassistant id: ha_hall_floor @@ -527,12 +476,14 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: hall_floor_button - bg_color: !lambda |- - return x - ? lv_color_hex(0x92702D) - : lv_color_hex(0x28313D); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: hall_floor_button + bg_color: !lambda |- + return x ? lv_color_hex(0x92702D) : lv_color_hex(0x28313D); - platform: homeassistant id: ha_hall_lights @@ -540,12 +491,14 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: hall_lights_button - bg_color: !lambda |- - return x - ? lv_color_hex(0xB88918) - : lv_color_hex(0x28313D); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: hall_lights_button + bg_color: !lambda |- + return x ? lv_color_hex(0xB88918) : lv_color_hex(0x28313D); - platform: homeassistant id: ha_bathroom_lights @@ -553,12 +506,14 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: bathroom_lights_button - bg_color: !lambda |- - return x - ? lv_color_hex(0xB88918) - : lv_color_hex(0x28313D); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: bathroom_lights_button + bg_color: !lambda |- + return x ? lv_color_hex(0xB88918) : lv_color_hex(0x28313D); - platform: homeassistant id: ha_patio_lights @@ -566,12 +521,14 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: patio_lights_button - bg_color: !lambda |- - return x - ? lv_color_hex(0xA87500) - : lv_color_hex(0x28313D); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: patio_lights_button + bg_color: !lambda |- + return x ? lv_color_hex(0xA87500) : lv_color_hex(0x28313D); - platform: homeassistant id: ha_garage_lights @@ -579,16 +536,17 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: garage_lights_button - bg_color: !lambda |- - if (id(ha_garage_door).state) { - return lv_color_hex(0xC25B13); - } - - return x - ? lv_color_hex(0xB88918) - : lv_color_hex(0x28313D); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: garage_lights_button + bg_color: !lambda |- + if (id(ha_garage_door).state) { + return lv_color_hex(0xC25B13); + } + return x ? lv_color_hex(0xB88918) : lv_color_hex(0x28313D); - platform: homeassistant id: ha_garage_door @@ -596,16 +554,19 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: garage_lights_button - bg_color: !lambda |- - if (x) { - return lv_color_hex(0xC25B13); - } - - return id(ha_garage_lights).state - ? lv_color_hex(0xB88918) - : lv_color_hex(0x28313D); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: garage_lights_button + bg_color: !lambda |- + if (x) { + return lv_color_hex(0xC25B13); + } + return id(ha_garage_lights).state + ? lv_color_hex(0xB88918) + : lv_color_hex(0x28313D); - platform: homeassistant id: ha_bathroom_fan @@ -613,12 +574,14 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: bathroom_fan_button - bg_color: !lambda |- - return x - ? lv_color_hex(0x1668A8) - : lv_color_hex(0x28313D); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: bathroom_fan_button + bg_color: !lambda |- + return x ? lv_color_hex(0x1668A8) : lv_color_hex(0x28313D); - platform: homeassistant id: ha_quiet_time @@ -626,65 +589,101 @@ binary_sensor: internal: true on_state: then: - - lvgl.widget.update: - id: bedtime_button - bg_color: !lambda |- - return x - ? lv_color_hex(0x705295) - : lv_color_hex(0x3B3048); - - - lvgl.label.update: - id: clock_status_label - text: !lambda |- - return x - ? std::string("Quiet Time active") - : std::string(""); + - if: + condition: + lambda: return id(lvgl_ready); + then: + - lvgl.widget.update: + id: bedtime_button + bg_color: !lambda |- + return x ? lv_color_hex(0x705295) : lv_color_hex(0x3B3048); + - lvgl.label.update: + id: clock_status_label + text: !lambda |- + return x ? std::string("Quiet Time active") : std::string(""); #:########################################################################################:# # INTERVAL: -# Update minute-resolution clock values locally +# Update clock and imported sensor labels only after LVGL startup is complete #:########################################################################################:# interval: - interval: 10s then: - if: condition: - lambda: |- - return id(ha_time).now().is_valid(); - + lambda: return id(lvgl_ready); then: - - lvgl.label.update: - id: clock_time_label - text: !lambda |- - auto now = id(ha_time).now(); + - if: + condition: + lambda: return id(ha_time).now().is_valid(); + then: + - lvgl.label.update: + id: clock_time_label + text: !lambda |- + auto now = id(ha_time).now(); + char buffer[8]; + now.strftime(buffer, sizeof(buffer), "%H:%M"); + return std::string(buffer); - char buffer[8]; - now.strftime(buffer, sizeof(buffer), "%H:%M"); - - return std::string(buffer); + - lvgl.label.update: + id: clock_date_label + text: !lambda |- + auto now = id(ha_time).now(); + char weekday[16]; + char month[16]; + now.strftime(weekday, sizeof(weekday), "%A"); + now.strftime(month, sizeof(month), "%B"); + char buffer[48]; + snprintf(buffer, sizeof(buffer), "%s, %d %s", weekday, now.day_of_month, month); + return std::string(buffer); - lvgl.label.update: - id: clock_date_label - text: !lambda |- - auto now = id(ha_time).now(); + id: bedroom_moon_value_label + text: + format: "%.1f%%" + args: [id(moon_phase).state] - char weekday[16]; - char month[16]; + - lvgl.label.update: + id: clock_moon_value_label + text: + format: "%.1f%%" + args: [id(moon_phase).state] - now.strftime(weekday, sizeof(weekday), "%A"); - now.strftime(month, sizeof(month), "%B"); + - lvgl.label.update: + id: bedroom_outdoor_value_label + text: + format: "%.1f°C" + args: [id(outdoor_temperature).state] - char buffer[48]; - snprintf( - buffer, - sizeof(buffer), - "%s, %d %s", - weekday, - now.day_of_month, - month - ); + - lvgl.label.update: + id: clock_outdoor_value_label + text: + format: "%.1f°C" + args: [id(outdoor_temperature).state] - return std::string(buffer); + - lvgl.label.update: + id: bedroom_indoor_value_label + text: + format: "%.1f°C" + args: [id(indoor_temperature).state] + + - lvgl.label.update: + id: clock_indoor_value_label + text: + format: "%.1f°C" + args: [id(indoor_temperature).state] + + - lvgl.label.update: + id: bedroom_humidity_value_label + text: + format: "%.0f%%" + args: [id(indoor_humidity).state] + + - lvgl.label.update: + id: clock_humidity_value_label + text: + format: "%.0f%%" + args: [id(indoor_humidity).state] #:########################################################################################:# # TEXT SENSOR COMPONENT: @@ -698,13 +697,10 @@ text_sensor: - platform: wifi_info ip_address: name: "${friendly_name} IP Address" - ssid: name: "${friendly_name} Connected SSID" - bssid: name: "${friendly_name} Connected BSSID" - mac_address: name: "${friendly_name} MAC Address" @@ -714,10 +710,8 @@ text_sensor: #:########################################################################################:# lvgl: id: panel_lvgl - displays: - main_display - touchscreens: - touchscreen_id: main_touchscreen long_press_time: 1200ms @@ -739,21 +733,15 @@ lvgl: id: clock_page animation: FADE_IN time: 250ms - - light.turn_on: id: display_backlight brightness: "${clock_brightness}" transition_length: 1500ms pages: - - #:####################################################################################:# - # BEDROOM PAGE - #:####################################################################################:# - id: bedroom_page bg_color: 0x10151D bg_opa: COVER - widgets: - label: x: 35 @@ -770,7 +758,6 @@ lvgl: text_font: font_small text_color: 0xF0A45D - # Four status readings across the top - label: x: 355 y: 12 @@ -779,7 +766,6 @@ lvgl: text_font: font_small text_align: CENTER text_color: 0xA9A0D4 - - label: id: bedroom_moon_value_label x: 355 @@ -798,7 +784,6 @@ lvgl: text_font: font_small text_align: CENTER text_color: 0x84B5D8 - - label: id: bedroom_outdoor_value_label x: 510 @@ -817,7 +802,6 @@ lvgl: text_font: font_small text_align: CENTER text_color: 0xD6B78F - - label: id: bedroom_indoor_value_label x: 665 @@ -836,7 +820,6 @@ lvgl: text_font: font_small text_align: CENTER text_color: 0x80BDA4 - - label: id: bedroom_humidity_value_label x: 820 @@ -847,7 +830,6 @@ lvgl: text_align: CENTER text_color: 0x97D2B7 - # Row 1 - button: id: north_lights_button x: 35 @@ -911,7 +893,6 @@ lvgl: data: entity_id: "${bedside_lamp_entity}" - # Row 2 - button: id: hall_floor_button x: 35 @@ -975,7 +956,6 @@ lvgl: data: entity_id: "${bathroom_lights_entity}" - # Row 3 - button: id: patio_lights_button x: 35 @@ -1039,7 +1019,6 @@ lvgl: data: entity_id: "${bathroom_fan_entity}" - # Bottom action bar - button: id: clock_now_button x: 35 @@ -1058,7 +1037,6 @@ lvgl: id: clock_page animation: FADE_IN time: 250ms - - light.turn_on: id: display_backlight brightness: "${clock_brightness}" @@ -1091,32 +1069,24 @@ lvgl: border_width: 2 border_color: 0x735E88 radius: 16 - on_long_press: then: - homeassistant.action: action: input_button.press data: entity_id: "${bedtime_button_entity}" - - lvgl.button.update: id: bedtime_button text: "Bedtime Activated" - - delay: 2s - - lvgl.button.update: id: bedtime_button text: "Hold for Bedtime" - #:####################################################################################:# - # CLOCK PAGE - #:####################################################################################:# - id: clock_page skip: true bg_color: 0x020304 bg_opa: COVER - widgets: - button: id: clock_wake_button @@ -1129,14 +1099,12 @@ lvgl: shadow_width: 0 radius: 0 text: "" - on_click: then: - lvgl.page.show: id: bedroom_page animation: FADE_OUT time: 250ms - - light.turn_on: id: display_backlight brightness: "${control_brightness}" @@ -1145,7 +1113,7 @@ lvgl: - label: id: clock_time_label align: TOP_MID - y: 30 + y: 40 text: "--:--" text_font: font_clock text_color: 0xE4DDD2 @@ -1154,27 +1122,25 @@ lvgl: - label: id: clock_date_label align: TOP_MID - y: 265 + y: 250 text: "Waiting for time" text_font: font_title text_color: 0xA8A198 clickable: false - # Four status readings - label: x: 80 - y: 355 + y: 350 width: 205 text: "Moon" text_font: font_small text_align: CENTER text_color: 0xA9A0D4 clickable: false - - label: id: clock_moon_value_label x: 80 - y: 387 + y: 382 width: 205 text: "--.-%" text_font: font_title @@ -1184,18 +1150,17 @@ lvgl: - label: x: 285 - y: 355 + y: 350 width: 205 text: "Outdoor" text_font: font_small text_align: CENTER text_color: 0x84B5D8 clickable: false - - label: id: clock_outdoor_value_label x: 285 - y: 387 + y: 382 width: 205 text: "--.-°C" text_font: font_title @@ -1205,18 +1170,17 @@ lvgl: - label: x: 490 - y: 355 + y: 350 width: 205 text: "Indoor" text_font: font_small text_align: CENTER text_color: 0xD6B78F clickable: false - - label: id: clock_indoor_value_label x: 490 - y: 387 + y: 382 width: 205 text: "--.-°C" text_font: font_title @@ -1226,18 +1190,17 @@ lvgl: - label: x: 695 - y: 355 + y: 350 width: 245 text: "Humidity" text_font: font_small text_align: CENTER text_color: 0x80BDA4 clickable: false - - label: id: clock_humidity_value_label x: 695 - y: 387 + y: 382 width: 245 text: "--%" text_font: font_title