Edit esp-bedside-panel.yaml

This commit is contained in:
ESPHome Device Builder
2026-07-16 22:42:55 +12:00
parent 07048708a9
commit 324cefef4c
+391 -9
View File
@@ -6,6 +6,7 @@
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-bedside-panel.yaml
#:########################################################################################:#
# VERSIONS:
# V1.3 2026-07-16 Added Security page with 640x360 Doorbell camera snapshot
# V1.2 2026-07-16 Removed Climate title and aligned Heat Pump heading above Off
# V1.1 2026-07-16 Increased Clock to 280px and date to 64px
# V1.0 2026-07-16 First full Bedroom/Climate/Clock release; added 2-hour Sleep timer
@@ -96,12 +97,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. Simplified Climate heading layout with aligned Heat Pump label. (Layout V1.1)"
description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside control panel. Security page with Home Assistant Doorbell camera snapshots. (Layout V1.1)"
device_area: "Bedroom"
# Project Naming
project_name: "Guition.JC1060P470C_I_W_Y"
project_version: "v1.2"
project_version: "v1.3"
# Passwords & Secrets
api_key: !secret esp-api_key
@@ -126,6 +127,12 @@ substitutions:
control_brightness: "80%"
clock_brightness: "4%"
# Security Camera Settings
# Change this only if homeassistant.local is not reachable from the panel.
home_assistant_internal_url: "http://homeassistant.local:8123"
security_camera_refresh_interval: "5s"
security_doorbell_camera_entity: "camera.view_road_front_door_fluent"
# Home Assistant Entities - Status / Environment
moon_phase_entity: "sensor.astroweather_moon_phase"
outdoor_temperature_entity: "sensor.lounge_outside_temperature"
@@ -796,6 +803,12 @@ globals:
restore_value: true
initial_value: "0"
# True only while the Security page is visible.
- id: security_page_active
type: bool
restore_value: false
initial_value: "false"
#:########################################################################################:#
# SCRIPTS:
# Refresh all state-dependent LVGL button colours
@@ -1237,6 +1250,75 @@ script:
? lv_color_hex(0x6B4A86)
: lv_color_hex(0x28313D);
# Download a current Doorbell image through the authenticated proxy path
# supplied by the Home Assistant camera entity.
- id: refresh_security_camera
mode: restart
then:
- if:
condition:
lambda: |-
return (
id(lvgl_ready) &&
id(security_page_active)
);
then:
- if:
condition:
lambda: |-
const auto path =
id(ha_doorbell_entity_picture).state;
return (
!path.empty() &&
path != "unknown" &&
path != "unavailable"
);
then:
- lvgl.label.update:
id: security_camera_status_label
text: "Loading Doorbell..."
- online_image.set_url:
id: security_camera_image
url: !lambda |-
const std::string path =
id(ha_doorbell_entity_picture).state;
std::string url;
if (
path.rfind("http://", 0) == 0 ||
path.rfind("https://", 0) == 0
) {
url = path;
} else {
url =
std::string(
"${home_assistant_internal_url}"
) + path;
}
char suffix[32];
snprintf(
suffix,
sizeof(suffix),
"%ctime=%lu",
url.find('?') == std::string::npos
? '?'
: '&',
static_cast<unsigned long>(millis())
);
return url + suffix;
else:
- lvgl.label.update:
id: security_camera_status_label
text: "Waiting for Doorbell camera"
- id: release_climate_profile_optimistic
mode: restart
then:
@@ -1340,6 +1422,16 @@ interval:
else:
- script.execute: refresh_sleep_timer
- interval: "${security_camera_refresh_interval}"
then:
- if:
condition:
lambda: |-
return id(security_page_active);
then:
- script.execute: refresh_security_camera
#:########################################################################################:#
# TEXT SENSOR COMPONENT:
# https://esphome.io/components/text_sensor/
@@ -1383,6 +1475,23 @@ text_sensor:
then:
- script.execute: refresh_climate_controls
# Home Assistant supplies a short-lived authenticated camera proxy URL in
# the entity_picture attribute. This avoids storing an HA token in firmware.
- platform: homeassistant
id: ha_doorbell_entity_picture
entity_id: "${security_doorbell_camera_entity}"
attribute: entity_picture
internal: true
on_value:
then:
- if:
condition:
lambda: |-
return id(security_page_active);
then:
- script.execute: refresh_security_camera
- platform: version
name: "${friendly_name} ESPHome Version"
hide_timestamp: true
@@ -1400,6 +1509,64 @@ text_sensor:
mac_address:
name: "${friendly_name} MAC Address"
#:########################################################################################:#
# HTTP REQUEST:
# Used by the online Doorbell image
# https://esphome.io/components/http_request/
#:########################################################################################:#
http_request:
timeout: 10s
follow_redirects: true
#:########################################################################################:#
# ONLINE SECURITY CAMERA IMAGE:
# Home Assistant camera proxy image, resized for the Security page
# https://esphome.io/components/image/online_image/
#:########################################################################################:#
image:
- platform: online_image
id: security_camera_image
url: "${home_assistant_internal_url}/"
format: JPEG
type: RGB565
resize: 640x360
update_interval: never
buffer_size: 32768
on_download_finished:
then:
- if:
condition:
lambda: |-
return (
id(lvgl_ready) &&
id(security_page_active)
);
then:
- lvgl.image.update:
id: security_camera_widget
src: security_camera_image
- lvgl.label.update:
id: security_camera_status_label
text: ""
on_error:
then:
- if:
condition:
lambda: |-
return (
id(lvgl_ready) &&
id(security_page_active)
);
then:
- lvgl.label.update:
id: security_camera_status_label
text: "Camera image unavailable"
#:########################################################################################:#
# LVGL:
# https://esphome.io/components/lvgl/
@@ -1427,6 +1594,11 @@ lvgl:
on_idle:
- timeout: "${clock_idle_timeout}"
then:
- lambda: |-
id(security_page_active) = false;
- online_image.release: security_camera_image
- lvgl.page.show:
id: clock_page
animation: FADE_IN
@@ -1863,25 +2035,41 @@ lvgl:
bg_color: 0x34404F
- button:
id: future_2_navigation_button
id: security_navigation_button
x: 612
y: 475
width: 190
height: 92
widgets:
- label:
id: future_2_navigation_button_label
id: security_navigation_button_label
align: CENTER
text: "Future2"
text: "Security"
text_font: font_button
text_color: 0xAEB8C4
bg_color: 0x28313D
text_color: 0xFFFFFF
bg_color: 0x493535
bg_opa: COVER
border_width: 2
border_color: 0x445365
border_color: 0x805858
radius: 16
pressed:
bg_color: 0x34404F
bg_color: 0x654949
on_click:
- lambda: |-
id(security_page_active) = true;
- lvgl.page.show:
id: security_page
animation: MOVE_LEFT
time: 220ms
- light.turn_on:
id: display_backlight
brightness: "${control_brightness}"
transition_length: 250ms
- script.execute: refresh_security_camera
- button:
id: clock_now_button
@@ -2579,6 +2767,200 @@ lvgl:
brightness: "${clock_brightness}"
transition_length: 1500ms
#:####################################################################################:#
# SECURITY PAGE
#:####################################################################################:#
- id: security_page
skip: true
bg_color: 0x0D1218
bg_opa: COVER
widgets:
#:################################################################################:#
# CAMERA SELECTION
#:################################################################################:#
- button:
id: security_doorbell_button
x: 25
y: 18
width: 220
height: 70
bg_color: 0x493535
bg_opa: COVER
border_width: 2
border_color: 0x9A6666
radius: 16
pressed:
bg_color: 0x654949
widgets:
- label:
align: CENTER
text: "Doorbell"
text_font: font_button
text_color: 0xFFFFFF
on_click:
- script.execute: refresh_security_camera
- button:
id: security_camera_2_button
x: 272
y: 18
width: 220
height: 70
bg_color: 0x28313D
bg_opa: COVER
border_width: 2
border_color: 0x445365
radius: 16
widgets:
- label:
align: CENTER
text: "Camera2"
text_font: font_button
text_color: 0x8D98A6
- button:
id: security_camera_3_button
x: 519
y: 18
width: 220
height: 70
bg_color: 0x28313D
bg_opa: COVER
border_width: 2
border_color: 0x445365
radius: 16
widgets:
- label:
align: CENTER
text: "Camera3"
text_font: font_button
text_color: 0x8D98A6
- button:
id: security_camera_4_button
x: 766
y: 18
width: 220
height: 70
bg_color: 0x28313D
bg_opa: COVER
border_width: 2
border_color: 0x445365
radius: 16
widgets:
- label:
align: CENTER
text: "Camera4"
text_font: font_button
text_color: 0x8D98A6
#:################################################################################:#
# 640x360 CAMERA IMAGE
#:################################################################################:#
- obj:
x: 190
y: 98
width: 644
height: 364
bg_color: 0x020304
bg_opa: COVER
border_width: 2
border_color: 0x445365
radius: 13
shadow_width: 0
clickable: false
- image:
id: security_camera_widget
x: 192
y: 100
width: 640
height: 360
src: security_camera_image
radius: 11
clip_corner: true
clickable: false
- label:
id: security_camera_status_label
x: 192
y: 260
width: 640
text: "Waiting for Doorbell camera"
text_font: font_button
text_align: CENTER
text_color: 0xD4D8DE
clickable: false
#:################################################################################:#
# BOTTOM NAVIGATION
#:################################################################################:#
- button:
id: security_back_button
x: 612
y: 475
width: 190
height: 92
bg_color: 0x315843
bg_opa: COVER
border_width: 2
border_color: 0x548C6C
radius: 16
pressed:
bg_color: 0x416F55
widgets:
- label:
align: CENTER
text: "Back"
text_font: font_button
text_color: 0xFFFFFF
on_click:
- lambda: |-
id(security_page_active) = false;
- online_image.release: security_camera_image
- lvgl.page.show:
id: bedroom_page
animation: MOVE_RIGHT
time: 220ms
- button:
id: security_clock_button
x: 810
y: 475
width: 190
height: 92
bg_color: 0x214F72
bg_opa: COVER
border_width: 2
border_color: 0x3E7FA7
radius: 16
pressed:
bg_color: 0x2E6A96
widgets:
- label:
align: CENTER
text: "Clock"
text_font: font_button
text_color: 0xFFFFFF
on_click:
- lambda: |-
id(security_page_active) = false;
- online_image.release: security_camera_image
- lvgl.page.show:
id: clock_page
animation: FADE_IN
time: 250ms
- light.turn_on:
id: display_backlight
brightness: "${clock_brightness}"
transition_length: 1500ms
#:####################################################################################:#
# CLOCK PAGE
#:####################################################################################:#