Lovelace: Button card

For SVG, you can use the solution from this post.

If you want to change the picture based on the color, you can use javascript templates to return the appropriate image path.

Thank you,
I’ll try this method.

For javascript I’m a total noob so I try that first.

I applied the code but it wasn’t quite doing what I wanted. It was still extremely helpful and I was hell-bent to get it right. Was it worth the effort? I’m not sure but it was fun. Regardless, I’ll share my config in case someone finds it useful in future. Instead of using state: I used style: as it allows me to template the colours.

- type: custom:button-card
  name: Dining Room
  entity: light.smart_bulb_3
  size: 20%
  show_label: true
  label: >
    [[[
      var b = states['light.smart_bulb_3'].attributes.brightness;
      return parseInt(b ? b/2.55 : '0') + '%';
    ]]]
  styles:
    name:
      - color: var(--paper-item-icon-color)
    label:
      - color: var(--paper-item-icon-color)
      - padding-left: 1ex
    card:
      - font-size: 12px
    grid:
      - grid-template-areas: '"l" "i" "n"'
      - grid-template-rows: min-content 1fr min-content
      - grid-template-columns: 1fr
    # https://community.home-assistant.io/t/lovelace-button-card/65981/4599
    icon:
      - color: >
          [[[
            let threshold = 255;
            if (entity.state === 'on' && entity.attributes.rgb_color) {
              let red = entity.attributes.rgb_color[0];
              let green = entity.attributes.rgb_color[1];
              let blue = entity.attributes.rgb_color[2];
              let brightness = entity.attributes.brightness;
              // 0 brightness means 50% – scale 0-255 to 0.5-1
              let brightness_factor = (brightness/255 + 1)/2;
              // imitate the built-in active icon colour for rgb lights when the light colour is white(-ish)
              if ((red >= threshold) && (green >= threshold) && (blue >= threshold)) {
                // this is a tint applied to typically a golden yellow ((FD,D8,35) or (253,216,53)) by multiplying by the brightness
                // so 50% brightness is the colour (189,162,39)
                let paper_item_icon_active_color = getComputedStyle(this.parentNode).getPropertyValue('--paper-item-icon-active-color').trim();
                // https://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb
                let re = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(paper_item_icon_active_color);
                red = parseInt(re[1], 16) * brightness_factor;
                green = parseInt(re[2], 16) * brightness_factor;
                blue = parseInt(re[3], 16) * brightness_factor;
              }
              // otherwise, show the actual colour adjusted for brightness
              return 'rgb(' + red + ',' + green + ',' + blue + ')';
            } else if (entity.state === 'off') {
              return 'var(--paper-item-icon-color)';
            } else {
              // default entity.state === 'unavailable' colour
              return 'var(--primary-text-color)';
            }
          ]]]
  tap_action:
    action: toggle
    haptic: light
  hold_action:
    action: more-info
    haptic: selection

Good stuff, I think you can really simplify everything by not using getComputedStyle and regexp and use the css attribute to apply the brightness:

filter: brightness(xx%)

What was missing from the code I’ve shared is brightness support.
What I’d have done is this (I didn’t test it, and it only covers the color/brightness part)

  variables:
    above_threshold: |
      [[[
        let threshold = 255;
        if (entity.state === 'on' && entity.attributes.rgb_color) {
          let rgb_sum = entity.attributes.rgb_color.reduce((a, b) => a + b, 0);
          return rgb_sum > 3 * threshold;
        }
        return false;
      ]]]

  styles:
    icon:
      - color: |
          [[[
            if (variables.above_threshold) { // above threshold == white here
              return 'var(--paper_item_icon_active_color)';
            } else if (entity.state === 'on') {
              return 'var(--button-card-light-color)'; // already includes brightness/color support
            } else if (entity.state === 'off') { // off
              return 'var(--paper-item-icon-color)';
            } else { // unavailable
              return 'var(--primary-text-color)';
            }
          ]]]
      - filter: '[[[ return variables.above_threshold ? `brightness(${(entity.attributes.brightness/255 + 1)/2})` : null; ]]]'
3 Likes

Ah, this is great. It’s definitely simpler and cleaner.

