Thanks. I was looking in the docs yesterday, but just couldn’t find it.
I’m completely in love with the template!
I do however run into two issues:
When trying to add a media player with the base template the action:toggle doesn’t play/pause the media player. I can’t seem to fix this without breaking it for other entities. Is there a way to make the base template play/pause as well?
- type: custom:button-card
entity: media_player.sonos_woonkamer
name: Monitorer
triggers_update: sensor.volume_sonos_woonkamer
hold_action:
!include popup/sonos_woonkamer.yaml
template:
- base
- icon_monitors
- circle
- loader
variables:
circle_input: >
[[[
var entity_id = 'sensor.volume_sonos_woonkamer';
return states[entity_id] === undefined ? null : states[entity_id].state;
]]]
I’ve also tried filling in the circle_input with my own Sonos volume template sensor, however that doesn’t show in the card either.
sensor:
- platform: template
sensors:
volume_sonos_woonkamer:
value_template: '{{ states.media_player.sonos_woonkamer.attributes.volume_level |float * 100 | round(0) }}'
friendly_name: 'Volume'
unit_of_measurement: '%'
Any tips on how to make this work?
Add a tap action for that button
tap_action:
action: call-service
service: media_player.media_play_pause
service_data:
entity_id: >
[[[ return entity.entity_id; ]]]
I don’t remember having any issues, I changed to how it works now because it’s easier not having to deal with input booleans
This works
state_display: >
[[[
if (entity) {
return entity.state.charAt(0).toUpperCase() + entity.state.slice(1);
}
]]]
But just now realized that css can handle that
https://github.com/thomasloven/lovelace-card-mod#styling-cards
So you’ll have to wrap it in mod-card or what I do, style from themes.yaml
#################################################
# #
# GRID CARD HEADINGS #
# #
#################################################
grid-layout$:
hui-grid-card:
$: |
/* default */
h1 {
...
hui-grid-card:nth-child(4):
$: |
h1 {
color: red !important;
}
https://github.com/matt8707/docker-compose-dsm
https://github.com/matt8707/docker-compose-rpi
(also linked from first post under “hardware”)
The problem is you have to install python module requests-html
. So for me moving that script to my rpi was an easy way out. It may also be possible with AppDaemon, but I have zero experience with it.
Thanks man!
For everyone wanting to add their Tesla to this amazing dashboard. These steps will show the range your car has. Will animate the icon if it is charging and will show a popup with more information on hold action.
- Install this integration
- Add this button to ui-dashboard
- type: custom:button-card
entity: sensor.tesla_model_y_range_sensor
tap_action:
!include popup/tesla.yaml
name: Tesla
variables:
retain: binary_sensor.tesla_model_y_charger_sensor
template:
- car
- icon_tesla
- Add these icon_tesla and car templates to button_card_templates:
#################################################
# #
# CAR #
# #
#################################################
car:
template:
- base
- circle
variables:
circle_input: >
[[[ return entity === undefined || Math.round(entity.attributes.brightness / 2.54); ]]]
hold_action:
action: fire-dom-event
browser_mod:
command: popup
title: >
[[[ return entity.attributes.friendly_name; ]]]
card:
type: custom:light-popup-card
entity: >
[[[ return entity.entity_id ]]]
icon: none
fullscreen: false
brightnessWidth: 130px
brightnessHeight: 360px
borderRadius: 1.7em
sliderColor: '#c7c7c7'
sliderTrackColor: rgba(25, 25, 25, 0.9)
displayType: slider
actionSize: 4.5em
actionsInARow: 3
actions:
- action: call-service
name: default
color: '#fefefe'
service: hue.hue_activate_scene
service_data:
group_name: living
scene_name: default
- action: call-service
service: light.turn_on
color: '#d8d9e1'
service_data:
entity_id: >
[[[ return entity.entity_id ]]]
color_temp: 153
- action: call-service
service: light.turn_on
color: '#d5b08d'
service_data:
entity_id: >
[[[ return entity.entity_id ]]]
color_temp: 326
- action: call-service
service: light.turn_on
color: '#ce944b'
service_data:
entity_id: >
[[[ return entity.entity_id ]]]
color_temp: 500
- action: fire-dom-event
image: >-
data:image/svg+xml,%3Csvg xmlns="http://www.w3.org/2000/svg" viewBox="0 0
50 50"%3E%3Cstyle%3Esvg%7Bbackground:radial-gradient(circle,rgba(255,255,
255,1) 0%25,rgba(255,255,255,0) 80%25),conic-gradient(%237827e6,%23e622e7,
%23e40588,%23e41919,%23e5691e,%23e8e22e,%237de629,%2334e828,%2333e75c,
%2334e8e0,%23207de5,%231227e5,%237827e6)%7D%3C/style%3E%3C/svg%3E
browser_mod:
command: popup
title: >
[[[ return entity.attributes.friendly_name ]]]
card:
type: custom:light-entity-card
entity: >
[[[ return entity.entity_id ]]]
brightness: true
color_temp: true
full_width_sliders: false
hide_header: true
show_slider_percent: true
smooth_color_wheel: true
persist_features: true
consolidate_entities: false
icon_tesla:
styles:
custom_fields:
icon:
- width: 78%
- margin-left: -10%
custom_fields:
icon: >
[[[
let state = states[variables.retain].attributes.charging_state;
return `
<svg viewBox="0 0 504 304.64" fill="var(--light-color)">
<style>
.Charging {
fill: url(#charging-fill);
}
.Stopped {
fill: red;
}
.Complete {
fill: #5daeea;
}
.resting {
transform: rotateZ(-90deg) translate(-1.5%, 0%);
transform-origin: 45% 41%;
}
</style>
<linearGradient id="charging-fill" x1="0.5" y1="1" x2="0.5" y2="0">
<stop offset="100%" stop-opacity="1" stop-color="#5daeea">
<animate attributeName="offset" values="0;1" repeatCount="indefinite" dur="3s" begin="0s"/>
</stop>
<stop offset="100%" stop-opacity="0" stop-color="#5daeea">
<animate attributeName="offset" values="0;1" repeatCount="indefinite" dur="3s" begin="0s"/>
</stop>
</linearGradient>
<g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="${state}" d="M490.56,90.72c-9-2.24-27.44-7.28-28.56,0s-3.35,20.16-3.35,20.16L443.52,112s-1.68-1.68-3.36-7.84-17.92-60.48-30.8-79S387.52,9,387.52,9v.56S337.13,0,251.44,0,115.36,9.52,115.36,9.52V9S107,6.72,93.52,25.2c-12.88,18.48-29.12,72.8-30.8,79S59.36,112,59.36,112L44.8,110.88S43.12,98,41.44,90.72c-1.12-7.28-19.6-2.24-28.56,0C4.48,92.4,0,106.4,0,109.2s2.24,5,6.16,6.72,28,3.36,31.92,3.36c4.48,0,3.92-1.12,3.92-1.12l14.56,1.12s-1.12,5-3.92,6.16-3.36,3.92-5,6.16-18.48,14.56-21.28,21.84c-6.16,14-1.12,41.44-1.12,62.16,0,20.16,3.92,52.64,5.6,66.08s12.88,23,12.88,23H95.2c7.28,0,21.28-2.24,28.56-2.24H380.24c7.28,0,21.28,2.24,28.56,2.24h51.52s11.76-9.52,12.88-23c1.68-13.45,5.6-45.93,5.6-66.08s5-47.6-1.12-62.16c-2.8-6.72-19.6-19-21.28-21.84-1.68-2.24-2.24-5-5-6.16s-3.92-6.16-3.92-6.16L462,118.16s-.56,1.12,3.92,1.12,28-1.12,31.92-3.36S504,112,504,109.2s-4.47-16.8-13.43-18.48ZM77.84,104.16C80.08,93.52,101.36,23.52,107.52,19c0,0,67.2-5,143.92-5s143.92,5,143.92,5c6.72,4.48,27.44,74.48,29.68,85.12s-1.12,10.64-1.12,10.64H79s-3.36,0-1.12-10.64ZM96.32,243c-3.92,0-47.6-.56-47.6-.56s9.52,18.48,11.2,21.84c1.68,3.92,1.68,10.64-3.92,9-5-1.68-10.64-12.88-12.32-19-1.68-6.72-3.92-23-3.92-23l66.07,5c0,.56-5.59,6.72-9.51,6.72ZM103,190.4c-16.24,0-37.52-6.16-43.68-7.84s-10.64-8.4-10.64-17.36,0-18.48,10.08-28.56c0,0,11.76,0,21.28,7.84,9,7.28,16.8,14,26.88,17.36,15.12,4.48,26.32,20.72,26.32,20.72s-14,7.84-30.24,7.84Zm267.68,93H133.28c-5.6,0-14-1.12-6.72-9,5.61-5.6,15.12-10.08,33.61-10.08H342.73c18.48,0,28,4.48,33.6,10.08,8.39,7.84,0,9-5.61,9Zm93.52-51.52s-2.24,16.24-3.92,23-7.28,17.36-12.32,19-5.6-5.6-3.92-9S455.28,243,455.28,243s-43.68.56-47.6.56-9-6.72-9-6.72Zm-9.52-66.64c0,9-3.92,15.68-10.64,17.36s-28,7.84-43.68,7.84c-16.24,0-30.24-7.84-30.24-7.84s10.64-16.24,26.32-20.72c10.08-2.8,17.36-10.08,26.88-17.36a38.11,38.11,0,0,1,21.28-7.84c10.08,10.08,10.08,19.6,10.08,28.56Z"/></g></g>
</svg>
`;
]]]
- Add the tesla popup below to the popup folder as tesla.yml. Enjoy!
action: fire-dom-event
browser_mod:
command: popup
title: Tesla
style:
.: |
:host .content {
width: calc(385px + 510px);
max-width: 90vw;
}
layout-card$grid-layout:
$: |
hui-vertical-stack-card {
animation: border 1s forwards;
}
@keyframes border {
0%, 100% {
border-right: 1.5px solid rgba(0, 0, 0, 0.2);
}
}
/* phone */
@media screen and (max-width: 800px) {
hui-vertical-stack-card {
border-bottom: 1.5px solid rgba(0, 0, 0, 0.2);
padding-right: 0;
animation: none;
}
}
$hui-vertical-stack-card:
$: |
hui-horizontal-stack-card {
padding: 0em 2em 2.3em 2em;
}
$hui-entities-card$: |
.card-content {
padding: var(--card-content-padding);
}
$hui-horizontal-stack-card$: |
#root {
justify-content: space-evenly;
}
card:
type: custom:layout-card
layout_type: custom:grid-layout
layout:
grid-template-columns: 1fr
grid-template-rows: 1fr
grid-template-areas: |
"info map"
mediaquery:
#phone
"(max-width: 800px)":
grid-template-columns: 1fr
grid-template-rows: repeat(2, 1fr)
grid-template-areas: |
"info"
"map"
cards:
#################################################
# #
# Tesla #
# #
#################################################
- type: vertical-stack
view_layout:
grid-area: info
cards:
- type: entities
card_mod:
class: header
entities:
- entity: binary_sensor.tesla_model_y_charger_sensor
- entity: climate.tesla_model_y_hvac_climate_system
icon: mdi:thermometer
- entity: switch.tesla_model_y_sentry_mode_switch
- entity: binary_sensor.tesla_model_y_online_sensor
- type: custom:bar-card
width: 55%
height: 2em
decimal: 0
unit_of_measurement: '%'
positions:
icon: outside
indicator: 'off'
name: outside
severity:
- color: '#303435'
from: 11
to: 100
- color: '#6d2525'
from: 0
to: 10
entity_row: true
entities:
- entity: sensor.tesla_model_y_battery_sensor
icon: mdi:battery
- entity: sensor.tesla_model_y_range_sensor
- entity: sensor.tesla_model_y_temperature_sensor_inside
- entity: sensor.tesla_model_y_temperature_sensor_outside
Is there a way to add multiple icons on the top right side of the card that can display information from entities? I want to have a card for my Prusa and have it display information while the printer is printing such as nozzle temp, bed temp, time remaining, etc. Something like this:
I quickly skimmed the thread but have not found someone that has done this already.
Nice, can you share the code please.
This is my code.
Widget Calendar
i use a date sensor
- type: custom:button-card
entity: calendar.lavoro
template:
- base
- widget_calendar
button_card_template.yaml
widget_calendar:
aspect_ratio: 1/1
show_icon: false
show_name: false
show_state: false
show_label: false
tap_action:
action: more-info
styles:
grid:
- grid-template-areas: |
"giorno"
"numero"
"testo"
"eventi"
- grid-template-columns: 1fr
- grid-template-rows: min-content min-content min-content 1fr
- gap: 0%
- overflow: hidden
card:
- color: >
[[[
if (states['sun.sun'].state == 'below_horizon'){
return 'rgba(0, 0, 0, 0.6)';
} else
return 'rgba(255, 255, 255, 0.8)';
]]]
- background-color: >
[[[
if (states['sun.sun'].state == 'below_horizon'){
return '#1c1c1e';
} else
return 'rgba(255, 255, 255, 0.8)';
]]]
custom_fields:
giorno:
- place-self: start
- color: '#ff3b2f'
- text-transform: uppercase
- font-weight: 500
numero:
- place-self: start
- color: >
[[[
if (states['sun.sun'].state == 'below_horizon'){
return 'rgba(255, 255, 255, 0.8)';
} else
return 'rgba(0, 0, 0, 0.6)';
]]]
- font-weight: 500
- margin-top: -10px
testo:
- place-self: start
- text-transform: uppercase
- color: '#8e8e90'
eventi:
- place-self: start
- border-left: 3px blue solid
- padding-left: 3px
- color: >
[[[
if (states['sun.sun'].state == 'below_horizon'){
return 'rgba(255, 255, 255, 0.8)';
} else
return 'rgba(0, 0, 0, 0.6)';
]]]
custom_fields:
giorno: >
[[[ return `${states['sensor.pretty_date'].attributes.week_day}` ]]]
numero: >
[[[ return `${states['sensor.pretty_date'].attributes.day}` ]]]
testo: >
[[[
if (states['sun.sun'].state == 'below_horizon'){
return "Domani";
} else
return " ";
]]]
eventi: '[[[ return entity.attributes.message ]]]'
extra_styles: |
[[[
return `
#giorno {
font-size: 1.3vw;
}
#numero {
font-size: 4.5vw;
}
#testo {
font-size: 1.1vw;
}
#eventi {
font-size: 1vw;
}
/* portrait */
@media screen and (max-width: 1200px) {
#numero {
font-size: 4.5vw;
}
#giorno {
font-size: 1.3vw;
}
#testo {
font-size: 1.1vw;
}
#eventi {
font-size: 1.1vw;
}
}
/* phone */
@media screen and (max-width: 800px) {
#giorno {
font-size: 3.5vw;
}
#numero {
font-size: 12vw;
}
#testo {
font-size: 3vw;
}
#eventi {
font-size: 2.8vw;
}
}
`
]]]
Widget Weather
I use a sensor for min and max temperatures
I use this icon animated.
- type: custom:button-card
entity: weather.openweathermap
name: Campobasso
template:
- base
- widget_weather
variables:
temp_min: sensor.min_temperatura
temp_max: sensor.max_temperatura
button_card_template.yaml
widget_weather:
variables:
temp_min: ''
temp_max: ''
aspect_ratio: 1/1
show_icon: false
show_entity_picture: true
show_name: true
show_state: true
show_label: true
tap_action:
action: more-info
styles:
grid:
- grid-template-areas: |
"n"
"temp"
"i"
"s"
"l"
- grid-template-columns: 1fr
- grid-template-rows: min-content repeat(2, 1fr) repeat(2, min-content)
- gap: 0%
card:
- color: rgba(255, 255, 255, 0.8)
- background: >
[[[
if (states['sun.sun'].state == 'below_horizon'){
return 'linear-gradient(to top, rgba(53,59,83,1) 0%, rgba(10,14,34,1) 100%)';
} else
return 'linear-gradient(to top, rgba(123,168,197,1) 0%, rgba(61,132,176,1) 100%)';
]]]
name:
- place-self: start
- text-transform: uppercase
- font-weight: 500
img_cell:
- justify-content: start
icon:
- width: 20%
label:
- place-self: start
- margin-left: -5px
custom_fields:
temp:
- place-self: start
- margin-top: -10px
label: >
[[[
return `<ha-icon
icon="mdi:arrow-up-thin"
style="width: 20px; height: 20px; margin-right: -5px;">
</ha-icon><span>: ${states[variables.temp_max].state}°</span>
<ha-icon
icon="mdi:arrow-down-thin"
style="width: 20px; height: 20px; margin-right: -5px;">
</ha-icon><span>: ${states[variables.temp_min].state}°</span>
`
]]]
custom_fields:
temp: >
[[[ return entity.attributes.temperature + "°"; ]]]
entity_picture: >
[[[
if ((entity.state == 'sunny') && (states['sun.sun'].state == 'above_horizon'))
return "/local/weather/clear-day.svg";
if ((entity.state == 'sunny') || (entity.state == 'clear-night') && (states['sun.sun'].state == 'below_horizon'))
return "/local/weather/clear-night.svg";
if (entity.state == 'fog')
return "/local/weather/fog.svg";
if ((entity.state == 'partlycloudy') && (states['sun.sun'].state == 'above_horizon'))
return "/local/weather/partly-cloudy-day.svg";
if ((entity.state == 'partlycloudy') && (states['sun.sun'].state == 'below_horizon'))
return "/local/weather/partly-cloudy-night.svg";
if (entity.state == 'rainy')
return "/local/weather/rain.svg";
if (entity.state == 'sleet')
return "/local/weather/sleet.svg";
if (entity.state == 'snow')
return "/local/weather/snow.svg";
if (entity.state == 'cloudy')
return "/local/weather/cloudy.svg";
else (entity.state == 'wind')
return "/local/weather/wind.svg";
]]]
extra_styles: |
[[[
return `
#name {
font-size: 1.3vw;
}
#temp {
font-size: 4.5vw;
}
#state {
font-size: 1.1vw;
}
#label {
font-size: 1.1vw;
}
/* portrait */
@media screen and (max-width: 1200px) {
#name {
font-size: 1.3vw;
}
#temp {
font-size: 4.5vw;
}
#state {
font-size: 1.1vw;
}
#label {
font-size: 1.1vw;
}
}
/* phone */
@media screen and (max-width: 800px) {
#name {
font-size: 3.5vw;
}
#temp {
font-size: 12vw;
}
#state {
font-size: 3.5vw;
}
#label {
font-size: 3.5vw;
}
}
@keyframes card_bounce {
0% {
transform: scale(1);
}
15% {
transform: scale(0.9);
}
25% {
transform: scale(1);
}
30% {
transform: scale(0.98);
}
100% {
transform: scale(1);
}
}
`
]]]
Widget Battery
- type: custom:button-card
template:
- base
- widget_phone
variables:
entity_phone: sensor.ipex_battery_level
entity_picture_iphone: /local/apple/i12.png
entity_watch: sensor.apple_watch_di_giuseppe_battery_state
entity_picture_watch: /local/apple/watch.png
entity_ipad: sensor.icompare_battery_level
entity_picture_ipad: /local/apple/ipad.png
entity_other: sensor.ipex6s_battery_level
entity_picture_other: /local/apple/6s.png
button_card_template.yaml
widget_custom_fields:
show_icon: false
show_state: false
show_name: false
show_entity_picture: true
tap_action:
action: none
styles:
# icon:
# - height: 50%
custom_fields:
circle:
- top: 0%
- left: 25%
- width: 50%
- position: absolute
custom_fields:
circle: >
[[[
if (entity.state >= 20) {
let input = entity.state,
radius = 20.5,
color = 'green',
circumference = radius * 2 * Math.PI,
dasharray = circumference,
dashoffset = circumference - input / 100 * circumference;
return `
<svg viewBox="0 0 50 50">
<circle cx="25" cy="25" r="${radius}" stroke="gray" stroke-opacity="50%" stroke-width="4.5" fill="none" />
<circle cx="25" cy="25" r="${radius}" stroke="${color}" stroke-dashoffset="${dashoffset}" stroke-dasharray="${dasharray}" stroke-linecap="round" stroke-width="4.5" fill="none" style="transform: rotate(-90deg); transform-origin: 50% 50%;" />
</svg>
`;
} else {
let input = entity.state,
radius = 20.5,
color = 'red',
circumference = radius * 2 * Math.PI,
dasharray = circumference,
dashoffset = circumference - input / 100 * circumference;
return `
<svg viewBox="0 0 50 50">
<circle cx="25" cy="25" r="${radius}" stroke="gray" stroke-opacity="50%" stroke-width="4.5" fill="none" />
<circle cx="25" cy="25" r="${radius}" stroke="${color}" stroke-dashoffset="${dashoffset}" stroke-dasharray="${dasharray}" stroke-linecap="round" stroke-width="4.5" fill="none" fill-opacity="0.3" style="transform: rotate(-90deg); transform-origin: 50% 50%;" />
</svg>
`;
}
]]]
widget_phone:
variables:
entity_phone: ''
entity_picture_iphone: ''
entity_watch: ''
entity_picture_watch: ''
entity_ipad: ''
entity_picture_ipad: ''
entity_other: ''
entity_picture_other: ''
aspect_ratio: 1/1
show_icon: false
show_name: false
show_state: false
show_label: false
styles:
grid:
- grid-template-areas: |
"phone watch"
"ipad other"
- grid-template-columns: repeat(2, 1fr)
- grid-template-rows: repeat(2, 1fr)
- gap: 0%
card:
- padding: 5%
- color: >
[[[
if (states['sun.sun'].state == 'below_horizon'){
return 'rgba(0, 0, 0, 0.6)';
} else
return 'rgba(255, 255, 255, 0.3)';
]]]
custom_fields:
phone:
- align-self: start
- justify-self: center
- width: 200%
watch:
- align-self: start
- justify-self: center
- width: 200%
ipad:
- align-self: end
- justify-self: center
- width: 200%
other:
- align-self: end
- justify-self: center
- width: 200%
custom_fields:
phone:
card:
type: custom:button-card
entity: '[[[ return variables.entity_phone ]]]'
template: widget_custom_fields
icon: phu:apple-iphone
entity_picture: '[[[ return variables.entity_picture_iphone ]]]'
watch:
card:
type: custom:button-card
entity: '[[[ return variables.entity_watch ]]]'
template: widget_custom_fields
icon: phu:apple-ipad-pro
entity_picture: '[[[ return variables.entity_picture_watch ]]]'
ipad:
card:
type: custom:button-card
entity: '[[[ return variables.entity_ipad ]]]'
template: widget_custom_fields
icon: phu:apple-ipad-pro
entity_picture: '[[[ return variables.entity_picture_ipad ]]]'
other:
card:
type: custom:button-card
entity: '[[[ return variables.entity_other ]]]'
template: widget_custom_fields
icon: phu:apple-iphone
entity_picture: '[[[ return variables.entity_picture_other ]]]'
Can you post a pic of it?
Thanks. I’ll be trying it
Gorgeous. Thanks for Sharing.
Hi
I’m obviously very new to HA.
The instructions may be really easy to understand - but I am missing a few things…
- do I clone the whole repo? and if yes… where to?
- it says to copy 4 files from repo manually… but to where?
- I copied them to config root…
- I applied the code to configuration.yaml
- also installed the 4 mods via HACS.
I see a lot of files in the repo… but I only copied 4…
sry if all this should be obvious.
Thanks! Updated original reply.
In the sidebar I wanted to insert custom: button-card to the button pusto, I added columns: 3 in the grid and I made a template of my liking …
the problem I find is that if I insert 3 / 6o9 card with the mobile it is not visible.
sidebar_button:
template: base
show_state: false
show_name: false
styles:
grid:
- grid-template-columns: 1fr
- grid-template-areas: '"icon "'
card:
- background-color: rgba(0, 0, 0, 0.0)
- box-shadow: none