This commit is contained in:
2026-03-26 12:10:21 +01:00
parent 1f4970c17c
commit d4d76db890
877 changed files with 631941 additions and 26195 deletions

View File

@@ -0,0 +1,46 @@
substitutions:
shutter_entity_1: "cover.hall_window"
shutter_entity_2: "cover.living_room_window"
shutter_entity_3: "cover.hall_window"
shutter_entity_4: "cover.living_room_window"
shutter_widget_name_1: "shutter1"
shutter_widget_name_2: "shutter2"
shutter_widget_name_3: "shutter3"
shutter_widget_name_4: "shutter4"
shutter_label_name_1: "shutter 1"
shutter_label_name_2: "shutter 2"
shutter_label_name_3: "shutter 3"
shutter_label_name_4: "shutter 4"
packages:
shutter_panel: !include shutter_panel.yaml
shutter_1: !include
file: shutter_widget.yaml
vars:
shutter_entity: "${shutter_entity_1}"
shutter_widget_name: "${shutter_widget_name_1}"
shutter_2: !include
file: shutter_widget.yaml
vars:
shutter_entity: "${shutter_entity_2}"
shutter_widget_name: "${shutter_widget_name_2}"
shutter_3: !include
file: shutter_widget.yaml
vars:
shutter_entity: "${shutter_entity_3}"
shutter_widget_name: "${shutter_widget_name_3}"
shutter_4: !include
file: shutter_widget.yaml
vars:
shutter_entity: "${shutter_entity_4}"
shutter_widget_name: "${shutter_widget_name_4}"

View File

@@ -0,0 +1,203 @@
substitutions:
exit_icon: "\U0000e902"
shutter_close_icon: "\U0000e91d"
swipe_icon: "\U0000e91a"
lvgl:
pages:
- id: shutter_group_page
bg_color: color_slate_blue_gray
widgets:
- button:
id: ${shutter_widget_name_1}_btn
x: 20
y: 20
width: 210
height: 160
align: TOP_LEFT
bg_color: color_steel_blue
bg_opa: 20%
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: ${shutter_widget_name_1}_shutter
y: 15
align: CENTER
text_color: color_steel_blue
text_font: icons_90
text: "${shutter_close_icon}"
- label:
id: ${shutter_widget_name_1}_lable_name
align: TOP_MID
text_font: nunito_16
text_color: color_misty_blue
text: "${shutter_label_name_1}"
- button:
id: ${shutter_widget_name_2}_btn
x: -20
y: 20
width: 210
height: 160
align: TOP_RIGHT
bg_color: color_steel_blue
bg_opa: 20%
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: ${shutter_widget_name_2}_shutter
y: 15
align: CENTER
text_color: color_steel_blue
text_font: icons_90
text: "${shutter_close_icon}"
- label:
id: ${shutter_widget_name_2}_lable_name
align: TOP_MID
text_font: nunito_16
text_color: color_misty_blue
text: "${shutter_label_name_2}"
- button:
id: ${shutter_widget_name_3}_btn
x: 20
y: 200
width: 210
height: 160
align: TOP_LEFT
bg_color: color_steel_blue
bg_opa: 20%
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: ${shutter_widget_name_3}_shutter
y: 15
align: CENTER
text_color: color_steel_blue
text_font: icons_90
text: "${shutter_close_icon}"
- label:
id: ${shutter_widget_name_3}_lable_name
align: TOP_MID
text_font: nunito_16
text_color: color_misty_blue
text: "${shutter_label_name_3}"
- button:
id: ${shutter_widget_name_4}_btn
x: -20
y: 200
width: 210
height: 160
align: TOP_RIGHT
bg_color: color_steel_blue
bg_opa: 20%
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: ${shutter_widget_name_4}_shutter
y: 15
align: CENTER
text_color: color_steel_blue
text_font: icons_90
text: "${shutter_close_icon}"
- label:
id: ${shutter_widget_name_4}_lable_name
align: TOP_MID
text_font: nunito_16
text_color: color_misty_blue
text: "${shutter_label_name_4}"
binary_sensor:
- platform: lvgl
id: ${shutter_widget_name_1}_btn_long_sensor
widget: ${shutter_widget_name_1}_btn
on_click:
- min_length: 50ms
max_length: 500ms
then:
- homeassistant.service:
service: cover.toggle
data:
entity_id: "${shutter_entity_1}"
- min_length: 800ms
max_length: 3000ms
then:
- lvgl.widget.hide: menu_controls_main
- lvgl.page.show:
id: ${shutter_widget_name_1}_shutter_page
animation: OUT_RIGHT
time: 300ms
- platform: lvgl
id: ${shutter_widget_name_2}_btn_long_sensor
widget: ${shutter_widget_name_2}_btn
on_click:
- min_length: 50ms
max_length: 500ms
then:
- homeassistant.service:
service: cover.toggle
data:
entity_id: "${shutter_entity_2}"
- min_length: 800ms
max_length: 3000ms
then:
- lvgl.widget.hide: menu_controls_main
- lvgl.page.show:
id: ${shutter_widget_name_2}_shutter_page
animation: OUT_RIGHT
time: 300ms
- platform: lvgl
id: ${shutter_widget_name_3}_btn_long_sensor
widget: ${shutter_widget_name_3}_btn
on_click:
- min_length: 50ms
max_length: 500ms
then:
- homeassistant.service:
service: cover.toggle
data:
entity_id: "${shutter_entity_3}"
- min_length: 800ms
max_length: 3000ms
then:
- lvgl.widget.hide: menu_controls_main
- lvgl.page.show:
id: ${shutter_widget_name_3}_shutter_page
animation: OUT_RIGHT
time: 300ms
- platform: lvgl
id: ${shutter_widget_name_4}_btn_long_sensor
widget: ${shutter_widget_name_4}_btn
on_click:
- min_length: 50ms
max_length: 500ms
then:
- homeassistant.service:
service: cover.toggle
data:
entity_id: "${shutter_entity_4}"
- min_length: 800ms
max_length: 3000ms
then:
- lvgl.widget.hide: menu_controls_main
- lvgl.page.show:
id: ${shutter_widget_name_4}_shutter_page
animation: OUT_RIGHT
time: 300ms

