diff --git a/kinderhandy.yaml b/kinderhandy.yaml new file mode 100644 index 0000000..b107f36 --- /dev/null +++ b/kinderhandy.yaml @@ -0,0 +1,226 @@ +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: 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_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' + +# ============================================================ +# Display +# ============================================================ + +lvgl: + 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" + else: + - globals.set: + id: timer_running + value: 'true' + - logger.log: + format: "Gestartet" + 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 +