Card template variables

The below is the code for one of my buttons for my person card, I'm using variables to make it easy to duplicate for other users. The issue I'm struggling with is referencing the variable in the if statement, it works fine as written below, but I would like to only have to update sensors once, rather than trawling through code to find the one I usually miss. Is it possible to reference the variables in the if statements?


                      battery:
                        card:
                          type: custom:button-card
                          entity: '[[[ return variables.battery ]]]'
                          show_icon: true
                          show_name: false
                          show_state: true
                          styles:
                            card:
                              - border-radius: 10%
                              - width: 65px
                              - height: 30px
                              - background: none
                            icon:
                              - left: 5%
                              - width: 20px
                              - color: |
                                  [[[ 
                                     var battery='sensor.daves_phone_battery_level';                                   
                                     if (states[battery].state < 30) return "#ff1a1a";
                                     if (states[battery].state < 60) return "#F3970A";
                                     if (states[battery].state < 101) return "#50A14F";
                                     else return "#ffc640" 
                                   ]]]    
                              - animation: >
                                  [[[ if
                                  (states['sensor.daves_phone_battery_level'].state
                                  <= 10) return 'blink 2s ease infinite'; ]]]
                            state:
                              - left: 45%
                              - position: absolute
                              - font-size: 12px
                              - font-weight: bold
                              - color: |
                                  [[[ 
                                     var battery='sensor.daves_phone_battery_level';                                   
                                     if (states[battery].state < 30) return "#ff1a1a";
                                     if (states[battery].state < 60) return "#F3970A";
                                     if (states[battery].state < 101) return "#50A14F";
                                     else return "#ffc640" 
                                   ]]] 
                              - animation: >
                                  [[[ if
                                  (states['sensor.daves_phone_battery_level'].state
                                  <= 10) return 'blink 2s ease infinite'; ]]] 

I've accomplished what you're trying to do by using one of two different methods depending on what my needs are.

Method One: Button Card Template

I use this method for every custom:button-card on my dashboard. It allows the user to create templates that define a specific set of parameters and then apply those templates to individual button cards based on their purpose. This avoids having to redefine the same parameters for multiple similar cards.

Below is an example of how I use this approach. The first section is applied directly to my dashboard and creates a custom button card that references two different templates. The second section contains the actual template definitions, which are added after the title: line in the “Raw configuration editor” of the dashboard. You can access this editor by clicking the three dots in the top-right corner while in editing mode.

The first template defines the default style that I use for most of the custom button cards on my dashboard. The second template defines a style used specifically for the OFF buttons on my dashboard and is only applied when certain conditions are met. This template also enables the tap action function, which is used to trigger a script that turns off the light.

You may notice that the second template includes some of the same style settings as the first template. This is intentional. Templates are applied in the order they are referenced in the card, meaning the settings from the template listed last will override any conflicting settings from templates listed before it.

- type: custom:button-card
  template:
    - default_button_01
    - light_button_off
  entity: light.bcl_local
  name: "OFF"
button_card_templates:
  default_button_01:
    aspect_ratio: 1/1
    show_icon: false
    styles:
      card:
        - '--mdc-ripple-color': white
        - '--mdc-ripple-press-opacity': 0.5
        - border-radius: 10%
        - padding: 5%
        - border-color: rgba(119, 119, 119, 0.4)
        - box-shadow: 0px 0px 0px 0px var(--primary-text-color)
      name:
        - font-size: 20px
        - font-weight: none
    tap_action: []
    double_tap_action: []
    hold_action: []
  light_button_off:
    tap_action:
      action: call-service
      service: script.light_buttons_001
      service_data:
        button: 'off'
        light: '[[[ return entity.entity_id ]]]'
    styles:
      card:
        - background-color: |
            [[[
              if (entity.state == 'off') 
                return 'rgba(255, 255, 255, 0.1 )';
              else return '';
            ]]]
      name:
        - font-weight: |
            [[[
              if (entity.state == 'off') return 500;
              else return '';
            ]]]
        - color: |
            [[[
              if (entity.state == 'off') return 'rgb(255, 255, 255)';
              else return '';
            ]]]

Below is an example of how you could apply this method to the code you provided.

- type: custom:button-card
  template:
    - battery_button
  entity: sensor.daves_phone_battery_level

- type: custom:button-card
  template:
    - battery_button
  entity: sensor.bobs_phone_battery_level

- type: custom:button-card
  template:
    - battery_button
  entity: sensor.mikes_phone_battery_level
