Lovelace: Button card

Bumpety bump :slight_smile:

Hi all,

So I’ve been reading the git pages, documentation and forums for 24 hours and I can’t get my head around something. I’m trying to change the color of the name and state ‘text’ rather than the color of the icon.

By following the documentation I can change the color of the icon without issues, but how do I just change the “Indoor Temp” and the value to a different color based on the value of the temperature ?

I realise that it’s probably simple but I think I’ve over complicated it inside my head :slight_smile:

Pete

If you want color to change with temperature, just add “styles” with “name” and “state” options - add “styles” under each condition. But if you just want a different color, put “styles” in root (like my example with “card” and brown).

btw…label doesn’t do anything in your case, since you don’t have it enabled (you should write “show_label: true” and define: “label: something”…

type: custom:button-card
entity: sensor.airpurifier_temperature
show_state: true
name: Indoor Temp
styles:  #example ...for non-conditional formatting, you can delete these lines...
  card: #   example...
    - background: brown #   example...
state:
  - value: 10
    operator: '<='
    color: blue
    styles:
      name:
        - color: blue
      state:
        - color: red
  - value: 18
    operator: '>='
    color: red
    styles:
      name: 
        - color: red
      state:
        - color: red
1 Like

Arh that’s perfect, exactly what I was looking for. Thanks so much.

Pete M

1 Like

Using linear-gradient color for icon or background works fine but not for a name or label. Anyone know a way to accomplish this?

Are you trying to color the text with a linear gradient? I’m not sure that’s possible. you can color a gradient behind name or label like this:

styles:
  name:
    - background: linear-gradient(0deg, blue, red)
    - padding: 4px
    - width: 100%
    - border-radius: 8px

Just posting another use for the custom:button-card. While there is room here for improvement, I have a great time building this. What a great card!

1 Like

Yes want to use the linear gradient color for the text but it seems only possible as a background color?

In my quest to streamline my application, I have some button-card-templates like this:

  patio_vizio:
    triggers_update: all
    variables:
      tv: patio_vizio
      ip: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'patio_vizio').ip ]]]
      port: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'patio_vizio').port ]]]
      auth: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'patio_vizio').auth ]]]
      clientaddr: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'patio_vizio').clientAddr ]]]
  office_vizio:
    triggers_update: all
    variables:
      tv: office_vizio
      ip: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'office_vizio').ip ]]]
      port: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'office_vizio').port ]]]
      auth: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'office_vizio').auth ]]]
      clientaddr: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'office_vizio').clientAddr ]]]

I would love to reduce the complexity here, most specifically I am trying to use the variable “tv” inside the other variables. Something like this:

    variables:
      tv: office_vizio
      ip: >-
        [[[ return states['sensor.vizio_tvs'].attributes.tvs.find(x=>x.name ==
        'variables.tv').ip ]]]

In other words, use the variable tv inside the template for ip. Then I could only have one template to set ip, port, auth, clientaddr that would get the variable passed in. I have 4 templates like above and it would reduce the code if I could have one for the meat and 4 to just set which TV.

I cannot figure out how to do it.
I have tried many things … setting a variable in the JS, backticks, brackets, adding/removing quotes … all of them yield errors like variables.tv cannot be interpreted in the “.find”. I even tried :

=>x.name == '' + variables.tv).ip

Thinking it was string issue, but no bueno.
It seems odd to me because in other parts of this integration I have this:

entity_id: '[[[ return ''media_player.'' + variables.tv ]]]'

This works fine.

Any hints on how one could write that?

Hello !
Maybe someon can help me with buttom card.

I would like to replace the colored icon on the right

battery

