Edit esp-bedside-panel.yaml
This commit is contained in:
+227
-42
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-bedside-panel.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# V0.8o 2026-07-16 Added reliable MDI setpoint arrows and optimistic mutually-exclusive Heat Pump profiles
|
||||
# V0.8n 2026-07-16 Fixed setpoint arrow icons using LVGL built-in FontAwesome symbols
|
||||
# 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
|
||||
@@ -82,12 +83,12 @@ substitutions:
|
||||
# Device Naming
|
||||
device_name: "esp-bedside-panel"
|
||||
friendly_name: "ESP Bedside Panel"
|
||||
description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside control panel. Climate controls with LVGL built-in setpoint arrow icons. (Layout V1.1)"
|
||||
description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside control panel. Reliable setpoint icons and optimistic Quiet / Powerful / None profile controls. (Layout V1.1)"
|
||||
device_area: "Bedroom"
|
||||
|
||||
# Project Naming
|
||||
project_name: "Guition.JC1060P470C_I_W_Y"
|
||||
project_version: "v0.8n"
|
||||
project_version: "v0.8o"
|
||||
|
||||
# Passwords & Secrets
|
||||
api_key: !secret esp-api_key
|
||||
@@ -145,8 +146,7 @@ substitutions:
|
||||
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"
|
||||
climate_profile_next_script: "script.master_bedroom_heat_pump_profile_next"
|
||||
|
||||
# Home Assistant Entities - Ceiling Fan / Air Filter / Night Power
|
||||
ceiling_fan_entity: "fan.tasmo_ifan02_3793_bedrm1_1"
|
||||
@@ -430,6 +430,15 @@ font:
|
||||
- "abcdefghijklmnopqrstuvwxyz"
|
||||
- "0123456789, .:/-%°+()"
|
||||
|
||||
# Dedicated MDI font for reliable setpoint chevron icons.
|
||||
- file: "https://raw.githubusercontent.com/Templarian/MaterialDesign-Webfont/master/fonts/materialdesignicons-webfont.ttf"
|
||||
id: font_mdi_setpoint
|
||||
size: 48
|
||||
bpp: 4
|
||||
glyphs:
|
||||
- "\U000F0140" # mdi-chevron-down
|
||||
- "\U000F0143" # mdi-chevron-up
|
||||
|
||||
#:########################################################################################:#
|
||||
# HOME ASSISTANT NUMERIC SENSORS:
|
||||
# https://esphome.io/components/sensor/homeassistant.html
|
||||
@@ -725,6 +734,22 @@ binary_sensor:
|
||||
? std::string("Quiet Time active")
|
||||
: std::string("");
|
||||
|
||||
#:########################################################################################:#
|
||||
# GLOBALS:
|
||||
# Local optimistic Heat Pump profile state
|
||||
#:########################################################################################:#
|
||||
globals:
|
||||
# -1 = follow HA, 0 = None, 1 = Quiet, 2 = Powerful / Boost.
|
||||
- id: climate_profile_optimistic
|
||||
type: int
|
||||
restore_value: false
|
||||
initial_value: "-1"
|
||||
|
||||
- id: climate_profile_cycle_attempts
|
||||
type: int
|
||||
restore_value: false
|
||||
initial_value: "0"
|
||||
|
||||
#:########################################################################################:#
|
||||
# SCRIPTS:
|
||||
# Refresh all state-dependent LVGL button colours
|
||||
@@ -940,43 +965,78 @@ script:
|
||||
? 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.
|
||||
# Quiet / Powerful are mutually exclusive. While a button action is
|
||||
# pending, the optimistic local value is shown immediately. Otherwise,
|
||||
# the HA profile helper is authoritative, with actual preset as fallback.
|
||||
- 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;
|
||||
int selected = id(climate_profile_optimistic);
|
||||
|
||||
const bool active = (
|
||||
profile == "Quiet" ||
|
||||
profile == "quiet" ||
|
||||
preset == "Quiet" ||
|
||||
preset == "quiet"
|
||||
);
|
||||
if (selected < 0) {
|
||||
const auto profile = id(ha_climate_profile).state;
|
||||
const auto preset = id(ha_climate_preset_mode).state;
|
||||
|
||||
return active
|
||||
if (profile == "Quiet" || profile == "quiet") {
|
||||
selected = 1;
|
||||
} else if (
|
||||
profile == "Boost" ||
|
||||
profile == "boost" ||
|
||||
profile == "Powerful" ||
|
||||
profile == "powerful"
|
||||
) {
|
||||
selected = 2;
|
||||
} else if (preset == "quiet" || preset == "Quiet") {
|
||||
selected = 1;
|
||||
} else if (
|
||||
preset == "boost" ||
|
||||
preset == "Boost" ||
|
||||
preset == "powerful" ||
|
||||
preset == "Powerful"
|
||||
) {
|
||||
selected = 2;
|
||||
} else {
|
||||
selected = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return selected == 1
|
||||
? 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;
|
||||
int selected = id(climate_profile_optimistic);
|
||||
|
||||
const bool active = (
|
||||
profile == "Boost" ||
|
||||
profile == "boost" ||
|
||||
profile == "Powerful" ||
|
||||
profile == "powerful" ||
|
||||
preset == "Boost" ||
|
||||
preset == "boost" ||
|
||||
preset == "Powerful" ||
|
||||
preset == "powerful"
|
||||
);
|
||||
if (selected < 0) {
|
||||
const auto profile = id(ha_climate_profile).state;
|
||||
const auto preset = id(ha_climate_preset_mode).state;
|
||||
|
||||
return active
|
||||
if (profile == "Quiet" || profile == "quiet") {
|
||||
selected = 1;
|
||||
} else if (
|
||||
profile == "Boost" ||
|
||||
profile == "boost" ||
|
||||
profile == "Powerful" ||
|
||||
profile == "powerful"
|
||||
) {
|
||||
selected = 2;
|
||||
} else if (preset == "quiet" || preset == "Quiet") {
|
||||
selected = 1;
|
||||
} else if (
|
||||
preset == "boost" ||
|
||||
preset == "Boost" ||
|
||||
preset == "powerful" ||
|
||||
preset == "Powerful"
|
||||
) {
|
||||
selected = 2;
|
||||
} else {
|
||||
selected = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return selected == 2
|
||||
? lv_color_hex(0x6B4A86)
|
||||
: lv_color_hex(0x28313D);
|
||||
|
||||
@@ -1043,6 +1103,69 @@ script:
|
||||
? lv_color_hex(0x5A4778)
|
||||
: lv_color_hex(0x28313D);
|
||||
|
||||
# Apply the optimistic target through the same HA profile-cycle script used
|
||||
# by the existing dashboard. It checks after each cycle, so no cycle order
|
||||
# is assumed. At most three cycles are attempted.
|
||||
- id: apply_climate_profile_target
|
||||
mode: restart
|
||||
then:
|
||||
- lambda: |-
|
||||
id(climate_profile_cycle_attempts) = 0;
|
||||
|
||||
- while:
|
||||
condition:
|
||||
lambda: |-
|
||||
if (id(climate_profile_cycle_attempts) >= 3) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int current = 0;
|
||||
const auto profile = id(ha_climate_profile).state;
|
||||
const auto preset = id(ha_climate_preset_mode).state;
|
||||
|
||||
if (profile == "Quiet" || profile == "quiet") {
|
||||
current = 1;
|
||||
} else if (
|
||||
profile == "Boost" ||
|
||||
profile == "boost" ||
|
||||
profile == "Powerful" ||
|
||||
profile == "powerful"
|
||||
) {
|
||||
current = 2;
|
||||
} else if (preset == "quiet" || preset == "Quiet") {
|
||||
current = 1;
|
||||
} else if (
|
||||
preset == "boost" ||
|
||||
preset == "Boost" ||
|
||||
preset == "powerful" ||
|
||||
preset == "Powerful"
|
||||
) {
|
||||
current = 2;
|
||||
}
|
||||
|
||||
return current != id(climate_profile_optimistic);
|
||||
|
||||
then:
|
||||
- homeassistant.action:
|
||||
action: script.turn_on
|
||||
data:
|
||||
entity_id: "${climate_profile_next_script}"
|
||||
|
||||
- lambda: |-
|
||||
id(climate_profile_cycle_attempts) += 1;
|
||||
|
||||
# Allow the HA script and Panasonic integration to update the
|
||||
# profile helper before deciding whether another cycle is needed.
|
||||
- delay: 1800ms
|
||||
|
||||
# Keep the optimistic highlight briefly, then return to authoritative HA.
|
||||
- delay: 1500ms
|
||||
|
||||
- lambda: |-
|
||||
id(climate_profile_optimistic) = -1;
|
||||
|
||||
- script.execute: refresh_climate_controls
|
||||
|
||||
# Two passes allow time for LVGL creation and Home Assistant state delivery.
|
||||
- id: startup_button_state_sync
|
||||
mode: restart
|
||||
@@ -1831,11 +1954,42 @@ lvgl:
|
||||
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}"
|
||||
# Quiet -> None when already active; otherwise select Quiet.
|
||||
- lambda: |-
|
||||
int selected = id(climate_profile_optimistic);
|
||||
|
||||
if (selected < 0) {
|
||||
const auto profile = id(ha_climate_profile).state;
|
||||
const auto preset = id(ha_climate_preset_mode).state;
|
||||
|
||||
if (
|
||||
profile == "Quiet" ||
|
||||
profile == "quiet" ||
|
||||
preset == "Quiet" ||
|
||||
preset == "quiet"
|
||||
) {
|
||||
selected = 1;
|
||||
} else if (
|
||||
profile == "Boost" ||
|
||||
profile == "boost" ||
|
||||
profile == "Powerful" ||
|
||||
profile == "powerful" ||
|
||||
preset == "Boost" ||
|
||||
preset == "boost" ||
|
||||
preset == "Powerful" ||
|
||||
preset == "powerful"
|
||||
) {
|
||||
selected = 2;
|
||||
} else {
|
||||
selected = 0;
|
||||
}
|
||||
}
|
||||
|
||||
id(climate_profile_optimistic) =
|
||||
selected == 1 ? 0 : 1;
|
||||
|
||||
- script.execute: refresh_climate_controls
|
||||
- script.execute: apply_climate_profile_target
|
||||
|
||||
- button:
|
||||
id: climate_powerful_button
|
||||
@@ -1857,11 +2011,42 @@ lvgl:
|
||||
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}"
|
||||
# Powerful -> None when already active; otherwise select Powerful.
|
||||
- lambda: |-
|
||||
int selected = id(climate_profile_optimistic);
|
||||
|
||||
if (selected < 0) {
|
||||
const auto profile = id(ha_climate_profile).state;
|
||||
const auto preset = id(ha_climate_preset_mode).state;
|
||||
|
||||
if (
|
||||
profile == "Quiet" ||
|
||||
profile == "quiet" ||
|
||||
preset == "Quiet" ||
|
||||
preset == "quiet"
|
||||
) {
|
||||
selected = 1;
|
||||
} else if (
|
||||
profile == "Boost" ||
|
||||
profile == "boost" ||
|
||||
profile == "Powerful" ||
|
||||
profile == "powerful" ||
|
||||
preset == "Boost" ||
|
||||
preset == "boost" ||
|
||||
preset == "Powerful" ||
|
||||
preset == "powerful"
|
||||
) {
|
||||
selected = 2;
|
||||
} else {
|
||||
selected = 0;
|
||||
}
|
||||
}
|
||||
|
||||
id(climate_profile_optimistic) =
|
||||
selected == 2 ? 0 : 2;
|
||||
|
||||
- script.execute: refresh_climate_controls
|
||||
- script.execute: apply_climate_profile_target
|
||||
|
||||
- button:
|
||||
id: climate_setpoint_down_button
|
||||
@@ -1879,8 +2064,8 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "\uF063"
|
||||
text_font: montserrat_36
|
||||
text: "\U000F0140"
|
||||
text_font: font_mdi_setpoint
|
||||
text_color: 0xFFFFFF
|
||||
on_click:
|
||||
- homeassistant.action:
|
||||
@@ -1923,8 +2108,8 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "\uF062"
|
||||
text_font: montserrat_36
|
||||
text: "\U000F0143"
|
||||
text_font: font_mdi_setpoint
|
||||
text_color: 0xFFFFFF
|
||||
on_click:
|
||||
- homeassistant.action:
|
||||
|
||||
Reference in New Issue
Block a user