20260326
This commit is contained in:
543
esphome/widgets/shutter/shutter_widget.yaml
Normal file
543
esphome/widgets/shutter/shutter_widget.yaml
Normal 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;'
|
||||
Reference in New Issue
Block a user