Lovelace: Button card

Great, that’s exactly it, thank you.
Just need to get rid of the idle state being displayed and looks like there is a surround around the actual timer, how do I remove both of these?
image

Thanks, getting closer… Getting an error on this template

            template: button_default_title

Also Its not clear to me where the following sensors are getting their data

binary_sensor.ha_update_available
sensor.ha_local_version
sensor.ha_remote_versio 
sensor.ha_current_stable_version
sensor.ha_available_version
sensor.ha_current_beta_version
sensor.ha_current_dev_version
sensor.supervisor_updates

Hello!
I show battery and signal strength with the card.
i would like the battery to be 20% and the signal level below 20 to be a different color. I found the code here (thank you)
2021-03-02_191755

  - type: 'custom:button-card'
    entity: sensor.0x04cf8cdf3c772d2d_battery
    icon: 'mdi:white-balance-sunny'
    aspect_ratio: 1/1
    name: WC lux
    styles:
      card:
        - background-color: ivory
        - border-radius: 6%
        - padding-left: 5px
        - color: grey
        - font-size: 15px
        - text-transform: capitalize
        - box-shadow: '0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19)'
      grid:
        - grid-template-areas: '"i i" "n n" "current current" "local local" '
        - grid-template-columns: 3fr
        - grid-template-rows: 3fr min-content min-content
      name:
        - font-weight: bold
        - font-size: 15px
        - align-self: middle
        - justify-self: start
        - padding-bottom: 4px
      img_cell:
        - justify-content: start
        - align-items: start
      icon:
        - color: |
            [[[
              if (entity.state == 'on') return 'red';
              return 'grey';
            ]]]
        - width: 50%
      custom_fields:
        current:
          - align-self: start
          - justify-self: start
          - '--text-color-sensor': |
              [[[ if (entity.state == 'on') return 'red'; return 'green'; ]]]
        local:
          - align-self: start
          - justify-self: start
    custom_fields:
      current: |
        [[[
          return `<ha-icon
            icon='mdi:battery'
            style='width: 20px; height: 20px; color: deepskyblue;'>
            </ha-icon><span>Battery: <span style='color: var(--text-color-sensor);'>${states['sensor.0x04cf8cdf3c772d2d_battery'].state}</span></span>`
        ]]]
      local: |
        [[[
          return `<ha-icon
            icon='mdi:signal'
            style='width: 20px; height: 20px; color: deepskyblue;'>
            </ha-icon><span>Signal: <span style='color: green;'>${states['sensor.0x04cf8cdf3c772d2d_linkquality'].state}</span></span>`
        ]]]

without the error we cant really help you…

which of those sensors did you actually try to find in the community here, they are readily available, of course, next to the core sensors for version.
Let me know so we can have a look where to add to your findings

This is in the docs but in short:

            cards:
              - type: custom:button-card
                ...
                show_state: false

UPDATE: I misread what you said and missed the “Idle”. Do you just want to display nothing in case the timer is idle?

Have a look at the state section of the docs.

Add this to the card main section:

                  styles:
                    card:
                      - box-shadow: none

I have been trying to get my popup working again after the browser_mod change. This code works for a standard button card (thanks to suxlala helping me with this post), but not the custom button card. The popup never pops up.

type: 'custom:button-card'
icon: 'mdi:music'
name: Media Players
layout: icon_name
entity: media_player.tv_room
tap_action:
  action: fire-dom-event
  browser_mod:
    command: popup
    title: Sonos
    hide_header: false
    large: false
    deviceID:
      - this
    card:
      cards:
        - artwork: cover
          entity: media_player.dining_room
          hide:
            power: true
            source: false
          info: short
          speaker_group:
            entities:
              - entity_id: media_player.tv_room
                name: Living Room
              - entity_id: media_player.bedroom_2
                name: Office
              - entity_id: media_player.bedroom
                name: Master Bedroom
            expanded: false
            platform: sonos
            show_group_count: true
          type: 'custom:mini-media-player'
        - artwork: cover
          entity: media_player.tv_room
          hide:
            power: true
            source: false
          info: short
          speaker_group:
            entities:
              - entity_id: media_player.dining_room
                name: Dining Room
              - entity_id: media_player.bedroom_2
                name: Office
              - entity_id: media_player.bedroom
                name: Master Bedroom
            expanded: false
            platform: sonos
            show_group_count: true
          type: 'custom:mini-media-player'
        - artwork: cover
          entity: media_player.bedroom_2
          hide:
            power: true
            source: false
          info: short
          type: 'custom:mini-media-player'
        - type: 'custom:button-card'
          name: Pause after Next Track
          icon: 'mdi:music-off'
          color: var(--accent-color)
          color_type: card
          tap_action:
            action: call-service
            service: automation.turn_on
            service_data:
              entity_id: automation.stop_music_after_current_track
          layout: icon_name
      type: vertical-stack

