Edit esp-bedside-panel.yaml

This commit is contained in:
ESPHome Device Builder
2026-07-28 18:00:54 +12:00
parent b268b3cbf9
commit adb533d6a3
+266 -15
View File
@@ -6,6 +6,7 @@
# https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-bedside-panel.yaml # https://home.fox.co.nz/gitea/zorruno/zorruno-homeassistant/src/branch/master/esphome/esp-bedside-panel.yaml
#:########################################################################################:# #:########################################################################################:#
# VERSIONS: # VERSIONS:
# V1.49 2026-07-28 Calibrated battery voltage, added approximate charge level and a subtle Clock-page battery indicator
# V1.48 2026-07-28 Added raw onboard battery ADC voltage monitoring on GPIO53 for divider calibration # V1.48 2026-07-28 Added raw onboard battery ADC voltage monitoring on GPIO53 for divider calibration
# V1.47 2026-07-20 Widened the alarm volume range while retaining 5-100% controls and the proven 6000 Hz tone # V1.47 2026-07-20 Widened the alarm volume range while retaining 5-100% controls and the proven 6000 Hz tone
# V1.46 2026-07-20 Raised the alarm tone to 6000 Hz, limited volume to 5-100%, and remapped 100% to the previous displayed 30% level # V1.46 2026-07-20 Raised the alarm tone to 6000 Hz, limited volume to 5-100%, and remapped 100% to the previous displayed 30% level
@@ -112,6 +113,7 @@
# - ES8311 audio codec: I2C address 0x18 # - ES8311 audio codec: I2C address 0x18
# - Audio I2S: MCLK GPIO13, BCLK GPIO12, LRCLK GPIO10, DOUT GPIO9 # - Audio I2S: MCLK GPIO13, BCLK GPIO12, LRCLK GPIO10, DOUT GPIO9
# - Speaker amplifier enable: GPIO11 (active high on this board revision) # - Speaker amplifier enable: GPIO11 (active high on this board revision)
# - Main battery voltage sense: GPIO53 / ADC, calibrated multiplier 1.6667
#:########################################################################################:# #:########################################################################################:#
# OPERATION NOTES: # OPERATION NOTES:
# - This build returns to the proven V0.8a structure. # - This build returns to the proven V0.8a structure.
@@ -158,8 +160,10 @@
# - Beep is a short 6000 Hz electronic tone. # - Beep is a short 6000 Hz electronic tone.
# - Alarm repeats a quick 6000 Hz beep-beep-beep group followed by a pause. # - Alarm repeats a quick 6000 Hz beep-beep-beep group followed by a pause.
# - Speaker tests generate audio locally and do not require Home Assistant or media files. # - Speaker tests generate audio locally and do not require Home Assistant or media files.
# - Raw battery-sense ADC voltage is exposed from GPIO53 for calibration. # - GPIO53 exposes both raw ADC voltage and calibrated main-battery voltage.
# - No battery divider multiplier or percentage estimate is applied in this test version. # - Battery percentage is an approximate voltage-based estimate for a single 18650 cell.
# - The Clock page shows a subtle battery icon and percentage while on battery.
# - When USB power is inferred, the Clock page shows only a full battery icon.
#:########################################################################################:# #:########################################################################################:#
# OFFLINE NOTES: # OFFLINE NOTES:
# - LVGL, the clock, touch and backlight operate locally. # - LVGL, the clock, touch and backlight operate locally.
@@ -178,12 +182,12 @@ substitutions:
# Device Naming # Device Naming
device_name: "esp-bedside-panel" device_name: "esp-bedside-panel"
friendly_name: "ESP Bedside Panel" friendly_name: "ESP Bedside Panel"
description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside panel with four alarms, local speaker tests, battery ADC monitoring and a 24-hour time editor. (Layout V1.1)" description_comment: "Guition JC1060P470C_I_W_Y ESP32-P4 bedside panel with four alarms, calibrated battery monitoring, Clock-page battery status and 24-hour alarm editing. (Layout V1.1)"
device_area: "Bedroom" device_area: "Bedroom"
# Project Naming # Project Naming
project_name: "Guition.JC1060P470C_I_W_Y" project_name: "Guition.JC1060P470C_I_W_Y"
project_version: "v1.48" project_version: "v1.49"
# Passwords & Secrets # Passwords & Secrets
api_key: !secret esp-api_key api_key: !secret esp-api_key
@@ -203,11 +207,25 @@ substitutions:
ambient_light_pin: "GPIO20" ambient_light_pin: "GPIO20"
ambient_light_update_interval: "1s" ambient_light_update_interval: "1s"
# Battery Voltage Test Settings # Battery Monitoring Settings
# GPIO53 is connected to the board battery-sense circuit. The raw ADC # GPIO53 is connected to the board's main battery-sense divider.
# voltage is published first so the onboard divider can be calibrated. # Testing gave 2.369 V at the ADC for approximately 3.95 V at the cell and
# 2.520 V at the ADC for approximately 4.20 V while charging. This supports
# a divider multiplier of 5/3, or 1.6667.
battery_voltage_pin: "GPIO53" battery_voltage_pin: "GPIO53"
battery_voltage_update_interval: "5s" battery_voltage_update_interval: "5s"
battery_voltage_multiplier: "1.6667"
# No dedicated VBUS-status GPIO has been confirmed for this board revision.
# USB presence is therefore inferred from a sustained battery-voltage rise,
# a charge-end voltage, or a clear voltage drop when USB is removed.
battery_usb_detect_rise_threshold: "0.006"
battery_usb_detect_rise_samples: "2"
battery_usb_disconnect_drop_threshold: "0.025"
battery_usb_full_threshold: "4.17"
battery_usb_stable_voltage_threshold: "4.10"
battery_usb_stable_delta_threshold: "0.002"
battery_usb_stable_samples: "4"
# Touchscreen Settings # Touchscreen Settings
touch_sda_pin: "GPIO7" touch_sda_pin: "GPIO7"
@@ -448,6 +466,7 @@ esphome:
- script.execute: refresh_jobs_page - script.execute: refresh_jobs_page
- script.execute: refresh_alarm_clock_page - script.execute: refresh_alarm_clock_page
- script.execute: refresh_alarm_audio_controls - script.execute: refresh_alarm_audio_controls
- script.execute: refresh_clock_battery_indicator
#:########################################################################################:# #:########################################################################################:#
# ESP PLATFORM AND FRAMEWORK: # ESP PLATFORM AND FRAMEWORK:
@@ -1108,17 +1127,20 @@ sensor:
update_interval: "${update_interval}" update_interval: "${update_interval}"
#:######################################################################################:# #:######################################################################################:#
# INTERNAL BATTERY ADC VOLTAGE # # MAIN BATTERY MONITORING #
#:######################################################################################:# #:######################################################################################:#
# #
# GPIO53 is connected to the JC1060P470 battery-sense circuit. # GPIO53 is connected to the JC1060P470 battery-sense divider. The raw ADC
# reading remains available for diagnostics. A calibrated copy applies the
# tested 1.6667 multiplier to estimate the actual 18650 terminal voltage.
# #
# This sensor intentionally reports the raw voltage present at the ADC pin. # Percentage is estimated from a piecewise single-cell Li-ion voltage curve.
# Do not treat it as the actual 18650 voltage until it has been compared with # It is intentionally approximate because voltage changes with load, charge
# a multimeter and the board's voltage-divider ratio has been established. # current, cell age and temperature.
# #
# The ADC samples every five seconds. A rolling median is published every # No confirmed board pin directly reports USB/VBUS presence. The external
# third sample, giving a new filtered value approximately every 15 seconds. # power state is inferred from sustained voltage rise, charge-end voltage and
# the clear voltage drop normally seen when USB power is removed.
- platform: adc - platform: adc
id: battery_adc_voltage id: battery_adc_voltage
@@ -1130,7 +1152,7 @@ sensor:
device_class: voltage device_class: voltage
state_class: measurement state_class: measurement
unit_of_measurement: "V" unit_of_measurement: "V"
icon: mdi:battery icon: mdi:battery-outline
entity_category: diagnostic entity_category: diagnostic
filters: filters:
- median: - median:
@@ -1138,6 +1160,139 @@ sensor:
send_every: 3 send_every: 3
send_first_at: 1 send_first_at: 1
- platform: copy
id: battery_voltage
name: "${friendly_name} Battery Voltage"
source_id: battery_adc_voltage
accuracy_decimals: 2
device_class: voltage
state_class: measurement
unit_of_measurement: "V"
icon: mdi:battery
filters:
- multiply: "${battery_voltage_multiplier}"
on_value:
then:
- lambda: |-
if (isnan(x)) {
return;
}
const float previous = id(battery_previous_voltage);
bool external_power = id(battery_external_power_present);
if (!isnan(previous)) {
const float delta = x - previous;
if (delta <= -${battery_usb_disconnect_drop_threshold}f) {
// A clear downward step is the most dependable indication
// that USB power has just been removed.
external_power = false;
id(battery_voltage_rise_samples) = 0;
id(battery_voltage_stable_samples) = 0;
} else if (delta >= ${battery_usb_detect_rise_threshold}f) {
// Require more than one rising sample so normal ADC noise does
// not make the Clock page claim that USB is connected.
if (id(battery_voltage_rise_samples) < 255) {
id(battery_voltage_rise_samples)++;
}
id(battery_voltage_stable_samples) = 0;
if (
id(battery_voltage_rise_samples) >=
${battery_usb_detect_rise_samples}
) {
external_power = true;
}
} else {
id(battery_voltage_rise_samples) = 0;
// If a previously inferred charging state becomes flat at a
// voltage well below charge-end, release it after four samples.
// This is mainly a recovery path for a missed unplug transition.
if (
external_power &&
x < ${battery_usb_stable_voltage_threshold}f &&
fabsf(delta) <= ${battery_usb_stable_delta_threshold}f
) {
if (id(battery_voltage_stable_samples) < 255) {
id(battery_voltage_stable_samples)++;
}
if (
id(battery_voltage_stable_samples) >=
${battery_usb_stable_samples}
) {
external_power = false;
id(battery_voltage_stable_samples) = 0;
}
} else {
id(battery_voltage_stable_samples) = 0;
}
}
}
// Near charge-end, show the full icon. A freshly charged cell that
// is booted directly on battery can also meet this threshold, which
// is harmless because the cell is genuinely full at that point.
if (x >= ${battery_usb_full_threshold}f) {
external_power = true;
}
id(battery_previous_voltage) = x;
id(battery_external_power_present) = external_power;
id(battery_external_power).publish_state(external_power);
// Piecewise voltage-to-percentage approximation for a single
// 4.20 V Li-ion cell. Interpolate between the surrounding points.
static const float voltage_points[] = {
3.30f, 3.50f, 3.60f, 3.70f, 3.75f, 3.80f, 3.85f,
3.90f, 3.95f, 4.00f, 4.05f, 4.10f, 4.15f, 4.20f
};
static const float percentage_points[] = {
0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f,
60.0f, 70.0f, 80.0f, 88.0f, 94.0f, 98.0f, 100.0f
};
constexpr size_t point_count =
sizeof(voltage_points) / sizeof(voltage_points[0]);
float percentage = 0.0f;
if (x <= voltage_points[0]) {
percentage = percentage_points[0];
} else if (x >= voltage_points[point_count - 1]) {
percentage = percentage_points[point_count - 1];
} else {
for (size_t i = 1; i < point_count; i++) {
if (x <= voltage_points[i]) {
const float position =
(x - voltage_points[i - 1]) /
(voltage_points[i] - voltage_points[i - 1]);
percentage =
percentage_points[i - 1] +
position *
(percentage_points[i] - percentage_points[i - 1]);
break;
}
}
}
percentage = fminf(fmaxf(percentage, 0.0f), 100.0f);
id(battery_level_percent).publish_state(percentage);
- script.execute: refresh_clock_battery_indicator
- platform: template
id: battery_level_percent
name: "${friendly_name} Battery Level"
device_class: battery
state_class: measurement
unit_of_measurement: "%"
accuracy_decimals: 0
icon: mdi:battery
update_interval: never
#:######################################################################################:# #:######################################################################################:#
# TEMT6000 AMBIENT LIGHT SENSOR # TEMT6000 AMBIENT LIGHT SENSOR
#:######################################################################################:# #:######################################################################################:#
@@ -1501,6 +1656,16 @@ sensor:
# Imported states used to colour LVGL buttons # Imported states used to colour LVGL buttons
#:########################################################################################:# #:########################################################################################:#
binary_sensor: binary_sensor:
#:######################################################################################:#
# BATTERY / EXTERNAL POWER STATUS #
#:######################################################################################:#
- platform: template
id: battery_external_power
name: "${friendly_name} USB Power Estimated"
device_class: plug
icon: mdi:power-plug
entity_category: diagnostic
#:######################################################################################:# #:######################################################################################:#
# ATTO 3 BINARY STATES # ATTO 3 BINARY STATES
#:######################################################################################:# #:######################################################################################:#
@@ -1759,6 +1924,29 @@ globals:
restore_value: false restore_value: false
initial_value: "1" initial_value: "1"
#:######################################################################################:#
# MAIN BATTERY STATUS #
#:######################################################################################:#
- id: battery_previous_voltage
type: float
restore_value: false
initial_value: "NAN"
- id: battery_external_power_present
type: bool
restore_value: false
initial_value: "false"
- id: battery_voltage_rise_samples
type: uint8_t
restore_value: false
initial_value: "0"
- id: battery_voltage_stable_samples
type: uint8_t
restore_value: false
initial_value: "0"
#:######################################################################################:# #:######################################################################################:#
# ALARM CLOCK SETTINGS # ALARM CLOCK SETTINGS
#:######################################################################################:# #:######################################################################################:#
@@ -1836,6 +2024,44 @@ globals:
# Refresh all state-dependent LVGL button colours # Refresh all state-dependent LVGL button colours
#:########################################################################################:# #:########################################################################################:#
script: script:
#:######################################################################################:#
# CLOCK PAGE BATTERY INDICATOR #
#:######################################################################################:#
- id: refresh_clock_battery_indicator
mode: restart
then:
- if:
condition:
lambda: |-
return id(lvgl_ready);
then:
- lvgl.label.update:
id: clock_battery_icon_label
text: "\U000F0079"
- lvgl.label.update:
id: clock_battery_percent_label
text: !lambda |-
if (id(battery_external_power_present)) {
return std::string("");
}
const float percentage = id(battery_level_percent).state;
if (isnan(percentage)) {
return std::string("--%");
}
char buffer[12];
snprintf(
buffer,
sizeof(buffer),
"%.0f%%",
percentage
);
return std::string(buffer);
#:######################################################################################:# #:######################################################################################:#
# ALARM CLOCK PAGE STATE REFRESH # ALARM CLOCK PAGE STATE REFRESH
#:######################################################################################:# #:######################################################################################:#
@@ -11678,6 +11904,31 @@ lvgl:
text_color: 0xE4DDD2 text_color: 0xE4DDD2
clickable: false clickable: false
# Subtle battery status in the top-right corner.
# On battery: icon plus approximate percentage.
# With inferred USB power: full battery icon only.
- label:
id: clock_battery_icon_label
x: 912
y: 20
width: 30
text: "\U000F0079"
text_font: font_mdi_vehicle
text_align: CENTER
text_color: 0x686D73
clickable: false
- label:
id: clock_battery_percent_label
x: 944
y: 24
width: 62
text: "--%"
text_font: font_small
text_align: LEFT
text_color: 0x686D73
clickable: false
- label: - label:
id: clock_date_label id: clock_date_label
align: TOP_MID align: TOP_MID