So, as mentioned above, if I was doing this again I’d use lovelace_gen from Thomas Loven.
My configuration, just for the remote, had grown to over 500 rows, much of it repetitive, it’s now 157.
I’ve learned more about CSS styling and so was able to overcome the issues I’d previously had with using icons. So this is much neater, easier to modify and easier to maintain.
Buttons still appear when they’re relevant and disappear when not and it looks similar but is much easier to adapt for different styles as well. The application buttons at the bottom are new and result from me getting an NVidia Shield and using the Android TV component. Took a while to figure out the commands for some of the apps, whichever one’s active gets coloured in.
What it looks like on my phone.
# lovelace_gen
title: Remote
path: remote
icon: mdi:play-pause
background: center / cover no-repeat url("/local/images/backgrounds/remote.jpg") fixed rgba(170, 170, 170, 1)
panel: true
cards:
- type: custom:layout-card
layout: vertical
cards:
############################################
## Activities
############################################
{% macro activity(entity, top, left) -%}
- type: state-icon
entity: {{ entity }}
tap_action:
action: toggle
style:
top: {{ top }}%
left: {{ left }}%
<<: &style_anchor
transform: matrix(1.8, 0, 0, 1.8, -20, -20)
background: rgb(105, 199, 252, .9)
filter: drop-shadow(2px 2px 5px rgb(100, 100, 100, 1)
border-radius: 100%
{%- endmacro %}
- type: picture-elements
image: /local/images/short-empty.png
elements:
{{ activity('switch.lounge_tv', 50, 12.5) }}
{{ activity('switch.usbc', 50, 37.5) }}
{{ activity('switch.ps3', 50, 62.5) }}
{{ activity('switch.soundbar', 50, 87.5) }}
############################################
## Conditional Activity Buttons
############################################
{% macro button(device, command, icon, top, left) -%}
- type: state-icon
entity: remote.lounge
tap_action:
action: call-service
service: remote.send_command
service_data:
entity_id: remote.lounge
device: {{ device }}
command: {{ command }}
icon: mdi:{{ icon }}
style:
<<: *style_anchor
top: {{ top }}%
left: {{ left }}%
{%- endmacro %}
{% macro nsbutton(device, command, icon, top, left) -%}
- type: state-icon
entity: remote.lounge
tap_action:
action: call-service
service: remote.send_command
service_data:
entity_id: remote.lounge
device: {{ device }}
command: {{ command }}
icon: mdi:{{ icon }}
style:
transform: matrix(2.5, 0, 0, 2.5, -20, -20)
top: {{ top }}%
left: {{ left }}%
{%- endmacro %}
############################################
## Volume controls for all activities
############################################
- type: conditional
conditions:
- entity: remote.lounge
state: "on"
card:
type: picture-elements
image: /local/images/short-empty.png
elements:
{{ button(29590185, 'VolumeDown', 'volume-minus', 50, 12.5) }}
{{ button(29590185, 'VolumeUp', 'volume-plus', 50, 37.5) }}
{{ button(29590185, 'Mute', 'volume-off', 50, 62.5) }}
{{ button(29590185, 'PowerToggle', 'speaker', 50, 87.5) }}
############################################
## Shield Remote
############################################
- type: conditional
conditions:
- entity: switch.lounge_tv
state: "on"
card:
type: picture-elements
image: /local/images/empty.png
elements:
- type: image
image: /local/images/remotecircle.png
style:
top: 50%
left: 50%
width: 60%
opacity: 0.9
filter: drop-shadow(2px 2px 5px rgb(100, 100, 100, 1)
border-radius: 100%
{{ button(64042126, 'Home', 'home-outline', 15, 12.5) }}
{{ button(64042126, 'Back', 'undo-variant', 15, 87.5) }}
{{ button(64042126, 'Select', 'keyboard-return', 50, 50) }}
transform: matrix(2.2, 0, 0, 2.2, -20, -20)
{{ nsbutton(64042126, 'DirectionUp', 'chevron-up', 22, 50) }}
{{ nsbutton(64042126, 'DirectionDown', 'chevron-down', 78, 50) }}
{{ nsbutton(64042126, 'DirectionLeft', 'chevron-left', 50, 27.5) }}
{{ nsbutton(64042126, 'DirectionRight', 'chevron-right', 50, 72.5) }}
{{ button(64042126, 'Pause', 'pause', 85, 12.5) }}
{{ button(64042126, 'Play', 'play', 85, 87.5) }}
############################################
## Applications
############################################
{% macro activity(app, top, left, adbcommand) -%}
- type: image
entity: sensor.cur_shield_app
tap_action:
action: call-service
service: script.launch_shield_app
service_data:
adbcommand: am start -a android.intent.action.VIEW -d -n {{ adbcommand }}
image: /local/images/logos/{{app}}.png
filter: grayscale(0.95) drop-shadow(2px 2px 5px rgb(100, 100, 100, 1)
state_filter:
'{{app}}': drop-shadow(2px 2px 5px rgb(100, 100, 100, 1)
style:
background: transparent
border-radius: 100%
top: {{ top }}%
left: {{ left }}%
width: 72px
{%- endmacro %}
- type: picture-elements
image: /local/images/medium-empty.png
elements:
{{ activity('iPlayer', 27.5, 12.5, 'com.nvidia.bbciplayer/.MainPlayerActivity') }}
{{ activity('PrimeVideo', 27.5, 37.5, 'com.amazon.amazonvideo.livingroom/com.amazon.ignition.IgnitionActivity') }}
{{ activity('Netflix', 27.5, 62.5, 'com.netflix.ninja/.MainActivity') }}
{{ activity('Kodi', 27.5, 87.5, 'org.xbmc.kodi/.Splash') }}
{{ activity('YouTube', 72.5, 12.5, 'com.google.android.youtube.tv/com.google.android.apps.youtube.tv.activity.ShellActivity') }}
{{ activity('RedBullTV', 72.5, 37.5, 'com.nousguide.android.rbtv/com.redbull.launch.SplashActivity') }}
{{ activity('ITVHub', 72.5, 62.5, 'air.ITVMobilePlayer/com.itv.tenft.itvhub.MainActivity') }}
{{ activity('GooglePlayMusic', 72.5, 87.5, 'com.google.android.music/.tv.HomeActivity') }}