Can someone please point out where I’ve gone wrong? Thank you!

See this post: Lovelace: Button card

Both versions are up to date, and nuking my cache didn’t fix it. :confused:

Thank you for much for the quick response and such a great custom card!

You also have to remove:

    deviceID:
      - this

Awesome, must have missed it, I was going through the docs alright :slight_smile:
And for the hiding of the “Idle” I can set the color to white when state = idle so it is not seen.
Many thanks

1 Like

Another card (button-card + card-mod) :

d650588e89b223e623532ecaf04ccca58665d2c8

code
name: Sonorisation
show_name: true
icon: 'mdi:speaker'
styles:
  custom_fields:
    wave:
      - background-color: 'rgba(0, 0, 0, 0)'
      - position: absolute
      - right: 5%
      - top: 5%
      - font-size: 13px
      - line-height: 20px
      - display: |
          [[[
            if (states["input_boolean.test2"].state == 'on') return '';
            else return 'none';
          ]]] 
      - '--icon-color': |
          [[[
            if (states["input_boolean.test2"].state == 'on') return 'var(--mail-color)';
            else return 'var(--primary-color)';
          ]]]
  card:
    - border: 2px solid var(--primary-color)
    - border-radius: 10px
  icon:
    - color: var(--primary-color)
  name:
    - font-variant: small-caps
    - color: var(--primary-color)
custom_fields:
  wave: |
    [[[
     return `
       <div class="loader-container">
         <div class="loader-3">
          <div class="item-1"></div>
          <div class="item-2"></div>
          <div class="item-3"></div>
          <div class="item-4"></div>
          <div class="item-5"></div>
         </div>
       </div>`
    ]]]   
type: 'custom:button-card'
style: |
  .loader-3{
    width: 40px;
    height: 40px;
  }

  .loader-3 div {
    height: 100%;
    width: 3px;
    display: inline-block;
  }
  .loader-3 div .item-1{
    height: 50%;
  }
  .loader-3 .item-1 {
    animation: loader-3-first-div 1.2s infinite linear;
    background-color: red;
  }

  .loader-3 .item-2 {
    animation: loader-3-second-div 1.2s infinite linear;
    animation-delay: -1.1s;
    background-color: darkorange;

  }

  .loader-3 .item-3 {
    animation: loader-3-third-div 1.2s infinite linear;
    animation-delay: -1.0s;
    background-color: gold;

  }

  .loader-3 .item-4 {
    animation: loader-3-fourth-div 1.2s infinite linear;
    animation-delay: -0.9s;
    background-color: green;
  }

  .loader-3 .item-5 {
    animation: loader-3-last-div 1.2s infinite linear;
    animation-delay: -0.8s;
    background-color: DarkOrchid;
  }

  @keyframes loader-3-first-div {
    25%,75% {
      transform: scaleY(0.2);
    }
    0%,50%,100%{
      transform: scaleY(0.6);
    }
  }  
  @keyframes loader-3-second-div {
    25%,75% {
      transform: scaleY(0.4);
    }
    0%,50%,100%{
      transform: scaleY(1);
    }
  }  
  @keyframes loader-3-third-div {
    25%,75% {
      transform: scaleY(0.4);
    }
    0%,50%,100%{
      transform: scaleY(1);
    }
  }  
  @keyframes loader-3-fourth-div {
    25%,75% {
      transform: scaleY(0.4);
    }
    0%,50%,100%{
      transform: scaleY(1);
    }
  }  
  @keyframes loader-3-last-div {
    25%,75% {
      transform: scaleY(0.2);
    }
    0%,50%,100%{
      transform: scaleY(0.6);
    }
  }

Inspired by https://codepen.io/ruslan_khomiak/pen/MbqWaK

13 Likes

Another card:
66392427c761839c2774705c650a4d4d50c78e16

Code
style: |
  @keyframes pulsation {
    25% {
      transform: scale(1.3);

    }  
    100% {
      box-shadow: 0 0 0 40px rgba(128, 0, 128, 0), 0 0 0 6px rgba(128, 0, 128, 0) inset;
      transform: scale(1)
    } 
  }
  #courrier{
   animation:
    {% if is_state('input_boolean.test2', 'on') %}
      pulsation 1s infinite ease-in;
    {% else %}
      None
    {% endif %}
    ;
