From 23d5c82222d661badac40322e52386c817a20e95 Mon Sep 17 00:00:00 2001 From: ESPHome Device Builder Date: Fri, 24 Jul 2026 22:31:37 +1200 Subject: [PATCH] Edit esp-bedside-panel.yaml --- esphome/esp-bedside-panel.yaml | 571 ++++++++++++++++----------------- 1 file changed, 279 insertions(+), 292 deletions(-) diff --git a/esphome/esp-bedside-panel.yaml b/esphome/esp-bedside-panel.yaml index aceceb5..660f2fe 100644 --- a/esphome/esp-bedside-panel.yaml +++ b/esphome/esp-bedside-panel.yaml @@ -179,7 +179,7 @@ substitutions: # Project Naming project_name: "Guition.JC1060P470C_I_W_Y" - project_version: "v1.46" + project_version: "v1.47" # Passwords & Secrets api_key: !secret esp-api_key @@ -1731,42 +1731,42 @@ globals: - id: alarm_enabled type: bool[4] restore_value: true - initial_value: '{false, false, false, false}' + initial_value: "{false, false, false, false}" - id: alarm_hour type: uint8_t[4] restore_value: true - initial_value: '{7, 7, 7, 7}' + initial_value: "{7, 7, 7, 7}" - id: alarm_minute type: uint8_t[4] restore_value: true - initial_value: '{0, 0, 0, 0}' + initial_value: "{0, 0, 0, 0}" - id: alarm_day_mask type: uint8_t[4] restore_value: true - initial_value: '{31, 31, 31, 31}' + initial_value: "{31, 31, 31, 31}" - id: alarm_snooze_enabled type: bool[4] restore_value: true - initial_value: '{false, false, false, false}' + initial_value: "{false, false, false, false}" - id: alarm_vibrate_option type: uint8_t[4] restore_value: true - initial_value: '{1, 1, 1, 1}' + initial_value: "{1, 1, 1, 1}" - id: alarm_sound_option type: uint8_t[4] restore_value: true - initial_value: '{1, 1, 1, 1}' + initial_value: "{1, 1, 1, 1}" - id: alarm_lamp_enabled type: bool[4] restore_value: true - initial_value: '{false, false, false, false}' + initial_value: "{false, false, false, false}" # Temporary values used by the shared time-editor page. - id: alarm_edit_row @@ -2345,7 +2345,6 @@ script: - script.execute: refresh_alarm_audio_controls - #:######################################################################################:# # ALARM CLOCK AUDIO TESTING #:######################################################################################:# @@ -2756,7 +2755,6 @@ script: - script.execute: refresh_alarm_audio_controls - #:######################################################################################:# # ALARM CLOCK TIME EDITOR #:######################################################################################:# @@ -3099,7 +3097,6 @@ script: return lv_color_hex(0x28313D); - - lvgl.label.update: id: job_1_status_label text: !lambda |- @@ -3277,7 +3274,6 @@ script: return state; - - lvgl.widget.update: id: job_2_button bg_color: !lambda |- @@ -3305,7 +3301,6 @@ script: return lv_color_hex(0x28313D); - - lvgl.label.update: id: job_2_status_label text: !lambda |- @@ -3483,7 +3478,6 @@ script: return state; - - lvgl.widget.update: id: job_3_button bg_color: !lambda |- @@ -3511,7 +3505,6 @@ script: return lv_color_hex(0x28313D); - - lvgl.label.update: id: job_3_status_label text: !lambda |- @@ -3689,7 +3682,6 @@ script: return state; - - lvgl.widget.update: id: job_4_button bg_color: !lambda |- @@ -3717,7 +3709,6 @@ script: return lv_color_hex(0x28313D); - - lvgl.label.update: id: job_4_status_label text: !lambda |- @@ -3895,7 +3886,6 @@ script: return state; - - lvgl.widget.update: id: job_5_button bg_color: !lambda |- @@ -3923,7 +3913,6 @@ script: return lv_color_hex(0x28313D); - - lvgl.label.update: id: job_5_status_label text: !lambda |- @@ -4101,7 +4090,6 @@ script: return state; - # Update Bedroom and Clock status values after LVGL has finished constructing. - id: refresh_header_status mode: restart @@ -4591,298 +4579,298 @@ script: return id(lvgl_ready); then: - # Lounge gas-heater state and user-facing status text. - - lvgl.label.update: - id: lounge_fire_button_label - text: !lambda |- - const auto status = id(ha_lounge_fire_status).state; + # Lounge gas-heater state and user-facing status text. + - lvgl.label.update: + id: lounge_fire_button_label + text: !lambda |- + const auto status = id(ha_lounge_fire_status).state; - if ( - status.empty() || - status == "unknown" || - status == "unavailable" - ) { - return std::string("Fire: --"); - } + if ( + status.empty() || + status == "unknown" || + status == "unavailable" + ) { + return std::string("Fire: --"); + } - return std::string("Fire: ") + status; + return std::string("Fire: ") + status; - - lvgl.widget.update: - id: lounge_fire_button - bg_color: !lambda |- - return id(ha_lounge_fire).state - ? lv_color_hex(0x8A3F22) - : lv_color_hex(0x28313D); + - lvgl.widget.update: + id: lounge_fire_button + bg_color: !lambda |- + return id(ha_lounge_fire).state + ? lv_color_hex(0x8A3F22) + : lv_color_hex(0x28313D); - # 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 requested = id(ha_climate_requested_mode).state; - const auto current = id(ha_climate_current_mode).state; + # 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 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 requested_none = ( + requested.empty() || + requested == "none" || + requested == "None" || + requested == "unknown" || + requested == "unavailable" + ); - const bool active = ( - requested == "off" || - requested == "Off" || - (requested_none && current == "off") - ); + const bool active = ( + requested == "off" || + requested == "Off" || + (requested_none && current == "off") + ); - return active - ? lv_color_hex(0x548C6C) - : lv_color_hex(0x28313D); + return active + ? lv_color_hex(0x548C6C) + : lv_color_hex(0x28313D); - - lvgl.widget.update: - id: climate_heat_button - bg_color: !lambda |- - const auto requested = id(ha_climate_requested_mode).state; - const auto current = id(ha_climate_current_mode).state; + - lvgl.widget.update: + id: climate_heat_button + bg_color: !lambda |- + 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 requested_none = ( + requested.empty() || + requested == "none" || + requested == "None" || + requested == "unknown" || + requested == "unavailable" + ); - const bool active = ( - requested == "heat" || - requested == "Heat" || - (requested_none && current == "heat") - ); + const bool active = ( + requested == "heat" || + requested == "Heat" || + (requested_none && current == "heat") + ); - return active - ? lv_color_hex(0xB76822) - : lv_color_hex(0x28313D); + return active + ? lv_color_hex(0xB76822) + : lv_color_hex(0x28313D); - - lvgl.widget.update: - id: climate_cool_button - bg_color: !lambda |- - const auto requested = id(ha_climate_requested_mode).state; - const auto current = id(ha_climate_current_mode).state; + - lvgl.widget.update: + id: climate_cool_button + bg_color: !lambda |- + 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 requested_none = ( + requested.empty() || + requested == "none" || + requested == "None" || + requested == "unknown" || + requested == "unavailable" + ); - const bool active = ( - requested == "cool" || - requested == "Cool" || - (requested_none && current == "cool") - ); + const bool active = ( + requested == "cool" || + requested == "Cool" || + (requested_none && current == "cool") + ); - return active - ? lv_color_hex(0x2E6A96) - : lv_color_hex(0x28313D); + return active + ? lv_color_hex(0x2E6A96) + : lv_color_hex(0x28313D); - - lvgl.widget.update: - id: climate_dry_button - bg_color: !lambda |- - const auto requested = id(ha_climate_requested_mode).state; - const auto current = id(ha_climate_current_mode).state; + - lvgl.widget.update: + id: climate_dry_button + bg_color: !lambda |- + 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 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 && + const bool active = ( + requested == "dry" || + requested == "Dry" || + requested == "dehumidify" || + requested == "Dehumidify" || ( - current == "dry" || - current == "dehumidify" + requested_none && + ( + current == "dry" || + current == "dehumidify" + ) ) + ); + + return active + ? lv_color_hex(0x32677F) + : lv_color_hex(0x28313D); + + # Quiet / Boost are mutually exclusive. Optimistic state wins + # immediately; actual Panasonic preset is authoritative afterwards. + - lvgl.widget.update: + id: climate_quiet_button + bg_color: !lambda |- + int selected = id(climate_profile_optimistic); + + if (selected < 0) { + const auto preset = id(ha_climate_preset_mode).state; + const auto helper = id(ha_climate_profile).state; + + if ( + preset == "quiet" || + preset == "Quiet" || + helper == "Quiet" || + helper == "quiet" + ) { + selected = 1; + } else if ( + preset == "powerful" || + preset == "Powerful" || + helper == "Boost" || + helper == "boost" + ) { + selected = 2; + } else { + selected = 0; + } + } + + return selected == 1 + ? lv_color_hex(0x315843) + : lv_color_hex(0x28313D); + + - lvgl.widget.update: + id: climate_boost_button + bg_color: !lambda |- + int selected = id(climate_profile_optimistic); + + if (selected < 0) { + const auto preset = id(ha_climate_preset_mode).state; + const auto helper = id(ha_climate_profile).state; + + if ( + preset == "quiet" || + preset == "Quiet" || + helper == "Quiet" || + helper == "quiet" + ) { + selected = 1; + } else if ( + preset == "powerful" || + preset == "Powerful" || + helper == "Boost" || + helper == "boost" + ) { + selected = 2; + } else { + selected = 0; + } + } + + return selected == 2 + ? lv_color_hex(0x6B4A86) + : lv_color_hex(0x28313D); + + - lvgl.widget.update: + id: climate_nanoe_button + bg_color: !lambda |- + bool active = id(ha_nanoe).state; + + if (id(nanoe_optimistic) >= 0) { + active = id(nanoe_optimistic) == 1; + } + + return active + ? lv_color_hex(0x315E82) + : lv_color_hex(0x28313D); + + # Heat-pump target setpoint. + - lvgl.label.update: + id: climate_setpoint_value_label + text: !lambda |- + const float value = id(ha_climate_setpoint).state; + + if (isnan(value)) { + return std::string("--.-°C"); + } + + char buffer[16]; + snprintf(buffer, sizeof(buffer), "%.1f°C", value); + return std::string(buffer); + + # One-button ceiling-fan cycle: Off -> Low -> Medium -> High -> Off. + - lvgl.label.update: + id: ceiling_fan_cycle_label + text: !lambda |- + if (!id(ha_ceiling_fan_on).state) { + return std::string("Fan:Off"); + } + + const float percentage = id(ha_ceiling_fan_percentage).state; + + if (isnan(percentage) || percentage < 50.0f) { + return std::string("Fan:Low"); + } + + if (percentage < 85.0f) { + return std::string("Fan:Medium"); + } + + return std::string("Fan:High"); + + - lvgl.widget.update: + id: ceiling_fan_cycle_button + bg_color: !lambda |- + return id(ha_ceiling_fan_on).state + ? lv_color_hex(0x315E82) + : lv_color_hex(0x28313D); + + # Air-filter text and Quiet highlighting. + - lvgl.label.update: + id: air_filter_quiet_label + text: !lambda |- + const float level = id(ha_air_filter_level).state; + + if (isnan(level)) { + return std::string("Filter:--"); + } + + if (level >= 0.0f && level <= 2.0f) { + return std::string("Filter:Quiet"); + } + + char buffer[24]; + snprintf( + buffer, + sizeof(buffer), + "Filter:%.0f", + level + ); + return std::string(buffer); + + - lvgl.widget.update: + id: air_filter_quiet_button + bg_color: !lambda |- + const float level = id(ha_air_filter_level).state; + + return ( + !isnan(level) && + level >= 0.0f && + level <= 2.0f ) - ); + ? lv_color_hex(0x315843) + : lv_color_hex(0x28313D); - return active - ? lv_color_hex(0x32677F) - : lv_color_hex(0x28313D); - - # Quiet / Boost are mutually exclusive. Optimistic state wins - # immediately; actual Panasonic preset is authoritative afterwards. - - lvgl.widget.update: - id: climate_quiet_button - bg_color: !lambda |- - int selected = id(climate_profile_optimistic); - - if (selected < 0) { - const auto preset = id(ha_climate_preset_mode).state; - const auto helper = id(ha_climate_profile).state; - - if ( - preset == "quiet" || - preset == "Quiet" || - helper == "Quiet" || - helper == "quiet" - ) { - selected = 1; - } else if ( - preset == "powerful" || - preset == "Powerful" || - helper == "Boost" || - helper == "boost" - ) { - selected = 2; - } else { - selected = 0; - } - } - - return selected == 1 - ? lv_color_hex(0x315843) - : lv_color_hex(0x28313D); - - - lvgl.widget.update: - id: climate_boost_button - bg_color: !lambda |- - int selected = id(climate_profile_optimistic); - - if (selected < 0) { - const auto preset = id(ha_climate_preset_mode).state; - const auto helper = id(ha_climate_profile).state; - - if ( - preset == "quiet" || - preset == "Quiet" || - helper == "Quiet" || - helper == "quiet" - ) { - selected = 1; - } else if ( - preset == "powerful" || - preset == "Powerful" || - helper == "Boost" || - helper == "boost" - ) { - selected = 2; - } else { - selected = 0; - } - } - - return selected == 2 - ? lv_color_hex(0x6B4A86) - : lv_color_hex(0x28313D); - - - lvgl.widget.update: - id: climate_nanoe_button - bg_color: !lambda |- - bool active = id(ha_nanoe).state; - - if (id(nanoe_optimistic) >= 0) { - active = id(nanoe_optimistic) == 1; - } - - return active - ? lv_color_hex(0x315E82) - : lv_color_hex(0x28313D); - - # Heat-pump target setpoint. - - lvgl.label.update: - id: climate_setpoint_value_label - text: !lambda |- - const float value = id(ha_climate_setpoint).state; - - if (isnan(value)) { - return std::string("--.-°C"); - } - - char buffer[16]; - snprintf(buffer, sizeof(buffer), "%.1f°C", value); - return std::string(buffer); - - # One-button ceiling-fan cycle: Off -> Low -> Medium -> High -> Off. - - lvgl.label.update: - id: ceiling_fan_cycle_label - text: !lambda |- - if (!id(ha_ceiling_fan_on).state) { - return std::string("Fan:Off"); - } - - const float percentage = id(ha_ceiling_fan_percentage).state; - - if (isnan(percentage) || percentage < 50.0f) { - return std::string("Fan:Low"); - } - - if (percentage < 85.0f) { - return std::string("Fan:Medium"); - } - - return std::string("Fan:High"); - - - lvgl.widget.update: - id: ceiling_fan_cycle_button - bg_color: !lambda |- - return id(ha_ceiling_fan_on).state - ? lv_color_hex(0x315E82) - : lv_color_hex(0x28313D); - - # Air-filter text and Quiet highlighting. - - lvgl.label.update: - id: air_filter_quiet_label - text: !lambda |- - const float level = id(ha_air_filter_level).state; - - if (isnan(level)) { - return std::string("Filter:--"); - } - - if (level >= 0.0f && level <= 2.0f) { - return std::string("Filter:Quiet"); - } - - char buffer[24]; - snprintf( - buffer, - sizeof(buffer), - "Filter:%.0f", - level - ); - return std::string(buffer); - - - lvgl.widget.update: - id: air_filter_quiet_button - bg_color: !lambda |- - const float level = id(ha_air_filter_level).state; - - 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); + # 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); # Update the Sleep timer label and active button colour. - id: refresh_sleep_timer @@ -5820,7 +5808,6 @@ lvgl: - online_image.release: security_camera_image pages: - #:####################################################################################:# # BEDROOM PAGE #:####################################################################################:#