It is a mix of a lot of different resources I’ve found in various places, so I’m sure it could be cleaner and more efficient, but here is the code I have right now. I’ve added some blank button cards into the navigation button rows to get a closer to centered look for now, but I’d still really love to find a way to get that to happen automatically so that I can reuse that template a bit more effectively.
Full YAML for dashboard view
- title: Mobile Home
path: mobile-home
type: custom:grid-layout
layout:
grid-template-columns: auto 400px auto
grid-template-rows: auto
grid-template-areas: |
"Gutter1 A Gutter2"
"Gutter1 B Gutter2"
"Gutter1 C Gutter2"
"Gutter1 D Gutter2"
background: center / cover no-repeat white fixed
badges: []
cards:
- type: custom:button-card
template: container
name: Speakers
show_name: false
custom_fields:
buttons:
card:
type: horizontal-stack
cards:
- type: custom:button-card
show_icon: false
show_name: false
show_state: false
size: 50%
tap_action:
action: none
hold_action:
action: none
styles:
card:
- height: 60px
- width: 80px
- border-radius: 100%
- align-self: left
- background: transparent
- type: custom:button-card
entity: input_boolean.sonos_playing_status
name: Sonos
icon: mdi:sofa
show_icon: true
show_name: false
show_state: false
size: 50%
tap_action:
action: toggle
hold_action:
action: more-info
styles:
card:
- height: 60px
- width: 60px
- border-radius: 100%
- background-color: rgb(254, 254, 254, 1)
- border: 1px solid rgb(0, 0, 0, 0.5)
- box-shadow: 0px 2px 2px 0px rgba(0,0,0,0.15)
- align-self: middle
icon:
- color: rgb(90, 153,92,1)
state:
- value: 'on'
styles:
card:
- box-shadow: inset 0px 1px 3px 0px rgba(0,0,0,0.35)
- border: 1px solid rgb(0, 167, 11)
- type: custom:button-card
entity: input_boolean.everywhere_playing_status
name: Everywhere
show_icon: true
show_name: false
show_state: false
size: 50%
icon: mdi:home
tap_action:
action: toggle
hold_action:
action: more-info
styles:
card:
- height: 60px
- width: 60px
- border-radius: 100%
- background-color: rgb(254, 254, 254, 1)
- border: 1px solid rgb(0, 0, 0, 0.5)
- box-shadow: 0px 2px 2px 0px rgba(0,0,0,0.15)
- align-self: middle
icon:
- color: rgb(255, 202, 55, 1)
state:
- value: 'on'
styles:
card:
- box-shadow: inset 0px 1px 3px 0px rgba(0,0,0,0.35)
- border: 1px solid rgb(255, 202, 55, 1)
- type: custom:button-card
entity: input_boolean.bathroom_playing_status
name: Bathroom
show_icon: true
show_name: false
show_state: false
icon: mdi:bathtub
size: 50%
tap_action:
action: toggle
hold_action:
action: more-info
styles:
card:
- height: 60px
- width: 60px
- border-radius: 100%
- background-color: rgb(254, 254, 254, 1)
- border: 1px solid rgb(0, 0, 0, 0.5)
- box-shadow: 0px 2px 2px 0px rgba(0,0,0,0.15)
- align-self: middle
icon:
- color: rgb(65, 106, 154, 1)
state:
- value: 'on'
styles:
card:
- box-shadow: inset 0px 1px 3px 0px rgba(0,0,0,0.35)
- border: 1px solid rgb(65, 106, 154, 1)
style: |
ha-card {
box-shadow: 0px 1px 1px 0px rgba(0,0,0,0.15)
border-radius: 50%
}
view_layout:
grid-area: A
- type: custom:button-card
entity: media_player.spotify_steph_tanner
show_entity_picture: true
show_name: false
tap_action:
action: more-info
styles:
grid:
- grid-template-areas: '"info"'
- grid-template-columns: 1fr
- grid-template-rows: min-content
card:
- background: none
- padding: 0
- position: relative
- '--mdc-ripple-press-opacity': 0
img_cell:
- position: absolute
icon:
- width: 150%
- opacity: var(--color-tint)
- '-webkit-filter': blur(20px)
- '-moz-filter': blur(20px)
- '-o-filter': blur(20px)
- '-ms-filter': blur(20px)
- filter: blur(20px)
custom_fields:
info:
card:
type: custom:button-card
entity: media_player.spotify_steph_tanner
show_entity_picture: true
name: |
[[[
if (states['media_player.spotify_steph_tanner'].attributes.media_title)
return states['media_player.spotify_steph_tanner'].attributes.media_title;
else
return "Nothing is playing";
]]]
label: |
[[[
if (states['media_player.spotify_steph_tanner'].attributes.media_artist)
return states['media_player.spotify_steph_tanner'].attributes.media_artist;
else
return "";
]]]
show_label: true
show_icon: true
styles:
grid:
- grid-template-areas: '"i gutter n" "i gutter l"'
- grid-template-columns: min-content 24px 1fr
- grid-template-rows: min-content
card:
- background: none
- border-radius: 0
- padding: 24px
- '--mdc-ripple-press-opacity': 0
img_cell:
- height: 80px
- width: 80px
- border-radius: 16px
icon:
- height: 100%
- width: 100%
name:
- font-size: 16px
- color: var(--contrast20)
- width: 100%
- text-align: left
- align-self: end
label:
- font-size: 12px
- color: var(--contrast20)
- opacity: 0.5
- width: 100%
- text-align: left
- align-self: start
custom_fields:
image:
- '--mdc-ripple-press-opacity': 0.5
view_layout:
grid-area: B
- type: entity-filter
entities:
- type: custom:mini-media-player
entity: media_player.living_room_sonos
group: true
artwork: none
hide:
controls: true
power: true
source: true
icon_state: false
progress: true
name: Sonos
icon: mdi:speaker
volume_step: '10'
- type: custom:mini-media-player
entity: media_player.living_room_echo
name: Living Room
group: true
source: icon
info: mdi:sofa
artwork: none
hide:
controls: true
power: true
source: true
icon_state: false
progress: true
icon: mdi:sofa
volume_step: '10'
- type: custom:mini-media-player
entity: media_player.bathroom_dot
group: true
artwork: none
hide:
controls: true
power: true
source: true
icon_state: false
progress: true
name: Bathroom
icon: mdi:shower
volume_step: '10'
- type: custom:mini-media-player
entity: media_player.steffie
group: true
artwork: none
hide:
controls: true
power: true
source: true
icon_state: false
progress: true
name: Steffie
icon: mdi:face-man
volume_step: '10'
- type: custom:mini-media-player
entity: media_player.laura
group: true
artwork: none
hide:
controls: true
power: true
source: true
icon_state: false
progress: true
name: Laura
icon: mdi:face-woman-shimmer
volume_step: '10'
- type: custom:mini-media-player
entity: media_player.steph_s_2nd_echo_dot
group: true
artwork: none
hide:
controls: true
power: true
source: true
icon_state: false
progress: true
name: Bullshit Room
icon: mdi:baguette
volume_step: '10'
state_color: true
show_header_toggle: false
state_filter:
- playing
card_mod:
style: |
ha-card {
--ha-card-background: color: rgb(220, 220, 220);
}
view_layout:
grid-area: D
- type: custom:button-card
template: container
name: controls
show_name: false
custom_fields:
buttons:
card:
type: horizontal-stack
cards:
- type: custom:button-card
entity: null
name: blank
show_icon: false
show_name: false
tap_action:
action: none
service: none
styles:
card:
- height: 60px
- width: 30px
- background: transparent
- type: custom:button-card
entity: null
name: blank
show_icon: false
show_name: false
tap_action:
action: none
service: none
styles:
card:
- height: 60px
- width: 40px
- background: transparent
- type: custom:button-card
entity: media_player.spotify_steph_tanner
name: Previous
size: 75%
icon: mdi:skip-previous-circle
show_icon: true
show_name: false
tap_action:
action: call-service
service: script.sonos_previous
styles:
card:
- height: 60px
- width: 60px
- type: custom:button-card
entity: media_player.spotify_steph_tanner
name: Play/Pause
show_icon: true
show_name: false
size: 75%
tap_action:
action: call-service
service: script.sonos_play_pause
state:
- value: playing
icon: mdi:pause-circle
- value: paused
icon: mdi:play-circle
- value: idle
icon: mdi:play-circle
styles:
card:
- height: 60px
- width: 60px
- type: custom:button-card
entity: media_player.spotify_steph_tanner
name: Next
icon: mdi:skip-next-circle
show_icon: true
show_name: false
tap_action:
action: call-service
service: script.sonos_next
size: 75%
styles:
card:
- height: 60px
- width: 60px
view_layout:
grid-area: C
Container Template
button_card_templates:
container:
color_type: label-card
color: rgb(220, 220, 220)
styles:
card:
- padding: 0
name:
- border-radius: 0.4em 0.4em 0 0
- padding: 0.1em
- width: 100%
grid:
- grid-template-areas: '"buttons"'
- grid-template-columns: 1fr
- grid-template-rows: 1fr min-content min-content
custom_fields:
buttons:
- margin: 0
- padding: 0.3em