entity: input_boolean.doors_opened
name: Ouvertures
show_name: true
state:
  - icon: 'mdi:door-open'
    value: 'on'
  - icon: 'mdi:door'
    value: 'off'
styles:
  custom_fields:
    courrier:
      - border-radius: 50%
      - box-shadow: >-
          rgb(247 193 57 / 60%) 0px 0px 0px 0px, rgb(247 193 57 / 60%) 0px 0px
          0px 6px inset
      - position: absolute
      - right: 5%
      - top: 5%
      - font-size: 13px
      - line-height: 20px
      - display: |
          [[[
            if (states["input_boolean.test2"].state == 'on') return '';
            else return 'none';
          ]]] 
      - '--icon-color': |
          [[[
            if (states["input_boolean.test2"].state == 'on') return 'var(--mail-color)';
          ]]]
  card:
    - border-radius: 10px
    - border: 2px solid var(--primary-color)
  icon:
    - color: var(--primary-color)
  name:
    - font-variant: small-caps
    - color: var(--primary-color)
custom_fields:
  courrier: |
    [[[
     return `
     <ha-icon
       icon="mdi:mail"
       style="width: 30px; height: 30px; color: var(--icon-color);">
       </ha-icon>`
    ]]]   
type: 'custom:button-card'

Inspiration : https://codepen.io/matchboxhero/pen/pWLOQb?editors=1100

14 Likes

this is awesome :slight_smile:

2 Likes

@Mariusthvdb

the error is

Button-card template 'button_default_title' is missing!

type: 'custom:button-card' 
name: Home Assistant version info 
template: button_default_title

and

Button-card template 'button_updater' is missing!
type: 'custom:button-card'
template: button_updater
entity: binary_sensor.ha_update_available
name: Update available

so I think I’m just missing the template for button_updater and button_default_title

Thanks for your help

button_default_title:
  aspect_ratio: 12/1
  styles:
    card:
      - background-color: var(--background-color-off)
      - color: var(--text-color-off)
      - font-size: 20px
      - font-weight: bold

and

button_updater:
  template: button_body
  state:
    - value: 'on'
      styles:
        icon:
          - color: green
          - animation: blink 2s ease infinite
        state:
          - color: green
          - animation: blink 2s ease infinite
    - operator: default
      styles:
        icon:
          - color: grey
        state:
          - color: grey

Display of a timer directly on the card (another way ? tell me how :heart_eyes: ):
(we can imagine a change in speaker color, name, etc. depending on the state of the timer)

animate

Code
name: |
  [[[
    var finishes_at = new Date(states['timer.hacf_timer'].attributes.finishes_at);
    var remaining = states['timer.hacf_timer'].attributes.remaining;
    if (finishes_at == 'Invalid Date') {
      if (remaining) {
        var remaining_first_element = remaining.split(':');
        if (remaining_first_element[0].length < 2 ) {
          if (remaining_first_element[0] == '0' ) {
            remaining_first_element = remaining_first_element.splice(1);
          } else {
            remaining_first_element[0] = '0' + remaining_first_element[0];
          }

        }
          result = remaining_first_element.toString().replaceAll(',',':');

      } else {
        result = 'Sonorisation';
      }
    } else {
      var timestamp = finishes_at.getTime();
      var timestamp_now = Date.now();
      var difference_between = timestamp - timestamp_now
      var time_remaining = new Date(difference_between).toUTCString();
      var hours = time_remaining.split(' ');
      var hours_split = hours[4].split(':');
      if (parseInt(hours_split[0]) == 0 ) {
        hours_split = hours_split.splice(1);
      }
      var result = hours_split.toString().replaceAll(',',':');;
    }
    return result;
  ]]]
triggers_update:
  - sensor.aleatoire
show_name: true
icon: 'mdi:speaker'
styles:
  custom_fields:
    wave:
      - background-color: 'rgba(0, 0, 0, 0)'
      - position: absolute
      - right: 5%
      - top: 5%
      - font-size: 13px
      - line-height: 20px
      - display: |
          [[[
            if (states["input_boolean.test2"].state == 'on') return '';
            else return 'none';
          ]]] 
      - '--icon-color': |
          [[[
            if (states["input_boolean.test2"].state == 'on') return 'var(--mail-color)';
            else return 'var(--primary-color)';
          ]]]
  card:
    - border: 2px solid var(--primary-color)
    - border-radius: 10px
  icon:
    - color: var(--primary-color)
  name:
    - font-variant: small-caps
    - color: var(--primary-color)