View File

@@ -0,0 +1,543 @@
substitutions:
arrow_up_icon: "\U0000e91f"
arrow_down_icon: "\U0000e920"
stop_icon: "\U0000e91c"
shutter_open_icon: "\U0000e91e"
shutter_close_icon: "\U0000e91d"
sensor:
# Shutter Current Position
- platform: homeassistant
id: ${shutter_widget_name}_shutter_current_pos
entity_id: "${shutter_entity}"
attribute: current_position
on_value:
then:
- script.execute: ${shutter_widget_name}_shutter_state_update
- lambda: |-
int pos = round(id(${shutter_widget_name}_shutter_current_pos).state / 10) * 10;
static const char* glyphs[] = {
"\U0000e91d", // 0 - shutter_closed
"\U0000e93d", // 10
"\U0000e93e", // 20
"\U0000e93f", // 30
"\U0000e940", // 40
"\U0000e941", // 50
"\U0000e93c", // 60
"\U0000e943", // 70
"\U0000e944", // 80
"\U0000e942", // 90
"\U0000e91e" // 100 - shutter_open
};
int idx = pos / 10;
if (idx < 0) idx = 0;
if (idx > 10) idx = 10;
lv_label_set_text(id(${shutter_widget_name}_shutter_icon), glyphs[idx]);
lv_label_set_text(id(${shutter_widget_name}_shutter), glyphs[idx]);
text_sensor:
# Shutter Name
- platform: homeassistant
id: ${shutter_widget_name}_shutter_name
entity_id: "${shutter_entity}"
attribute: friendly_name
on_value:
- lvgl.label.update:
id: ${shutter_widget_name}_shutter_label_name
text: !lambda return x;
# Shutter State
- platform: homeassistant
id: ${shutter_widget_name}_shutter_state
entity_id: "${shutter_entity}"
on_value:
then:
- script.execute:
id: ${shutter_widget_name}_get_and_set_translated_state
state_str: !lambda 'return id(${shutter_widget_name}_shutter_state).state;'
- lvgl.label.update:
id: ${shutter_widget_name}_shutter_label_state
y: 5
align: TOP_MID
- if:
condition:
lambda: 'return x == "opening";'
then:
- lvgl.widget.show: ${shutter_widget_name}_shutter_label_pos
- if:
condition:
lambda: 'return x == "closing";'
then:
- lvgl.widget.show: ${shutter_widget_name}_shutter_label_pos
- if:
condition:
lambda: 'return x == "open";'
then:
- lvgl.widget.show: ${shutter_widget_name}_shutter_label_pos
- if:
condition:
lambda: 'return x == "closed";'
then:
- lvgl.widget.hide: ${shutter_widget_name}_shutter_label_pos
- lvgl.label.update:
id: ${shutter_widget_name}_shutter_label_state
y: 0
align: CENTER
lvgl:
pages:
- id: ${shutter_widget_name}_shutter_page
bg_color: color_slate_blue_gray
widgets:
- obj:
id: ${shutter_widget_name}_shutter_bg_state
x: -20
y: 40
width: 320
height: 54
align: TOP_RIGHT
bg_opa: transp
pad_all: 0
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: ${shutter_widget_name}_shutter_label_state
y: 5
align: TOP_MID
text_font: nunito_16
text_color: color_misty_blue
text: " "
- label:
id: ${shutter_widget_name}_shutter_label_pos
y: -5
align: BOTTOM_MID
text_font: nunito_16
text_color: color_misty_blue
text: " "
- obj:
id: ${shutter_widget_name}_shutter_bg_controls
x: 20
y: 20
width: 100
height: 320
align: TOP_LEFT
# bg_color: color_steel_blue
bg_opa: transp
pad_all: 0
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- obj:
y: 20
width: 90
height: 90
align: top_mid
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 70
height: 70
align: center
clickable: true
radius: 50
pad_all: 0
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 8
shadow_spread: 2
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 5
on_press:
- homeassistant.action:
action: cover.open_cover
data:
entity_id: "${shutter_entity}"
- obj:
width: 60
height: 60
align: center
clickable: false
radius: 45
pad_all: 0
bg_opa: transp
border_opa: transp
shadow_width: 4
shadow_color: 0xFFFFFF
shadow_ofs_x: -4
shadow_ofs_y: -2
shadow_opa: 30%
- obj:
width: 65
height: 65
pad_all: 0
align: center
clickable: false
radius: 50
border_opa: transp
bg_color: color_slate_blue_gray
widgets:
- label:
align: CENTER
text_font: icons_32
text_color: color_misty_blue
text: "${arrow_up_icon}"
- obj:
width: 90
height: 90
align: center
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 70
height: 70
align: center
clickable: true
radius: 50
pad_all: 0
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 8
shadow_spread: 2
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 5
on_press:
- homeassistant.action:
action: cover.stop_cover
data:
entity_id: "${shutter_entity}"
- obj:
width: 60
height: 60
align: center
clickable: false
radius: 45
pad_all: 0
bg_opa: transp
border_opa: transp
shadow_width: 4
shadow_color: 0xFFFFFF
shadow_ofs_x: -4
shadow_ofs_y: -2
shadow_opa: 30%
- obj:
width: 65
height: 65
pad_all: 0
align: center
clickable: false
radius: 50
border_opa: transp
bg_color: color_slate_blue_gray
widgets:
- label:
align: CENTER
text_font: icons_32
text_color: color_misty_blue
text: "${stop_icon}"
- obj:
y: -20
width: 90
height: 90
align: bottom_mid
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 70
height: 70
align: center
clickable: true
radius: 50
pad_all: 0
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 8
shadow_spread: 2
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 5
on_press:
- homeassistant.action:
action: cover.close_cover
data:
entity_id: "${shutter_entity}"
- obj:
width: 60
height: 60
align: center
clickable: false
radius: 45
pad_all: 0
bg_opa: transp
border_opa: transp
shadow_width: 4
shadow_color: 0xFFFFFF
shadow_ofs_x: -4
shadow_ofs_y: -2
shadow_opa: 30%
- obj:
width: 65
height: 65
pad_all: 0
align: center
clickable: false
radius: 50
border_opa: transp
bg_color: color_slate_blue_gray
widgets:
- label:
align: CENTER
text_font: icons_32
text_color: color_misty_blue
text: "${arrow_down_icon}"
- obj:
id: ${shutter_widget_name}_shutter_bg_slider
x: -20
y: 94
width: 320
height: 310
align: TOP_RIGHT
# bg_color: color_steel_blue
bg_opa: transp
pad_all: 0
border_opa: transp
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: ${shutter_widget_name}_shutter_icon
align: CENTER
text_font: icons_300
text_color: color_misty_blue
text: "\U0000e91d"
- slider:
id: ${shutter_widget_name}_shutter_set_pos_slider
hidden: false
radius: 0
bg_opa: TRANSP
y: -32
align: BOTTOM_MID
width: 210
height: 220
min_value: 0
max_value: 100
indicator:
bg_opa: TRANSP
radius: 0
knob:
bg_opa: TRANSP
on_value:
then:
- script.execute:
id: ${shutter_widget_name}_shutter_slider_preview_update
value: !lambda 'return x;'
on_release:
- homeassistant.action:
action: cover.set_cover_position
data:
entity_id: "${shutter_entity}"
position: !lambda return int(x);
- obj:
id: ${shutter_widget_name}_shutter_back
x: 20
y: 360
width: 100
height: 100
align: TOP_LEFT
bg_opa: transp
pad_all: 0
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- obj:
width: 90
height: 90
align: center
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 70
height: 70
align: center
clickable: true
radius: 10
pad_all: 0
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 8
shadow_spread: 2
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 5
on_press:
then:
- lvgl.widget.show: menu_controls_main
- lvgl.page.show:
id: shutter_group_page
animation: OUT_RIGHT
time: 300ms
- label:
id: ${shutter_widget_name}_shutter_back_label
align: center
text_font: icons_28
text_color: color_misty_blue
text: "${exit_icon}"
- obj:
id: ${shutter_widget_name}_shutter_bg_name
x: -20
y: 400
width: 320
height: 36
align: TOP_RIGHT
bg_opa: transp
pad_all: 0
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: ${shutter_widget_name}_shutter_label_name
align: CENTER
text_font: nunito_16
text_color: color_misty_blue
text: "shutter"
script:
- id: ${shutter_widget_name}_shutter_state_update
then:
- lvgl.slider.update:
id: ${shutter_widget_name}_shutter_set_pos_slider
value: !lambda |-
return round(id(${shutter_widget_name}_shutter_current_pos).state / 10) * 10;
- lvgl.label.update:
id: ${shutter_widget_name}_shutter_label_pos
text: !lambda |-
return to_string((int)id(${shutter_widget_name}_shutter_current_pos).state) + "%";
- id: ${shutter_widget_name}_shutter_slider_preview_update
parameters:
value: int
then:
- lvgl.label.update:
id: ${shutter_widget_name}_shutter_label_pos
text: !lambda |-
return to_string((int)value) + "%";
- lambda: |-
int pos = round(value / 10) * 10;
static const char* glyphs[] = {
"\U0000e91d", // 0 - shutter_closed
"\U0000e93d", // 10
"\U0000e93e", // 20
"\U0000e93f", // 30
"\U0000e940", // 40
"\U0000e941", // 50
"\U0000e93c", // 60
"\U0000e943", // 70
"\U0000e944", // 80
"\U0000e942", // 90
"\U0000e91e" // 100 - shutter_open
};
int idx = pos / 10;
if (idx < 0) idx = 0;
if (idx > 10) idx = 10;
lv_label_set_text(id(${shutter_widget_name}_shutter_icon), glyphs[idx]);
lv_label_set_text(id(${shutter_widget_name}_shutter), glyphs[idx]);
- id: ${shutter_widget_name}_get_and_set_translated_state
parameters:
state_str: string
then:
- lambda: |-
std::string state = state_str;
auto it = id(cover_translations).find(state);
std::string translated_state = (it != id(cover_translations).end()) ? it->second : state;
lv_label_set_text(id(${shutter_widget_name}_shutter_label_state), translated_state.c_str());
select:
- platform: lvgl
widget: language_dropdown
id: ${shutter_widget_name}_select_language
on_value:
then:
- delay: 300ms
- script.execute:
id: ${shutter_widget_name}_get_and_set_translated_state
state_str: !lambda 'return id(${shutter_widget_name}_shutter_state).state;'
esphome:
on_boot:
priority: -100
then:
- if:
condition:
lambda: 'return id(${shutter_widget_name}_shutter_state).has_state();'
then:
- script.execute:
id: ${shutter_widget_name}_get_and_set_translated_state
state_str: !lambda 'return id(${shutter_widget_name}_shutter_state).state;'
api:
on_client_connected:
- if:
condition:
lambda: 'return id(${shutter_widget_name}_shutter_state).has_state();'
then:
- script.execute:
id: ${shutter_widget_name}_get_and_set_translated_state
state_str: !lambda 'return id(${shutter_widget_name}_shutter_state).state;'