The left badge have template:

  badge:
    layout: vertical
    variables:
      size: 70
    tap_action:
      action: toggle
    hold_action:
      action: more-info
    custom_fields:
      top_left_info: |
        [[[
          if (variables && variables.top_left_icon) {
            var icon = variables.top_left_icon;
            if (variables.top_left_icon == 'battery') {
              var suffix = '-unknown';
              var prefix = '';
              if (variables.battery_entity) {
                var intBatteryLevel = states[variables.battery_entity].state;
                if (!isNaN(intBatteryLevel)) {
                    if (intBatteryLevel == 100)
                      suffix = '';
                    else if (intBatteryLevel > 9)
                      suffix = '-'+('' + intBatteryLevel)[0] + '0';
                    else
                      suffix = '-alert';

                    if (variables.charging_sensor && states[variables.charging_sensor].state == 'on') {
                      prefix = '-charging';
                      if (intBatteryLevel == 100)
                        suffix = '-100';
                      else if (intBatteryLevel < 10)
                        suffix = '-outline';
                    }
                }
              }

              icon = "mdi:battery"+prefix+suffix;
            }
            return `<ha-icon
                        icon="${icon}">
                        </ha-icon>`;
          }
          return "";
        ]]]
    styles:
      card:
        - background: unset
        - box-shadow: none
        - padding: 0
        - max-width: '[[[return variables.size + ''px'';]]]'
        - margin: 0 auto
      img_cell:
        - background: var(--card-background-color, white)
        - width: '[[[return variables.size + ''px'';]]]'
        - height: '[[[return variables.size + ''px'';]]]'
        - border-top-right-radius: |
            [[[
              if (variables && variables.top_right_icon)
                return '10%';
              else
                return '40%';
            ]]]
        - border-bottom-right-radius: 40%
        - border-bottom-left-radius: |
            [[[
              if (variables && variables.bottom_left_icon)
                return '10%';
              else
                return '40%';
            ]]]
        - border-top-left-radius: |
            [[[
              if (variables && variables.top_left_icon)
                return '10%';
              else
                return '40%';
            ]]]
      icon:
        - width: '[[[return variables.size/2 + ''px'';]]]'
        - color: var(--paper-item-icon-color)
      state:
        - color: var(--secondary-text-color)
        - font-size: 12px
      custom_fields:
        top_left_info:
          - color: |
              [[[
                if (variables && variables.top_left_icon && variables.top_left_icon == 'battery')
                  return "var(--paper-item-icon-color)";
                else
                  return "var(--paper-item-icon-active-color)";
              ]]]
          - display: block
          - position: absolute
          - left: 0
          - top: 0
          - height: '[[[return variables.size/5 + ''px'';]]]'
          - width: '[[[return variables.size/5 + ''px'';]]]'
          - font-size: 0
          - padding: 4%
          - opacity: |
              [[[
                if (variables && variables.top_left_icon && variables.top_left_icon == 'battery')
                  return "0.7";
                else
                  return "1";
              ]]]

And this its the card:

type: custom:button-card
entity: person.dani
show_entity_picture: false
tap_action:
  action: more-info
template: badge
show_state: true
show_name: false
triggers_update:
  - sensor.dani_telefon_battery_level
  - binary_sensor.dani_telefon_is_charging
  - binary_sensor.dani_telefon_headphones
variables:
  size: 100
  top_left_icon: |
    [[[
      if (states['binary_sensor.dani_telefon_is_charging'].state == 'on')
        return "mdi:lightning-bolt-circle";
      return null;
    ]]]
  bottom_left_icon: |
    [[[
      if (states['binary_sensor.dani_telefon_headphones'].state == 'on')
        return "mdi:headset";
      else if (states['binary_sensor.dani_telefon_headphones'].state == 'on' ) {
        return "mdi:headset";
      }
      return null;
    ]]]
  battery_entity: sensor.dani_telefon_battery_level
  charging_sensor: binary_sensor.dani_telefon_is_charging
  top_right_icon: battery

And this its the colored battery:

type: custom:button-card
custom_fields:
  battery: |
    [[[
      var i = states['sensor.dani_telefon_battery_level'].attributes.icon;
      var b = states['sensor.dani_telefon_battery_level'].state;
      return `<span style='vertical-align: 1px'></span><ha-icon icon='${i}' style='width: 16px; vertical-align:2px'></ha-icon>${b}%`
    ]]]
styles:
  custom_fields:
    battery:
      - position: absolute
      - left: 14px
      - top: 1px
      - font-size: 14px
      - color: >-
          [[[ if (states["sensor.dani_telefon_battery_level"].state < 20) return
          "#ff0000"; if (states["sensor.dani_telefon_battery_level"].state < 45)
          return "#ffa229"; if
          (states["sensor.dani_telefon_battery_level"].state < 101) return
          "#00ff00"; else return "#ffc640"]]]

The second problem, i cant line up icons horizontally.