custom_fields:
  wave: |
    [[[
     return `
       <div class="loader-container">
         <div class="loader-3">
          <div class="item-1"></div>
          <div class="item-2"></div>
          <div class="item-3"></div>
          <div class="item-4"></div>
          <div class="item-5"></div>
         </div>
       </div>`
    ]]]   
type: 'custom:button-card'
style: |
  .loader-3{
    width: 40px;
    height: 40px;
  }

  .loader-3 div {
    height: 100%;
    width: 3px;
    display: inline-block;
  }
  .loader-3 div .item-1{
    height: 50%;
  }
  .loader-3 .item-1 {
    animation: loader-3-first-last-div 1.2s infinite linear;
    background-color: red;
  }

  .loader-3 .item-2 {
    animation: loader-3-middle-div 1.2s infinite linear;
    animation-delay: -1.1s;
    background-color: darkorange;

  }

  .loader-3 .item-3 {
    animation: loader-3-middle-div 1.2s infinite linear;
    animation-delay: -1.0s;
    background-color: gold;

  }

  .loader-3 .item-4 {
    animation: loader-3-middle-div 1.2s infinite linear;
    animation-delay: -0.9s;
    background-color: green;
  }

  .loader-3 .item-5 {
    animation: loader-3-first-last-div 1.2s infinite linear;
    animation-delay: -0.8s;
    background-color: DarkOrchid;
  }

  @keyframes loader-3-first-last-div {
    25%,75% {
      transform: scaleY(0.2);
    }
    0%,50%,100%{
      transform: scaleY(0.6);
    }
  }  
  @keyframes loader-3-middle-div {
    25%,75% {
      transform: scaleY(0.4);
    }
    0%,50%,100%{
      transform: scaleY(1);
    }
  }  

A timer entity must be used:

sensor:
  - platform: random
    name: Aléatoire
    maximum: 999

We must add a random entity (which serves as a trigger to update the button-card):

sensor:
  - platform: random
    name: Aléatoire
    maximum: 999

You need an automation that runs every second to update this entity:

Automation to update entity
alias: mise a jour de sensor.aleatoire
description: Mise à jour pour affichage des timers sur les cartes
trigger:
  - platform: time_pattern
    seconds: '*'
condition: []
action:
  - service: homeassistant.update_entity
    target:
      entity_id: sensor.aleatoire
mode: restart

En français dans le texte

Edit: without random entity and automation but update directly in button-card with javascript (thanks @RomRider) :

3 Likes

@sd_dracula Can you post the code you came up with? This is exactly what I’m trying to do.

Cheers, Richard

Here you go

color: auto
color_type: card
entity: vacuum.robovac
hold_action:
  action: more-info
icon: 'mdi:robot-vacuum'
size: 50%
show_label: true
state:
  - color: white
    styles:
      card:
        - animation: blink 2s ease infinite
        - color: 'rgb(255, 0, 0)'
    value: 'on'
  - color: 'rgb(255, 255, 255)'
    value: 'off'
styles:
  grid:
    - grid-template-areas: '"t" "i" "n"'
    - grid-template-rows: min-content 1fr min-content
    - grid-template-columns: 1fr
  card:
    - height: 95px
    - width: 95px
  label:
    - font-size: 14px
  name:
    - font-size: 14px
custom_fields:
  t:
    card:
      type: 'custom:button-card'
      name: Timer
      entity: timer.robovac_timer
      margin: none
      show_name: false
      show_icon: false
      show_state: true
      styles:
        card:
          - box-shadow: none
          - font-size: 12px
        state:
          - color: |
              [[[
                if (states['timer.robovac_timer'].state == 'idle')
                  return "white";
                else
                  return "red";
              ]]]
type: 'custom:button-card'

2 Likes

Hi all,
i made a card with custom:button-card with my temperature sensors like this:


Is it possible to make a custom:button-card that change background color like mini-graph card with color thresholds concept? Like this:
52573150-cbd05900-2e19-11e9-9e01-740753169093
but working with background button card color?
Thanks in advance

1 Like

Yes, everything is possible if you develop some code to do it :slight_smile: but color threshold is not a simple javascript code.

This is how I build the color of the header in apexcharts-card based on a color_threshold list: https://github.com/RomRider/apexcharts-card/blob/68b1097cbd601b9c20cc6fc28146fe28a29b3d2e/src/apexcharts-card.ts#L986-L1008