521 lines
13 KiB
YAML
521 lines
13 KiB
YAML
esphome:
|
|
name: "panel"
|
|
friendly_name: "Panely"
|
|
platformio_options:
|
|
board_build.flash_mode: dio
|
|
|
|
esp32:
|
|
board: esp32-s3-devkitc-1
|
|
variant: esp32s3
|
|
flash_size: 16MB
|
|
framework:
|
|
type: esp-idf
|
|
sdkconfig_options:
|
|
COMPILER_OPTIMIZATION_SIZE: y
|
|
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: "y"
|
|
CONFIG_ESP32S3_DATA_CACHE_64KB: "y"
|
|
CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y"
|
|
CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
|
|
CONFIG_SPIRAM_RODATA: y
|
|
|
|
psram:
|
|
mode: octal
|
|
speed: 80MHz
|
|
|
|
# Enable logging
|
|
logger:
|
|
|
|
# Enable Home Assistant API
|
|
api:
|
|
|
|
|
|
ota:
|
|
platform: esphome
|
|
|
|
wifi:
|
|
ssid: "DNTD"
|
|
password: "wifipassword"
|
|
ap:
|
|
ssid: "Panel"
|
|
password: "wifipassword"
|
|
|
|
time:
|
|
- platform: homeassistant
|
|
id: time_comp
|
|
on_time_sync:
|
|
- script.execute: time_update
|
|
on_time:
|
|
- minutes: '*'
|
|
seconds: 0
|
|
then:
|
|
- script.execute: time_update
|
|
|
|
script:
|
|
- id: time_update
|
|
# update the clock display
|
|
then:
|
|
- lvgl.indicator.update:
|
|
id: minute_hand
|
|
value: !lambda |-
|
|
return id(time_comp).now().minute;
|
|
- lvgl.indicator.update:
|
|
id: hour_hand
|
|
value: !lambda |-
|
|
auto now = id(time_comp).now();
|
|
return std::fmod(now.hour, 12) * 60 + now.minute;
|
|
- lvgl.label.update:
|
|
id: date_label
|
|
text: !lambda |-
|
|
static const char * const mon_names[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
|
|
static char date_buf[8];
|
|
auto now = id(time_comp).now();
|
|
snprintf(date_buf, sizeof(date_buf), "%s %2d", mon_names[now.month-1], now.day_of_month);
|
|
return date_buf;
|
|
- lvgl.label.update:
|
|
id: day_label
|
|
text: !lambda |-
|
|
static const char * const day_names[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
|
|
return day_names[id(time_comp).now().day_of_week - 1];
|
|
|
|
web_server:
|
|
port: 80
|
|
|
|
captive_portal:
|
|
|
|
sensor:
|
|
- platform: wifi_signal
|
|
name: "WiFi Signal"
|
|
id: wifi_signal_db
|
|
update_interval: 60s
|
|
entity_category: diagnostic
|
|
internal: true
|
|
|
|
# Reports the WiFi signal strength in %
|
|
- platform: copy
|
|
source_id: wifi_signal_db
|
|
name: "WiFi Strength"
|
|
filters:
|
|
- lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
|
|
unit_of_measurement: "%"
|
|
entity_category: diagnostic
|
|
|
|
text_sensor:
|
|
- platform: wifi_info
|
|
ip_address:
|
|
name: "IP Address"
|
|
id: ip_address
|
|
entity_category: diagnostic
|
|
on_value:
|
|
then:
|
|
- lvgl.label.update:
|
|
id: ip_address_label
|
|
text:
|
|
format: "%s"
|
|
args: [ 'id(ip_address).get_state().c_str()' ]
|
|
ssid:
|
|
name: "Connected SSID"
|
|
entity_category: diagnostic
|
|
mac_address:
|
|
name: "Mac Address"
|
|
entity_category: diagnostic
|
|
|
|
color:
|
|
# Create a Home Assistant blue color
|
|
- id: ha_blue
|
|
hex: 51c0f2
|
|
|
|
#-------------------------------------------
|
|
# LVGL Buttons
|
|
#-------------------------------------------
|
|
lvgl:
|
|
id: lvgl_comp
|
|
displays:
|
|
- my_display
|
|
touchscreens:
|
|
- touchscreen_id: my_touchscreen
|
|
on_idle:
|
|
- timeout: 10s
|
|
then:
|
|
- logger.log: idle timeout
|
|
- if:
|
|
condition:
|
|
lvgl.is_idle:
|
|
timeout: 5s
|
|
then:
|
|
- logger.log: LVGL is idle
|
|
- timeout: 15s
|
|
then:
|
|
- logger.log: idle 15s timeout
|
|
- light.turn_off:
|
|
id: backlight
|
|
transition_length: 5s
|
|
- lvgl.pause:
|
|
show_snow: true
|
|
#- lvgl.pause:
|
|
#- light.turn_off:
|
|
# id: display_backlight
|
|
# transition_length: 5s
|
|
|
|
style_definitions:
|
|
- id: style_line
|
|
line_color: 0x0000FF
|
|
line_width: 8
|
|
line_rounded: true
|
|
- id: date_style
|
|
text_font: roboto24
|
|
align: center
|
|
text_color: 0x333333
|
|
bg_opa: cover
|
|
radius: 4
|
|
pad_all: 2
|
|
|
|
theme:
|
|
button:
|
|
text_font: roboto24
|
|
scroll_on_focus: true
|
|
#group: general
|
|
radius: 25
|
|
width: 150
|
|
height: 109
|
|
pad_left: 10px
|
|
pad_top: 10px
|
|
pad_bottom: 10px
|
|
pad_right: 10px
|
|
shadow_width: 0
|
|
bg_color: 0x313131
|
|
text_color: 0xB6B6B6
|
|
checked:
|
|
bg_color: 0xCC5E14
|
|
text_color: 0xB6B6B6
|
|
|
|
page_wrap: true
|
|
pages:
|
|
- id: main_page
|
|
skip: false
|
|
layout:
|
|
type: flex
|
|
flex_flow: column_wrap
|
|
width: 100%
|
|
bg_color: 0x000000
|
|
bg_opa: cover
|
|
pad_all: 5
|
|
widgets:
|
|
- button:
|
|
height: 223
|
|
checkable: true
|
|
id: lv_button_1
|
|
widgets:
|
|
- label:
|
|
text_font: light40
|
|
align: top_left
|
|
text: $lightbulb
|
|
id: lv_button_1_icon
|
|
- label:
|
|
align: bottom_left
|
|
text: "Center Light"
|
|
long_mode: dot
|
|
on_click:
|
|
light.toggle: internal_light
|
|
- obj:
|
|
widgets:
|
|
- label:
|
|
id: ip_address_label
|
|
align: CENTER
|
|
text: 'Not connected'
|
|
text_color: ha_blue
|
|
y: +10
|
|
- meter:
|
|
height: 200
|
|
width: 200
|
|
align: center
|
|
widgets:
|
|
bg_opa: TRANSP
|
|
text_color: 0xFFFFFF
|
|
scales:
|
|
- ticks:
|
|
width: 1
|
|
count: 61
|
|
length: 10
|
|
color: 0xFFFFFF
|
|
range_from: 0
|
|
range_to: 60
|
|
angle_range: 360
|
|
rotation: 270
|
|
indicators:
|
|
- line:
|
|
id: minute_hand
|
|
value: !lambda |-
|
|
return id(time_comp).now().minute;
|
|
width: 3
|
|
color: 0xE0E0E0
|
|
r_mod: -1
|
|
-
|
|
angle_range: 330
|
|
rotation: 300
|
|
range_from: 1
|
|
range_to: 12
|
|
ticks:
|
|
width: 1
|
|
count: 12
|
|
length: 1
|
|
major:
|
|
stride: 1
|
|
width: 4
|
|
length: 8
|
|
color: 0xC0C0C0
|
|
label_gap: 6
|
|
|
|
- angle_range: 360
|
|
rotation: 270
|
|
range_from: 0
|
|
range_to: 720
|
|
indicators:
|
|
- line:
|
|
id: hour_hand
|
|
value: !lambda |-
|
|
auto now = id(time_comp).now();
|
|
return std::fmod(now.hour, 12) * 60 + now.minute;
|
|
width: 4
|
|
color: 0xA0A0A0
|
|
r_mod: -20
|
|
- obj:
|
|
widgets:
|
|
- label:
|
|
styles: date_style
|
|
id: day_label
|
|
y: -20
|
|
text: !lambda |-
|
|
static const char * const day_names[] = {"SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"};
|
|
return day_names[id(time_comp).now().day_of_week-1];
|
|
- label:
|
|
styles: date_style
|
|
id: date_label
|
|
y: +20
|
|
text: !lambda |-
|
|
static const char * const mon_names[] = {"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
|
|
static char date_buf[8];
|
|
auto now = id(time_comp).now();
|
|
snprintf(date_buf, sizeof(date_buf), "%s %2d", mon_names[now.month-1], now.day_of_month);
|
|
return date_buf;
|
|
- obj:
|
|
id: popup_obj
|
|
hidden: true
|
|
clickable: false
|
|
x: 0
|
|
y: 0
|
|
width: 100%
|
|
height: 100%
|
|
pad_all: 10
|
|
bg_opa: cover
|
|
widgets:
|
|
- label:
|
|
id: lbl_popup_title
|
|
x: 2
|
|
y: 2
|
|
text: "OTA in progress"
|
|
- label:
|
|
id: popup_lbl_percentage
|
|
x: 2
|
|
y: 30
|
|
width: 100%
|
|
text: "0 %"
|
|
- bar:
|
|
id: popup_pb_percentage
|
|
x: 2
|
|
y: 60
|
|
width: 100%
|
|
height: 10
|
|
max_value: 100
|
|
min_value: 0
|
|
value: 0
|
|
|
|
|
|
#-------------------------------------------
|
|
# Internal outputs
|
|
#-------------------------------------------
|
|
output:
|
|
# Backlight LED
|
|
- platform: ledc
|
|
pin: GPIO38
|
|
id: GPIO38
|
|
frequency: 100Hz
|
|
|
|
# Built in 240v relay
|
|
- id: internal_relay_1
|
|
platform: gpio
|
|
pin: 40
|
|
|
|
# Additional relays (3 relay model)
|
|
- id: internal_relay_2
|
|
platform: gpio
|
|
pin: 2
|
|
- id: internal_relay_3
|
|
platform: gpio
|
|
pin: 1
|
|
|
|
#-------------------------------------------
|
|
# Internal lights
|
|
#-------------------------------------------
|
|
light:
|
|
- platform: monochromatic
|
|
output: GPIO38
|
|
name: Backlight
|
|
id: backlight
|
|
restore_mode: ALWAYS_ON
|
|
|
|
- platform: binary
|
|
output: internal_relay_1
|
|
name: Internal Light
|
|
id: internal_light
|
|
on_turn_on:
|
|
then:
|
|
- lvgl.widget.update:
|
|
id: lv_button_1_icon
|
|
text_color: 0xFFFF00
|
|
- lvgl.widget.update:
|
|
id: lv_button_1
|
|
state:
|
|
checked: true
|
|
on_turn_off:
|
|
then:
|
|
- lvgl.widget.update:
|
|
id: lv_button_1_icon
|
|
text_color: 0xB6B6B6
|
|
- lvgl.widget.update:
|
|
id: lv_button_1
|
|
state:
|
|
checked: false
|
|
|
|
#-------------------------------------------
|
|
# Graphics and Fonts
|
|
#-------------------------------------------
|
|
font:
|
|
- file: "gfonts://Roboto"
|
|
id: roboto24
|
|
size: 24
|
|
bpp: 4
|
|
extras:
|
|
- file: "https://cdnjs.cloudflare.com/ajax/libs/MaterialDesign-Webfont/7.4.47/fonts/materialdesignicons-webfont.ttf"
|
|
glyphs:
|
|
[
|
|
"\U000F004B",
|
|
"\U000F006E",
|
|
"\U000F012C",
|
|
"\U000F179B",
|
|
"\U000F0748",
|
|
"\U000F1A1B",
|
|
"\U000F02DC",
|
|
"\U000F0A02",
|
|
"\U000F035F",
|
|
"\U000F0156",
|
|
"\U000F0C5F",
|
|
"\U000F0084",
|
|
"\U000F0091",
|
|
]
|
|
|
|
- file: "https://cdnjs.cloudflare.com/ajax/libs/MaterialDesign-Webfont/7.4.47/fonts/materialdesignicons-webfont.ttf"
|
|
id: light40
|
|
size: 40
|
|
bpp: 4
|
|
glyphs: [
|
|
"\U000F0335", # mdi-lightbulb
|
|
"\U000F0769", # mdi-ceiling-light
|
|
"\U000F06B5", # mdi-lamp
|
|
"\U000F08DD", # mdi-floor-lamp
|
|
"\U000F12BA", # mdi-string-lights
|
|
]
|
|
|
|
#-------------------------------------------
|
|
# Touchscreen gt911 i2c
|
|
#-------------------------------------------
|
|
i2c:
|
|
- id: bus_a
|
|
sda: GPIO19
|
|
scl: GPIO45
|
|
#frequency: 100kHz
|
|
|
|
touchscreen:
|
|
platform: gt911
|
|
transform:
|
|
mirror_x: false
|
|
mirror_y: false
|
|
id: my_touchscreen
|
|
display: my_display
|
|
|
|
on_touch:
|
|
- logger.log:
|
|
format: Touch at (%d, %d)
|
|
args: [touch.x, touch.y]
|
|
- lambda: |-
|
|
ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
|
|
touch.x,
|
|
touch.y,
|
|
touch.x_raw,
|
|
touch.y_raw
|
|
);
|
|
on_release:
|
|
then:
|
|
- if:
|
|
condition: lvgl.is_paused
|
|
then:
|
|
- light.turn_on: backlight
|
|
- lvgl.resume:
|
|
- lvgl.widget.redraw:
|
|
#-------------------------------------------
|
|
# Display st7701s spi
|
|
#-------------------------------------------
|
|
spi:
|
|
- id: lcd_spi
|
|
clk_pin: GPIO48
|
|
mosi_pin: GPIO47
|
|
|
|
display:
|
|
- platform: st7701s
|
|
id: my_display
|
|
update_interval: never
|
|
auto_clear_enabled: False
|
|
spi_mode: MODE3
|
|
data_rate: 2MHz
|
|
color_order: RGB
|
|
invert_colors: False
|
|
dimensions:
|
|
width: 480
|
|
height: 480
|
|
cs_pin: 39
|
|
de_pin: 18
|
|
hsync_pin: 16
|
|
vsync_pin: 17
|
|
pclk_pin: 21
|
|
pclk_frequency: 12MHz
|
|
pclk_inverted: False
|
|
hsync_pulse_width: 8
|
|
hsync_front_porch: 10
|
|
hsync_back_porch: 20
|
|
vsync_pulse_width: 8
|
|
vsync_front_porch: 10
|
|
vsync_back_porch: 10
|
|
init_sequence:
|
|
- 1
|
|
# Custom sequences are an array, first byte is command, the rest are data.
|
|
- [0xFF, 0x77, 0x01, 0x00, 0x00, 0x10] # CMD2_BKSEL_BK0
|
|
- [0xCD, 0x00] # disable MDT flag
|
|
data_pins:
|
|
red:
|
|
- 11 #r1
|
|
- 12 #r2
|
|
- 13 #r3
|
|
- 14 #r4
|
|
- 0 #r5
|
|
green:
|
|
- 8 #g0
|
|
- 20 #g1
|
|
- 3 #g2
|
|
- 46 #g3
|
|
- 9 #g4
|
|
- 10 #g5
|
|
blue:
|
|
- 4 #b1
|
|
- 5 #b2
|
|
- 6 #b3
|
|
- 7 #b4
|
|
- 15 #b5 |