1078 lines
46 KiB
YAML
1078 lines
46 KiB
YAML
############################################################
|
||
# CYD Base – LVGL UI + scripts layer
|
||
# Include via: packages: !include cyd-base-ui.yaml
|
||
############################################################
|
||
|
||
lvgl:
|
||
displays:
|
||
- my_display
|
||
touchscreens:
|
||
- touchscreen_id: ts_touch
|
||
# Use a 1/10th frame buffer (~15KB) instead of the default full frame (~150KB).
|
||
# Required on CYDs without PSRAM. The display is rendered in horizontal strips.
|
||
buffer_size: 10%
|
||
|
||
style_definitions:
|
||
- id: style_tile
|
||
bg_color: 0xFFFFFF
|
||
bg_opa: 95%
|
||
radius: 18
|
||
border_width: 0
|
||
pad_left: 8
|
||
pad_right: 8
|
||
pad_top: 8
|
||
pad_bottom: 8
|
||
shadow_width: 0
|
||
shadow_opa: 40%
|
||
|
||
- id: style_tile_disabled
|
||
bg_color: 0x939391
|
||
bg_opa: 95%
|
||
radius: 18
|
||
border_width: 0
|
||
pad_left: 8
|
||
pad_right: 8
|
||
pad_top: 8
|
||
pad_bottom: 8
|
||
shadow_width: 0
|
||
shadow_opa: 25%
|
||
|
||
- id: style_icon_circle
|
||
bg_color: 0xFEC600
|
||
bg_opa: COVER
|
||
radius: 999
|
||
border_width: 0
|
||
|
||
- id: style_icon_circle_disabled
|
||
bg_color: 0x7B7B6F
|
||
bg_opa: 95%
|
||
radius: 999
|
||
border_width: 0
|
||
|
||
- id: style_room
|
||
text_font: headline
|
||
text_color: 0xFFFFFF
|
||
text_opa: 100%
|
||
|
||
- id: style_time
|
||
text_font: time_label
|
||
text_color: 0xFFFFFF
|
||
text_opa: 100%
|
||
|
||
- id: style_title
|
||
text_font: label
|
||
text_color: 0x000000
|
||
text_opa: 100%
|
||
|
||
- id: style_value
|
||
text_font: sublabel
|
||
text_color: 0x7A7A7C
|
||
text_opa: 100%
|
||
|
||
- id: style_value_big
|
||
text_font: sublabel_big
|
||
text_color: 0xFFFFFF
|
||
text_opa: 80%
|
||
|
||
- id: style_title_disabled
|
||
text_font: label
|
||
text_color: 0xFFFFFF
|
||
text_opa: 100%
|
||
|
||
- id: style_value_disabled
|
||
text_font: sublabel
|
||
text_color: 0xD9D9D9
|
||
text_opa: 100%
|
||
|
||
pages:
|
||
- id: home_page
|
||
bg_color: 0x000000
|
||
bg_opa: COVER
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- image:
|
||
id: bg
|
||
src: bg_home
|
||
x: 0
|
||
y: 0
|
||
|
||
- label:
|
||
id: lbl_room
|
||
x: 11
|
||
y: 14
|
||
text: "${ROOM_NAME}"
|
||
styles: style_room
|
||
|
||
- label:
|
||
id: lbl_time
|
||
align: TOP_RIGHT
|
||
x: -11
|
||
y: 14
|
||
text: ""
|
||
styles: style_time
|
||
|
||
# ---------- TILE 1 ----------
|
||
- obj:
|
||
id: tile1
|
||
x: 9
|
||
y: 54
|
||
width: 147
|
||
height: 52
|
||
styles: style_tile
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- obj:
|
||
id: tile1_icon_circle
|
||
x: 0
|
||
y: 0
|
||
width: 36
|
||
height: 36
|
||
styles: style_icon_circle
|
||
clickable: false
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- label:
|
||
id: tile1_icon_lbl
|
||
align: CENTER
|
||
text_font: materialdesign_icons
|
||
text_color: 0xFFFFFF
|
||
text: "${TILE1_ICON}"
|
||
clickable: false
|
||
- label:
|
||
id: t1_title
|
||
x: 48
|
||
y: 4
|
||
text: "${TILE1_TITLE}"
|
||
styles: style_title
|
||
clickable: false
|
||
- label:
|
||
id: t1_value
|
||
x: 48
|
||
y: 18
|
||
text: "—"
|
||
styles: style_value
|
||
clickable: false
|
||
on_short_click:
|
||
- script.execute: { id: publish_action, action: "tile1_press" }
|
||
- script.execute:
|
||
id: do_tile_action
|
||
tile_type: "${TILE1_TYPE}"
|
||
tap_action: "${TILE1_TAP_ACTION}"
|
||
service: "${TILE1_TAP_SERVICE}"
|
||
entity_id: "${TILE1_ENTITY}"
|
||
param_key: "${TILE1_TAP_PARAM_KEY}"
|
||
param_val: "${TILE1_TAP_PARAM_VAL}"
|
||
was_on: !lambda "return id(ha_state_tile1).state;"
|
||
on_long_press:
|
||
- if:
|
||
condition:
|
||
lambda: |-
|
||
std::string lp = "${TILE1_LONGPRESS}";
|
||
std::string type = "${TILE1_TYPE}";
|
||
if (lp == "none") return false;
|
||
if (lp == "auto") return (type == "light" || type == "fan");
|
||
return (lp == "brightness" || lp == "percentage");
|
||
then:
|
||
- script.execute:
|
||
id: open_value_overlay
|
||
title: "${TILE1_TITLE}"
|
||
entity: "${TILE1_ENTITY}"
|
||
tile_type: "${TILE1_TYPE}"
|
||
longpress_mode: "${TILE1_LONGPRESS}"
|
||
was_on: !lambda "return id(ha_state_tile1).state;"
|
||
off_value: !lambda "return atoi(\"${TILE1_LONGPRESS_OFF_VALUE}\");"
|
||
brightness_value: !lambda "return id(tile1_brightness).state;"
|
||
percentage_value: !lambda "return id(tile1_percentage).state;"
|
||
icon_text: "${TILE1_ICON}"
|
||
slider_bg_color: ${TILE1_BG_DISABLED_COLOR}
|
||
slider_fill_color: ${TILE1_CIRCLE_ACTIVE_COLOR}
|
||
slider_icon_color: ${TILE1_ICON_ACTIVE_COLOR}
|
||
|
||
# ---------- TILE 2 ----------
|
||
- obj:
|
||
id: tile2
|
||
x: 164
|
||
y: 54
|
||
width: 147
|
||
height: 52
|
||
styles: style_tile
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- obj:
|
||
id: tile2_icon_circle
|
||
x: 0
|
||
y: 0
|
||
width: 36
|
||
height: 36
|
||
styles: style_icon_circle
|
||
clickable: false
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- label:
|
||
id: tile2_icon_lbl
|
||
align: CENTER
|
||
text_font: materialdesign_icons
|
||
text_color: 0xFFFFFF
|
||
text: "${TILE2_ICON}"
|
||
clickable: false
|
||
- label:
|
||
id: t2_title
|
||
x: 48
|
||
y: 4
|
||
text: "${TILE2_TITLE}"
|
||
styles: style_title
|
||
clickable: false
|
||
- label:
|
||
id: t2_value
|
||
x: 48
|
||
y: 18
|
||
text: "—"
|
||
styles: style_value
|
||
clickable: false
|
||
on_short_click:
|
||
- script.execute: { id: publish_action, action: "tile2_press" }
|
||
- script.execute:
|
||
id: do_tile_action
|
||
tile_type: "${TILE2_TYPE}"
|
||
tap_action: "${TILE2_TAP_ACTION}"
|
||
service: "${TILE2_TAP_SERVICE}"
|
||
entity_id: "${TILE2_ENTITY}"
|
||
param_key: "${TILE2_TAP_PARAM_KEY}"
|
||
param_val: "${TILE2_TAP_PARAM_VAL}"
|
||
was_on: !lambda "return id(ha_state_tile2).state;"
|
||
on_long_press:
|
||
- if:
|
||
condition:
|
||
lambda: |-
|
||
std::string lp = "${TILE2_LONGPRESS}";
|
||
std::string type = "${TILE2_TYPE}";
|
||
if (lp == "none") return false;
|
||
if (lp == "auto") return (type == "light" || type == "fan");
|
||
return (lp == "brightness" || lp == "percentage");
|
||
then:
|
||
- script.execute:
|
||
id: open_value_overlay
|
||
title: "${TILE2_TITLE}"
|
||
entity: "${TILE2_ENTITY}"
|
||
tile_type: "${TILE2_TYPE}"
|
||
longpress_mode: "${TILE2_LONGPRESS}"
|
||
was_on: !lambda "return id(ha_state_tile2).state;"
|
||
off_value: !lambda "return atoi(\"${TILE2_LONGPRESS_OFF_VALUE}\");"
|
||
brightness_value: !lambda "return id(tile2_brightness).state;"
|
||
percentage_value: !lambda "return id(tile2_percentage).state;"
|
||
icon_text: "${TILE2_ICON}"
|
||
slider_bg_color: ${TILE2_BG_DISABLED_COLOR}
|
||
slider_fill_color: ${TILE2_CIRCLE_ACTIVE_COLOR}
|
||
slider_icon_color: ${TILE2_ICON_ACTIVE_COLOR}
|
||
|
||
# ---------- TILE 3 ----------
|
||
- obj:
|
||
id: tile3
|
||
x: 9
|
||
y: 114
|
||
width: 147
|
||
height: 52
|
||
styles: style_tile
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- obj:
|
||
id: tile3_icon_circle
|
||
x: 0
|
||
y: 0
|
||
width: 36
|
||
height: 36
|
||
styles: style_icon_circle
|
||
clickable: false
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- label:
|
||
id: tile3_icon_lbl
|
||
align: CENTER
|
||
text_font: materialdesign_icons
|
||
text_color: 0xFFFFFF
|
||
text: "${TILE3_ICON}"
|
||
clickable: false
|
||
- label:
|
||
id: t3_title
|
||
x: 48
|
||
y: 4
|
||
text: "${TILE3_TITLE}"
|
||
styles: style_title
|
||
clickable: false
|
||
- label:
|
||
id: t3_value
|
||
x: 48
|
||
y: 18
|
||
text: "—"
|
||
styles: style_value
|
||
clickable: false
|
||
on_short_click:
|
||
- script.execute: { id: publish_action, action: "tile3_press" }
|
||
- script.execute:
|
||
id: do_tile_action
|
||
tile_type: "${TILE3_TYPE}"
|
||
tap_action: "${TILE3_TAP_ACTION}"
|
||
service: "${TILE3_TAP_SERVICE}"
|
||
entity_id: "${TILE3_ENTITY}"
|
||
param_key: "${TILE3_TAP_PARAM_KEY}"
|
||
param_val: "${TILE3_TAP_PARAM_VAL}"
|
||
was_on: !lambda "return id(ha_state_tile3).state;"
|
||
on_long_press:
|
||
- if:
|
||
condition:
|
||
lambda: |-
|
||
std::string lp = "${TILE3_LONGPRESS}";
|
||
std::string type = "${TILE3_TYPE}";
|
||
if (lp == "none") return false;
|
||
if (lp == "auto") return (type == "light" || type == "fan");
|
||
return (lp == "brightness" || lp == "percentage");
|
||
then:
|
||
- script.execute:
|
||
id: open_value_overlay
|
||
title: "${TILE3_TITLE}"
|
||
entity: "${TILE3_ENTITY}"
|
||
tile_type: "${TILE3_TYPE}"
|
||
longpress_mode: "${TILE3_LONGPRESS}"
|
||
was_on: !lambda "return id(ha_state_tile3).state;"
|
||
off_value: !lambda "return atoi(\"${TILE3_LONGPRESS_OFF_VALUE}\");"
|
||
brightness_value: !lambda "return id(tile3_brightness).state;"
|
||
percentage_value: !lambda "return id(tile3_percentage).state;"
|
||
icon_text: "${TILE3_ICON}"
|
||
slider_bg_color: ${TILE3_BG_DISABLED_COLOR}
|
||
slider_fill_color: ${TILE3_CIRCLE_ACTIVE_COLOR}
|
||
slider_icon_color: ${TILE3_ICON_ACTIVE_COLOR}
|
||
|
||
# ---------- TILE 4 ----------
|
||
- obj:
|
||
id: tile4
|
||
x: 164
|
||
y: 114
|
||
width: 147
|
||
height: 52
|
||
styles: style_tile
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- obj:
|
||
id: tile4_icon_circle
|
||
x: 0
|
||
y: 0
|
||
width: 36
|
||
height: 36
|
||
styles: style_icon_circle
|
||
clickable: false
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- label:
|
||
id: tile4_icon_lbl
|
||
align: CENTER
|
||
text_font: materialdesign_icons
|
||
text_color: 0xFFFFFF
|
||
text: "${TILE4_ICON}"
|
||
clickable: false
|
||
- label:
|
||
id: t4_title
|
||
x: 48
|
||
y: 4
|
||
text: "${TILE4_TITLE}"
|
||
styles: style_title
|
||
clickable: false
|
||
- label:
|
||
id: t4_value
|
||
x: 48
|
||
y: 18
|
||
text: "—"
|
||
styles: style_value
|
||
clickable: false
|
||
on_short_click:
|
||
- script.execute: { id: publish_action, action: "tile4_press" }
|
||
- script.execute:
|
||
id: do_tile_action
|
||
tile_type: "${TILE4_TYPE}"
|
||
tap_action: "${TILE4_TAP_ACTION}"
|
||
service: "${TILE4_TAP_SERVICE}"
|
||
entity_id: "${TILE4_ENTITY}"
|
||
param_key: "${TILE4_TAP_PARAM_KEY}"
|
||
param_val: "${TILE4_TAP_PARAM_VAL}"
|
||
was_on: !lambda "return id(ha_state_tile4).state;"
|
||
on_long_press:
|
||
- if:
|
||
condition:
|
||
lambda: |-
|
||
std::string lp = "${TILE4_LONGPRESS}";
|
||
std::string type = "${TILE4_TYPE}";
|
||
if (lp == "none") return false;
|
||
if (lp == "auto") return (type == "light" || type == "fan");
|
||
return (lp == "brightness" || lp == "percentage");
|
||
then:
|
||
- script.execute:
|
||
id: open_value_overlay
|
||
title: "${TILE4_TITLE}"
|
||
entity: "${TILE4_ENTITY}"
|
||
tile_type: "${TILE4_TYPE}"
|
||
longpress_mode: "${TILE4_LONGPRESS}"
|
||
was_on: !lambda "return id(ha_state_tile4).state;"
|
||
off_value: !lambda "return atoi(\"${TILE4_LONGPRESS_OFF_VALUE}\");"
|
||
brightness_value: !lambda "return id(tile4_brightness).state;"
|
||
percentage_value: !lambda "return id(tile4_percentage).state;"
|
||
icon_text: "${TILE4_ICON}"
|
||
slider_bg_color: ${TILE4_BG_DISABLED_COLOR}
|
||
slider_fill_color: ${TILE4_CIRCLE_ACTIVE_COLOR}
|
||
slider_icon_color: ${TILE4_ICON_ACTIVE_COLOR}
|
||
|
||
# ---------- TILE 5 ----------
|
||
- obj:
|
||
id: tile5
|
||
x: 9
|
||
y: 174
|
||
width: 147
|
||
height: 52
|
||
styles: style_tile
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- obj:
|
||
id: tile5_icon_circle
|
||
x: 0
|
||
y: 0
|
||
width: 36
|
||
height: 36
|
||
styles: style_icon_circle
|
||
clickable: false
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- label:
|
||
id: tile5_icon_lbl
|
||
align: CENTER
|
||
text_font: materialdesign_icons
|
||
text_color: 0xFFFFFF
|
||
text: "${TILE5_ICON}"
|
||
clickable: false
|
||
- label:
|
||
id: t5_title
|
||
x: 48
|
||
y: 4
|
||
text: "${TILE5_TITLE}"
|
||
styles: style_title
|
||
clickable: false
|
||
- label:
|
||
id: t5_value
|
||
x: 48
|
||
y: 18
|
||
text: "—"
|
||
styles: style_value
|
||
clickable: false
|
||
on_short_click:
|
||
- script.execute: { id: publish_action, action: "tile5_press" }
|
||
- script.execute:
|
||
id: do_tile_action
|
||
tile_type: "${TILE5_TYPE}"
|
||
tap_action: "${TILE5_TAP_ACTION}"
|
||
service: "${TILE5_TAP_SERVICE}"
|
||
entity_id: "${TILE5_ENTITY}"
|
||
param_key: "${TILE5_TAP_PARAM_KEY}"
|
||
param_val: "${TILE5_TAP_PARAM_VAL}"
|
||
was_on: !lambda "return id(ha_state_tile5).state;"
|
||
on_long_press:
|
||
- if:
|
||
condition:
|
||
lambda: |-
|
||
std::string lp = "${TILE5_LONGPRESS}";
|
||
std::string type = "${TILE5_TYPE}";
|
||
if (lp == "none") return false;
|
||
if (lp == "auto") return (type == "light" || type == "fan");
|
||
return (lp == "brightness" || lp == "percentage");
|
||
then:
|
||
- script.execute:
|
||
id: open_value_overlay
|
||
title: "${TILE5_TITLE}"
|
||
entity: "${TILE5_ENTITY}"
|
||
tile_type: "${TILE5_TYPE}"
|
||
longpress_mode: "${TILE5_LONGPRESS}"
|
||
was_on: !lambda "return id(ha_state_tile5).state;"
|
||
off_value: !lambda "return atoi(\"${TILE5_LONGPRESS_OFF_VALUE}\");"
|
||
brightness_value: !lambda "return id(tile5_brightness).state;"
|
||
percentage_value: !lambda "return id(tile5_percentage).state;"
|
||
icon_text: "${TILE5_ICON}"
|
||
slider_bg_color: ${TILE5_BG_DISABLED_COLOR}
|
||
slider_fill_color: ${TILE5_CIRCLE_ACTIVE_COLOR}
|
||
slider_icon_color: ${TILE5_ICON_ACTIVE_COLOR}
|
||
|
||
# ---------- TILE 6 ----------
|
||
- obj:
|
||
id: tile6
|
||
x: 164
|
||
y: 174
|
||
width: 147
|
||
height: 52
|
||
styles: style_tile
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- obj:
|
||
id: tile6_icon_circle
|
||
x: 0
|
||
y: 0
|
||
width: 36
|
||
height: 36
|
||
styles: style_icon_circle
|
||
clickable: false
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
widgets:
|
||
- label:
|
||
id: tile6_icon_lbl
|
||
align: CENTER
|
||
text_font: materialdesign_icons
|
||
text_color: 0xFFFFFF
|
||
text: "${TILE6_ICON}"
|
||
clickable: false
|
||
- label:
|
||
id: t6_title
|
||
x: 48
|
||
y: 4
|
||
text: "${TILE6_TITLE}"
|
||
styles: style_title
|
||
clickable: false
|
||
- label:
|
||
id: t6_value
|
||
x: 48
|
||
y: 18
|
||
text: "—"
|
||
styles: style_value
|
||
clickable: false
|
||
on_short_click:
|
||
- script.execute: { id: publish_action, action: "tile6_press" }
|
||
- script.execute:
|
||
id: do_tile_action
|
||
tile_type: "${TILE6_TYPE}"
|
||
tap_action: "${TILE6_TAP_ACTION}"
|
||
service: "${TILE6_TAP_SERVICE}"
|
||
entity_id: "${TILE6_ENTITY}"
|
||
param_key: "${TILE6_TAP_PARAM_KEY}"
|
||
param_val: "${TILE6_TAP_PARAM_VAL}"
|
||
was_on: !lambda "return id(ha_state_tile6).state;"
|
||
on_long_press:
|
||
- if:
|
||
condition:
|
||
lambda: |-
|
||
std::string lp = "${TILE6_LONGPRESS}";
|
||
std::string type = "${TILE6_TYPE}";
|
||
if (lp == "none") return false;
|
||
if (lp == "auto") return (type == "light" || type == "fan");
|
||
return (lp == "brightness" || lp == "percentage");
|
||
then:
|
||
- script.execute:
|
||
id: open_value_overlay
|
||
title: "${TILE6_TITLE}"
|
||
entity: "${TILE6_ENTITY}"
|
||
tile_type: "${TILE6_TYPE}"
|
||
longpress_mode: "${TILE6_LONGPRESS}"
|
||
was_on: !lambda "return id(ha_state_tile6).state;"
|
||
off_value: !lambda "return atoi(\"${TILE6_LONGPRESS_OFF_VALUE}\");"
|
||
brightness_value: !lambda "return id(tile6_brightness).state;"
|
||
percentage_value: !lambda "return id(tile6_percentage).state;"
|
||
icon_text: "${TILE6_ICON}"
|
||
slider_bg_color: ${TILE6_BG_DISABLED_COLOR}
|
||
slider_fill_color: ${TILE6_CIRCLE_ACTIVE_COLOR}
|
||
slider_icon_color: ${TILE6_ICON_ACTIVE_COLOR}
|
||
|
||
# ---------- VALUE SLIDER OVERLAY ----------
|
||
- obj:
|
||
id: brightness_overlay
|
||
x: 0
|
||
y: 0
|
||
width: 320
|
||
height: 240
|
||
bg_opa: TRANSP
|
||
hidden: true
|
||
scrollable: false
|
||
scrollbar_mode: 'OFF'
|
||
pad_left: 0
|
||
pad_right: 0
|
||
pad_top: 0
|
||
pad_bottom: 0
|
||
border_width: 0
|
||
widgets:
|
||
- image:
|
||
id: brightness_overlay_bg
|
||
src: bg_home
|
||
x: 0
|
||
y: 0
|
||
clickable: true
|
||
on_click:
|
||
- lvgl.widget.hide: brightness_overlay
|
||
- obj:
|
||
id: brightness_overlay_dim
|
||
x: 0
|
||
y: 0
|
||
width: 320
|
||
height: 240
|
||
bg_color: 0x000000
|
||
bg_opa: 18%
|
||
border_width: 0
|
||
clickable: false
|
||
scrollable: false
|
||
- label:
|
||
id: overlay_title
|
||
align: TOP_MID
|
||
y: 10
|
||
text: "Light"
|
||
styles: style_room
|
||
- label:
|
||
id: overlay_value
|
||
align: TOP_MID
|
||
y: 35
|
||
text: "100 %"
|
||
styles: style_value_big
|
||
- slider:
|
||
id: overlay_slider
|
||
align: CENTER
|
||
y: 18
|
||
width: 96
|
||
height: 160
|
||
min_value: 0
|
||
max_value: 100
|
||
value: 100
|
||
adv_hittest: false
|
||
bg_color: 0x939391
|
||
bg_opa: 100%
|
||
radius: 28
|
||
border_width: 0
|
||
indicator:
|
||
bg_color: 0xFEC600
|
||
bg_opa: 100%
|
||
radius: 28
|
||
knob:
|
||
bg_opa: 0%
|
||
border_width: 0
|
||
shadow_width: 0
|
||
pad_all: 10
|
||
on_value:
|
||
- script.execute:
|
||
id: slider_preview
|
||
value: !lambda "return x;"
|
||
on_release:
|
||
- script.execute:
|
||
id: slider_commit
|
||
value: !lambda "return lv_slider_get_value(id(overlay_slider));"
|
||
widgets:
|
||
- label:
|
||
id: overlay_icon
|
||
align: BOTTOM_MID
|
||
y: -10
|
||
text_font: materialdesign_icons
|
||
text_color: 0xFFFFFF
|
||
text: "${TILE1_ICON}"
|
||
clickable: false
|
||
|
||
script:
|
||
- id: publish_action
|
||
mode: queued
|
||
parameters:
|
||
action: string
|
||
then:
|
||
- text_sensor.template.publish:
|
||
id: smartdisplay_action
|
||
state: !lambda 'return action;'
|
||
- delay: 200ms
|
||
- text_sensor.template.publish:
|
||
id: smartdisplay_action
|
||
state: ""
|
||
|
||
- id: slider_preview
|
||
parameters:
|
||
value: int
|
||
then:
|
||
- lambda: |-
|
||
char buf[20];
|
||
snprintf(buf, sizeof(buf), "%d%s", value, id(active_value_suffix).c_str());
|
||
lv_label_set_text(id(overlay_value), buf);
|
||
|
||
- id: slider_commit
|
||
parameters:
|
||
value: int
|
||
then:
|
||
- if:
|
||
condition:
|
||
lambda: "return id(active_control_kind) == \"light_brightness\";"
|
||
then:
|
||
- homeassistant.action:
|
||
action: light.turn_on
|
||
data:
|
||
entity_id: !lambda "return id(active_entity);"
|
||
brightness_pct: !lambda "return value;"
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: "return id(active_control_kind) == \"fan_percentage\";"
|
||
then:
|
||
- if:
|
||
condition:
|
||
lambda: "return value <= 0;"
|
||
then:
|
||
- homeassistant.action:
|
||
action: fan.turn_off
|
||
data:
|
||
entity_id: !lambda "return id(active_entity);"
|
||
else:
|
||
- homeassistant.action:
|
||
action: fan.turn_on
|
||
data:
|
||
entity_id: !lambda "return id(active_entity);"
|
||
- delay: 150ms
|
||
- homeassistant.action:
|
||
action: fan.set_percentage
|
||
data:
|
||
entity_id: !lambda "return id(active_entity);"
|
||
percentage: !lambda "return value;"
|
||
|
||
- id: do_tile_action
|
||
mode: queued
|
||
parameters:
|
||
tile_type: string
|
||
tap_action: string
|
||
service: string
|
||
entity_id: string
|
||
param_key: string
|
||
param_val: string
|
||
was_on: bool
|
||
then:
|
||
- if:
|
||
condition:
|
||
lambda: 'return std::string("${DIRECT_ACTIONS}") == "true";'
|
||
then:
|
||
- lambda: |-
|
||
ESP_LOGD("tile", "do_tile_action type=%s action=%s service=%s entity=%s key=%s val=%s was_on=%d",
|
||
tile_type.c_str(), tap_action.c_str(), service.c_str(), entity_id.c_str(),
|
||
param_key.c_str(), param_val.c_str(), (int)was_on);
|
||
- if:
|
||
condition:
|
||
lambda: "return tap_action == \"fan_toggle_preset\";"
|
||
then:
|
||
- if:
|
||
condition:
|
||
lambda: "return was_on;"
|
||
then:
|
||
- homeassistant.action:
|
||
action: fan.turn_off
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
else:
|
||
- homeassistant.action:
|
||
action: fan.turn_on
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
- delay: 150ms
|
||
- homeassistant.action:
|
||
action: fan.set_preset_mode
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
preset_mode: !lambda 'return param_val;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: |-
|
||
std::string r = tap_action;
|
||
if (r == "auto") r = (tile_type == "scene" || tile_type == "script") ? "activate" : "toggle";
|
||
return r == "toggle";
|
||
then:
|
||
- if:
|
||
condition:
|
||
lambda: "return service.size() > 0;"
|
||
then:
|
||
- homeassistant.action:
|
||
action: !lambda 'return service;'
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: 'return tile_type == "light";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: light.toggle
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: 'return tile_type == "fan";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: fan.toggle
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: 'return tile_type == "switch";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: switch.toggle
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: |-
|
||
std::string r = tap_action;
|
||
if (r == "auto") r = (tile_type == "scene" || tile_type == "script") ? "activate" : "toggle";
|
||
return r == "activate";
|
||
then:
|
||
- if:
|
||
condition:
|
||
lambda: "return service.size() > 0;"
|
||
then:
|
||
- if:
|
||
condition:
|
||
lambda: 'return param_key == "preset_mode";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: !lambda 'return service;'
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
preset_mode: !lambda 'return param_val;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: 'return param_key == "brightness_pct";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: !lambda 'return service;'
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
brightness_pct: !lambda 'return atoi(param_val.c_str());'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: 'return param_key == "percentage";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: !lambda 'return service;'
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
percentage: !lambda 'return atoi(param_val.c_str());'
|
||
else:
|
||
- homeassistant.action:
|
||
action: !lambda 'return service;'
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: 'return tile_type == "scene";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: scene.turn_on
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: 'return tile_type == "script";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: script.turn_on
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: 'return tile_type == "light";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: light.turn_on
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: 'return tile_type == "fan";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: fan.turn_on
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
else:
|
||
- if:
|
||
condition:
|
||
lambda: 'return tile_type == "switch";'
|
||
then:
|
||
- homeassistant.action:
|
||
action: switch.turn_on
|
||
data:
|
||
entity_id: !lambda 'return entity_id;'
|
||
|
||
- id: open_value_overlay
|
||
parameters:
|
||
title: string
|
||
entity: string
|
||
tile_type: string
|
||
longpress_mode: string
|
||
was_on: bool
|
||
off_value: int
|
||
brightness_value: float
|
||
percentage_value: float
|
||
icon_text: string
|
||
slider_bg_color: uint32_t
|
||
slider_fill_color: uint32_t
|
||
slider_icon_color: uint32_t
|
||
then:
|
||
- lambda: |-
|
||
std::string mode = longpress_mode;
|
||
if (mode == "auto") {
|
||
if (tile_type == "light") mode = "brightness";
|
||
else if (tile_type == "fan") mode = "percentage";
|
||
else mode = "none";
|
||
}
|
||
if (mode == "none") return;
|
||
id(active_entity) = entity;
|
||
id(active_value_suffix) = " %";
|
||
id(overlay_slider_bg_color) = slider_bg_color;
|
||
id(overlay_slider_fill_color) = slider_fill_color;
|
||
int pct = off_value;
|
||
if (mode == "brightness") {
|
||
id(active_control_kind) = "light_brightness";
|
||
if (was_on) {
|
||
if (isnan(brightness_value)) pct = 100;
|
||
else pct = (int) lround((brightness_value / 255.0f) * 100.0f);
|
||
}
|
||
} else if (mode == "percentage") {
|
||
id(active_control_kind) = "fan_percentage";
|
||
if (was_on) {
|
||
if (isnan(percentage_value)) pct = 0;
|
||
else pct = (int) lround(percentage_value);
|
||
}
|
||
} else { return; }
|
||
if (pct < 0) pct = 0;
|
||
if (pct > 100) pct = 100;
|
||
lv_label_set_text(id(overlay_title), title.c_str());
|
||
lv_label_set_text(id(overlay_icon), icon_text.c_str());
|
||
lv_slider_set_value(id(overlay_slider), pct, LV_ANIM_OFF);
|
||
char buf[20];
|
||
snprintf(buf, sizeof(buf), "%d%s", pct, id(active_value_suffix).c_str());
|
||
lv_label_set_text(id(overlay_value), buf);
|
||
lv_obj_set_style_bg_color(id(overlay_slider), lv_color_hex(slider_bg_color), LV_PART_MAIN);
|
||
lv_obj_set_style_bg_opa(id(overlay_slider), LV_OPA_COVER, LV_PART_MAIN);
|
||
lv_obj_set_style_bg_color(id(overlay_slider), lv_color_hex(slider_fill_color), LV_PART_INDICATOR);
|
||
lv_obj_set_style_bg_opa(id(overlay_slider), LV_OPA_COVER, LV_PART_INDICATOR);
|
||
lv_obj_set_style_text_color(id(overlay_icon), lv_color_hex(slider_icon_color), 0);
|
||
- lvgl.widget.show: brightness_overlay
|
||
|
||
- id: ui_refresh
|
||
mode: queued
|
||
then:
|
||
- lambda: |-
|
||
auto set_lbl = [](lv_obj_t* lbl, const std::string& s) {
|
||
if (lbl) lv_label_set_text(lbl, s.c_str());
|
||
};
|
||
auto set_value_auto = [&](lv_obj_t* lbl, bool on,
|
||
const std::string& tile_type, const std::string& value_mode,
|
||
float brightness, float percentage, const std::string& preset,
|
||
const std::string& label_on, const std::string& label_off) {
|
||
std::string mode = value_mode;
|
||
if (mode == "auto" || mode.empty()) {
|
||
if (tile_type == "light") mode = "brightness";
|
||
else if (tile_type == "fan") mode = preset.empty() ? "percentage" : "preset";
|
||
else mode = "text";
|
||
}
|
||
if (mode == "brightness") {
|
||
if (!on) { set_lbl(lbl, label_off); return; }
|
||
if (isnan(brightness)) { set_lbl(lbl, "100 %"); return; }
|
||
int pct = (int) lround((brightness / 255.0f) * 100.0f);
|
||
char buf[8]; snprintf(buf, sizeof(buf), "%d %%", pct);
|
||
set_lbl(lbl, std::string(buf)); return;
|
||
}
|
||
if (mode == "percentage") {
|
||
if (!on) { set_lbl(lbl, label_off); return; }
|
||
int pct = isnan(percentage) ? 0 : (int) lround(percentage);
|
||
char buf[8]; snprintf(buf, sizeof(buf), "%d %%", pct);
|
||
set_lbl(lbl, std::string(buf)); return;
|
||
}
|
||
if (mode == "preset") {
|
||
if (!on) { set_lbl(lbl, label_off); return; }
|
||
set_lbl(lbl, !preset.empty() ? preset : label_on); return;
|
||
}
|
||
if (mode == "text") {
|
||
if (tile_type == "scene" || tile_type == "script") set_lbl(lbl, label_on);
|
||
else set_lbl(lbl, on ? label_on : label_off);
|
||
return;
|
||
}
|
||
set_lbl(lbl, "—");
|
||
};
|
||
set_value_auto(id(t1_value), id(ha_state_tile1).state, "${TILE1_TYPE}", "${TILE1_VALUE_MODE}",
|
||
id(tile1_brightness).state, id(tile1_percentage).state, std::string(id(tile1_preset).state.c_str()),
|
||
"${TILE1_LABEL_ON}", "${TILE1_LABEL_OFF}");
|
||
set_value_auto(id(t2_value), id(ha_state_tile2).state, "${TILE2_TYPE}", "${TILE2_VALUE_MODE}",
|
||
id(tile2_brightness).state, id(tile2_percentage).state, std::string(id(tile2_preset).state.c_str()),
|
||
"${TILE2_LABEL_ON}", "${TILE2_LABEL_OFF}");
|
||
set_value_auto(id(t3_value), id(ha_state_tile3).state, "${TILE3_TYPE}", "${TILE3_VALUE_MODE}",
|
||
id(tile3_brightness).state, id(tile3_percentage).state, std::string(id(tile3_preset).state.c_str()),
|
||
"${TILE3_LABEL_ON}", "${TILE3_LABEL_OFF}");
|
||
set_value_auto(id(t4_value), id(ha_state_tile4).state, "${TILE4_TYPE}", "${TILE4_VALUE_MODE}",
|
||
id(tile4_brightness).state, id(tile4_percentage).state, std::string(id(tile4_preset).state.c_str()),
|
||
"${TILE4_LABEL_ON}", "${TILE4_LABEL_OFF}");
|
||
set_value_auto(id(t5_value), id(ha_state_tile5).state, "${TILE5_TYPE}", "${TILE5_VALUE_MODE}",
|
||
id(tile5_brightness).state, id(tile5_percentage).state, std::string(id(tile5_preset).state.c_str()),
|
||
"${TILE5_LABEL_ON}", "${TILE5_LABEL_OFF}");
|
||
set_value_auto(id(t6_value), id(ha_state_tile6).state, "${TILE6_TYPE}", "${TILE6_VALUE_MODE}",
|
||
id(tile6_brightness).state, id(tile6_percentage).state, std::string(id(tile6_preset).state.c_str()),
|
||
"${TILE6_LABEL_ON}", "${TILE6_LABEL_OFF}");
|
||
{
|
||
auto now = id(homeassistant_time).now();
|
||
char buf[10];
|
||
if (std::string("${TIME_24H}") == "true") {
|
||
snprintf(buf, sizeof(buf), "%02d:%02d", now.hour, now.minute);
|
||
} else {
|
||
int h = now.hour % 12; if (h == 0) h = 12;
|
||
snprintf(buf, sizeof(buf), "%d:%02d %s", h, now.minute, now.hour >= 12 ? "PM" : "AM");
|
||
}
|
||
set_lbl(id(lbl_time), std::string(buf));
|
||
}
|
||
auto apply_tile = [&](bool active, lv_obj_t* tile, lv_obj_t* circle,
|
||
lv_obj_t* title, lv_obj_t* value, lv_obj_t* icon_lbl,
|
||
uint32_t ca, uint32_t cd, uint32_t ia, uint32_t id_,
|
||
uint32_t ba, uint32_t bd, uint32_t ta, uint32_t td,
|
||
uint32_t va, uint32_t vd) {
|
||
lv_obj_set_style_bg_color(tile, lv_color_hex(active ? ba : bd), 0);
|
||
lv_obj_set_style_bg_color(circle, lv_color_hex(active ? ca : cd), 0);
|
||
lv_obj_set_style_text_color(icon_lbl, lv_color_hex(active ? ia : id_), 0);
|
||
lv_obj_set_style_text_color(title, lv_color_hex(active ? ta : td), 0);
|
||
lv_obj_set_style_text_color(value, lv_color_hex(active ? va : vd), 0);
|
||
};
|
||
apply_tile(id(ha_state_tile1).state, id(tile1), id(tile1_icon_circle), id(t1_title), id(t1_value), id(tile1_icon_lbl),
|
||
${TILE1_CIRCLE_ACTIVE_COLOR}, ${TILE1_CIRCLE_DISABLED_COLOR}, ${TILE1_ICON_ACTIVE_COLOR}, ${TILE1_ICON_DISABLED_COLOR},
|
||
${TILE1_BG_ACTIVE_COLOR}, ${TILE1_BG_DISABLED_COLOR}, ${TILE1_TITLE_ACTIVE_COLOR}, ${TILE1_TITLE_DISABLED_COLOR},
|
||
${TILE1_VALUE_ACTIVE_COLOR}, ${TILE1_VALUE_DISABLED_COLOR});
|
||
apply_tile(id(ha_state_tile2).state, id(tile2), id(tile2_icon_circle), id(t2_title), id(t2_value), id(tile2_icon_lbl),
|
||
${TILE2_CIRCLE_ACTIVE_COLOR}, ${TILE2_CIRCLE_DISABLED_COLOR}, ${TILE2_ICON_ACTIVE_COLOR}, ${TILE2_ICON_DISABLED_COLOR},
|
||
${TILE2_BG_ACTIVE_COLOR}, ${TILE2_BG_DISABLED_COLOR}, ${TILE2_TITLE_ACTIVE_COLOR}, ${TILE2_TITLE_DISABLED_COLOR},
|
||
${TILE2_VALUE_ACTIVE_COLOR}, ${TILE2_VALUE_DISABLED_COLOR});
|
||
apply_tile(id(ha_state_tile3).state, id(tile3), id(tile3_icon_circle), id(t3_title), id(t3_value), id(tile3_icon_lbl),
|
||
${TILE3_CIRCLE_ACTIVE_COLOR}, ${TILE3_CIRCLE_DISABLED_COLOR}, ${TILE3_ICON_ACTIVE_COLOR}, ${TILE3_ICON_DISABLED_COLOR},
|
||
${TILE3_BG_ACTIVE_COLOR}, ${TILE3_BG_DISABLED_COLOR}, ${TILE3_TITLE_ACTIVE_COLOR}, ${TILE3_TITLE_DISABLED_COLOR},
|
||
${TILE3_VALUE_ACTIVE_COLOR}, ${TILE3_VALUE_DISABLED_COLOR});
|
||
apply_tile(id(ha_state_tile4).state, id(tile4), id(tile4_icon_circle), id(t4_title), id(t4_value), id(tile4_icon_lbl),
|
||
${TILE4_CIRCLE_ACTIVE_COLOR}, ${TILE4_CIRCLE_DISABLED_COLOR}, ${TILE4_ICON_ACTIVE_COLOR}, ${TILE4_ICON_DISABLED_COLOR},
|
||
${TILE4_BG_ACTIVE_COLOR}, ${TILE4_BG_DISABLED_COLOR}, ${TILE4_TITLE_ACTIVE_COLOR}, ${TILE4_TITLE_DISABLED_COLOR},
|
||
${TILE4_VALUE_ACTIVE_COLOR}, ${TILE4_VALUE_DISABLED_COLOR});
|
||
apply_tile(id(ha_state_tile5).state, id(tile5), id(tile5_icon_circle), id(t5_title), id(t5_value), id(tile5_icon_lbl),
|
||
${TILE5_CIRCLE_ACTIVE_COLOR}, ${TILE5_CIRCLE_DISABLED_COLOR}, ${TILE5_ICON_ACTIVE_COLOR}, ${TILE5_ICON_DISABLED_COLOR},
|
||
${TILE5_BG_ACTIVE_COLOR}, ${TILE5_BG_DISABLED_COLOR}, ${TILE5_TITLE_ACTIVE_COLOR}, ${TILE5_TITLE_DISABLED_COLOR},
|
||
${TILE5_VALUE_ACTIVE_COLOR}, ${TILE5_VALUE_DISABLED_COLOR});
|
||
apply_tile(id(ha_state_tile6).state, id(tile6), id(tile6_icon_circle), id(t6_title), id(t6_value), id(tile6_icon_lbl),
|
||
${TILE6_CIRCLE_ACTIVE_COLOR}, ${TILE6_CIRCLE_DISABLED_COLOR}, ${TILE6_ICON_ACTIVE_COLOR}, ${TILE6_ICON_DISABLED_COLOR},
|
||
${TILE6_BG_ACTIVE_COLOR}, ${TILE6_BG_DISABLED_COLOR}, ${TILE6_TITLE_ACTIVE_COLOR}, ${TILE6_TITLE_DISABLED_COLOR},
|
||
${TILE6_VALUE_ACTIVE_COLOR}, ${TILE6_VALUE_DISABLED_COLOR});
|
||
- component.update: my_display
|