esphome: name: lilka friendly_name: lilka on_boot: priority: 600 then: - output.turn_on: display_power - delay: 100ms esp32: board: esp32-s3-devkitc-1 framework: type: esp-idf logger: api: encryption: key: "Yw3yq8lxsaze+jdggjAwxKpV4GD6gNZptvw4d6OPfOc=" ota: - platform: esphome password: "bb198feb99159fdaefc8092f10039acd" wifi: ssid: !secret wifi_ssid password: !secret wifi_password ap: ssid: "Lilka Fallback Hotspot" password: "hnYImYM4O6I0" captive_portal: # Веб-сервер web_server: port: 80 # Увімкнення живлення дисплея output: - platform: gpio pin: 46 id: display_power inverted: false # Сенсор батареї sensor: - platform: adc pin: GPIO3 name: "Battery Voltage" id: battery_voltage update_interval: 10s attenuation: 12db filters: - multiply: 1.33 - platform: template name: "Battery Level" id: battery_level unit_of_measurement: "%" accuracy_decimals: 0 update_interval: 10s lambda: |- float voltage = id(battery_voltage).state; float percent = (voltage - 3.0) / (4.2 - 3.0) * 100.0; if (percent > 100) percent = 100; if (percent < 0) percent = 0; return percent; # SPI шина spi: clk_pin: 18 mosi_pin: 17 # Дисплей ST7789V display: - platform: mipi_spi model: ST7789V id: my_display dc_pin: 15 cs_pin: 7 update_interval: 1s rotation: 270 invert_colors: true color_order: BGR pixel_mode: 16bit dimensions: width: 280 height: 240 offset_width: 20 offset_height: 0 auto_clear_enabled: false # LVGL - з чорним фоном lvgl: log_level: INFO style_definitions: - id: default_style bg_color: 0x000000 text_color: 0xFFFFFF - id: focused_style border_color: 0xFFFFFF border_width: 3 outline_color: 0xFFFFFF outline_width: 2 pages: - id: main_page bg_color: 0x000000 widgets: # Червона кнопка - Battery % - button: id: red_button align: CENTER y: -40 width: 180 height: 50 bg_color: 0xFF0000 # Червоний widgets: - label: id: battery_label text: "Battery: --" align: CENTER text_color: 0xFFFFFF # Зелена кнопка - Voltage - button: id: green_button align: CENTER y: 20 width: 180 height: 50 bg_color: 0x00FF00 # Зелений widgets: - label: id: voltage_label text: "Voltage: --" align: CENTER text_color: 0x000000 # Синя кнопка - Lilka LVGL - button: id: blue_button align: CENTER y: 80 width: 180 height: 50 bg_color: 0x0000FF # Синій widgets: - label: text: "Lilka LVGL" align: CENTER text_color: 0xFFFFFF # Глобальна змінна для відстеження поточної кнопки globals: - id: current_button_index type: int restore_value: no initial_value: '0' # Кнопки керування binary_sensor: - platform: gpio pin: number: 38 mode: INPUT_PULLUP inverted: true name: "Button Up" id: button_up filters: - delayed_on_off: 50ms on_press: - lambda: |- id(current_button_index) -= 1; if (id(current_button_index) < 0) id(current_button_index) = 2; # Прибираємо обводку з усіх кнопок - lvgl.widget.update: id: red_button border_width: 0 - lvgl.widget.update: id: green_button border_width: 0 - lvgl.widget.update: id: blue_button border_width: 0 # Додаємо обводку до вибраної - if: condition: lambda: 'return id(current_button_index) == 0;' then: - lvgl.widget.update: id: red_button border_width: 3 border_color: 0xFFFFFF - if: condition: lambda: 'return id(current_button_index) == 1;' then: - lvgl.widget.update: id: green_button border_width: 3 border_color: 0xFFFFFF - if: condition: lambda: 'return id(current_button_index) == 2;' then: - lvgl.widget.update: id: blue_button border_width: 3 border_color: 0xFFFFFF - platform: gpio pin: number: 41 mode: INPUT_PULLUP inverted: true name: "Button Down" id: button_down filters: - delayed_on_off: 50ms on_press: - lambda: |- id(current_button_index) += 1; if (id(current_button_index) > 2) id(current_button_index) = 0; # Прибираємо обводку з усіх кнопок - lvgl.widget.update: id: red_button border_width: 0 - lvgl.widget.update: id: green_button border_width: 0 - lvgl.widget.update: id: blue_button border_width: 0 # Додаємо обводку до вибраної - if: condition: lambda: 'return id(current_button_index) == 0;' then: - lvgl.widget.update: id: red_button border_width: 3 border_color: 0xFFFFFF - if: condition: lambda: 'return id(current_button_index) == 1;' then: - lvgl.widget.update: id: green_button border_width: 3 border_color: 0xFFFFFF - if: condition: lambda: 'return id(current_button_index) == 2;' then: - lvgl.widget.update: id: blue_button border_width: 3 border_color: 0xFFFFFF - platform: gpio pin: number: 39 mode: INPUT_PULLUP inverted: true name: "Button Left" id: button_left filters: - delayed_on_off: 50ms - platform: gpio pin: number: 40 mode: INPUT_PULLUP inverted: true name: "Button Right" id: button_right filters: - delayed_on_off: 50ms - platform: gpio pin: number: 5 mode: INPUT_PULLUP inverted: true name: "Button A" id: button_a filters: - delayed_on_off: 50ms - platform: gpio pin: number: 6 mode: INPUT_PULLUP inverted: true name: "Button B" id: button_b filters: - delayed_on_off: 50ms - platform: gpio pin: number: 10 mode: INPUT_PULLUP inverted: true name: "Button C" id: button_c filters: - delayed_on_off: 50ms - platform: gpio pin: number: 9 mode: INPUT_PULLUP inverted: true name: "Button D" id: button_d filters: - delayed_on_off: 50ms - platform: gpio pin: number: 4 mode: INPUT_PULLUP inverted: true name: "Button Start" id: button_start filters: - delayed_on_off: 50ms - platform: gpio pin: number: 0 mode: INPUT_PULLUP inverted: true name: "Button Select" id: button_select filters: - delayed_on_off: 50ms # Оновлення даних на кнопках interval: - interval: 5s then: - lvgl.label.update: id: battery_label text: !lambda |- return std::string("Battery: ") + to_string((int)id(battery_level).state) + "%"; - lvgl.label.update: id: voltage_label text: !lambda |- char buf[20]; snprintf(buf, sizeof(buf), "Voltage: %.2fV", id(battery_voltage).state); return std::string(buf);