Edit esp-bedside-panel.yaml
This commit is contained in:
+167
-22
@@ -6,6 +6,7 @@
|
||||
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-bedside-panel.yaml
|
||||
#:########################################################################################:#
|
||||
# VERSIONS:
|
||||
# V1.0 2026-07-16 First full Bedroom/Climate/Clock release; added 2-hour Sleep timer
|
||||
# V0.8u 2026-07-16 Enlarged Clock and date; moved environment readings lower
|
||||
# V0.8t 2026-07-16 Corrected Panasonic presets to quiet / powerful / none
|
||||
# V0.8s 2026-07-16 Added direct Panasonic preset control and optimistic Nano-X
|
||||
@@ -74,7 +75,9 @@
|
||||
# - Touching the clock:
|
||||
# - Returns to the Bedroom controls.
|
||||
# - Restores normal brightness.
|
||||
# - The Climate page contains working Off, Heat, Cool and Dehumid controls.
|
||||
# - The Climate page contains heat-pump, ceiling-fan, air-filter and Night Power controls.
|
||||
# - Sleep: 2 hrs starts a local 120-minute countdown and turns the heat pump off.
|
||||
# - Pressing the active Sleep button again cancels the countdown.
|
||||
#:########################################################################################:#
|
||||
# OFFLINE NOTES:
|
||||
# - LVGL, the clock, touch and backlight operate locally.
|
||||
@@ -91,12 +94,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. Larger bedside clock and date with lower environment status row. (Layout V1.1)"
|
||||
description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside control panel. V1.0 Bedroom, Climate and Clock release with local 2-hour Sleep timer. (Layout V1.1)"
|
||||
device_area: "Bedroom"
|
||||
|
||||
# Project Naming
|
||||
project_name: "Guition.JC1060P470C_I_W_Y"
|
||||
project_version: "v0.8u"
|
||||
project_version: "v1.0"
|
||||
|
||||
# Passwords & Secrets
|
||||
api_key: !secret esp-api_key
|
||||
@@ -223,6 +226,7 @@ esphome:
|
||||
|
||||
- script.execute: refresh_api_indicator
|
||||
- script.execute: refresh_button_states
|
||||
- script.execute: refresh_sleep_timer
|
||||
|
||||
#:########################################################################################:#
|
||||
# ESP PLATFORM AND FRAMEWORK:
|
||||
@@ -783,6 +787,13 @@ globals:
|
||||
restore_value: false
|
||||
initial_value: "-1"
|
||||
|
||||
# Unix timestamp at which the 2-hour Sleep timer expires.
|
||||
# A value of 0 means that the timer is inactive.
|
||||
- id: sleep_timer_end_epoch
|
||||
type: uint32_t
|
||||
restore_value: true
|
||||
initial_value: "0"
|
||||
|
||||
#:########################################################################################:#
|
||||
# SCRIPTS:
|
||||
# Refresh all state-dependent LVGL button colours
|
||||
@@ -1121,7 +1132,7 @@ script:
|
||||
snprintf(buffer, sizeof(buffer), "%.1f°C", value);
|
||||
return std::string(buffer);
|
||||
|
||||
# One-button ceiling-fan cycle: Off -> 1 -> 2 -> 3 -> Off.
|
||||
# One-button ceiling-fan cycle: Off -> Low -> Medium -> High -> Off.
|
||||
- lvgl.label.update:
|
||||
id: ceiling_fan_cycle_label
|
||||
text: !lambda |-
|
||||
@@ -1132,14 +1143,14 @@ script:
|
||||
const float percentage = id(ha_ceiling_fan_percentage).state;
|
||||
|
||||
if (isnan(percentage) || percentage < 50.0f) {
|
||||
return std::string("Ceiling Fan: 1");
|
||||
return std::string("Ceiling Fan: Low");
|
||||
}
|
||||
|
||||
if (percentage < 85.0f) {
|
||||
return std::string("Ceiling Fan: 2");
|
||||
return std::string("Ceiling Fan: Medium");
|
||||
}
|
||||
|
||||
return std::string("Ceiling Fan: 3");
|
||||
return std::string("Ceiling Fan: High");
|
||||
|
||||
- lvgl.widget.update:
|
||||
id: ceiling_fan_cycle_button
|
||||
@@ -1170,6 +1181,60 @@ script:
|
||||
? lv_color_hex(0x5A4778)
|
||||
: lv_color_hex(0x28313D);
|
||||
|
||||
# Update the Sleep timer label and active button colour.
|
||||
- id: refresh_sleep_timer
|
||||
mode: restart
|
||||
then:
|
||||
- if:
|
||||
condition:
|
||||
lambda: |-
|
||||
return id(lvgl_ready);
|
||||
|
||||
then:
|
||||
- lvgl.label.update:
|
||||
id: sleep_timer_button_label
|
||||
text: !lambda |-
|
||||
const auto now = id(ha_time).now();
|
||||
|
||||
if (
|
||||
id(sleep_timer_end_epoch) == 0 ||
|
||||
!now.is_valid() ||
|
||||
now.timestamp >= id(sleep_timer_end_epoch)
|
||||
) {
|
||||
return std::string("Sleep: 2 hrs (0)");
|
||||
}
|
||||
|
||||
const uint32_t seconds_remaining =
|
||||
id(sleep_timer_end_epoch) - now.timestamp;
|
||||
|
||||
const uint32_t minutes_remaining =
|
||||
(seconds_remaining + 59) / 60;
|
||||
|
||||
char buffer[32];
|
||||
snprintf(
|
||||
buffer,
|
||||
sizeof(buffer),
|
||||
"Sleep: 2 hrs (%u)",
|
||||
static_cast<unsigned>(minutes_remaining)
|
||||
);
|
||||
|
||||
return std::string(buffer);
|
||||
|
||||
- lvgl.widget.update:
|
||||
id: sleep_timer_button
|
||||
bg_color: !lambda |-
|
||||
const auto now = id(ha_time).now();
|
||||
|
||||
const bool active = (
|
||||
id(sleep_timer_end_epoch) > 0 &&
|
||||
now.is_valid() &&
|
||||
now.timestamp < id(sleep_timer_end_epoch)
|
||||
);
|
||||
|
||||
return active
|
||||
? lv_color_hex(0x6B4A86)
|
||||
: lv_color_hex(0x28313D);
|
||||
|
||||
- id: release_climate_profile_optimistic
|
||||
mode: restart
|
||||
then:
|
||||
@@ -1199,6 +1264,7 @@ script:
|
||||
|
||||
- delay: 3500ms
|
||||
- script.execute: refresh_button_states
|
||||
- script.execute: refresh_sleep_timer
|
||||
|
||||
#:########################################################################################:#
|
||||
# INTERVAL:
|
||||
@@ -1246,6 +1312,32 @@ interval:
|
||||
|
||||
return std::string(buffer);
|
||||
|
||||
# Maintain the local two-hour Sleep countdown.
|
||||
- if:
|
||||
condition:
|
||||
lambda: |-
|
||||
const auto now = id(ha_time).now();
|
||||
|
||||
return (
|
||||
id(sleep_timer_end_epoch) > 0 &&
|
||||
now.is_valid() &&
|
||||
now.timestamp >= id(sleep_timer_end_epoch)
|
||||
);
|
||||
|
||||
then:
|
||||
- lambda: |-
|
||||
id(sleep_timer_end_epoch) = 0;
|
||||
|
||||
- homeassistant.action:
|
||||
action: script.turn_on
|
||||
data:
|
||||
entity_id: "${climate_off_script}"
|
||||
|
||||
- script.execute: refresh_sleep_timer
|
||||
|
||||
else:
|
||||
- script.execute: refresh_sleep_timer
|
||||
|
||||
#:########################################################################################:#
|
||||
# TEXT SENSOR COMPONENT:
|
||||
# https://esphome.io/components/text_sensor/
|
||||
@@ -2249,13 +2341,13 @@ lvgl:
|
||||
step: "0.5"
|
||||
|
||||
#:################################################################################:#
|
||||
# CEILING FAN / AIR FILTER / NIGHT POWER
|
||||
# CEILING FAN / AIR FILTER / NIGHT POWER / SLEEP TIMER
|
||||
#:################################################################################:#
|
||||
- button:
|
||||
id: ceiling_fan_cycle_button
|
||||
x: 25
|
||||
y: 356
|
||||
width: 306
|
||||
width: 220
|
||||
height: 100
|
||||
bg_color: 0x28313D
|
||||
bg_opa: COVER
|
||||
@@ -2269,10 +2361,10 @@ lvgl:
|
||||
id: ceiling_fan_cycle_label
|
||||
align: CENTER
|
||||
text: "Ceiling Fan: Off"
|
||||
text_font: font_button
|
||||
text_font: font_small
|
||||
text_color: 0xFFFFFF
|
||||
on_click:
|
||||
# Off -> speed 1
|
||||
# Off -> Low
|
||||
- if:
|
||||
condition:
|
||||
lambda: |-
|
||||
@@ -2286,7 +2378,7 @@ lvgl:
|
||||
percentage: "33"
|
||||
|
||||
else:
|
||||
# Speed 1 -> speed 2
|
||||
# Low -> Medium
|
||||
- if:
|
||||
condition:
|
||||
lambda: |-
|
||||
@@ -2306,7 +2398,7 @@ lvgl:
|
||||
percentage: "66"
|
||||
|
||||
else:
|
||||
# Speed 2 -> speed 3
|
||||
# Medium -> High
|
||||
- if:
|
||||
condition:
|
||||
lambda: |-
|
||||
@@ -2322,7 +2414,7 @@ lvgl:
|
||||
entity_id: "${ceiling_fan_entity}"
|
||||
percentage: "100"
|
||||
|
||||
# Speed 3 -> Off
|
||||
# High -> Off
|
||||
else:
|
||||
- homeassistant.action:
|
||||
action: fan.turn_off
|
||||
@@ -2331,9 +2423,9 @@ lvgl:
|
||||
|
||||
- button:
|
||||
id: air_filter_quiet_button
|
||||
x: 352
|
||||
x: 272
|
||||
y: 356
|
||||
width: 306
|
||||
width: 220
|
||||
height: 100
|
||||
bg_color: 0x28313D
|
||||
bg_opa: COVER
|
||||
@@ -2345,8 +2437,8 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "Air Filter Quiet"
|
||||
text_font: font_button
|
||||
text: "Air Filter: Quiet"
|
||||
text_font: font_small
|
||||
text_color: 0xFFFFFF
|
||||
on_click:
|
||||
- homeassistant.action:
|
||||
@@ -2357,9 +2449,9 @@ lvgl:
|
||||
|
||||
- button:
|
||||
id: climate_night_power_button
|
||||
x: 679
|
||||
x: 519
|
||||
y: 356
|
||||
width: 307
|
||||
width: 220
|
||||
height: 100
|
||||
bg_color: 0x28313D
|
||||
bg_opa: COVER
|
||||
@@ -2371,8 +2463,8 @@ lvgl:
|
||||
widgets:
|
||||
- label:
|
||||
align: CENTER
|
||||
text: "Climate 9pm-12"
|
||||
text_font: font_button
|
||||
text: "Climate: 9pm-12am"
|
||||
text_font: font_small
|
||||
text_color: 0xFFFFFF
|
||||
on_click:
|
||||
- homeassistant.action:
|
||||
@@ -2380,6 +2472,59 @@ lvgl:
|
||||
data:
|
||||
entity_id: "${climate_night_power_entity}"
|
||||
|
||||
- button:
|
||||
id: sleep_timer_button
|
||||
x: 766
|
||||
y: 356
|
||||
width: 220
|
||||
height: 100
|
||||
bg_color: 0x28313D
|
||||
bg_opa: COVER
|
||||
border_width: 2
|
||||
border_color: 0x80619B
|
||||
radius: 18
|
||||
pressed:
|
||||
bg_color: 0x6B4A86
|
||||
widgets:
|
||||
- label:
|
||||
id: sleep_timer_button_label
|
||||
align: CENTER
|
||||
text: "Sleep: 2 hrs (0)"
|
||||
text_font: font_small
|
||||
text_color: 0xFFFFFF
|
||||
on_click:
|
||||
# Pressing an active Sleep timer cancels it. Otherwise, start
|
||||
# a new 120-minute countdown.
|
||||
- if:
|
||||
condition:
|
||||
lambda: |-
|
||||
const auto now = id(ha_time).now();
|
||||
|
||||
return (
|
||||
id(sleep_timer_end_epoch) > 0 &&
|
||||
now.is_valid() &&
|
||||
now.timestamp < id(sleep_timer_end_epoch)
|
||||
);
|
||||
|
||||
then:
|
||||
- lambda: |-
|
||||
id(sleep_timer_end_epoch) = 0;
|
||||
|
||||
else:
|
||||
- if:
|
||||
condition:
|
||||
lambda: |-
|
||||
return id(ha_time).now().is_valid();
|
||||
|
||||
then:
|
||||
- lambda: |-
|
||||
const auto now = id(ha_time).now();
|
||||
|
||||
id(sleep_timer_end_epoch) =
|
||||
now.timestamp + (120 * 60);
|
||||
|
||||
- script.execute: refresh_sleep_timer
|
||||
|
||||
#:################################################################################:#
|
||||
# BOTTOM NAVIGATION
|
||||
#:################################################################################:#
|
||||
|
||||
Reference in New Issue
Block a user