button_card_templates:                  
  battery_button:
    show_icon: true
    show_name: false
    show_state: true
    styles:
      card:
        - border-radius: 10%
        - width: 65px
        - height: 30px
        - background: none
      icon:
        - left: 5%
        - width: 20px
        - color: |
            [[[ 
              if (entity.state < 30) 
                return "#ff1a1a";
              else if (entity.state < 60) 
                return "#F3970A";
              else if (entity.state < 101)
                return "#50A14F";
              else return "#ffc640" 
             ]]]               
        - animation: >
            [[[ 
              if (entity.state <= 10) 
                return 'blink 2s ease infinite'; 
            ]]]
      state:
        - left: 45%
        - position: absolute
        - font-size: 12px
        - font-weight: bold
        - color: |
            [[[ 
              if (entity.state < 30) 
                return "#ff1a1a";
              else if (entity.state < 60) 
                return "#F3970A";
              else if (entity.state < 101)
                return "#50A14F";
              else return "#ffc640" 
             ]]]               
        - animation: >
            [[[ 
              if (entity.state <= 10) 
                return 'blink 2s ease infinite'; 
            ]]]

Method Two: Decluttering Card

Since Method One only applies to the custom:button-card, I use this method for other card types or when working with multiple cards. This approach allows the user to create templates that define entire cards, not just individual parameters like the button card template method.

Below is an example of how I use it. The first section is applied directly to a grid card on my dashboard. For each card in the grid, I reference the same decluttering card template but define the variables differently based on each card’s purpose. The second section contains the actual decluttering card template definition, which is added after the title: line in the “Raw configuration editor” of the dashboard, just like the button card template section.

If you are using both methods, place the decluttering card template section first and the button card template section after it.

type: grid
title: null
square: false
columns: 3
cards:
  - type: custom:decluttering-card
    variables:
      - atlas_sensor: sensor.atlas_001_do_value
      - atlas_color: rgba(243, 187, 67,1.0)
      - atlas_alt_color: black
      - atlas_parameter: Disolved Oxygen
      - atlas_icon: mdi:gauge
    template: atlas_iot_001_declutter
  - type: custom:decluttering-card
    variables:
      - atlas_sensor: sensor.atlas_001_ph_value
      - atlas_color: rgba(255, 77, 0,1.0)
      - atlas_alt_color: white
      - atlas_parameter: pH
      - atlas_icon: mdi:gauge
    template: atlas_iot_001_declutter
  - type: custom:decluttering-card
    variables:
      - atlas_sensor: sensor.atlas_001_ph_value
      - atlas_color: rgba(80, 174, 87,1.0)
      - atlas_alt_color: white
      - atlas_parameter: EC
      - atlas_icon: mdi:gauge
    template: atlas_iot_001_declutter
decluttering_templates:
  atlas_iot_001_declutter:
    default: null
    card:
      type: custom:button-card
      template: default_button_01
      aspect_ratio: null
      entity: '[[atlas_sensor]]'
      show_name: false
      show_state: true
      styles:
        card:
          - height: 175px
          - font-size: 400%
          - font-weight: bold
          - background-color: '[[atlas_color]]'
        state:
          - color: '[[atlas_alt_color]]'
        custom_fields:
          parameter:
            - position: absolute
            - right: 15px
            - top: 5px
            - font-size: 0.50em
            - color: '[[atlas_alt_color]]'
          icon:
            - position: absolute
            - left: 15px
            - top: 5px
            - font-size: 0.50em
            - color: '[[atlas_alt_color]]'
      custom_fields:
        parameter: |
          [[[ return '[[atlas_parameter]]' ]]]    
        icon: |
          [[[ return `<ha-icon
                  icon="[[atlas_icon]]"
                  style="width: 24px; height: 24px; color: '[[atlas_alt_color]]';">
                  </ha-icon>` ]]]

Below is an example of how you could apply this method to the code you provided.

- type: custom:decluttering-card
  variables:
    - phone_user: sensor.daves_phone_battery_level
  template: battery_level
decluttering_templates:
  battery_level:
    default: null
    card:
      type: custom:button-card
      entity: '[[phone_user]]'
      show_icon: true
      show_name: false
      show_state: true
      styles:
        card:
          - border-radius: 10%
          - width: 65px
          - height: 30px
          - background: none
        icon:
          - left: 5%
          - width: 20px
          - color: |
              [[[ 
                if (entity.state < 30) 
                  return "#ff1a1a";
                else if (entity.state < 60) 
                  return "#F3970A";
                else if (entity.state < 101)
                  return "#50A14F";
                else return "#ffc640" 
               ]]]               
          - animation: >
              [[[ 
                if (entity.state <= 10) 
                  return 'blink 2s ease infinite'; 
              ]]]
        state:
          - left: 45%
          - position: absolute
          - font-size: 12px
          - font-weight: bold
          - color: |
              [[[ 
                if (entity.state < 30) 
                  return "#ff1a1a";
                else if (entity.state < 60) 
                  return "#F3970A";
                else if (entity.state < 101)
                  return "#50A14F";
                else return "#ffc640" 
               ]]]               
          - animation: >
              [[[ 
                if (entity.state <= 10) 
                  return 'blink 2s ease infinite'; 
              ]]]

Thanks for the information, I'll take a look at both options.