I’ve fixed two small typos and otherwise works exactly as advertised: There’s a missing bracket in the filter line before brightness in the calculation and it needs to be qualified with entity.attributes. – if you want to update your post. I’ll post my config anyway.

I saw the brightness() function in the CSS when I was inspecting the code but didn’t realise it was the same that’s in some of the examples under the button’s docs under styling. This is definitely helpful.

- type: custom:button-card
  name: Dining Room
  entity: light.smart_bulb_3
  size: 20%
  show_label: true
  label: >
    [[[
      var b = states['light.smart_bulb_3'].attributes.brightness;
      return parseInt(b ? b/2.55 : '0') + '%';
    ]]]
  variables:
    above_threshold: |
      [[[
        let threshold = 255;
        if (entity.state === 'on' && entity.attributes.rgb_color) {
          let rgb_sum = entity.attributes.rgb_color.reduce((a, b) => a + b, 0);
          return rgb_sum >= 3 * threshold;
        }
        return false;
      ]]]
  styles:
    name:
      - color: var(--paper-item-icon-color)
    label:
      - color: var(--paper-item-icon-color)
      - padding-left: 1ex
    card:
      - font-size: 12px
    grid:
      - grid-template-areas: '"l" "i" "n"'
      - grid-template-rows: min-content 1fr min-content
      - grid-template-columns: 1fr
    icon:
      - color: |
          [[[
            if (variables.above_threshold) { // above threshold == white here
              return 'var(--paper-item-icon-active-color)';
            } else if (entity.state === 'on') {
              return 'var(--button-card-light-color)'; // already includes brightness/color support
            } else if (entity.state === 'off') { // off
              return 'var(--paper-item-icon-color)';
            } else { // unavailable
              return 'var(--primary-text-color)';
            }
          ]]]
      - filter: '[[[ return variables.above_threshold ? `brightness(${(entity.attributes.brightness/255 + 1)/2})` : null; ]]]'
  tap_action:
    action: toggle
    haptic: light
  hold_action:
    action: more-info
    haptic: selection

I’m trying to launch Android apps from a Lovelace dashboard being run on Fully Kiosk.
The method outlined here works well using weblinks. However, the way weblinks are displayed isn’t great.
I’ve tried using the URL tap_action of button-card, but it attempts to open the link in a new tab in Fully…which doesn’t work. I’ve also tried using the Fully API method outlined here, but its not ideal because there is a 5+ second delay.

Any chance there is a way to get a tap action for button-card that is similar to how weblinks work?

Please look here, you have a solution:

Looks like you have been pointed in the right direction already but here is my implementation for reference.

card:
  styles:
    - width: 100px
    - height: 100px
entity_picture: /local/lovelace/spotify-trans.png
name: Spotify
show_entity_picture: true
size: 80px
tap_action:
  action: javascript
  launch: |
    [[[
      fully.startApplication('com.spotify.music')
    ]]]
type: 'custom:button-card'
1 Like

Hi,
could someone possibly please help me template the below? I wanted to change the icon depending on door/window state and also for the actual state to say closed instead of off.

Thank you kindly!

    [[[
      return `<ha-icon
        icon='mdi:window-closed-variant'
        style='width: 20px; height: 20px; color: grey;'> 
        </ha-icon><span><span style='color: grey;'> ${states['binary_sensor.aqara_contact_window_kitchen'].state}</span></span>`
    ]]]

thank you PodPerson!

Hi, I cannot find the button-card within HACS lovelace repositories, for installation.
Is that somewhere else?
Thank you for any help.

Hello, I really liked your idea of ​​managing with buttons like a radio button, but even with your explanations and those of RomRider, I was unable to implement the final code. Could you please share your code, automation, script and lovelace config of buttons??? Thanks.

Screenshot_20201121-200429

I made this button for my AC but I wanted to display temperature and humidity values within this button (2 separate sensors) in the right superior corner next to a temperature icon. How can I do this? Tried multiple examples but always get it wrong.

This is my code:

