Well, that worked flawlessly, thanks a lot Marius!
kind regards,
Ben
Well, that worked flawlessly, thanks a lot Marius!
kind regards,
Ben
I really like the custom:button-card. However, I am not able to achieve following use-case and hope you can help.
I am using the custom button-card for opening and closing of my gate doors, which functionality wise works just fine.
I would like enable some icon animation while the gate doors open or close (hence, when in motion).
I would as well like to disable multiple button-clicks while the doors are in motion.
Since the gate only has two states, âOpenâ and âClosedâ and hence, no state called âOpening/Closingâ, I would like to use a time-frame (15sec) after button-click to represent the state âOpening/Closingâ and also during this time-frame to enable the animation and and disabling of multiple clicks.
Any ideas how to best achieve this?
Thanks.
I rely heavily on the button-card
for all my dashboards. It hasnât been supported since 2021 and there have not been any commits in at least 2 years. With the latest 2023.3 version of HA, there is a new precision masking feature (actual name??) that allows you to set the decimals of precision. I has JS code to set the precision in some tiny buttons that would display a huge red box when the sensor is not working. Without the JS, the box is empty so I changed the precision on the device (Humidity without decimals) and removed the JS. Problem is that button-card
does not support this new feature and it is unsupported so no chance of it ever being addedâŚ
This is how it displays with the JS code in place
This is how it displays once I removed the JS code even though I set the humidity to not have decimals:
This is the YAML:
type: custom:button-card
entity: sensor.office_multi_sensor_humidity
state_display: |
[[[
var result = Number(entity.state).toFixed(0);
return result.concat("%");
]]]
styles:
card:
- height: 100%
- width: 42px
- padding: 0px 0px 0px 2px
name:
- text-transform: uppercase
- font-size: 12px
- font-weight: normal
- justify-self: center
- letter-spacing: 2px
- padding: 0%
tap_action:
action: none
show_icon: false
show_name: false
show_state: true
layout: name_state
While there may be a way to keep the JS code that sets precision and not have it break the dashboard if something happens to the sensor, I am quite concerned that some future update will blow up all my 50 or so views where I likely used the button-card
. Are there alternatives? Is some brilliant developer willing to take on maintenance from the original developer @RomRider ? I love this card but I donât want to keep using it if it isnât supported⌠too big of a risk.
Example of my main dashboard where I heavily rely on it⌠all of those are button-card
s
I just found âPaper buttons Rowâ in HACS and iâm playing a bit with it. First test look promisingâŚit seems that it has all from button card plus more.
But⌠since i also have a lot of custom:button cards going to a different card will take a lot of time and programmingâŚ
yes, this might become a issue.
was wondering why I had no issues in my button-cards since the latest update, and my taking out all(!) rounds in the yaml config though, I just realized Ive had
${Math.round(states['sensor.raw_value'].state)}
since forever on those.
So, as much as I would hope to see an updated, or maybe should say maintained custom:button-card, the latest (great) change in HA really holds no issue for this card at all.
as a matter of fact: it simply returns what you say it should and in that, is way more predictable and configurable than any core Frontend card
btw, there are subtle differences between the various methods for rounding Math.round(), toInt(), toFixed():
Hi Juan,
sorry for this late response, but please let me ask how you get the colored icon background in the first?
been looking for a way to get the same effect as on the new Tile cards and dit find something like:
'radial-gradient(var(--card-background-color) 60%, transparent calc(60% + 1px)), conic-gradient(var(--tile-color) {{ (states(config.entity) |float * 100) | round(0) }}% 0%, var(--card-background-color) 0% 100%);
tried to rebuild that to JS and add it to
styles:
icon:
- background: >
[[[ return 'radial-gradient(var(--card-background-color) 60%,transparent calc(60% + 1px)), conic-gradient(var(--tile-color) Math.round(states[config.entity])% 0%, var(--card-background-color) 0% 100%)';
]]]
but no such luck just yetâŚ
the color is set correctly by this, but the background size isntâŚ
styles:
img_cell:
# - background-color: "rgba(var(--color-theme),0.05)"
- border-radius: 50%
- place-self: start
- width: 42px
- height: 42px
icon:
# - filter: drop-shadow(0 0 12px var(--button-card-light-color))
- background: >
[[[ var color = entity.attributes.rgb_color;
return (entity.state === 'on') ?
'rgba(' + color + ',0.2)' : 'none'; ]]]
this is copied from mushroom internal templates, and I only moved it to the start of the cell, as that is where I want the iconsâŚ
@Mariusthvdb I will add my response here to not clutter the Mushroom thread with custom:button-card stuff.
This line defines the size of the icon within the img_cell. And could it be that there is some overflowing not allowed or margin/padding from other areas in your card that cut off the icon bit?
thanks! yes, I just added a line indeed not to clutter Mushroom.
on the button, no I dont think so, and even in itâs cleanest form:
- type: custom:button-card
entity: light.dining
icon: mdi:silverware
<<: &style
# template: button_light
show_last_changed: false
styles:
img_cell:
# - background-color: "rgba(var(--color-theme),0.05)"
- border-radius: 24px
- place-self: start
- width: 42px
- height: 42px
icon:
# - filter: drop-shadow(0 0 12px var(--button-card-light-color))
- background: >
[[[ var color = entity.attributes.rgb_color;
return (entity.state === 'on') ?
'rgba(' + color + ',0.2)' : 'none'; ]]]
still doest not show the full circle:
with my light template:
- type: custom:button-card
entity: light.dining
icon: mdi:silverware
<<: &style
template: button_light
show_last_changed: false
styles:
img_cell:
# - background-color: "rgba(var(--color-theme),0.05)"
- border-radius: 50%
- place-self: start
- width: 42px
- height: 42px
icon:
# - filter: drop-shadow(0 0 12px var(--button-card-light-color))
- background: >
[[[ var color = entity.attributes.rgb_color;
return (entity.state === 'on') ?
'rgba(' + color + ',0.2)' : 'none'; ]]]
its back to the one posted aboveâŚ
taking the img_cell section out brings back all to its correct proportions, only doesnt set the background circle:
If you try to add some padding to the img_cell? Then other parts should inherit that information and probably not cutoff the icon part.
no that does not help (yet) as it the background itself simply isnt complete yet.
adding padding 2px to this:
- type: custom:button-card
entity: light.dining
icon: mdi:silverware
size: 24px
<<: &style
template: button_light
show_last_changed: false
styles:
img_cell:
- border-radius: 50%
- padding: 2px
- place-self: start
- width: 42px
- height: 42px
icon:
- background: >
[[[ var color = entity.attributes.rgb_color;
return (entity.state === 'on') ?
'rgba(' + color + ',0.2)' : 'none'; ]]]
so I am looking for a before and after of the currently visible background
It must be something in the rest of your card. For now I cannot determine it because you use yaml-anchors and templates. But a simple setup with the same code used by you returns to this:
- type: "custom:button-card"
size: 20px
entity: sensor.lowest_price
show_label: false
show_name: false
color: blue
styles:
img_cell:
- background-color: "rgba(var(--color-blue),0.05)"
- border-radius: "50%"
- place-self: "start"
- width: "42px"
- height: "42px"
# added to overrule theme settings for general card design
card:
- background: "none"
- box-shadow: "none"
using:
- type: "custom:button-card"
entity: light.dining
icon: mdi:silverware
show_label: false
show_name: false
color: auto
styles:
img_cell:
- background-color: "rgba(entity.attributes.rgb_color,0.05)"
- border-radius: "50%"
- place-self: "start"
- width: "42px"
- height: "42px"
card:
- background: "none"
- box-shadow: "none"
background-color needs to be set on the icon:
âŚ
so we know theming has nothing to do with it, this is default theme:
on to something:
- type: grid
columns: 5
# square: false
cards:
- type: custom:button-card
template: button_light
size: 24px
entity: light.dining
icon: mdi:silverware
show_last_changed: false
color: auto
styles:
img_cell:
- background-color: >
[[[ return 'rgba(' + entity.attributes.rgb_color + ',0.2)'; ]]]
- border-radius: 24px
- place-self: "start"
- width: "38px"
- height: "38px"
- type: custom:button-card
template: button_light
size: 24px
entity: light.dining
icon: mdi:silverware
show_last_changed: false
styles:
img_cell:
# - background-color: >
# [[[ return 'rgba(' + entity.attributes.rgb_color + ',0.2)'; ]]]
- border-radius: 50%
# - padding: 2px
- place-self: start
- width: "38px"
- height: "38px"
icon:
# - filter: drop-shadow(0 0 12px var(--button-card-light-color))
- background: >
[[[ var color = entity.attributes.rgb_color;
return (entity.state === 'on') ?
'rgba(' + color + ',0.2)' : 'none'; ]]]
# - background: >
# [[[ return 'radial-gradient(var(--card-background-color) 60%,transparent calc(60% + 1px)), conic-gradient(var(--tile-color) 2% 0%, var(--card-background-color) 0% 100%)';
# ]]]
- type: custom:button-card
template: button_light
size: 24px
entity: light.dining
icon: mdi:silverware
show_last_changed: false
apparently, when setting the background to the icon, it only sees the smaller area, where using it on the img_cell it takes all into accountâŚ
I did that before, because somehow I couldnât get the color to show at all. Probably a template mistake, because now I see:
so 2 things left after this progress!
adding justify-content: center
makes at least the icon placement work (the padding is depending on grid columns, 4 is ok, 4 starts to be too low). This is required because by default the cells are rendered with:
styles_img_cell:
styles:
img_cell:
- align-items: start
- justify-content: start
in my other buttons⌠pfff
- type: custom:button-card
template: button_light
size: 24px
entity: light.dining
icon: mdi:silverware
show_last_changed: false
color: auto
styles:
img_cell:
- justify-content: center
- background-color: >
[[[ return 'rgba(' + entity.attributes.rgb_color + ',0.2)'; ]]]
- border-radius: 24px
- place-self: start
- width: 38px
- height: 38px
guess placement will have to do for now, maybe I will play some more with the paddings.
left now is the coloring when off;
- background-color: >
[[[ var rgb = (entity.state === 'on') ? entity.attributes.rgb_color : 'var(--primary)';
return 'rgba(' + rgb + ',0.2)'; ]]]
with var(âprimary) being the single rgb value primary: 99,107,117
seems to be the way to go, but then I need to adjust my other colors once more, because they are not standing out
o wellâŚIll fix it for now on
- background-color: >
[[[ var rgb = (entity.state === 'on') ? entity.attributes.rgb_color : '211,211,211';
return 'rgba(' + rgb + ',0.2)'; ]]]
though darker themes require extra workâŚ
Glad you found a way to make it work
This what exactly that I was expecting; some styling related to the img_cell/icon in one of your templates/anchors. At least from the snippets shown I was not able to help any further
Dark themes are always a bit more difficult with creating a fitting contrast.
I never even noticed it was no longer maintained!!
I am in deep trouble if this ever stops working.
This, for example is almost 100% buttons
argghhh⌠feeling your pain already
btw @basbrus my main issue now is the various display devices messing with some carefully crafted buttons in grids (4 or 5 card, who to let drop off the card, have it overflowâŚe tc etc)
because of that, ive just rewritten a full button-card config especially for this, and though it seems utterly simple, the template behind it require attention for all detailsâŚ
- type: grid
columns: 4
square: false
cards:
- type: custom:button-card
entity: light.dining
icon: mdi:silverware
<<: &style
template:
- styles_state_default_auto
- action_default
color: auto-no-temperature
layout: icon_name
show_state: false
size: 20px
styles:
card:
- padding: 5px
- font-weight: bold
- font-size: 13px
- border-right: >
[[[
return (entity.state === 'on')
? '0.5rem solid var(--button-card-light-color)' : 'none';
]]]
img_cell:
- justify-content: center
- background-color: >
[[[ var rgb = (entity.state === 'on')
? entity.attributes.rgb_color : '211,211,211';
return 'rgba(' + rgb + ',0.2)'; ]]]
- border-radius: 24px
- place-self: start
- width: 34px
- height: 34px
- type: custom:button-card
entity: light.living
<<: *style
believe it or not, but even the bottom 34pxâs need to be adjusted to 32px for these buttons so show a round (and not flattened circle on mobile)
Good day Marius, no problem. I eventually found the solution.
Please see below my âroom-cardâ version. I use decluttering to avoid repetition.
decluttering_templates:
card_room:
card:
type: custom:button-card
aspect_ratio: 1/1
entity: '[[entity]]'
name: '[[name]]'
icon: '[[icon]]'
show_icon: true
show_label: false
show_state: false
# size: 50%
tap_action:
action: navigate
navigation_path: /lovelace-mobidash/[[room]]
double_tap_action:
action: navigate
navigation_path: /lovelace-mobidash/[[room]]
hold_action:
action: toggle
custom_fields:
chips:
card:
type: custom:mushroom-chips-card
chips:
- type: conditional
conditions:
- entity: '[[light_group]]'
state: 'on'
chip:
type: template
entity: '[[light_group]]'
icon: mdi:lightbulb-outline
icon_color: >
{% if is_state('[[light_group]]', 'on') %}
#FFBF00
{% else %} light-blue {% endif %}
content_info: none
tap_action:
action: more-info
card_mod:
style: |
@keyframes clip {
0% {
clip-path: inset(100% 0 0 0);
}
100% {
clip-path: inset(0 0 0 0);
}
}
ha-card {
--chip-box-shadow: 0px 0px;
animation: clip linear infinite;
{% if is_state('[[input_boolean_autooff]]', 'off') %}
animation-duration: 3s;
{%- else -%}
{%- endif %}
}
- type: conditional
conditions:
- entity: '[[switch_group]]'
state: 'on'
chip:
type: entity
entity: '[[switch_group]]'
icon: mdi:toggle-switch-variant-off
icon_color: '#FFBF00'
content_info: none
tap_action:
action: more-info
- type: conditional
conditions:
- entity: '[[motion_group]]'
state: 'on'
chip:
type: entity
entity: '[[motion_group]]'
icon: mdi:motion-sensor
icon_color: green
content_info: none
tap_action:
action: more-info
- type: conditional
conditions:
- entity: '[[media_group]]'
state_not: 'off'
chip:
type: entity
entity: '[[media_group]]'
icon: mdi:play-pause
icon_color: green
content_info: none
tap_action:
action: more-info
- type: conditional
conditions:
- entity: '[[door_group]]'
state: 'on'
chip:
type: entity
entity: '[[door_group]]'
icon: mdi:door-open
icon_color: red
content_info: none
tap_action:
action: more-info
# - type: conditional
# conditions:
# - entity: '[[aircon_switch]]'
# state_not: 'off'
# chip:
# type: template
# entity: '[[climate]]'
# icon_color: >
# {% if is_state('[[climate]]','fan_only') %}
# yellow
# {% elif is_state('[[climate]]','cool') %}
# light-blue
# {% elif is_state('[[climate]]','dry') %}
# light-blue
# {% else %} {% endif %}
# icon: >
# {% if is_state('[[climate]]','fan_only') %}
# mdi:fan
# {% elif is_state('[[climate]]','cool') %}
# mdi:snowflake
# {% elif is_state('[[climate]]','dry') %}
# mdi:snowflake
# {% else %} {% endif %}
# # content: '{{state_attr("[[climate]]", "hvac_action") }}'
# tap_action:
# action: call-service
# service: climate.turn_off
# target:
# entity_id: '[[climate]]'
# hold_action:
# action: more-info
# card_mod:
# style: |
# @keyframes rotation {
# 0% {
# transform: rotate(0deg);
# }
# 100% {
# transform: rotate(360deg);
# }
# }
# ha-card {
# --chip-box-shadow: 0px 0px;
# animation: rotation linear infinite;
# {% if is_state('[[climate]]','fan_only') %}
# animation-duration: 3s;
# {%- else -%}
# {%- endif %}
# }
- type: conditional
conditions:
- entity: '[[fan_switch]]'
state_not: 'off'
chip:
type: entity
entity: '[[fan_switch]]'
icon: mdi:fan
icon_color: light-blue
content_info: none
tap_action:
action: toggle
hold_action:
action: more-info
card_mod:
style: |
@keyframes rotation {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
ha-card {
--chip-box-shadow: 0px 0px;
animation: rotation linear infinite;
{% if is_state('[[fan_switch]]','on') %}
animation-duration: 3s;
{%- else -%}
{%- endif %}
}
- type: conditional
conditions:
- entity: '[[cover]]'
state: 'closed'
chip:
type: template
entity: '[[cover]]'
icon_color: light-blue
icon: mdi:curtains-closed
tap_action:
action: more-info
- type: conditional
conditions:
- entity: '[[alarm]]'
state_not: 'disarmed'
chip:
type: template
entity: '[[alarm]]'
icon_color: red
icon: '{{ "mdi:shield-account-outline" if states("[[alarm]]") in ["armed_night","armed_away"] }}'
tap_action:
action: call-service
service: alarm_control_panel.alarm_disarm
target:
entity_id: '[[alarm]]'
hold_action:
action: more-info
card_mod:
style: |
@keyframes blink {
50% {opacity: 0;}
}
ha-card {
--chip-box-shadow: 0px 0px;
animation: blink linear infinite;
{% if states("[[alarm]]") in ["armed_night","armed_away"] %}
animation-duration: 3s;
{%- else -%}
{%- endif %}
}
- type: conditional
conditions:
- entity: sensor.unraid_disk_status
state_not: 'Ok'
chip:
type: template
entity: '[[sensor_disk]]'
icon_color: red
icon: "{{'mdi:harddisk' if is_state_attr('[[entity]]', 'friendly_name','Unraid Disk Status') }}"
tap_action:
action: more-info
- type: conditional
conditions:
- entity: sensor.unavailable_entities
state_not: '0'
chip:
type: template
entity: '[[sensor_unavailable]]'
icon_color: red
icon: "{{'mdi:alert-circle' if is_state_attr('[[entity]]', 'friendly_name','Unraid Disk Status') }}"
tap_action:
action: more-info
- type: conditional
conditions:
- entity: binary_sensor.home_assistant_condition
state: 'on'
chip:
type: template
entity: '[[sensor_hass]]'
icon_color: red
icon: "{{'mdi:home-assistant' if is_state_attr('[[entity]]', 'friendly_name','Unraid Disk Status') }}"
tap_action:
action: more-info
- type: conditional
conditions:
- entity: '[[entity]]'
state_not: 'unavailable'
chip:
type: template
entity: '[[entity]]'
icon_color: light-blue
icon: "{{'mdi:cctv' if is_state_attr('[[entity]]', 'friendly_name','Doorbell') }}"
tap_action:
action: navigate
navigation_path: surveillance
alignment: start
layout: vertical
card_mod:
style:
.: |
ha-card {
margin-left: 30%;
background: none;
--chip-box-shadow: none;
--chip-border-width: 0;
--chip-icon-size: 20px;
--chip-height: 20px;
--chip-background: none;
--chip-spacing: 3px;
padding-top: 0px;
border: 0px;
box-shadow: none;
}
:host {
--mush-icon-size: 20px;
--mush-chip-spacing: 3px;
}
ambient: >
[[[
if (states['[[entity]]'].attributes.friendly_name != 'Unraid Disk Status' && (states['[[entity]]'].attributes.friendly_name != 'Doorbell'))
return `${Math.round(states['[[temperature]]'].state) }°C | ${Math.round(states['[[humidity]]'].state) }%`;
return `${Math.round(states['[[temperature]]'].state) }°C`;
]]]
styles:
custom_fields:
chips:
- padding: 5px 0px 0px 20%
- overflow: unset
- align-self: start
- justify-self: end
# - filter: opacity(50%)
ambient:
- margin-top: -280%
- font-size: 12px
- padding: 0px 0px 0px 3px
- justify-self: start
- color: > # added the enitity filter to accomodate outdoor, which has no climate
[[[
if ((states['[[entity]]'].attributes.friendly_name != 'Outdoor Lights') && (states['[[entity]]'].attributes.friendly_name != 'Unraid Disk Status')
&& (states['[[entity]]'].attributes.friendly_name != 'Doorbell') && (states['[[climate]]'].state == 'fan_only')) return "yellow";
if ((states['[[entity]]'].attributes.friendly_name != 'Outdoor Lights') && (states['[[entity]]'].attributes.friendly_name != 'Unraid Disk Status')
&& (states['[[entity]]'].attributes.friendly_name != 'Doorbell') && (states['[[climate]]'].state == 'cool')) return "#03A9F4";
if ((states['[[entity]]'].attributes.friendly_name != 'Outdoor Lights') && (states['[[entity]]'].attributes.friendly_name != 'Unraid Disk Status')
&& (states['[[entity]]'].attributes.friendly_name != 'Doorbell') && (states['[[climate]]'].state == 'dry')) return "deepskyblue";
]]]
# - align-self: middle
card:
- overflow: hidden
- border-width: 0
- border-style: outset
grid:
- grid-template-areas: '"n chips" "ambient chips" "i chips"'
- grid-template-columns: 1fr 1fr
- grid-template-rows: 1fr min-content min-content
- padding: 0px 0px 0px 0px
- justify-items: "center"
img_cell:
- background-color: > # var(--secondary-background-color) # rgba(0,0,0,.2) #"rgba(var(--color-green),0.05)"
[[[
if (entity.state == 'on') return '#d4ebf2';
if (states['sun.sun'].state == 'above_horizon') return 'rgba(0,0,0,.1)';
if (states['sun.sun'].state == 'below_horizon') return 'rgba(100, 100, 100,.5)';
else return 'var(--theme-color)';
]]]
- border-radius: "50%"
- width: "75%"
- height: "75%"
- max-width: "none"
- max-height: "none"
- position: "absolute"
- left: "50%"
- top: "50%"
- transform: "translate(-50%,-50%)"
- margin-top: "25%"
- margin-left: "-25%"
icon:
- place-self: center
- padding: 0px 0px 0px 0px
- color: >
[[[
if (entity.state == 'on') return '#03A9F4';
else return 'grey';
]]]
- width: 50%
- justify-self: start
- overflow: "hidden"
# - display: "grid"
name:
- margin-bottom: 150%
- justify-self: start
- font-size: 16px
- font-weight: bold
- padding: 0px 0px 0px 3px
- text-overflow: "ellipsis"
- overflow: unset
and a sample use
type: custom:decluttering-card
template: card_room
variables:
- entity: group.master_room_lights
- icon: fas:restroom
- name: Master
- temperature: sensor.avg_master_temperature
- humidity: sensor.master_humidity
- room: master
- climate: climate.master
- input_boolean_autooff: input_boolean.plate01_autooff
- light_group: group.master_room_lights
- motion_group: group.master_room_motion
- media_group: group.master_room_media
- door_group:
- aircon_switch: switch.master_aircon_power
- fan_switch: fan.masterfan
- cover: cover.mastercurtains
- sensor_disk: sensor.unraid_disk_status
- sensor_unavailable: sensor.unavailable_entities
- sensor_hass: binary_sensor.home_assistant_condition
thanks, nice,
will have a thorough peek and c&p where required
I use a decluttering template for this. Hoping that it could help you; the length is to do with time only or date and time input datetime card.
datetime_format_extra:
card:
type: custom:button-card
entity: '[[ent]]'
show_name: false
show_state: false
show_icon: false
show_label: true
label: |-
[[[
return (entity.state).substring(0,((entity.state).length == 19 ? 16 : 5 ))
]]]
styles:
border-radius: 1px
card:
- height: 30px
- width: 80px
label:
- color: >-
[[[ var id = states['[[flag]]'].state; return (id == "on") ?
"green": "red" ]]]
tap_action:
action: more-info
I have a card that rotates through some background images, but once the temperature passes a threashold I want a solid background color to flash. The background color works, but not the flashing.
card:
- animation: |
[[[ if (entity.state <= 58)
return "bgswap1 20s linear infinite";
else
"blink 2s ease infinite";
]]]