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
Hi everyone, i have tried this dashboard, followed the guidelines but all was not successful. Is there any one in the community who can share already made version in English language. without any code writing please.
I’m trying to resize my background.png to make the aspect ratio fit my iPad 2017. However changing the background resolution and aspect ratio doesn’t seem to change a thing.
I’ve tried emptying the cache and rebooting home assistant but it doesn’t work.
Anyone have any clue what I do wrong?
Thank to Mathias and all the contributors!
Learned a lot and with a severe copy and paste activity and a lot of debugging I’m now on the right path (I look now like Mathias in HA and most of the wording is in swedish,…)
need some direction tough:
-battery level: the reports shows the state (chargin/not chargin) instead of the level. Tried some corrections with no luck. Any idea?
-the sidebar format is worong: I’m not able to change the fonts and it occupies only the area needed, the lenght is not down to the bottom. Maybe this pic will help in understanding
-also the backgorund style is not loaded
edit: Found replies to pit 2 and 3 above…
Thanks!!
Could you share your code? Especially styles for the person cards
It is looking really great!
Hi all, been playing around a little and have a question re: grid layout.
In the current setup, what would be the quickest / most straightforward way to turn the 3 columns (each have 4 buttons) in 2 columns with 6 buttons each?
Just change grid in ui-lovelace.yaml
and then put more cards to columns
Is there a way to use another entity color?
I’m using a shelly that turn on a hue light and would like to have the hue entity color instead of the base blue one
I’m trying to pass a variable to icon_hue template with no success (while it works for the light template)
Can you give me the complete code and where you added it?