type: 'custom:button-card'
entity: climate.ac_sala
name: AC
icon: 'mdi:fan'
tap_action:
  action: call-service
  service: browser_mod.popup
  service_data:
    card:
      entity: climate.ac_sala
      hide:
        temperature: true
      icon:
        cool: 'mdi:snowflake'
        heat: 'mdi:radiator'
        'off': 'mdi:power'
      modes:
        cool:
          icon: 'mdi:snowflake'
        heat:
          icon: 'mdi:radiator'
        include: true
        name: 'Off'
        'off':
          icon: 'mdi:power-standby'
      sensors:
        - entity: sensor.temperaturasala
          icon: 'mdi:thermometer'
          name: Temperatura
        - entity: sensor.humidadesala
          icon: 'mdi:water-percent'
          name: Humidade
      step_size: 0.5
      type: 'custom:simple-thermostat'
    deviceID:
      - this
    style:
      opacity: 0.9
      top: 5%
    title: Ar Condicionado - Sala
color: auto
size: 30%
show_state: true
styles:
  card:
    - border-radius: 15px
    - height: 130px
    - width: 130px
    - '--paper-card-background-color': 'rgb(255, 251, 239)'
  icon:
    - padding: 0px 60px 0px 0px
  name:
    - padding: 0px 10px
    - font-size: 13px
    - font-family: Helvetica
    - justify-self: start
    - font-weight: bold
  label:
    - color: gray
    - font-size: 11px
    - font-family: Helvetica
    - padding: 0px 10px
    - justify-self: start
  state:
    - font-size: 11px
    - font-family: Helvetica
    - padding: 0px 10px
    - justify-self: start
    - text-transform: capitalize
    - font-weight: bold
state:
  - value: 'on'
    styles:
      name:
        - color: white
      state:
        - color: gray
  - value: 'off'
    style:
      - opacity: 0.4
    styles:
      icon:
        - color: '#666666'
      name:
        - color: '#666666'
      state:
        - color: '#666666'
  - value: unavailable
    style:
      - opacity: 0.2
    styles:
      icon:
        - color: '#666666'
      name:
        - color: '#666666'
      state:
        - color: '#666666'

Try to define a grid and have a look at the 2nd example here.

Hello, I have read almost the entire post, looked at options, but my knowledge does not give me or I do not know what I am looking for, in the image, as you can see there is a connection and a battery, I would like to be able to do in the connection if it is connected is green, and on the battery the icon changes based on its level. Can somebody help me?? thanks, I have tried several templates but none of them work.

image

This works for me:

- platform: template
  sensors:
    battery_huawei:
      unit_of_measurement: '%'
      value_template: >-
          {% if states('sensor.lya_l29_battery_level') %}
              {{ states('sensor.lya_l29_battery_level') | round }}
          {% else %}
              {{ states('sensor.battery_huawei') }}
          {% endif %}
      icon_template: >-
        {% if is_state('sensor.battery_huawei', 'unknown') %}
          mdi:battery-unknown
        {% elif is_state('sensor.lya_l29_battery_state', 'charging') %}
          mdi:battery-charging
        {% elif states('sensor.lya_l29_battery_level')|float <= 5 %}
          mdi:battery-outline
        {% elif states('sensor.lya_l29_battery_level')|float >= 95 %}
          mdi:battery          
        {% else %}
          mdi:battery-{{(states('sensor.lya_l29_battery_level')|float / 10)|round*10}}
        {% endif %}

Changes the icon of the battery based on its level and whether it’s charging or not. No colors, though. To do that, you can check out battery state card / entity row available on HACS.

Hi all
Just started to use this card.
I need some help because I can not change the color of the card or of the text when the switch-light is off.
I need the color of the text to be blue for example when the switch is off. Right now I can’t see the the icon or the text of the card (it’s light gray)

Screenshot 2020-11-22 160808

the template I use is

button_card_templates:
  light:
    aspect_ratio: 1/1
    color: auto-no-temperature
    color_type: card
    tap_action:
      action: toggle
    hold_action:
      action: more-info
    show_icon: true
    show_name: true
    styles:
      card:
        - font-size: 90%

One more question is how I can change the color of the card when the switch is on. Right now it turns to yellow which is acceptable but I would like the option if possible.

@RomRider sorry to @ you. I’m creating custom svg elements and the most recent build of the card adds an ellipsis class and the svg is not vertically aligned inside it. It’s rather frustrating because this used to not have this item. Do you have any idea how to have an svg item placed in that element vertically centered? There’s about 10% of the pixel height 4px added at the bottom of this ellipsis class that I cannot remove.

