Files
hassos_config/esphome/widgets/alarm_panel/alarm_panel.yaml
2026-03-26 12:10:21 +01:00

870 lines
30 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
substitutions:
alarm_panel_entity: "alarm_control_panel.security"
pin_code: "1234"
shield_home_icon: "\U000F068A" # home
shield_away_icon: "\U000F099D" # away
shield_night_icon: "\U000F1828" # night
shield_vacation_icon: "\U000F06BB" # vacation
shield_disarm_icon: "\U000F099E" # disarmed
shield_arming_icon: "\U000F0498" # arming
globals:
- id: alarm_panel_pending_action
type: std::string
restore_value: no
initial_value: ""
lvgl:
pages:
- id: alarm_panel_page
bg_color: color_slate_blue_gray
widgets:
- obj:
id: alarm_panel_state_bg
x: 20
y: 20
width: 440
height: 80
pad_all: 0
align: TOP_LEFT
bg_color: color_steel_blue
bg_opa: 20%
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- obj:
id: alarm_panel_state_icon_bg
x: 20
align: LEFT_MID
width: 60
height: 60
radius: 30
pad_all: 0
bg_color: color_blue
bg_opa: 60%
shadow_opa: transp
border_opa: transp
border_width: 0
- label:
id: alarm_panel_state_icon
x: 30
align: LEFT_MID
text_font: mdi_icons_40
text_color: color_blue
text: "${shield_disarm_icon}"
- label:
x: 110
id: alarm_panel_state_text
align: LEFT_MID
text_font: nunito_18
text_color: color_misty_blue
text: " "
- obj:
id: alarm_panel_state_control
hidden: false
x: 20
y: 120
width: 440
height: 260
align: TOP_LEFT
bg_color: color_steel_blue
bg_opa: 20%
border_opa: TRANSP
shadow_opa: TRANSP
radius: 10
widgets:
- obj:
id: alarm_panel_button_disarmed
width: 200
height: 200
align: center
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 160
height: 160
align: center
clickable: true
radius: 80
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 25
shadow_spread: 4
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 7
on_press:
- lambda: |-
id(alarm_panel_pending_action) = std::string("disarm");
- lvgl.widget.show: alarm_panel_keypad_page
- lvgl.widget.hide: alarm_panel_state_bg
- lvgl.widget.hide: alarm_panel_state_control
- obj:
width: 152
height: 152
align: center
clickable: false
radius: 80
bg_opa: transp
border_opa: transp
shadow_width: 8
shadow_color: 0xFFFFFF
shadow_ofs_x: -6
shadow_ofs_y: -3
shadow_opa: 30%
- obj:
width: 152
height: 152
align: center
clickable: false
radius: 80
bg_opa: transp
border_opa: transp
shadow_width: 8
shadow_color: 0x000000
shadow_ofs_x: 6
shadow_ofs_y: 3
- obj:
width: 156
height: 156
align: center
clickable: false
radius: 80
border_opa: transp
bg_color: color_slate_blue_gray
widgets:
- label:
id: alarm_panel_state_btn_disarmed
align: center
text_font: mdi_icons_68
text_color: color_steel_blue
text: "${shield_disarm_icon}"
- obj:
id: alarm_panel_button_home
hidden: true
width: 110
height: 110
x: -60
y: -60
align: center
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 90
height: 90
align: center
clickable: true
radius: 50
pad_all: 0
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 15
shadow_spread: 2
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 5
on_press:
- lambda: |-
id(alarm_panel_pending_action) = std::string("arm_home");
- lvgl.widget.show: alarm_panel_keypad_page
- lvgl.widget.hide: alarm_panel_state_bg
- lvgl.widget.hide: alarm_panel_state_control
- obj:
width: 80
height: 80
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: 80
height: 80
align: center
clickable: false
radius: 45
pad_all: 0
bg_opa: transp
border_opa: transp
shadow_width: 4
shadow_color: 0x000000
shadow_ofs_x: 4
shadow_ofs_y: 2
- obj:
width: 85
height: 85
pad_all: 0
align: center
clickable: false
radius: 50
border_opa: transp
bg_color: color_slate_blue_gray
widgets:
- label:
id: alarm_panel_state_btn_home
align: center
text_font: mdi_icons_52
text_color: color_steel_blue
text: "${shield_home_icon}"
- obj:
id: alarm_panel_button_away
hidden: true
width: 110
height: 110
x: 60
y: -60
align: center
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 90
height: 90
align: center
clickable: true
radius: 50
pad_all: 0
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 15
shadow_spread: 2
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 5
on_press:
- lambda: |-
id(alarm_panel_pending_action) = std::string("arm_away");
- lvgl.widget.show: alarm_panel_keypad_page
- lvgl.widget.hide: alarm_panel_state_bg
- lvgl.widget.hide: alarm_panel_state_control
- obj:
width: 80
height: 80
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: 80
height: 80
align: center
clickable: false
radius: 45
pad_all: 0
bg_opa: transp
border_opa: transp
shadow_width: 4
shadow_color: 0x000000
shadow_ofs_x: 4
shadow_ofs_y: 2
- obj:
width: 85
height: 85
pad_all: 0
align: center
clickable: false
radius: 50
border_opa: transp
bg_color: color_slate_blue_gray
widgets:
- label:
id: alarm_panel_state_btn_away
align: center
text_font: mdi_icons_52
text_color: color_steel_blue
text: "${shield_away_icon}"
- obj:
id: alarm_panel_button_night
hidden: true
width: 110
height: 110
x: -60
y: 60
align: center
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 90
height: 90
align: center
clickable: true
radius: 50
pad_all: 0
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 15
shadow_spread: 2
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 5
on_press:
- lambda: |-
id(alarm_panel_pending_action) = std::string("arm_night");
- lvgl.widget.show: alarm_panel_keypad_page
- lvgl.widget.hide: alarm_panel_state_bg
- lvgl.widget.hide: alarm_panel_state_control
- obj:
width: 80
height: 80
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: 80
height: 80
align: center
clickable: false
radius: 45
pad_all: 0
bg_opa: transp
border_opa: transp
shadow_width: 4
shadow_color: 0x000000
shadow_ofs_x: 4
shadow_ofs_y: 2
- obj:
width: 85
height: 85
pad_all: 0
align: center
clickable: false
radius: 50
border_opa: transp
bg_color: color_slate_blue_gray
widgets:
- label:
id: alarm_panel_state_btn_night
align: center
text_font: mdi_icons_52
text_color: color_steel_blue
text: "${shield_night_icon}"
- obj:
id: alarm_panel_button_vacation
hidden: true
width: 110
height: 110
x: 60
y: 60
align: center
pad_all: 0
bg_opa: transp
shadow_opa: transp
border_opa: transp
widgets:
- obj:
width: 90
height: 90
align: center
clickable: true
radius: 50
pad_all: 0
bg_opa: transp
border_opa: transp
border_width: 0
shadow_width: 15
shadow_spread: 2
shadow_color: color_black
pressed:
bg_color: 0x3A3A4C
shadow_width: 5
on_press:
- lambda: |-
id(alarm_panel_pending_action) = std::string("arm_vacation");
- lvgl.widget.show: alarm_panel_keypad_page
- lvgl.widget.hide: alarm_panel_state_bg
- lvgl.widget.hide: alarm_panel_state_control
- obj:
width: 80
height: 80
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: 80
height: 80
align: center
clickable: false
radius: 45
pad_all: 0
bg_opa: transp
border_opa: transp
shadow_width: 4
shadow_color: 0x000000
shadow_ofs_x: 4
shadow_ofs_y: 2
- obj:
width: 85
height: 85
pad_all: 0
align: center
clickable: false
radius: 50
border_opa: transp
bg_color: color_slate_blue_gray
widgets:
- label:
id: alarm_panel_state_btn_vacation
align: center
text_font: mdi_icons_52
text_color: color_steel_blue
text: "${shield_vacation_icon}"
- obj:
id: alarm_panel_keypad_page
hidden: true
x: 20
y: 20
width: 440
height: 360
align: TOP_LEFT
bg_color: color_steel_blue
bg_opa: 20%
border_opa: TRANSP
shadow_opa: TRANSP
radius: 10
widgets:
- obj:
width: 400
height: 40
align: top_mid
border_width: 1
border_color: color_steel_blue
pad_all: 0
bg_opa: transp
shadow_opa: transp
radius: 10
widgets:
- label:
id: alarm_panel_keypad_code_label
align: center
text_font: nunito_18
text: "Enter code"
text_color: color_misty_blue
text_align: center
- buttonmatrix:
id: alarm_panel_keypad
width: 400
height: 270
pad_all: 0
bg_opa: transp
border_opa: transp
x: 2
y: 30
align: center
items:
bg_opa: transp
border_color: color_steel_blue
border_width: 1
shadow_opa: transp
text_font: montserrat_20
text_color: color_misty_blue
pressed:
bg_color: color_steel_blue
rows:
- buttons:
- text: 1
control:
no_repeat: true
- text: 2
control:
no_repeat: true
- text: 3
control:
no_repeat: true
- buttons:
- text: 4
control:
no_repeat: true
- text: 5
control:
no_repeat: true
- text: 6
control:
no_repeat: true
- buttons:
- text: 7
control:
no_repeat: true
- text: 8
control:
no_repeat: true
- text: 9
control:
no_repeat: true
- buttons:
- text: "\uF55A"
key_code: "*"
control:
no_repeat: true
- text: 0
control:
no_repeat: true
- text: "\uF00C"
key_code: "#"
control:
no_repeat: true
# Return
- button:
x: 20
y: 400
width: 60
height: 60
align: TOP_LEFT
bg_color: color_steel_blue
bg_opa: 20%
border_opa: TRANSP
shadow_opa: TRANSP
radius: 10
widgets:
- label:
align: CENTER
text_font: icons_28
text_color: color_misty_blue
text: "${exit_icon}"
on_press:
- lvgl.page.show: devices_page
- lvgl.widget.show: menu_controls_main
# alarm panel entity friendly name
- obj:
id: alarm_panel_bg_name
x: -20
y: 400
width: 360
height: 60
align: TOP_RIGHT
bg_color: color_steel_blue
bg_opa: 20%
border_opa: TRANSP
border_width: 0
shadow_opa: TRANSP
radius: 10
widgets:
- label:
id: alarm_panel_label_name
align: CENTER
text_font: nunito_16
text_color: color_misty_blue
text: "friendly name"
key_collector:
- source_id: alarm_panel_keypad
min_length: 4
max_length: 4
end_keys: "#"
end_key_required: true
back_keys: "*"
allowed_keys: "0123456789*#"
timeout: 5s
on_progress:
- if:
condition:
lambda: return (0 != x.compare(std::string{""}));
then:
- lvgl.label.update:
id: alarm_panel_keypad_code_label
text: !lambda 'return x.c_str();'
else:
- lvgl.label.update:
id: alarm_panel_keypad_code_label
text_font: nunito_18
text_color: color_misty_blue
text: "Enter code"
on_result:
- if:
condition:
lambda: 'return x == "${pin_code}";'
then:
# Если код верный, отправляем команду в Home Assistant для снятия с охраны
- if:
condition:
lambda: 'return id(alarm_panel_pending_action) == "disarm";'
then:
- homeassistant.action:
action: alarm_control_panel.alarm_disarm
data:
entity_id: "${alarm_panel_entity}"
code: "${pin_code}"
- if:
condition:
lambda: 'return id(alarm_panel_pending_action) == "arm_home";'
then:
- homeassistant.action:
action: alarm_control_panel.alarm_arm_home
data:
entity_id: "${alarm_panel_entity}"
code: "${pin_code}"
- if:
condition:
lambda: 'return id(alarm_panel_pending_action) == "arm_away";'
then:
- homeassistant.action:
action: alarm_control_panel.alarm_arm_away
data:
entity_id: "${alarm_panel_entity}"
code: "${pin_code}"
- if:
condition:
lambda: 'return id(alarm_panel_pending_action) == "arm_night";'
then:
- homeassistant.action:
action: alarm_control_panel.alarm_arm_night
data:
entity_id: "${alarm_panel_entity}"
code: "${pin_code}"
- if:
condition:
lambda: 'return id(alarm_panel_pending_action) == "arm_vacation";'
then:
- homeassistant.action:
action: alarm_control_panel.alarm_arm_vacation
data:
entity_id: "${alarm_panel_entity}"
code: "${pin_code}"
- lvgl.widget.hide: alarm_panel_keypad_page
- lvgl.widget.show: alarm_panel_state_bg
- lvgl.widget.show: alarm_panel_state_control
# Получаем статус сигнализации из Home Assistant
text_sensor:
- platform: homeassistant
id: alarm_panel_sensor_state
entity_id: ${alarm_panel_entity}
on_value:
then:
- script.execute:
id: alarm_panel_get_and_set_translated_state
state_str: !lambda 'return id(alarm_panel_sensor_state).state;'
- if:
condition:
lambda: 'return x == "disarmed";'
then:
- lvgl.widget.show: alarm_panel_button_home
- lvgl.widget.show: alarm_panel_button_away
- lvgl.widget.show: alarm_panel_button_night
- lvgl.widget.show: alarm_panel_button_vacation
- lvgl.widget.hide: alarm_panel_button_disarmed
- lvgl.label.update:
id: alarm_panel_status
text_color: color_steel_blue
- lvgl.label.update:
id: alarm_panel_state_icon
text_color: color_blue
text: "${shield_disarm_icon}"
- lvgl.obj.update:
id: alarm_panel_state_icon_bg
bg_color: color_blue
else:
- lvgl.label.update:
id: alarm_panel_status
text_color: color_crimson
- lvgl.widget.hide: alarm_panel_button_home
- lvgl.widget.hide: alarm_panel_button_away
- lvgl.widget.hide: alarm_panel_button_night
- lvgl.widget.hide: alarm_panel_button_vacation
- lvgl.widget.show: alarm_panel_button_disarmed
- if:
condition:
lambda: 'return x == "arming";'
then:
- lvgl.label.update:
id: alarm_panel_state_icon
text_color: color_gray
text: "${shield_arming_icon}"
- lvgl.obj.update:
id: alarm_panel_state_icon_bg
bg_color: color_gray
- if:
condition:
lambda: 'return x == "armed_home";'
then:
- lvgl.label.update:
id: alarm_panel_state_icon
text_color: color_green
text: "${shield_home_icon}"
- lvgl.obj.update:
id: alarm_panel_state_icon_bg
bg_color: color_green
- if:
condition:
lambda: 'return x == "armed_away";'
then:
- lvgl.label.update:
id: alarm_panel_state_icon
text_color: color_green
text: "${shield_away_icon}"
- lvgl.obj.update:
id: alarm_panel_state_icon_bg
bg_color: color_green
- if:
condition:
lambda: 'return x == "armed_night";'
then:
- lvgl.label.update:
id: alarm_panel_state_icon
text_color: color_green
text: "${shield_night_icon}"
- lvgl.obj.update:
id: alarm_panel_state_icon_bg
bg_color: color_green
- if:
condition:
lambda: 'return x == "armed_vacation";'
then:
- lvgl.label.update:
id: alarm_panel_state_icon
text_color: color_green
text: "${shield_vacation_icon}"
- lvgl.obj.update:
id: alarm_panel_state_icon_bg
bg_color: color_green
- platform: homeassistant
id: alarm_panel_sensor_name
entity_id: ${alarm_panel_entity}
attribute: friendly_name
on_value:
then:
- lvgl.label.update:
id: alarm_panel_label_name
text: !lambda return x;
script:
- id: alarm_panel_get_and_set_translated_state
parameters:
state_str: string
then:
- lambda: |-
std::string state = state_str;
auto it = id(alarm_panel_translations).find(state);
std::string translated_state = (it != id(alarm_panel_translations).end()) ? it->second : state;
lv_label_set_text(id(alarm_panel_state_text), translated_state.c_str());
select:
- platform: lvgl
widget: language_dropdown
id: alarm_panel_select_language
on_value:
then:
- delay: 300ms
- script.execute:
id: alarm_panel_get_and_set_translated_state
state_str: !lambda 'return id(alarm_panel_sensor_state).state;'
esphome:
on_boot:
priority: -100
then:
- if:
condition:
lambda: 'return id(alarm_panel_sensor_state).has_state();'
then:
- script.execute:
id: alarm_panel_get_and_set_translated_state
state_str: !lambda 'return id(alarm_panel_sensor_state).state;'
api:
on_client_connected:
- if:
condition:
lambda: 'return id(alarm_panel_sensor_state).has_state();'
then:
- script.execute:
id: alarm_panel_get_and_set_translated_state
state_str: !lambda 'return id(alarm_panel_sensor_state).state;'