ikon

    styles:
      grid:
        - grid-template-areas: >-
            "n dryer space s"  "n fan space s"  "n humidifier space s" "n
            cleaning space s"  "n heater space s" "l l l humidity"
        - grid-template-rows: min-content min-content
        - grid-template-columns: min-content min-content 1fr min-content
      name:
        - align-self: center
        - font-size: 20px
      label:
        - justify-self: start
        - color: var(--secondary-text-color)
        - font-size: 12px
      state:
        - justify-self: end
        - font-size: 22px
      custom fields:
        fan:
          - align-self: start
          - justify-self: center
        cleaning:
          - align-self: start
          - justify-self: center
        dryer:
          - align-self: start
          - justify-self: center
        humidifier:
          - align-self: start
          - justify-self: center
        heater:
          - align-self: start
          - justify-self: center
        humidity:
          - justify-self: end;
          - color: var(--secondary-text-color)
      card:
        - pointer-events: none
        - background: unset
        - box-shadow: none
        - padding: 0 4px 16px 4px

I know it’s not a small request, if anyone can help, thank you in advance!

1 Like

Just posting my solution for anybody who might need inspiration/help.
I’ve been struggling with the template values, seems to be a lot of nuances to the configuration (if you aren’t familiar with it), I know there is a lot to be improved upon by using template files… baby steps. :smiley:

For non-SA guys, Geyser refers to residential water heater which is controlled by a custom controller.

Blinking state if the preconfigured button matches the target temperature:

type: vertical-stack
cards:
  - type: horizontal-stack
    cards:
      - type: custom:button-card
        color_type: icon
        entity: binary_sensor.geyser0_active
        show_name: false
        show_label: true
        show_state: false
        state:
          - operator: template
            value: |
              [[[
                var sensor_state = (states['binary_sensor.geyser0_active'].state);
                var setpoint_state = (states['sensor.geyser0_setpoint'].state);
                if (sensor_state == "on" &&
                    setpoint_state == 65) 
                  return true; 
                else 
                  return false
              ]]]
            icon: mdi:water-alert-outline
            color: orangered
            label: 65 °C
            styles:
              card:
                - box-shadow: 1px 1px 9px 3px red
                - animation: blink 3s ease infinite
          - operator: default
            icon: mdi:water
            color: orangered
            label: 65 °C
        tap_action:
          action: call-service
          service: mqtt.publish
          service_data:
            payload: 65
            topic: geyser/0/set
      - type: custom:button-card
        color_type: icon
        entity: binary_sensor.geyser0_active
        show_name: false
        show_label: true
        show_state: false
        state:
          - operator: template
            value: |
              [[[
                var sensor_state = (states['binary_sensor.geyser0_active'].state);
                var setpoint_state = (states['sensor.geyser0_setpoint'].state);
                if (sensor_state == "on" &&
                    setpoint_state == 45) 
                  return true; 
                else 
                  return false
              ]]]
            icon: mdi:water-alert-outline
            color: orange
            styles:
              card:
                - box-shadow: 1px 1px 9px 3px orangered
                - animation: blink 2s ease infinite
          - operator: default
            icon: mdi:water
            color: orange
            label: 45 °C
        tap_action:
          action: call-service
          service: mqtt.publish
          service_data:
            payload: 45
            topic: geyser/0/set
      - type: custom:button-card
        color_type: card
        entity: binary_sensor.geyser0_active
        show_name: false
        show_label: true
        show_state: false
        state:
          - value: 'on'
            styles: null
            icon: mdi:water-alert-outline
            color: red
            label: Turn Off
          - value: 'off'
            styles: null
            icon: mdi:water-outline
            color: white
            label: 'Off'
        styles:
          card:
            - text-transform: uppercase
            - font-size: 14px
        tap_action:
          action: call-service
          service: mqtt.publish
          service_data:
            payload: 0
            topic: geyser/0/set
  - type: gauge
    entity: sensor.geyser0_temperature
    name: Temperature
    needle: true
    severity:
      green: 50
      yellow: 30
      red: 50
    max: 75
    min: 15
  - type: entities
    entities:
      - entity: binary_sensor.geyser0_active
        secondary_info: last-changed
        name: Heating Active
      - entity: binary_sensor.geyser0_heating
        name: Element On
      - entity: sensor.geyser0_temperature
        name: Lower Water Temperature
        secondary_info: last-changed
      - entity: sensor.geyser0_setpoint
        name: Target Temperature
        icon: mdi:thermometer-alert
        secondary_info: last-changed
      - entity: sensor.geyser0_next_program_2
        name: Next Program
    title: Geyser Information
    show_header_toggle: false

2 Likes

Apologies, another shameless ask for trouble shooting help:

I’ve managed to generate the following card using this yaml -

blur-photo.com_1661446604

