Files
esphome/kinderhandy.yaml

273 lines
7.3 KiB
YAML

# TODO:
# - auto turn off
# - navigation bar at bottom
# - buttons for home assistant actions
substitutions:
device_name: kinderhandy
friendly_name: Kinder Handy
esphome:
name: $device_name
friendly_name: $friendly_name
esp32:
board: esp32dev
framework:
type: arduino
logger:
api:
encryption:
key: !secret api_encryption_key
wifi:
ssid: WLAN
password: !secret wifi_password
# ============================================================
# Hardware
# ============================================================
light:
- platform: monochromatic
output: backlight_pwm
name: Display Backlight
id: display_backlight
restore_mode: ALWAYS_ON
spi:
- id: tft
clk_pin: GPIO14
mosi_pin: GPIO13
miso_pin: GPIO12
- id: touch
clk_pin: GPIO25
mosi_pin: GPIO32
miso_pin: GPIO39
# Setup a pin to control the backlight
output:
- platform: ledc
pin: GPIO21
id: backlight_pwm
display:
- platform: ili9xxx
model: ili9341
spi_id: tft
cs_pin: GPIO15
dc_pin: GPIO2
invert_colors: false
color_palette: 8BIT
# Set up the xpt2046 touch platform
touchscreen:
platform: xpt2046
spi_id: touch
cs_pin: GPIO33
interrupt_pin: GPIO36
update_interval: never
threshold: 400
calibration:
x_min: 280
x_max: 3850
y_min: 190
y_max: 3765
transform:
swap_xy: false
mirror_x: true
on_release:
- if:
condition: lvgl.is_paused
then:
- logger.log: "LVGL resuming"
- lvgl.resume:
- lvgl.widget.redraw:
- light.turn_on: display_backlight
# on_touch:
# - lambda: |-
# ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
# touch.x,
# touch.y,
# touch.x_raw,
# touch.y_raw
# );
# ============================================================
# Globals
# ============================================================
globals:
- id: timer_seconds
type: int
initial_value: '120'
- id: timer_running
type: bool
initial_value: 'false'
# ============================================================
# Variables
# ============================================================
number:
- platform: template
name: LVGL Screen timeout
optimistic: true
id: display_timeout
unit_of_measurement: "s"
initial_value: 45
restore_value: true
min_value: 10
max_value: 180
step: 5
mode: box
# ============================================================
# Display
# ============================================================
lvgl:
on_idle:
timeout: !lambda "return (id(display_timeout).state * 1000);"
then:
- logger.log: "LVGL is idle"
- light.turn_off: display_backlight
- lvgl.pause:
buffer_size: 50%
widgets:
- label:
align: TOP_MID
y: 10
text: "Lukas und Hannas\nZahnputz Timer"
text_font: montserrat_20
- container:
id: arc_container
align: CENTER
y: 20
width: 240
height: 240
on_press:
then:
- if:
condition:
lambda: 'return id(timer_running);'
then:
- globals.set:
id: timer_running
value: 'false'
- logger.log:
format: "Pause"
- lvgl.arc.update:
id: arc_timer
indicator:
arc_color: 0x0000EE
else:
- globals.set:
id: timer_running
value: 'true'
- logger.log:
format: "Gestartet"
- lvgl.arc.update:
id: arc_timer
value: !lambda return id(timer_seconds);
indicator:
arc_color: 0xFF0000
on_long_press:
then:
- globals.set:
id: timer_seconds
value: '120'
- globals.set:
id: timer_running
value: 'false'
- lvgl.arc.update:
id: arc_timer
value: 0
indicator:
arc_color: 0xFF0000
- lvgl.label.update:
id: timer_label
text: !lambda 'return std::string("02:00");'
- logger.log:
format: "Timer reset (long press)"
widgets:
- arc:
id: arc_timer
align: CENTER
width: 220
height: 220
min_value: 0
max_value: 120
value: 0
arc_width: 8
arc_color: 0x404040
# Indicator arc styling (the progress)
indicator:
arc_width: 20
arc_opa: COVER
arc_color: 0xFF0000 # Start with red
- label:
id: timer_label
align: CENTER
text_font: montserrat_28
text: "02:00"
interval:
- interval: 1s
then:
- if:
condition:
lambda: 'return id(timer_running);'
then:
- globals.set:
id: timer_seconds
value: !lambda 'return max(0, (int)id(timer_seconds) - 1);'
- lvgl.arc.update:
id: arc_timer
value: !lambda 'return (int)(id(timer_seconds));'
indicator:
arc_color: !lambda |
float f = (120.0 - (float)id(timer_seconds)) / 120.0;
if (f < 0) f = 0;
if (f > 1) f = 1;
if (f <= 0.5) {
// Red to Yellow (f: 0.0 to 0.5)
float t = f / 0.5;
int r = 255;
int g = (int)(255 * t + 0.5);
int b = 0;
int hex = (r << 16) | (g << 8) | b;
return lv_color_hex(hex);
} else {
// Yellow to Green (f: 0.5 to 1.0)
float t = (f - 0.5) / 0.5;
int r = (int)(255 * (1.0 - t) + 0.5);
int g = 255;
int b = 0;
int hex = (r << 16) | (g << 8) | b;
return lv_color_hex(hex);
}
- lambda: |-
ESP_LOGI("timer", "timer_seconds=%d fraction=%.2f", id(timer_seconds), (float)id(timer_seconds)/120.0);
- lvgl.label.update:
id: timer_label
text: !lambda 'char buf[6]; sprintf(buf, "%02d:%02d", id(timer_seconds)/60, id(timer_seconds)%60); return std::string(buf);'
- if:
condition:
lambda: 'return id(timer_seconds) <= 0;'
then:
- globals.set:
id: timer_running
value: 'false'
- logger.log:
format: "Timer finished"
- lvgl.arc.update:
id: arc_timer
value: 120
indicator:
arc_color: 0x00FF00