561 lines
17 KiB
YAML
561 lines
17 KiB
YAML
substitutions:
|
|
ha_server: "http://192.168.1.44:8123"
|
|
media_player_entity: "media_player.yandex_station_m00bv9j00dc7sg"
|
|
|
|
power_icon: "\U0000e909"
|
|
play_icon: "\U0000e90a"
|
|
pause_icon: "\U0000e90b"
|
|
back_step_icon: "\U0000e90c"
|
|
forward_step_icon: "\U0000e90d"
|
|
volume_off_icon: "\U0000e90e"
|
|
volume_on_icon: "\U0000e90f"
|
|
volume_minus_icon: "\U0000e910"
|
|
volume_plus_icon: "\U0000e911"
|
|
repeat_all_icon: "\U0000e912"
|
|
repeat_off_icon: "\U0000e913"
|
|
repeat_one_icon: "\U0000e914"
|
|
|
|
globals:
|
|
- id: repeat_modes
|
|
type: std::vector<std::string>
|
|
initial_value: '{"all", "one", "off"}'
|
|
- id: repeat_icons
|
|
type: std::vector<std::string>
|
|
initial_value: '{"${repeat_all_icon}", "${repeat_one_icon}", "${repeat_off_icon}"}'
|
|
- id: current_repeat_mode_idx
|
|
type: int
|
|
initial_value: '0'
|
|
- id: tmp_repeat_mode
|
|
type: std::string
|
|
restore_value: no
|
|
initial_value: '"all"'
|
|
- id: tmp_repeat_icon
|
|
type: std::string
|
|
restore_value: no
|
|
initial_value: '"${repeat_all_icon}"'
|
|
- id: cover_url
|
|
type: std::string
|
|
restore_value: no
|
|
initial_value: '""'
|
|
- id: duration_slider_user_interaction
|
|
type: bool
|
|
restore_value: no
|
|
initial_value: 'false'
|
|
- id: slider_position
|
|
type: float
|
|
restore_value: no
|
|
initial_value: '0.0'
|
|
- id: pending_cover_url
|
|
type: std::string
|
|
restore_value: no
|
|
initial_value: '""'
|
|
- id: pending_repeat_value
|
|
type: std::string
|
|
restore_value: no
|
|
initial_value: '""'
|
|
|
|
script:
|
|
- id: update_cover_script
|
|
mode: restart
|
|
then:
|
|
- lambda: |-
|
|
std::string url = id(pending_cover_url);
|
|
id(cover_url) = url;
|
|
- homeassistant.action:
|
|
action: display_tools.save_media_cover
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
size: small
|
|
- delay: 1s
|
|
- online_image.release: media_image_jpeg
|
|
- online_image.set_url:
|
|
id: media_image_jpeg
|
|
url: "${ha_server}/local/display_tools/cover.jpeg"
|
|
|
|
- id: update_repeat_mode_script
|
|
mode: restart
|
|
then:
|
|
- lambda: |-
|
|
std::string x = id(pending_repeat_value);
|
|
auto modes = id(repeat_modes);
|
|
auto icons = id(repeat_icons);
|
|
for (int i = 0; i < modes.size(); i++) {
|
|
if (modes[i] == x) {
|
|
id(current_repeat_mode_idx) = i;
|
|
id(tmp_repeat_mode) = modes[i];
|
|
id(tmp_repeat_icon) = icons[i];
|
|
break;
|
|
}
|
|
}
|
|
- lvgl.label.update:
|
|
id: media_player_repeat_label
|
|
text: !lambda 'return id(tmp_repeat_icon);'
|
|
|
|
- id: handle_repeat_press_script
|
|
mode: restart
|
|
then:
|
|
- lambda: |-
|
|
int idx = id(current_repeat_mode_idx);
|
|
auto modes = id(repeat_modes);
|
|
auto icons = id(repeat_icons);
|
|
idx = (idx + 1) % modes.size();
|
|
id(current_repeat_mode_idx) = idx;
|
|
std::string new_mode = modes[idx];
|
|
std::string new_icon = icons[idx];
|
|
id(tmp_repeat_mode) = new_mode;
|
|
id(tmp_repeat_icon) = new_icon;
|
|
- lvgl.label.update:
|
|
id: media_player_repeat_label
|
|
text: !lambda 'return id(tmp_repeat_icon);'
|
|
- homeassistant.action:
|
|
action: media_player.repeat_set
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
repeat: !lambda 'return id(tmp_repeat_mode);'
|
|
|
|
- id: handle_duration_slider_release_script
|
|
mode: restart
|
|
then:
|
|
- homeassistant.service:
|
|
service: media_player.media_seek
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
seek_position: !lambda 'return std::to_string(int(id(slider_position)));'
|
|
- delay: 2s
|
|
- lambda: |-
|
|
id(duration_slider_user_interaction) = false;
|
|
|
|
lvgl:
|
|
pages:
|
|
- id: media_player_page
|
|
bg_color: color_slate_blue_gray
|
|
widgets:
|
|
|
|
# Cover
|
|
- obj:
|
|
id: media_cover
|
|
x: 10
|
|
y: 10
|
|
width: 140
|
|
height: 140
|
|
align: TOP_LEFT
|
|
bg_color: color_steel_blue
|
|
bg_image_src: media_image_jpeg
|
|
border_color: color_slate_blue_gray
|
|
border_width: 10
|
|
shadow_opa: TRANSP
|
|
radius: 20
|
|
|
|
# Title/Artist/Duration
|
|
- obj:
|
|
x: -20
|
|
y: 20
|
|
width: 300
|
|
height: 120
|
|
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: media_player_title_label
|
|
height: 40
|
|
width: 260
|
|
long_mode: DOT
|
|
y: -25
|
|
align: CENTER
|
|
text_color: color_misty_blue
|
|
text_font: nunito_20
|
|
text: "Title"
|
|
- label:
|
|
id: media_player_artist_label
|
|
height: 30
|
|
width: 260
|
|
long_mode: DOT
|
|
y: 3
|
|
align: CENTER
|
|
text_color: color_misty_blue
|
|
text_font: nunito_16
|
|
text: "Artist"
|
|
- slider:
|
|
id: media_player_duration_pos_slider
|
|
radius: 2
|
|
y: 35
|
|
bg_color: color_slate_blue_gray
|
|
align: CENTER
|
|
width: 260
|
|
height: 5
|
|
min_value: 0
|
|
max_value: 100
|
|
indicator:
|
|
bg_color: color_misty_blue
|
|
radius: 2
|
|
knob:
|
|
bg_opa: TRANSP
|
|
on_press:
|
|
- lambda: |-
|
|
id(duration_slider_user_interaction) = true;
|
|
on_release:
|
|
- lambda: |-
|
|
id(slider_position) = x;
|
|
- script.execute: handle_duration_slider_release_script
|
|
|
|
# Controls
|
|
- obj:
|
|
y: 160
|
|
width: 440
|
|
height: 120
|
|
align: TOP_MID
|
|
bg_color: color_steel_blue
|
|
bg_opa: 20%
|
|
border_opa: TRANSP
|
|
shadow_opa: TRANSP
|
|
radius: 10
|
|
widgets:
|
|
# Off
|
|
- label:
|
|
x: 10
|
|
align: LEFT_MID
|
|
text_color: color_steel_blue
|
|
text_font: icons_38
|
|
text: "${power_icon}"
|
|
on_press:
|
|
- homeassistant.action:
|
|
action: media_player.turn_off
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
# back
|
|
- label:
|
|
x: -80
|
|
align: CENTER
|
|
text_color: color_misty_blue
|
|
text_font: icons_38
|
|
text: "${back_step_icon}"
|
|
on_press:
|
|
- homeassistant.action:
|
|
action: media_player.media_previous_track
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
|
|
# play / pause
|
|
- obj:
|
|
id: media_player_control_play_bg
|
|
height: 90
|
|
width: 90
|
|
bg_color: color_steel_blue
|
|
bg_opa: 80%
|
|
border_opa: TRANSP
|
|
radius: 50
|
|
align: CENTER
|
|
widgets:
|
|
- label:
|
|
id: media_player_state_label
|
|
align: CENTER
|
|
text_color: color_misty_blue
|
|
text_font: icons_48
|
|
text: "${play_icon}"
|
|
on_press:
|
|
- if:
|
|
condition:
|
|
lambda: 'return id(media_player_state).state == "playing";'
|
|
then:
|
|
- homeassistant.action:
|
|
action: media_player.media_pause
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
else:
|
|
- homeassistant.action:
|
|
action: media_player.media_play
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
|
|
# forward
|
|
- label:
|
|
x: 80
|
|
align: CENTER
|
|
text_color: color_misty_blue
|
|
text_font: icons_38
|
|
text: "${forward_step_icon}"
|
|
on_press:
|
|
- homeassistant.action:
|
|
action: media_player.media_next_track
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
|
|
# repeat
|
|
- label:
|
|
id: media_player_repeat_label
|
|
x: -10
|
|
align: RIGHT_MID
|
|
text_color: color_steel_blue
|
|
text_font: icons_38
|
|
text: "${repeat_all_icon}"
|
|
on_press:
|
|
- script.execute: handle_repeat_press_script
|
|
|
|
# Volume
|
|
- obj:
|
|
y: 300
|
|
width: 440
|
|
height: 80
|
|
align: TOP_MID
|
|
bg_color: color_steel_blue
|
|
bg_opa: 20%
|
|
border_opa: TRANSP
|
|
shadow_opa: TRANSP
|
|
radius: 10
|
|
widgets:
|
|
# mute
|
|
- label:
|
|
id: media_player_mute_label
|
|
x: 10
|
|
align: LEFT_MID
|
|
text_color: color_steel_blue
|
|
text_font: icons_32
|
|
text: "${volume_on_icon}"
|
|
on_press:
|
|
- if:
|
|
condition:
|
|
lambda: 'return id(media_player_is_volume_muted).state;'
|
|
then:
|
|
- homeassistant.action:
|
|
action: media_player.volume_mute
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
is_volume_muted: "false"
|
|
else:
|
|
- homeassistant.action:
|
|
action: media_player.volume_mute
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
is_volume_muted: "true"
|
|
|
|
# vol down
|
|
- label:
|
|
id: media_player_vol_down_label
|
|
x: -280
|
|
align: RIGHT_MID
|
|
text_color: color_steel_blue
|
|
text_font: icons_32
|
|
text: "${volume_minus_icon}"
|
|
on_press:
|
|
- homeassistant.action:
|
|
action: media_player.volume_down
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
|
|
# set vol
|
|
- slider:
|
|
id: media_player_volume_slider
|
|
bg_color: color_slate_blue_gray
|
|
bg_opa: 100%
|
|
align: RIGHT_MID
|
|
x: -60
|
|
width: 200
|
|
height: 10
|
|
min_value: 0
|
|
max_value: 100
|
|
indicator:
|
|
bg_color: color_misty_blue
|
|
knob:
|
|
bg_color: color_misty_blue
|
|
on_release:
|
|
- homeassistant.action:
|
|
action: media_player.volume_set
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
volume_level: !lambda 'return float(x) / 100.0;'
|
|
|
|
# vol up
|
|
- label:
|
|
id: media_player_vol_up_label
|
|
x: -10
|
|
align: RIGHT_MID
|
|
text_color: color_steel_blue
|
|
text_font: icons_32
|
|
text: "${volume_plus_icon}"
|
|
on_press:
|
|
- homeassistant.action:
|
|
action: media_player.volume_up
|
|
data:
|
|
entity_id: "${media_player_entity}"
|
|
|
|
# Media player name
|
|
- obj:
|
|
x: -20
|
|
y: 400
|
|
width: 360
|
|
height: 60
|
|
align: TOP_RIGHT
|
|
bg_color: color_steel_blue
|
|
bg_opa: 20%
|
|
border_opa: TRANSP
|
|
shadow_opa: TRANSP
|
|
radius: 10
|
|
widgets:
|
|
- label:
|
|
id: media_player_name_label
|
|
align: CENTER
|
|
long_mode: DOT
|
|
text_color: color_misty_blue
|
|
text_font: nunito_16
|
|
text: "Friendly name"
|
|
|
|
# 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
|
|
|
|
text_sensor:
|
|
- platform: homeassistant
|
|
id: media_player_state
|
|
entity_id: "${media_player_entity}"
|
|
on_value:
|
|
- if:
|
|
condition:
|
|
lambda: 'return x == "paused";'
|
|
then:
|
|
- lvgl.label.update:
|
|
id: media_player_state_label
|
|
x: 0
|
|
text: "${play_icon}"
|
|
else:
|
|
- lvgl.label.update:
|
|
id: media_player_state_label
|
|
x: 0
|
|
text: "${pause_icon}"
|
|
|
|
- platform: homeassistant
|
|
id: media_player_cover
|
|
entity_id: "${media_player_entity}"
|
|
attribute: entity_picture
|
|
on_value:
|
|
- lambda: |-
|
|
id(pending_cover_url) = x;
|
|
- script.execute: update_cover_script
|
|
|
|
- platform: homeassistant
|
|
id: media_player_title_sensor
|
|
entity_id: "${media_player_entity}"
|
|
attribute: media_title
|
|
on_value:
|
|
- delay: 1s
|
|
- lvgl.label.update:
|
|
id: media_player_title_label
|
|
text: !lambda return x;
|
|
|
|
- platform: homeassistant
|
|
id: media_player_artist_sensor
|
|
entity_id: "${media_player_entity}"
|
|
attribute: media_artist
|
|
on_value:
|
|
- delay: 1s
|
|
- lvgl.label.update:
|
|
id: media_player_artist_label
|
|
text: !lambda return x;
|
|
|
|
- platform: homeassistant
|
|
id: media_player_repeat
|
|
entity_id: "${media_player_entity}"
|
|
attribute: repeat
|
|
on_value:
|
|
- lambda: |-
|
|
id(pending_repeat_value) = x;
|
|
- script.execute: update_repeat_mode_script
|
|
|
|
- platform: homeassistant
|
|
id: media_player_friendly_name
|
|
entity_id: "${media_player_entity}"
|
|
attribute: friendly_name
|
|
on_value:
|
|
- lvgl.label.update:
|
|
id: media_player_name_label
|
|
text: !lambda return x;
|
|
|
|
sensor:
|
|
- platform: homeassistant
|
|
id: media_player_volume_level
|
|
entity_id: "${media_player_entity}"
|
|
attribute: volume_level
|
|
on_value:
|
|
- lvgl.slider.update:
|
|
id: media_player_volume_slider
|
|
value: !lambda 'return int(x * 100);'
|
|
|
|
- platform: homeassistant
|
|
id: media_player_media_duration
|
|
entity_id: "${media_player_entity}"
|
|
attribute: media_duration
|
|
on_value:
|
|
- lambda: |-
|
|
lv_slider_set_range(id(media_player_duration_pos_slider), 0, x);
|
|
|
|
- platform: homeassistant
|
|
id: media_player_media_position
|
|
entity_id: "${media_player_entity}"
|
|
attribute: media_position
|
|
on_value:
|
|
- if:
|
|
condition:
|
|
lambda: 'return !id(duration_slider_user_interaction);'
|
|
then:
|
|
- lvgl.slider.update:
|
|
id: media_player_duration_pos_slider
|
|
value: !lambda return x;
|
|
|
|
|
|
binary_sensor:
|
|
- platform: homeassistant
|
|
id: media_player_is_volume_muted
|
|
entity_id: "${media_player_entity}"
|
|
attribute: is_volume_muted
|
|
on_state:
|
|
- if:
|
|
condition:
|
|
lambda: 'return x;'
|
|
then:
|
|
- lvgl.label.update:
|
|
id: media_player_mute_label
|
|
text: "${volume_off_icon}"
|
|
else:
|
|
- lvgl.label.update:
|
|
id: media_player_mute_label
|
|
text: "${volume_on_icon}"
|
|
|
|
online_image:
|
|
- url: "https://www.example.com/example.jpeg"
|
|
format: JPEG
|
|
type: RGB565
|
|
resize: 120x120
|
|
id: media_image_jpeg
|
|
on_download_finished:
|
|
- lvgl.obj.update:
|
|
id: media_cover
|
|
bg_image_src: media_image_jpeg
|
|
|
|
|
|
|
|
|
|
|
|
|