type: custom:button-card
entity: person.NAMEISHERE
name: NAME
show_icon: false
show_name: true
styles:
  card:
    - border-radius: 4%
    - padding: 5%
  grid:
    - grid-template-areas: '"n n""i i""zone zone""battery battery"'
    - grid-template-columns: 1fr 1fr
    - grid-template-rows: 1fr min-content min-content min-content min-content
  name:
    - text-transform: uppercase
    - letter-spacing: 0.1em
    - font-familly: cursive
    - justify-self: middle
    - align-self: middle
    - padding: 1px 1px
    - color: black
  state:
    - justify-self: start
    - font-familly: cursive
    - padding: 1px 1px
  custom_fields:
    i:
      - scale: 100%
    zone:
      - font_familly: cursive
      - font-size: 15px
      - self-start: center
      - align-self: center
      - justify-self: start
      - padding-bottom: 4px
    battery:
      - entity: sensor.NAMEISHERE_phone_battery_state
      - font-size: 15px
      - font_familly: cursive
      - align-self: center
      - justify-self: start
      - '--text-color-sensor': >-
          [[[ if (states["sensor.NAMEISHERE_phone_battery_level"].state <= 20)
          return "red"; ]]]
custom_fields:
  i: |
    <img width= 38% src='/local/_20220825_155544.JPG'>
  zone: |
    [[[
      if (states['person.NAMEISHERE'].state ='Home')
        return `<ha-icon
          icon="mdi:home"
          style="width:20px;height:20px;color:SteelBlue">
          </ha-icon><span> <span style="color: var(--text-color-sensor);">${states['person.NAMEISHERE'].state}</span></span>`
       else 
        return `<ha-icon
          icon="mdi:google-maps"
          style="width:20px;height:20px;color:DarkOrange">
          </ha-icon><span> <span style="color: var(--text-color-sensor);">${states['person.NAMEISHERE'].state}</span></span>`
    ]]]
  battery: |
    [[[
      if (states['sensor.NAMEISHERE_phone_battery_state'] = 'charging')
        return `<ha-icon
          icon="mdi:battery-charging"
          style="width:20px;height:20px;color:lime">`
      else 
        return `<ha-icon
          icon="mdi:battery"
          style="width:20px;height:20px">
          </ha-icon><span> <span style="color: var(--text-color-sensor);">${states['sensor.NAMEISHERE_phone_battery_level'].state}%</span></span>`
    ]]]

The issue I have are the following:

  • When the person state changes (home/away) it is not reflected on the card, either by name, icon or color as it’s meant to.
  • The battery value is displaying and updating correctly but when plugging in the phone it does not update and show it charging, neither icon or color.

Been tinkering with it all day to no avail - any master out there who could set me straight?

1 Like

Does anyone know if I can pass a variable from button_card to a card_mod style? Something like this?

        card_mod:
          style: |
            :host {
              --mush-icon-border-radius: [[[ return variables.radius ]]];
            }

Cual es el código y tarjeta en Home Assistant?

Hey folks, I’m trying to get my head around adding a new state to my Person card (which I plagiarized from a different thread), but really struggling to get my head around the YAML, particularly the grid section which is what’s tripping me up. Have read the doco through and through, and can’t work it out

