Perfect thanks for your quick response.
I have a problem with light entity that doesn’t have brightness attribiute. When I turn on the light the custom button card shows NaN% in the upper right corner. Is there a way to disable this feature for entities without such attribiutes? The same goes for hue parameter.
Looks amazing, is there an option you can share all the code please?
Super please share it amazing what we can acomplish togheter
cool
check out line:
event1time: |
[[[
return "Kl: " + (states['sensor.ical_daniel_kalender_event_0'].attributes.start).substr(11,5);
]]]
if you change substr(11,5) to (0,10) for example, you will get the day instead. the substr just “clips” out the string that you specify.
Here is one more widget clock/quote of the day
type: custom:button-card
view_layout:
grid-area: one
template:
- widgets
entity: sensor.date
show_state: true
tap_action:
action: fire-dom-event
browser_mod:
command: popup
title: Ställ in ett alarm
hide_header: false
card:
type: vertical-stack
cards:
- type: custom:time-picker-card
style: |
ha-card {
box-shadow: none;
}
entity: input_datetime.date
hour_mode: 24
hour_step: 1
minute_step: 1
second_step: 5
name: Alarm
layout:
embedded: true
align_controls: center
name: header
hide:
name: true
seconds: true
- type: entities
style: |
ha-card {
box-shadow: none;
}
entities:
- entity: automation.alarm
name: Aktivera
icon: ios:clock-badge-exclamationmark-fill
name: |
[[[ return states['sensor.time'].state; ]]]
state_display: |
[[[ return "- " + states['sensor.quote'].attributes.author; ]]]
styles:
state:
- position: absolute
- bottom: 20px
- left: 50%
- transform: translate(-50%, 0%)
- font-weight: bold
name:
- position: absolute
- color: rgb(255,255,255,0.9)
- top: 5%
- left: 50%
- transform: translate(-50%, 0%)
- font-size: 70px
custom_fields:
quote:
- position: absolute
- top: 43%
- left: 5%
- width: 90%
- height: 34%
- white-space: normal
- color: rgb(255,255,255,0.6)
- font-size: 14px
- font-style: italic
- letter-spacing: 0.05vw
custom_fields:
quote: |
[[[ return "´" + states['sensor.quote'].attributes.quote + "´"; ]]]
And the quote sensor in configuration.yaml:
sensor:
- platform: rest
resource: https://quotes.rest/qod?language=en
name: Quote
scan_interval: 42000
json_attributes_path: '$.contents.quotes[0]'
json_attributes:
- quote
- author
- category
Great idea, its working, thank you!
Beautiful. This is exactly what I was looking for. Would love your code once you are ready to share!
Here is a nicer icon if someone is interested.
type: custom:button-card
view_layout:
grid-area: seven
template:
- widgets
name: BATTERIER
styles:
name:
- font-size: 14px
- font-weight: bold
- top: 20px
- left: 20px
- position: absolute
custom_fields:
iphonese:
- top: 40px
- left: '-5px'
- width: 110%
- border-bottom: 1px solid rgb(255,255,255,0.1)
- padding: 10px
- position: absolute
- font-size: 16px
- text-shadow: 0px 0px 1px black
iphonesebattery:
- top: 60px
- right: 15px
- position: absolute
- font-size: 14px
iphone11:
- top: 100px
- left: '-5px'
- width: 110%
- border-bottom: 1px solid rgb(255,255,255,0.1)
- padding: 10px
- position: absolute
- font-size: 16px
- text-shadow: 0px 0px 1px black
iphone11battery:
- top: 120px
- right: 15px
- position: absolute
- font-size: 14px
ipad:
- top: 160px
- left: '-5px'
- width: 110%
- padding: 10px
- position: absolute
- font-size: 16px
- text-shadow: 0px 0px 1px black
ipadbattery:
- top: 180px
- right: 15px
- position: absolute
- font-size: 14px
custom_fields:
iphonese: |
[[[
return `<div align="left"> <ha-icon
icon="mdi:cellphone"
style="width: 20px; height: 20px; color:grey; padding: 10px;">
</ha-icon>iPhone SE</div>`
]]]
iphonesebattery: |
[[[
if (states["sensor.iphone_battery_level"].state > 40) {
let input = states["sensor.iphone_battery_level"].state / 3,
state = states["sensor.iphone_battery_level"].state,
color = '#08ff4e';
return `
<svg width="86" height="24">
<rect x="40" y="1" rx="5" ry="5" width="40" height="18" stroke="gray" fill="transparent" stroke-width="2"/>
<rect x="43" y="4" rx="3" ry="3" width="${input}" height="12" fill="${color}" stroke-width="0"/>
<rect x="82" y="6" rx="2" ry="2" width="2" height="9" fill="grey" stroke-width="0"/>
`;
} if (states["sensor.iphone_battery_level"].state > 15) {
let input = states["sensor.iphone_battery_level"].state / 3,
state = states["sensor.iphone_battery_level"].state,
color = 'orange';
return `
<svg width="86" height="24">
<rect x="40" y="1" rx="5" ry="5" width="40" height="18" stroke="gray" fill="transparent" stroke-width="2"/>
<rect x="43" y="4" rx="3" ry="3" width="${input}" height="12" fill="${color}" stroke-width="0"/>
<rect x="82" y="6" rx="2" ry="2" width="2" height="9" fill="grey" stroke-width="0"/>
`;
} else {
let state = states["sensor.iphone_battery_level"].state,
color = 'red';
return `
<svg width="86" height="24">
<rect x="40" y="1" rx="5" ry="5" width="40" height="18" stroke="gray" fill="transparent" stroke-width="2"/>
<rect x="43" y="4" rx="3" ry="3" width="5" height="12" fill="${color}" stroke-width="0"/>
<rect x="82" y="6" rx="2" ry="2" width="2" height="9" fill="grey" stroke-width="0"/>
`;
}
]]]
iphone11: |
[[[
return `<div align="left"> <ha-icon
icon="mdi:cellphone"
style="width: 20px; height: 20px; color:grey; padding: 10px;">
</ha-icon>iPhone 11</div>`
]]]
iphone11battery: |
[[[
if (states["sensor.malins_iphone_battery_level"].state > 40) {
let input = states["sensor.malins_iphone_battery_level"].state / 3,
state = states["sensor.malins_iphone_battery_level"].state,
color = '#08ff4e';
return `
<svg width="86" height="24">
<rect x="40" y="1" rx="5" ry="5" width="40" height="18" stroke="gray" fill="transparent" stroke-width="2"/>
<rect x="43" y="4" rx="3" ry="3" width="${input}" height="12" fill="${color}" stroke-width="0"/>
<rect x="82" y="6" rx="2" ry="2" width="2" height="9" fill="grey" stroke-width="0"/>
`;
} if (states["sensor.malins_iphone_battery_level"].state > 15) {
let input = states["sensor.malins_iphone_battery_level"].state / 3,
state = states["sensor.malins_iphone_battery_level"].state,
color = 'orange';
return `
<svg width="86" height="24">
<rect x="40" y="1" rx="5" ry="5" width="40" height="18" stroke="gray" fill="transparent" stroke-width="2"/>
<rect x="43" y="4" rx="3" ry="3" width="${input}" height="12" fill="${color}" stroke-width="0"/>
<rect x="82" y="6" rx="2" ry="2" width="2" height="9" fill="grey" stroke-width="0"/>
`;
} else {
let state = states["sensor.malins_iphone_battery_level"].state,
color = 'red';
return `
<svg width="86" height="24">
<rect x="40" y="1" rx="5" ry="5" width="40" height="18" stroke="gray" fill="transparent" stroke-width="2"/>
<rect x="43" y="4" rx="3" ry="3" width="5" height="12" fill="${color}" stroke-width="0"/>
<rect x="82" y="6" rx="2" ry="2" width="2" height="9" fill="grey" stroke-width="0"/>
`;
}
]]]
ipad: |
[[[
return `<div align="left"> <ha-icon
icon="mdi:tablet-android"
style="width: 20px; height: 20px; color:grey; padding: 10px;">
</ha-icon>iPad Pro</div>`
]]]
ipadbattery: |
[[[
if (states["sensor.daniels_ipad_battery_level"].state > 40) {
let input = states["sensor.daniels_ipad_battery_level"].state / 3,
state = states["sensor.daniels_ipad_battery_level"].state,
color = '#08ff4e';
return `
<svg width="86" height="24">
<rect x="40" y="1" rx="5" ry="5" width="40" height="18" stroke="gray" fill="transparent" stroke-width="2"/>
<rect x="43" y="4" rx="3" ry="3" width="${input}" height="12" fill="${color}" stroke-width="0"/>
<rect x="82" y="6" rx="2" ry="2" width="2" height="9" fill="grey" stroke-width="0"/>
`;
} if (states["sensor.daniels_ipad_battery_level"].state > 15) {
let input = states["sensor.daniels_ipad_battery_level"].state / 3,
state = states["sensor.daniels_ipad_battery_level"].state,
color = 'orange';
return `
<svg width="86" height="24">
<rect x="40" y="1" rx="5" ry="5" width="40" height="18" stroke="gray" fill="transparent" stroke-width="2"/>
<rect x="43" y="4" rx="3" ry="3" width="${input}" height="12" fill="${color}" stroke-width="0"/>
<rect x="82" y="6" rx="2" ry="2" width="2" height="9" fill="grey" stroke-width="0"/>
`;
} else {
let state = states["sensor.daniels_ipad_battery_level"].state,
color = 'red';
return `
<svg width="86" height="24">
<rect x="40" y="1" rx="5" ry="5" width="40" height="18" stroke="gray" fill="transparent" stroke-width="2"/>
<rect x="43" y="4" rx="3" ry="3" width="5" height="12" fill="${color}" stroke-width="0"/>
<rect x="82" y="6" rx="2" ry="2" width="2" height="9" fill="grey" stroke-width="0"/>
`;
}
]]]
Hi. Can anyone help me with the sidebar? I need to add a margin-left here… But I can’t figure out how…
#################################################
# #
# SIDEBAR #
# #
#################################################
- type: vertical-stack
view_layout:
grid-area: sidebar
cards:
- type: custom:button-card
entity: sensor.template_sidebar
template: sidebar
- type: horizontal-stack
cards:
- type: custom:button-card
entity: switch.bedroom
name: Cold lights
template:
- icon_only
- type: custom:button-card
entity: switch.bedroom
name: Cold lights
template:
- icon_only
like this?
action: fire-dom-event
browser_mod:
command: popup
title: Frontyard
style:
.: |
:host .content {
width: calc(385px + 495px);
max-width: 90vw;
}
/* phone */
@media screen and (max-width: 800px) {
:host .content {
max-width: 100vw;
}
}
layout-card$grid-layout:
$: |
hui-vertical-stack-card {
border-right: 1.5px solid rgba(0, 0, 0, 0.2);
border-radius: 0;
transition: none;
}
/* phone */
@media screen and (max-width: 800px) {
hui-vertical-stack-card {
border-right: none;
border-bottom: 1.5px solid rgba(0, 0, 0, 0.2);
}
}
$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;
max-width: 82vw; /* iphonex */
}
card:
type: custom:layout-card
layout_type: custom:grid-layout
layout:
grid-template-columns: 385px 495px
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:
- type: vertical-stack
view_layout:
grid-area: info
cards:
- type: entities
# title: Backyard Control
card_mod:
class: header
entities:
- entity: binary_sensor.door_sensor
name: Girls Door Sensor
- entity: binary_sensor.multipurpose_sensor_contact
name: Home Door Sensor
- type: horizontal-stack
cards:
- type: grid
columns: 3
cards:
- type: custom:button-card
entity: switch.front_yard_lights
name: Front Yard
show_state: false
custom_fields:
icon: >
<ha-icon icon="mdi:light-flood-down"></ha-icon>
template:
- base
- type: custom:button-card
entity: switch.hall_front_yard_lights
name: Hall
show_state: false
custom_fields:
icon: >
<ha-icon icon="mdi:light-flood-up"></ha-icon>
template:
- base
- type: custom:button-card
entity: switch.garage_lights
name: Garage
show_state: false
custom_fields:
icon: >
<ha-icon icon="mdi:track-light"></ha-icon>
template:
- base
- type: vertical-stack
view_layout:
grid-area: map
cards:
- type: 'custom:aarlo-glance'
entity: camera.aarlo_front_yard_camera
name: front door
image_view: direct
image_bottom: 'motion,library,stream,battery'
image_click: 'recordings'
library_sizes: '3,4,2'
template: base
This UI has given me the perfect foundation to build mine upon. Thanks @Mattias_Persson for sharing and answering our questions.
I have modified the sidebar considerably (I only need the part you see here with the 2 rows of nameless buttons). I cannot for the life of me figure out how to get rid of the space that follows the grid with the sidebar buttons.
The part I’ve marked in red is what I want to get rid of so the cameras area follows the sidebar without a space. Here are the relevant bits of code
This is the layout definition (sidebar is called “modes” and cameras is “camera”
views:
- type: custom:grid-layout
path: 0
layout:
#default
grid-gap: var(--custom-layout-card-padding)
grid-template-columns: 20% 1fr 1fr 1fr
grid-template-rows: 0 repeat(3, fit-content(100%))
grid-template-areas: |
" . . . . ."
"modes lights media controls ."
"camera lights scenes controls ."
" . lights climate controls ."
This is the grid with the sidebar:
- type: grid
square: false
view_layout:
grid-area: modes
columns: 1
cards:
- type: 'custom:button-card'
template: control_container
color: '#07171c'
name: 'CONTROLS'
custom_fields:
buttons:
card:
type: vertical-stack
cards:
- type: horizontal-stack
cards:
- type: custom:button-card
entity: lock.front_door
name: ' '
tap_action:
action: toggle
template: monitoring_button
- type: custom:button-card
entity: binary_sensor.active_lights
tap_action: !include popup/active_lights.yaml
name: ' '
template: monitoring_button
- type: custom:button-card
entity: binary_sensor.home_modes
tap_action: !include popup/modes.yaml
name: ' '
template: monitoring_button
- type: custom:button-card
tap_action: !include popup/boilers.yaml
entity: binary_sensor.boilers
name: ' '
template: monitoring_button
- type: custom:button-card
tap_action: !include popup/boilers.yaml
entity: binary_sensor.boilers
name: ' '
template: monitoring_button
- type: horizontal-stack
cards:
- type: custom:button-card
entity: binary_sensor.perimeter
tap_action: !include popup/perimeter.yaml
name: ' '
template: monitoring_button
- type: custom:button-card
entity: binary_sensor.active_media_players
tap_action: !include popup/active_media_players.yaml
name: ' '
template: monitoring_button
- type: custom:button-card
entity: binary_sensor.perimeter
tap_action: !include popup/perimeter.yaml
name: ' '
template: monitoring_button
- type: custom:button-card
entity: binary_sensor.active_media_players
tap_action: !include popup/active_media_players.yaml
name: ' '
template: monitoring_button
- type: custom:button-card
entity: binary_sensor.active_media_players
tap_action: !include popup/active_media_players.yaml
name: ' '
template: monitoring_button
and this is the camera area:
- type: grid
square: false
view_layout:
grid-area: camera
columns: 1
cards:
- type: 'custom:button-card'
template: control_container
color: '#0f1416'
name: CAMERAS
custom_fields:
buttons:
card:
type: vertical-stack
cards:
- type: horizontal-stack
cards:
- aspect_ratio: 92%
camera_view: live
entity: camera.adam_substream
name: ADAM
show_name: true
show_state: false
type: picture-entity
- aspect_ratio: 92%
camera_view: live
entity: camera.porch_substream
name: PORCH
show_name: true
show_state: false
type: picture-entity
- type: horizontal-stack
cards:
- aspect_ratio: 92%
camera_view: live
entity: camera.garage_substream
name: GARAGE
show_name: true
show_state: false
type: picture-entity
- aspect_ratio: 92%
camera_view: live
entity: camera.entryway_substream
name: ENTRYWAY
show_name: true
show_state: false
type: picture-entity
Here’s the whole UI as it currently stands for perspective (still under construction)
Laffer;
Can u share the code for your weather card also?
I’m not too sure about the colors, yet.
lovelace-ui.yaml
- type: custom:button-card
entity: weather.openweathermap
name: Location
tap_action:
!include popup/weather.yaml
template:
- base
- weather_forecast
variables:
temp_min: sensor.weather_min_temp
temp_max: sensor.weather_max_temp
button_card_templates.yaml
weather_forecast:
variables:
temp_min: ''
temp_max: ''
aspect_ratio: 1/1
show_icon: false
show_entity_picture: true
show_name: true
show_state: false
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(157, 160, 162, 1) #rgba(84, 85, 85, 1) #rgba(85, 86, 86, 1)
[[[
if (states['sun.sun'].state == 'below_horizon'){
return 'rgba(157, 160, 162, 1)';
} else
return 'rgba(84, 85, 85, 1)';
]]]
- background: > # else linear-gradient(to top, rgba(123,168,197,0.8) 0%, rgba(61,132,176,0.8) 100%)
[[[
if (states['sun.sun'].state == 'below_horizon'){
return 'linear-gradient(to top, rgba(53,59,83,0.8) 0%, rgba(10,14,34,0.8) 100%)';
} else
return 'linear-gradient(to top, rgb(123 168 197) 0%, #b0c5d3 100%)';
]]]
# return 'linear-gradient(to top, rgb(123 168 197) 0%, #b0c5d3 100%)'; --- rgb(213, 215, 216)
name:
- place-self: start
- text-transform: uppercase
- font-weight: 400
img_cell:
- justify-content: start
icon:
- width: 37%
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: 1.3em; height: 1.3em; margin-right: -0.3em;"></ha-icon>
<span> ${states[variables.temp_max].state}°</span>
<ha-icon icon="mdi:arrow-down-thin" style="width: 1.3em; height: 1.3em; margin-right: -0.3em;"></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/svg/weather/animated/clear-day.svg";
if ((entity.state == 'sunny') || (entity.state == 'clear-night') && (states['sun.sun'].state == 'below_horizon'))
return "/local/svg/weather/animated/clear-night.svg";
if (entity.state == 'fog')
return "/local/svg/weather/animated/fog.svg";
if ((entity.state == 'partlycloudy') && (states['sun.sun'].state == 'above_horizon'))
return "/local/svg/weather/animated/partly-cloudy-day.svg";
if ((entity.state == 'partlycloudy') && (states['sun.sun'].state == 'below_horizon'))
return "/local/svg/weather/animated/partly-cloudy-night.svg";
if (entity.state == 'rainy')
return "/local/svg/weather/animated/rain.svg";
if (entity.state == 'sleet')
return "/local/svg/weather/animated/sleet.svg";
if (entity.state == 'snow')
return "/local/svg/weather/animated/snow.svg";
if (entity.state == 'cloudy')
return "/local/svg/weather/animated/cloudy.svg";
else (entity.state == 'wind')
return "/local/svg/weather/animated/wind.svg";
]]]
extra_styles: |
[[[
return `
#name {
font-size: 0.8vw;
}
#temp {
font-size: 1.8vw;
}
#state {
font-size: 0.8vw;
}
#label {
font-size: 0.8vw;
}
/* portrait */
@media screen and (max-width: 2000px) {
#name {
font-size: 0.7vw !important;
}
#temp {
font-size: 1.8vw !important;
}
#state {
font-size: 0.7vw !important;
}
#label {
font-size: 0.7vw !important;
}
}
/* phone */
@media screen and (max-width: 800px) {
#name {
font-size: 2vw !important;
}
#temp {
font-size: 4.5vw !important;
}
#state {
font-size: 2vw !important;
}
#label {
font-size: 2vw !important;
}
}
@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);
}
}
`
]]]
Can you share the code one more time I am trying to copy to the system for a separate window and for some reason it does not work.
Which code? It’s right there
Thanks Laffer!
I believe the credit should go to pex81, or whoever made it, but you’re welcome
What about the weather svg icons, From where i can download it?
If anyone ever runs into this, I ended up solving it by creating a separate button-card of the right size only for the state display portion and a second button-card for the rest of the button I want to display (essentially two buttons on the same line). Works like a charm, thanks @Mattias_Persson for the marquee code!