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,870 @@
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;'