Edit esp-bedside-panel.yaml

This commit is contained in:
ESPHome Device Builder
2026-07-16 19:54:10 +12:00
parent b8681f7741
commit caa4d906c4
+280 -40
View File
@@ -6,6 +6,7 @@
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-bedside-panel.yaml
#:########################################################################################:#
# VERSIONS:
# V0.8m 2026-07-16 Added Quiet / Powerful profiles, Night Power toggle and improved Climate state highlighting
# V0.8l 2026-07-16 Completed primary Climate controls, ceiling fan cycle and Air Filter Low
# V0.8k 2026-07-16 Revised Bedroom header and added five-button navigation row
# V0.8j 2026-07-16 Added delayed Home Assistant state synchronisation for button highlighting at startup
@@ -80,12 +81,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. Heat-pump setpoint, ceiling-fan and air-filter controls. (Layout V1.1)"
description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside control panel. Climate modes, profiles, setpoint, ceiling fan, quiet air filter and Night Power. (Layout V1.1)"
device_area: "Bedroom"
# Project Naming
project_name: "Guition.JC1060P470C_I_W_Y"
project_version: "v0.8l"
project_version: "v0.8m"
# Passwords & Secrets
api_key: !secret esp-api_key
@@ -137,15 +138,19 @@ substitutions:
# Home Assistant Entities - Climate
climate_entity: "climate.master_bedroom"
climate_requested_mode_entity: "input_select.master_bedroom_hvac_requested_mode"
climate_profile_entity: "input_select.master_bedroom_heat_pump_profile"
climate_off_script: "script.master_bedroom_hvac_off"
climate_heat_script: "script.master_bedroom_hvac_heat"
climate_cool_script: "script.master_bedroom_hvac_cool"
climate_dry_script: "script.master_bedroom_hvac_dry"
climate_setpoint_adjust_script: "script.master_bedroom_setpoint_adjust"
climate_quiet_preset: "quiet"
climate_powerful_preset: "boost"
# Home Assistant Entities - Ceiling Fan / Air Filter
# Home Assistant Entities - Ceiling Fan / Air Filter / Night Power
ceiling_fan_entity: "fan.tasmo_ifan02_3793_bedrm1_1"
air_filter_level_entity: "number.bedroom_1_air_filter_bedroom_1_air_filter_speed_level"
climate_night_power_entity: "input_boolean.master_bedroom_night_power_mode"
#:########################################################################################:#
# PACKAGES:
@@ -406,7 +411,7 @@ font:
glyphs:
- "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
- "abcdefghijklmnopqrstuvwxyz"
- "0123456789, .:/-%°+()"
- "0123456789, .:/-%°+()↑↓"
- file: "gfonts://Roboto"
id: font_button
@@ -691,6 +696,14 @@ binary_sensor:
then:
- script.execute: refresh_climate_controls
- platform: homeassistant
id: ha_climate_night_power
entity_id: "${climate_night_power_entity}"
internal: true
on_state:
then:
- script.execute: refresh_climate_controls
- platform: homeassistant
id: ha_quiet_time
entity_id: "${quiet_time_entity}"
@@ -820,44 +833,152 @@ script:
- id: refresh_climate_controls
mode: restart
then:
# Heat-pump mode buttons.
# Heat-pump mode buttons. The requested mode wins while a change is
# pending; when it is "none", the actual climate state is used.
- lvgl.widget.update:
id: climate_off_button
bg_color: !lambda |-
const auto mode = id(ha_climate_requested_mode).state;
return (mode == "Off" || mode == "off")
const auto requested = id(ha_climate_requested_mode).state;
const auto current = id(ha_climate_current_mode).state;
const bool requested_none = (
requested.empty() ||
requested == "none" ||
requested == "None" ||
requested == "unknown" ||
requested == "unavailable"
);
const bool active = (
requested == "off" ||
requested == "Off" ||
(requested_none && current == "off")
);
return active
? lv_color_hex(0x548C6C)
: lv_color_hex(0x28313D);
- lvgl.widget.update:
id: climate_heat_button
bg_color: !lambda |-
const auto mode = id(ha_climate_requested_mode).state;
return (mode == "Heat" || mode == "heat")
const auto requested = id(ha_climate_requested_mode).state;
const auto current = id(ha_climate_current_mode).state;
const bool requested_none = (
requested.empty() ||
requested == "none" ||
requested == "None" ||
requested == "unknown" ||
requested == "unavailable"
);
const bool active = (
requested == "heat" ||
requested == "Heat" ||
(requested_none && current == "heat")
);
return active
? lv_color_hex(0xB76822)
: lv_color_hex(0x28313D);
- lvgl.widget.update:
id: climate_cool_button
bg_color: !lambda |-
const auto mode = id(ha_climate_requested_mode).state;
return (mode == "Cool" || mode == "cool")
const auto requested = id(ha_climate_requested_mode).state;
const auto current = id(ha_climate_current_mode).state;
const bool requested_none = (
requested.empty() ||
requested == "none" ||
requested == "None" ||
requested == "unknown" ||
requested == "unavailable"
);
const bool active = (
requested == "cool" ||
requested == "Cool" ||
(requested_none && current == "cool")
);
return active
? lv_color_hex(0x2E6A96)
: lv_color_hex(0x28313D);
- lvgl.widget.update:
id: climate_dry_button
bg_color: !lambda |-
const auto mode = id(ha_climate_requested_mode).state;
return (
mode == "Dry" ||
mode == "dry" ||
mode == "Dehumidify" ||
mode == "dehumidify"
)
const auto requested = id(ha_climate_requested_mode).state;
const auto current = id(ha_climate_current_mode).state;
const bool requested_none = (
requested.empty() ||
requested == "none" ||
requested == "None" ||
requested == "unknown" ||
requested == "unavailable"
);
const bool active = (
requested == "dry" ||
requested == "Dry" ||
requested == "dehumidify" ||
requested == "Dehumidify" ||
(
requested_none &&
(
current == "dry" ||
current == "dehumidify"
)
)
);
return active
? lv_color_hex(0x32677F)
: lv_color_hex(0x28313D);
# Quiet / Powerful profile buttons. The HA profile helper and actual
# climate preset are both checked so the display remains authoritative.
- lvgl.widget.update:
id: climate_quiet_button
bg_color: !lambda |-
const auto profile = id(ha_climate_profile).state;
const auto preset = id(ha_climate_preset_mode).state;
const bool active = (
profile == "Quiet" ||
profile == "quiet" ||
preset == "Quiet" ||
preset == "quiet"
);
return active
? lv_color_hex(0x315843)
: lv_color_hex(0x28313D);
- lvgl.widget.update:
id: climate_powerful_button
bg_color: !lambda |-
const auto profile = id(ha_climate_profile).state;
const auto preset = id(ha_climate_preset_mode).state;
const bool active = (
profile == "Boost" ||
profile == "boost" ||
profile == "Powerful" ||
profile == "powerful" ||
preset == "Boost" ||
preset == "boost" ||
preset == "Powerful" ||
preset == "powerful"
);
return active
? lv_color_hex(0x6B4A86)
: lv_color_hex(0x28313D);
# Heat-pump target setpoint.
- lvgl.label.update:
id: climate_setpoint_value_label
@@ -899,16 +1020,28 @@ script:
? lv_color_hex(0x315E82)
: lv_color_hex(0x28313D);
# Air-filter Low is active when the HA number is set to level 2.
# Air Filter Quiet is highlighted for filter levels 0, 1 or 2.
- lvgl.widget.update:
id: air_filter_low_button
id: air_filter_quiet_button
bg_color: !lambda |-
const float level = id(ha_air_filter_level).state;
return (!isnan(level) && level > 1.5f && level < 2.5f)
return (
!isnan(level) &&
level >= 0.0f &&
level <= 2.0f
)
? lv_color_hex(0x315843)
: lv_color_hex(0x28313D);
# Climate 9pm-12 follows the Night Power helper state.
- lvgl.widget.update:
id: climate_night_power_button
bg_color: !lambda |-
return id(ha_climate_night_power).state
? lv_color_hex(0x5A4778)
: lv_color_hex(0x28313D);
# Two passes allow time for LVGL creation and Home Assistant state delivery.
- id: startup_button_state_sync
mode: restart
@@ -970,7 +1103,7 @@ interval:
# https://esphome.io/components/text_sensor/
#:########################################################################################:#
text_sensor:
# Requested heat-pump mode used for button highlighting.
# Requested heat-pump mode helper used while a mode change is pending.
- platform: homeassistant
id: ha_climate_requested_mode
entity_id: "${climate_requested_mode_entity}"
@@ -979,6 +1112,34 @@ text_sensor:
then:
- script.execute: refresh_climate_controls
# Actual current HVAC mode provides the fallback when requested mode is none.
- platform: homeassistant
id: ha_climate_current_mode
entity_id: "${climate_entity}"
internal: true
on_value:
then:
- script.execute: refresh_climate_controls
# Existing HA profile helper uses values such as Quiet and Boost.
- platform: homeassistant
id: ha_climate_profile
entity_id: "${climate_profile_entity}"
internal: true
on_value:
then:
- script.execute: refresh_climate_controls
# Actual climate preset provides an additional authoritative profile state.
- platform: homeassistant
id: ha_climate_preset_mode
entity_id: "${climate_entity}"
attribute: preset_mode
internal: true
on_value:
then:
- script.execute: refresh_climate_controls
- platform: version
name: "${friendly_name} ESPHome Version"
hide_timestamp: true
@@ -1638,20 +1799,74 @@ lvgl:
entity_id: "${climate_dry_script}"
#:################################################################################:#
# HEAT-PUMP SETPOINT
# HEAT-PUMP PROFILE / SETPOINT
#:################################################################################:#
- label:
align: TOP_MID
x: 535
y: 187
width: 270
text: "Setpoint"
text_font: font_small
text_align: CENTER
text_color: 0x8FA0B3
- button:
id: climate_setpoint_down_button
x: 100
id: climate_quiet_button
x: 25
y: 218
width: 190
width: 170
height: 105
bg_color: 0x28313D
bg_opa: COVER
border_width: 2
border_color: 0x548C6C
radius: 18
pressed:
bg_color: 0x315843
widgets:
- label:
align: CENTER
text: "Quiet"
text_font: font_button
text_color: 0xFFFFFF
on_click:
- homeassistant.action:
action: climate.set_preset_mode
data:
entity_id: "${climate_entity}"
preset_mode: "${climate_quiet_preset}"
- button:
id: climate_powerful_button
x: 205
y: 218
width: 170
height: 105
bg_color: 0x28313D
bg_opa: COVER
border_width: 2
border_color: 0x80619B
radius: 18
pressed:
bg_color: 0x6B4A86
widgets:
- label:
align: CENTER
text: "Powerful"
text_font: font_button
text_color: 0xFFFFFF
on_click:
- homeassistant.action:
action: climate.set_preset_mode
data:
entity_id: "${climate_entity}"
preset_mode: "${climate_powerful_preset}"
- button:
id: climate_setpoint_down_button
x: 405
y: 218
width: 120
height: 105
bg_color: 0x28313D
bg_opa: COVER
@@ -1663,7 +1878,7 @@ lvgl:
widgets:
- label:
align: CENTER
text: "-0.5"
text: ""
text_font: font_title
text_color: 0xFFFFFF
on_click:
@@ -1674,9 +1889,9 @@ lvgl:
- button:
id: climate_setpoint_display
x: 315
x: 535
y: 218
width: 394
width: 270
height: 105
bg_color: 0x1C2632
bg_opa: COVER
@@ -1693,9 +1908,9 @@ lvgl:
- button:
id: climate_setpoint_up_button
x: 734
x: 815
y: 218
width: 190
width: 120
height: 105
bg_color: 0x28313D
bg_opa: COVER
@@ -1707,7 +1922,7 @@ lvgl:
widgets:
- label:
align: CENTER
text: "+0.5"
text: ""
text_font: font_title
text_color: 0xFFFFFF
on_click:
@@ -1717,13 +1932,13 @@ lvgl:
step: "0.5"
#:################################################################################:#
# CEILING FAN / AIR FILTER
# CEILING FAN / AIR FILTER / NIGHT POWER
#:################################################################################:#
- button:
id: ceiling_fan_cycle_button
x: 65
x: 25
y: 356
width: 430
width: 310
height: 100
bg_color: 0x28313D
bg_opa: COVER
@@ -1798,10 +2013,10 @@ lvgl:
entity_id: "${ceiling_fan_entity}"
- button:
id: air_filter_low_button
x: 529
id: air_filter_quiet_button
x: 357
y: 356
width: 430
width: 310
height: 100
bg_color: 0x28313D
bg_opa: COVER
@@ -1813,7 +2028,7 @@ lvgl:
widgets:
- label:
align: CENTER
text: "Air Filter Low"
text: "Air Filter Quiet"
text_font: font_button
text_color: 0xFFFFFF
on_click:
@@ -1823,6 +2038,31 @@ lvgl:
entity_id: "${air_filter_level_entity}"
value: "2"
- button:
id: climate_night_power_button
x: 689
y: 356
width: 310
height: 100
bg_color: 0x28313D
bg_opa: COVER
border_width: 2
border_color: 0x80619B
radius: 18
pressed:
bg_color: 0x5A4778
widgets:
- label:
align: CENTER
text: "Climate 9pm-12"
text_font: font_button
text_color: 0xFFFFFF
on_click:
- homeassistant.action:
action: input_boolean.toggle
data:
entity_id: "${climate_night_power_entity}"
- button:
id: climate_back_button
x: 365