I have this card, and want to add Travel Time under Distance From Home.

  - type: custom:button-card
    entity: person.andrew
    aspect_ratio: 1/1
    name: Person
    show_entity_picture: true
    show_name: false
    hold_action:
      action: none
    state:
      - value: home
        styles:
          custom_fields:
            icon:
              - border-color: '#77c66e'
              - icon-color: green
      - value: not_home
        styles:
          card: null
          custom_fields:
            icon:
              - border-color: '#EF4F1A'
      - value: Work
        styles:
          custom_fields:
            icon:
              - border-color: deepskyblue
    styles:
      card:
        - border-radius: 5%
        - padding: 5%
        - color: gray
        - font-size: 10px
        - text-shadow: 0px 0px 0px black
        - text-transform: capitalize
        - justify-self: end
        - align-self: middle
      grid:
        - grid-template-areas: '"icon status" "n n" "battery proximity" "wifi ss" "sd sd"'
        - grid-template-columns: 2fr
        - grid-template-rows: 1fr min-content min-content min-content min-content
      name:
        - font-size: 15px
        - align-self: middle
        - justify-self: start
        - padding-bottom: 10px
      custom_fields:
        icon:
          - clip-path: circle()
          - width: 80%
          - pointer-events: none
          - display: grid
          - border: 5px solid
          - border-color: gray
          - border-radius: 500px
          - margin: 0 +10% 0 0
          - justify-self: end
          - opacity: 1
        status:
          - align-self: start
          - justify-self: end
          - color: white
        proximity:
          - padding: 0.5em 0px
          - align-self: middle
          - justify-self: start
          - color: white
        wifi:
          - padding: 0.5em 0px
          - align-self: middle
          - justify-self: start
          - color: white
          - '--text-wifi-color-sensor': >-
              [[[ if (states["sensor.pixel_3_xl_wifi_connection"].state == '<not
              connected>') return "#aaaaaa"; ]]]
        battery:
          - padding: 0.5em 0px
          - align-self: middle
          - justify-self: start
          - color: white
          - '--text-color-sensor': >-
              [[[ if (states["sensor.pixel_3_xl_battery_level"].state < 50)
              return "#EF4F1A"; ]]]
    custom_fields:
      icon: >
        [[[ return entity === undefined ? null : `<img
        src="${states[entity.entity_id].attributes.entity_picture}"
        width="100%">`; ]]]
      status: |
        [[[
          if (states['person.andrew'].state =='not_home') { 
          return `<ha-icon icon="mdi:home-export-outline"
            style="width: 20px; height: 20px; color: '#888888';">
            </ha-icon><span> Away</span>`;
          } 
          if (states['person.andrew'].state =='home') { 
          return `<ha-icon 
            icon="mdi:home"
            style="width: 20px; height: 20px; color: 888888;">
            </ha-icon><span> ${entity.state}</span>`;
          } else {
          return `<ha-icon 
            icon="mdi:map-marker-radius"
            style="width: 20px; height: 20px; color: 888888;">
            </ha-icon><span> ${entity.state}</span>`;
          }
        ]]]
      proximity: |
        [[[
          return `<ha-icon
            icon="mdi:map-marker-distance"
            style="width: 20px; height: 20px; color: #888888;">
            </ha-icon>  <span>\<span style="color: var(--text-color-sensor);">${states['proximity.andrew'].state} Kms</span></span>`
        ]]]
      battery: |
        [[[
          if (states['sensor.pixel_3_xl_battery_state'].state =='charging') { 
            return `<ha-icon
            icon="mdi:battery-charging"
            style="width: 20px; height: 20px; color: #888888;">
            </ha-icon> <span><span style="color: var(--text-color-sensor);">${states['sensor.pixel_3_xl_battery_level'].state}% battery</span></span>`;
          } else {
            return `<ha-icon
            icon="mdi:battery"
            style="width: 20px; height: 20px; color: #888888;">
            </ha-icon> <span><span style="color: var(--text-color-sensor);">${states['sensor.pixel_3_xl_battery_level'].state}% battery</span></span>`;
          }
        ]]]
      wifi: |
        [[[
          if (states['sensor.pixel_3_xl_wifi_connection'].state =='<not connected>') { 
            return `<ha-icon
            icon="mdi:wifi"
            style="width: 20px; height: 20px; color: var(--text-wifi-color-sensor);">
            </ha-icon> <span><span style="color: var(--text-wifi-color-sensor);">Disconnected</span></span>`; 
          } else {
            return `<ha-icon
            icon="mdi:wifi"
            style="width: 20px; height: 20px; color: #888888;">
            </ha-icon> <span><span style="color: var(--text-color-sensor);">${states['sensor.pixel_3_xl_wifi_connection'].state}</span></span>`;
          }
        ]]]

Before delving into a lot of work would like to confirm following;
Am I right in thinking you can only have a ‘tap-action’ on the full card and not the separate custom-fields?
Solution would then be to use separate button cards for the custom fields?

Nope, I’ve used tap-action on a button and then another tap-action on a custom field successfully.

1 Like

OK thanks, even more versatile then I thought.
That will give me something to do then.

I have this button card with a slider and I can’t figure out how to either just disable the thing blue thing over the knob or make it visible. Any ideas? Here’s the code

image

For a similar card I am not using a grid at all, just absolute positioning for the additional information in the corners. This is how the relevant part looks like:

styles:
  name:
    - font-size: 16px
  label:
    - font-size: 8px
  custom_fields:
    icloud3zone:
      - position: absolute
      - left: 2%
      - bottom: 2%
      - font-size: 10px
    distance:
      - position: absolute
      - left: 2%
      - top: 2%
      - font-size: 10px
    traveltime:
      - position: absolute
      - left: 2%
      - top: 11%
      - font-size: 10px
    direction:
      - position: absolute
      - left: 35%
      - top: 2%
      - font-size: 9px

The result is like this:
grafik

2 Likes