Using this as a style

custom_fields:
  custom_icon: |
    [[[
      return `
        <svg viewBox="0 0 24 24">
          <path fill="var(--paper-item-icon-color)" d="m4.0251 14.59c-0.33095 0.0581-0.66771 0.0755-1.0161 0.12194l-1.0626-3.1121v3.2457c-0.33095 0.03484-0.63287 0.08128-0.94641 0.12773v-5.9456h0.88258l1.2077 3.3735v-3.3735h0.93481zm1.829-3.385c0.36001 0 0.9116-0.0174 1.2425-0.0174v0.92899c-0.41226 0-0.89416 0-1.2425 0.0174v1.3819c0.54581-0.0348 1.0916-0.0813 1.6432-0.0988v0.89412l-2.5722 0.20326v-5.4869h2.5722v0.92901h-1.6432zm5.0979-1.2483h-0.96383v4.2734c-0.31354 0-0.62709 0-0.92896 0.0115v-4.285h-0.96383v-0.92903h2.8567zm1.5096 1.1845h1.2716v0.92899h-1.2716v2.1077h-0.91165v-5.1502h2.5955v0.92901h-1.6838zm3.1935 2.2238c0.52839 0.0115 1.0625 0.0522 1.5793 0.0813v0.9174c-0.83028-0.0522-1.6606-0.10447-2.5083-0.12194v-5.214h0.92898zm2.3632 1.0626c0.29612 0.0174 0.60966 0.0348 0.91158 0.0697v-5.4695h-0.91158zm4.9818-5.3998-1.1787 2.8277 1.1787 3.118c-0.34841-0.0465-0.69678-0.11032-1.0452-0.16839l-0.66769-1.7186-0.67927 1.5793c-0.33683-0.0581-0.66198-0.0755-0.99868-0.12199l1.1961-2.7231-1.08-2.7928h0.99864l0.60966 1.5619 0.65033-1.5619z" />
        </svg>
        `;
    ]]]
styles:
  card:
  - border-radius: 18%
  - padding: 0px
  - --ha-card-background: var(--primary-background-color)
  custom_fields:
    custom_icon:
    - position: absolute
    - top: 50%
    - left: 50%
    - width: 75%
    - transform: translate(-50%, -50%)
    - justify-self: center
    - overflow: visible

It’s driving me nuts.

EDIT: as a band aid I added 2 pixels in the Y absolute position calc.

Hi to all,
I’ve finaly managed how to change color programmatically in svg… now I wish to applicate the same method to Label, Name and State but without rewrote the code 3 times.
How can I create a local variable and apply that to all interested elements?

This is the code (from the svg section):

      - fill: |
          [[[
            if (entity.state === 'on')
            {
             if (entity.attributes.brightness <= 128)
             {
              return '#ffffff';
             }
             else if (entity.attributes.brightness > 128 && entity.attributes.brightness < 230)
             {
              if (entity.attributes.color_temp >= 330 && entity.attributes.color_temp <= 380)
             {
               return '#ffffff';
              }
             }
             else if (entity.attributes.brightness >= 230)
             {
              if (entity.attributes.color_temp >= 425)
              {
               return '#ffffff';
              }
              else if (entity.attributes.color_temp >= 260 && entity.attributes.color_temp < 425)
              {
               return '#000000';
              }
             }
            }
            else if (entity.state === 'off')
            {
             return '#b3b3b3'; //grigio
            }
            else
            {
             return '#000000'; //nero
            }
          ]]]

Hi there all,
can I put a card inside the button-card please ?
I need it cause I want to use the action:navigate for the custom:weather-card

  - type: custom:button-card
    aspect_ratio: 1/0.93
    gridcol: 2 / 3
    gridrow: 2 / 5
    tap_action: 
      action: navigate
      navigation_path: /lovelace/7/
    cards:
      - type: custom:weather-card
        entity: weather.baubau
        style: "ha-card { height: 350px; }"
        name: Baubau

The button -card it’s work, but the I can’t see the weather-card…it’s empty:

Thanks all
Denis