Fun with custom:button-card

Tried a bunch of things… even tried putting it inside of a layout card to control it a bit more. Is there a way to get the button to “fill” the space of its container? I just can’t seem to get the sizes to be the same. Really open to any suggestions…

For anyone curious… was finally able to get it to work. Basically used layout card to make a grid layout. The key was setting “height: 100%” in my button-card template to force the buttons to use the space provided by the grid.

I’m trying out templates for the first time and I’m attempting to turn as much of the following into a template as possible as I have five gates and I’m constantly tweaking so a template would make life much easier.

I’ve got most of it working but I’m stuck on the two custom_fields sections as I don’t know how to return a variable in those sections. I’ve defined the card at the bottom just in case I’ve not done that correctly either. Can anyone assist please?

color: green
color_type: icon
custom_fields:
  notification: |
    [[[ return states['sensor.steel_gate_battery'].state ]]]
entity: binary_sensor.steel_gate
icon: mdi:gate
name: Steel
size: 50%
state:
  - color: red
    icon: mdi:gate
    styles:
      icon:
        - animation: blink 5s ease infinite
    value: 'on'
  - color: green
    icon: mdi:gate
    value: 'off'
  - color: orange
    icon: mdi:gate-alert
    styles:
      icon:
        - animation: blink 3s ease infinite
    value: unavailable
styles:
  card:
    - border-radius: 10%
    - background-color: '--paper-card-background-color'
  custom_fields:
    notification:
      - background-color: |
          [[[
            if (states['sensor.steel_gate_battery'].state >= 98)
              return "green";
            return "red";
          ]]]
      - border-radius: 50%
      - position: absolute
      - left: 75%
      - top: 5%
      - height: 25px
      - width: 25px
      - font-size: 12px
      - line-height: 23px
      - color: var(--text-color)
  grid:
    - position: relative
type: custom:button-card

image

    cards:
      - template: gates
        entity: binary_sensor.steel_gate
        variables:
          e_n_value: states.sensor.steel_gate_battery.state
        type: custom:button-card

Cracked it!

button_card_templates:
  gates:
    color: green
    color_type: icon
    custom_fields:
      notification: |
        [[[ return (states[variables.e_n_value].state) ]]]
    size: 50%
    variables:
      notification_entity: n_e_value
    state:
      - color: red
        icon: mdi:gate
        styles:
          icon:
            - animation: blink 5s ease infinite
        value: 'on'
      - color: green
        icon: mdi:gate
        value: 'off'
      - color: orange
        icon: mdi:gate-alert
        styles:
          icon:
            - animation: blink 3s ease infinite
        value: unavailable
    styles:
      card:
        - border-radius: 10%
        - background-color: '--paper-card-background-color'
      custom_fields:
        notification:
          - background-color: |
              [[[
                if ((states[variables.e_n_value].state) >= 95)
                  return "green";
                return "red";
              ]]]
          - border-radius: 50%
          - position: absolute
          - left: 75%
          - top: 5%
          - height: 25px
          - width: 25px
          - font-size: 12px
          - line-height: 23px
          - color: var(--text-color)
      grid:
        - position: relative
    cards:
      - template: gates
        entity: binary_sensor.steel_gate
        variables:
          e_n_value: sensor.steel_gate_battery
        type: custom:button-card

Another random one I’m struggling with… trying to make a single button, that shows two icons… e.g. two different states at the same time… and has a single tap_action. Possible?

Check this other post I did that might be similar to what you want to do:

1 Like

Actually came up with a kinda hack… Actually made my own icons…

Now I need to figure out how to change the color of different parts of the icon…

Almost fully there now…

Basically the main icon is an SVG I am drawing with JS Templating to color different paths. The button opens a popup where i have controls for the individual doors and “dual” door functions. The issue is that when I click the main icon the “multiple” actions are being triggered… e.g. the buttons in the popup are somehow being triggered even though I clicked on the main icon…

Thoughts?

          - type: custom:button-card
            tap_action:
              action: fire-dom-event
              browser_mod:
                service: browser_mod.popup
                data:
                  title: Single Garage Door
                  content:
                    type: vertical-stack
                    cards:
                      - type: custom:frigate-card
                        cameras:
                          - camera_entity: camera.garage
                      - type: horizontal-stack
                        cards:
                          - entity: cover.single_garage_door
                            name: Open
                            icon: "emf:garage-single-open"
                            type: "custom:button-card"
                            aspect_ratio: 2/1
                            tap_action:
                              action: call-service
                              service: cover.open_cover
                              service_data:
                                entity_id: "cover.single_garage_door"
                          - entity: cover.single_garage_door
                            name: Crack
                            icon: "emf:garage-single-cracked"
                            type: "custom:button-card"
                            aspect_ratio: 2/1
                            tap_action:
                              action: call-service
                              service: button.press
                              service_data:
                                entity_id: "button.single_crack"
                          - entity: cover.single_garage_door
                            name: Close
                            icon: "emf:garage-single-closed"
                            type: "custom:button-card"
                            aspect_ratio: 2/1
                            tap_action:
                              action: call-service
                              service: cover.close_cover
                              service_data:
                                entity_id: "cover.single_garage_door"
                      - type: horizontal-stack
                        cards:
                          - entity: cover.double_garage_door
                            name: Open
                            icon: "emf:garage-double-open"
                            type: "custom:button-card"
                            aspect_ratio: 2/1
                            tap_action:
                              action: call-service
                              service: cover.open_cover
                              service_data:
                                entity_id: "cover.double_garage_door"
                          - entity: cover.double_garage_door
                            name: Crack
                            icon: "emf:garage-double-cracked"
                            type: "custom:button-card"
                            aspect_ratio: 2/1
                            tap_action:
                              action: call-service
                              service: button.press
                              service_data:
                                entity_id: "button.double_crack"
                          - entity: cover.double_garage_door
                            name: Close
                            icon: "emf:garage-double-closed"
                            type: "custom:button-card"
                            aspect_ratio: 2/1
                            tap_action:
                              action: call-service
                              service: cover.close_cover
                              service_data:
                                entity_id: "cover.double_garage_door"
                      - type: horizontal-stack
                        cards:
                          - entity: cover.double_garage_door
                            name: Open
                            icon: "emf:garage-dual-open-open"
                            type: "custom:button-card"
                            aspect_ratio: 2/1
                            tap_action:
                              action: nothing
                              multi_calls: |
                                [[[
                                  hass.callService(
                                    "cover",
                                    "open_cover",
                                    { entity_id: "cover.double_garage_door"}
                                  );
                                  hass.callService(
                                    "cover",
                                    "open_cover",
                                    { entity_id: "cover.single_garage_door"}
                                  );
                                ]]]
                          - entity: cover.double_garage_door
                            name: Crack & Closed
                            icon: "emf:garage-dual-closed-cracked"
                            type: "custom:button-card"
                            aspect_ratio: 2/1
                            tap_action:
                              action: nothing
                              multi_calls: |
                                [[[
                                  hass.callService(
                                    "cover",
                                    "close_cover",
                                    { entity_id: "cover.double_garage_door"}
                                  );
                                  hass.callService(
                                    "button",
                                    "press",
                                    { entity_id: "button.single_crack"}
                                  );
                                ]]]
                          - entity: cover.double_garage_door
                            name: Close
                            icon: "emf:garage-dual-closed-closed"
                            type: "custom:button-card"
                            aspect_ratio: 2/1
                            tap_action:
                              action: nothing
                              multi_calls: |
                                [[[
                                  hass.callService(
                                    "cover",
                                    "close_cover",
                                    { entity_id: "cover.double_garage_door"}
                                  );
                                  hass.callService(
                                    "cover",
                                    "close_cover",
                                    { entity_id: "cover.single_garage_door"}
                                  );
                                ]]]
            entity:
            name: Garage
            show_name: true
            show_icon: false
            size: 80%
            styles:
              card:
                - padding: 0.2em
                - "--mdc-ripple-color": yellow
                - "--mdc-ripple-press-opacity": 0.5
                - height: 100%
              icon:
                - opacity: 0.5
                # - max-height: 4.5rem #tweaking the auto-size to prevent vertical inflation of the UI on my wall tablets
              name:
                - font-size: 0.65em
                - white-space: normal
              state:
                - font-size: 0.65em
                - white-space: normal
              label:
                - font-size: 0.4em
                - white-space: normal
              grid:
                - grid-template-areas: '"info" "n"'
                - grid-template-columns: 1fr
                - grid-template-rows: 1fr min-content
              custom_fields:
                info:
                  - opacity: 0.5
            custom_fields:
              info: >
                [[[
                  var colorSingle = '#0000FF';
                  var colorDouble = '#0000FF';

                  if ((states['cover.single_garage_door'].state == 'open') && !(states['sensor.single_garage_door_position'].state == 'Cracked')) {
                    colorSingle = '#00FF00';
                  } else if ((states['cover.single_garage_door'].state == 'open') && (states['sensor.single_garage_door_position'].state == 'Cracked')) {
                    colorSingle = '#FF0000';
                  }


                  if ((states['cover.double_garage_door'].state == 'open') && !(states['sensor.double_garage_door_position'].state == 'Cracked')) {
                    colorDouble = '#00FF00';
                  } else if ((states['cover.double_garage_door'].state == 'open') && (states['sensor.double_garage_door_position'].state == 'Cracked')) {
                    colorDouble = '#FF0000';
                  }
                  
                  var toReturn = '<svg viewBox="0 0 24 24" version="1.1" id="svg67">';
                  toReturn += `<path
                    style="stroke-width:0.715542;fill:var(--primary-text-color)"
                    d="M 7.1992188,6.5 0.80078125,9.6992188 V 18.5 H 2.0800781 V 11.300781 H 12.320312 V 18.5 h 0.0039 v 0.02539 h 1.599609 v -7.199219 h 8 v 7.199219 h 1.59961 V 9.7265625 l -5.59961,-3.2011719 -4.978516,2.8457032 z"
                    id="path65"
                    inkscape:label="garage" />
                      <path
                      style="stroke-width:0.715542;fill:${colorSingle}"
                      d="m 14.724609,12.125 v 1.601562 H 21.125 V 12.125 Z"
                      id="path238"
                      inkscape:label="single-open" />
                    <path
                      style="stroke-width:0.715542;fill:${colorDouble}"
                      d="m 2.7207031,12.099609 v 1.59961 h 8.9589849 v -1.59961 z"
                      id="path236"
                      inkscape:label="double-open" />`

                  if (states['cover.single_garage_door'].state == 'closed') {
                    toReturn += `<path
                          style="stroke-width:0.715542;fill:${colorSingle}"
                          d="m 14.724609,16.925781 v 1.59961 H 21.125 v -1.59961 z"
                          id="path246"
                          inkscape:label="single-closed" />
                          <path
                          style="stroke-width:0.715542;fill:${colorSingle}"
                          d="M 14.724609,14.525391 V 16.125 H 21.125 v -1.599609 z"
                          id="path242"
                          inkscape:label="single-cracked" />`;
                  } else if ((states['cover.single_garage_door'].state == 'open') && (states['sensor.single_garage_door_position'].state == 'Cracked')) {
                    toReturn += `<path
                          style="stroke-width:0.715542;fill:${colorSingle}"
                          d="M 14.724609,14.525391 V 16.125 H 21.125 v -1.599609 z"
                          id="path242"
                          inkscape:label="single-cracked" />`;
                  };


                  if (states['cover.double_garage_door'].state == 'closed') {
                    toReturn += `<path
                          style="stroke-width:0.715542;fill:${colorDouble}"
                          d="M 2.7207031,16.900391 V 18.5 h 8.9589849 v -1.599609 z"
                          id="path244"
                          inkscape:label="double-closed" />
                        <path
                          style="stroke-width:0.715542;fill:${colorDouble}"
                          d="m 2.7207031,14.5 v 1.599609 H 11.679688 V 14.5 Z"
                          id="path240"
                          inkscape:label="double-cracked" />`;
                  } else if ((states['cover.double_garage_door'].state == 'open') && (states['sensor.double_garage_door_position'].state == 'Cracked')) {
                    toReturn += `<path
                          style="stroke-width:0.715542;fill:${colorDouble}"
                          d="m 2.7207031,14.5 v 1.599609 H 11.679688 V 14.5 Z"
                          id="path240"
                          inkscape:label="double-cracked" />`;
                  };


                  return toReturn + '</svg>';
                ]]]

Are you looking for already working custom cards?
If yes, please vote for this feature request.

For anyone interested… built a two car garage into a single button. Made custom SVGs, with states for open/closed/cracked … as well as animated states for opening/closing … The action is a popup that has buttons to control all the states as well as a frigate card from my garage camera. It’s still a work in progress. But pretty fun and cool I think.

type: custom:button-card
tap_action:
  action: fire-dom-event
  browser_mod:
    service: browser_mod.popup
    data:
      title: Single Garage Door
      content:
        type: vertical-stack
        cards:
          - type: custom:frigate-card
            cameras:
              - camera_entity: camera.garage
          - type: horizontal-stack
            cards:
              - entity: cover.single_garage_door
                name: Open
                icon: "emf:garage-single-open"
                type: "custom:button-card"
                aspect_ratio: 2/1
                tap_action:
                  action: call-service
                  service: cover.open_cover
                  service_data:
                    entity_id: "cover.single_garage_door"
              - entity: cover.single_garage_door
                name: Crack
                icon: "emf:garage-single-cracked"
                type: "custom:button-card"
                aspect_ratio: 2/1
                tap_action:
                  action: call-service
                  service: button.press
                  service_data:
                    entity_id: "button.single_crack"
              - entity: cover.single_garage_door
                name: Close
                icon: "emf:garage-single-closed"
                type: "custom:button-card"
                aspect_ratio: 2/1
                tap_action:
                  action: call-service
                  service: cover.close_cover
                  service_data:
                    entity_id: "cover.single_garage_door"
          - type: horizontal-stack
            cards:
              - entity: cover.double_garage_door
                name: Open
                icon: "emf:garage-double-open"
                type: "custom:button-card"
                aspect_ratio: 2/1
                tap_action:
                  action: call-service
                  service: cover.open_cover
                  service_data:
                    entity_id: "cover.double_garage_door"
              - entity: cover.double_garage_door
                name: Crack
                icon: "emf:garage-double-cracked"
                type: "custom:button-card"
                aspect_ratio: 2/1
                tap_action:
                  action: call-service
                  service: button.press
                  service_data:
                    entity_id: "button.double_crack"
              - entity: cover.double_garage_door
                name: Close
                icon: "emf:garage-double-closed"
                type: "custom:button-card"
                aspect_ratio: 2/1
                tap_action:
                  action: call-service
                  service: cover.close_cover
                  service_data:
                    entity_id: "cover.double_garage_door"
          - type: horizontal-stack
            cards:
              - entity: cover.double_garage_door
                name: Open
                icon: "emf:garage-dual-open-open"
                type: "custom:button-card"
                aspect_ratio: 2/1
                tap_action:
                  action: call-service
                  service: button.press
                  service_data:
                    entity_id: "button.open_both"
              - entity: cover.double_garage_door
                name: Crack & Closed
                icon: "emf:garage-dual-closed-cracked"
                type: "custom:button-card"
                aspect_ratio: 2/1
                tap_action:
                  action: call-service
                  service: button.press
                  service_data:
                    entity_id: "button.single_crack_and_close_double"
              - entity: cover.double_garage_door
                name: Close
                icon: "emf:garage-dual-closed-closed"
                type: "custom:button-card"
                aspect_ratio: 2/1
                tap_action:
                  action: call-service
                  service: button.press
                  service_data:
                    entity_id: "button.close_both"
entity:
name: Garage
show_name: true
show_icon: false
size: 80%
styles:
  card:
    - padding: 0.2em
    - "--mdc-ripple-color": yellow
    - "--mdc-ripple-press-opacity": 0.5
    - height: 100%
  icon:
    - opacity: 0.5
    # - max-height: 4.5rem #tweaking the auto-size to prevent vertical inflation of the UI on my wall tablets
  name:
    - font-size: 0.65em
    - white-space: normal
  state:
    - font-size: 0.65em
    - white-space: normal
  label:
    - font-size: 0.4em
    - white-space: normal
  grid:
    - grid-template-areas: '"info" "n"'
    - grid-template-columns: 1fr
    - grid-template-rows: 1fr min-content
  custom_fields:
    info:
      - opacity: 0.5
custom_fields:
  info: >
    [[[
      var cssStyleSheet = '';

      var stateColors = {
        'closed': '#0000FF',
        'open': '#00FF00',
        'cracked': '#FF0000',
        'closing': '#FFFF00',
        'opening': '#FF00FF'
      };

      var stateSingle = "unknown";
      if ((states['cover.single_garage_door'].state == 'open') && !(states['sensor.single_garage_door_position'].state == 'Cracked')) {
        stateSingle = "open";
      } else if ((states['cover.single_garage_door'].state == 'open') && (states['sensor.single_garage_door_position'].state == 'Cracked')) {
        stateSingle = "cracked";
      } else if (states['cover.single_garage_door'].state == 'opening') {
        stateSingle = "opening";
      } else if (states['cover.single_garage_door'].state == 'closing') {
        stateSingle = "closing";
      } else if (states['cover.single_garage_door'].state == 'closed') {
        stateSingle = "closed";
      }

      var stateDouble = "unknown";
      if ((states['cover.double_garage_door'].state == 'open') && !(states['sensor.double_garage_door_position'].state == 'Cracked')) {
        stateDouble = "open";
      } else if ((states['cover.double_garage_door'].state == 'open') && (states['sensor.double_garage_door_position'].state == 'Cracked')) {
        stateDouble = "cracked";
      } else if (states['cover.double_garage_door'].state == 'opening') {
        stateDouble = "opening";
      } else if (states['cover.double_garage_door'].state == 'closing') {
        stateDouble = "closing";
      } else if (states['cover.double_garage_door'].state == 'closed') {
        stateDouble = "closed";
      }

      var svgOutline = `<path
        style="stroke-width:0.715542;fill:var(--primary-text-color)"
        d="M 7.1992188,6.5 0.80078125,9.6992188 V 18.5 H 2.0800781 V 11.300781 H 12.320312 V 18.5 h 0.0039 v 0.02539 h 1.599609 v -7.199219 h 8 v 7.199219 h 1.59961 V 9.7265625 l -5.59961,-3.2011719 -4.978516,2.8457032 z"
        id="path65"
        inkscape:label="garage" />`;

      var svgSingleTop = `<path
          style="stroke-width:0.715542;fill:${stateColors[stateSingle]}"
          d="m 14.724609,12.125 v 1.601562 H 21.125 V 12.125 Z"
          id="svgSingleTop"
          inkscape:label="single-open" />`;

      var svgSingleMiddle = `<path
              style="stroke-width:0.715542;fill:${stateColors[stateSingle]}"
              d="M 14.724609,14.525391 V 16.125 H 21.125 v -1.599609 z"
              id="svgSingleMiddle"
              inkscape:label="single-cracked" />`;
      
      var svgSingleBottom = `<path
              style="stroke-width:0.715542;fill:${stateColors[stateSingle]}"
              d="m 14.724609,16.925781 v 1.59961 H 21.125 v -1.59961 z"
              id="svgSingleBottom"
              inkscape:label="single-closed" />`;

      var svgDoubleTop = `<path
          style="stroke-width:0.715542;fill:${stateColors[stateDouble]}"
          d="m 2.7207031,12.099609 v 1.59961 h 8.9589849 v -1.59961 z"
          id="svgDoubleTop"
          inkscape:label="double-open" />`;

      var svgDoubleMiddle = `<path
              style="stroke-width:0.715542;fill:${stateColors[stateDouble]}"
              d="m 2.7207031,14.5 v 1.599609 H 11.679688 V 14.5 Z"
              id="svgDoubleMiddle"
              inkscape:label="double-cracked" />`;

      var svgDoubleBottom = `<path
              style="stroke-width:0.715542;fill:${stateColors[stateDouble]}"
              d="M 2.7207031,16.900391 V 18.5 h 8.9589849 v -1.599609 z"
              id="svgDoubleBottom"
              inkscape:label="double-closed" />`;

      var toReturn = '<svg viewBox="0 0 24 24" version="1.1" id="svg67">';
      toReturn += svgOutline;

      if (stateSingle === 'open') {
        toReturn += svgSingleTop;
      } else if (stateSingle === 'cracked') {
        toReturn += svgSingleTop + svgSingleMiddle;
      } else if (stateSingle === 'closed') {
          toReturn += svgSingleTop + svgSingleMiddle + svgSingleBottom;
      } else if (stateSingle === 'closing') {
        toReturn += svgSingleTop + svgSingleMiddle + svgSingleBottom;

        cssStyleSheet += `<style>
                  @keyframes hideshow {
                    0% { opacity: 1; }
                    25% { opacity: 1; }
                    50% { opacity: 0; }
                    75% { opacity: 0; }
                    100% { opacity: 0; }
                  } 
                  #svgSingleTop {
                    animation: hideshow 4s ease infinite;
                  }
                  #svgSingleMiddle {
                    opacity: 0;
                    animation: hideshow 4s 0.5s ease infinite;
                  }
                  #svgSingleBottom {
                    opacity: 0;
                    animation: hideshow 4s 1.0s ease infinite;
                  }
              </style>`;

      } else if (stateSingle === 'opening') {
        toReturn += svgSingleTop + svgSingleMiddle + svgSingleBottom;

        cssStyleSheet += `<style>
                  @keyframes hideshow {
                    0% { opacity: 1; }
                    25% { opacity: 1; }
                    50% { opacity: 0; }
                    75% { opacity: 0; }
                    100% { opacity: 0; }
                  } 
                  #svgSingleBottom {
                    animation: hideshow 4s ease infinite;
                  }
                  #svgSingleMiddle {
                    opacity: 0;
                    animation: hideshow 4s 0.5s ease infinite;
                  }
                  #svgSingleTop {
                    opacity: 0;
                    animation: hideshow 4s 1.0s ease infinite;
                  }
              </style>`;
      } else {

      }


      if (stateDouble === 'open') {
        toReturn += svgDoubleTop;
      } else if (stateDouble === 'cracked') {
        toReturn += svgDoubleTop + svgDoubleMiddle;
      } else if (stateDouble === 'closed') {
        toReturn += svgDoubleTop + svgDoubleMiddle + svgDoubleBottom;
      } else if (stateDouble === 'closing') {
        toReturn += svgDoubleTop + svgDoubleMiddle + svgDoubleBottom;
      
        cssStyleSheet += `<style>
                  @keyframes hideshow {
                    0% { opacity: 1; }
                    25% { opacity: 1; }
                    50% { opacity: 0; }
                    75% { opacity: 0; }
                    100% { opacity: 0; }
                  } 
                  #svgDoubleTop {
                    animation: hideshow 4s ease infinite;
                  }
                  #svgDoubleMiddle {
                    opacity: 0;
                    animation: hideshow 4s 0.5s ease infinite;
                  }
                  #svgDoubleBottom {
                    opacity: 0;
                    animation: hideshow 4s 1.0s ease infinite;
                  }
              </style>`;
      } else if (stateDouble === 'opening') {
        toReturn += svgDoubleTop + svgDoubleMiddle + svgDoubleBottom;
      
        cssStyleSheet += `<style>
                  @keyframes hideshow {
                    0% { opacity: 1; }
                    25% { opacity: 1; }
                    50% { opacity: 0; }
                    75% { opacity: 0; }
                    100% { opacity: 0; }
                  } 
                  #svgDoubleBottom {
                    animation: hideshow 4s ease infinite;
                  }
                  #svgDoubleMiddle {
                    opacity: 0;
                    animation: hideshow 4s 0.5s ease infinite;
                  }
                  #svgDoubleTop {
                    opacity: 0;
                    animation: hideshow 4s 1.0s ease infinite;
                  }
              </style>`;
      } else {

      }

      return toReturn + cssStyleSheet + '</svg>';
    ]]]

Does anyone know if there is anyway to make an icon flash two different colours?

I can use the below code to make it flash on a certain state, however this is only flashing the icon on and off. But if I wanted to flash between two colours (for example flash between red and green), is there anyway to do that?

Hope that makes sense!

Thanks

    state:
      - value: 1
        styles:
          icon:
            - animation: blink 5s ease infinite

Look above, there was a reference to a dual toggle a few posts up. You can do it using keyframes

Thanks @efaden, I’m not familiar with keyframes, so I’ll check them out.

Look at the post I made above. I use them to animate an SVG.

Can some one give me a hand with the active/background’s variable?
I want to differentiate the active option from the others:

fancard

In this case the activated options are 30º, as the angle, and Normal, as the Mode; but I can’t seem to find the right way to differentiate those from the others…

type: vertical-stack
cards:
  - type: entity
    entity: fan.fan
    state_color: true
    attribute: percentage
    unit: '%'
  - type: horizontal-stack
    cards:
      - show_name: true
        show_icon: true
        type: custom:button-card
        name: 30º
        tap_action:
          action: call-service
          service: script.fan_30
        show_state: false
        color_type: card
        color: rgb(66, 134, 244)
        icon: ''
      - show_name: true
        show_icon: false
        color_type: card
        color: rgb(66, 134, 244)
        type: custom:button-card
        name: 60º
        tap_action:
          action: call-service
          service: script.fan_60
        show_state: false
        icon: ''
      - show_name: true
        show_icon: false
        type: custom:button-card
        name: 90º
        tap_action:
          action: call-service
          service: script.fan_90
        show_state: false
        color_type: card
        color: rgb(66, 134, 244)
        icon: ''
      - show_name: true
        show_icon: false
        type: custom:button-card
        name: 120º
        tap_action:
          action: call-service
          service: script.fan_120
        show_state: false
        color_type: card
        color: rgb(66, 134, 244)
        icon: ''
  - type: horizontal-stack
    cards:
      - show_name: true
        show_icon: true
        type: custom:button-card
        name: Normal
        tap_action:
          action: call-service
          service: script.fan_normal
        show_state: false
        icon: ''
      - show_name: true
        show_icon: true
        type: custom:button-card
        name: Breeze
        tap_action:
          action: call-service
          service: script.fan_breeze
        show_state: false
        icon: ''
  • type: custom:button-card
    show_name: true
    show_icon: true
    show_state: false
    entity: number.lr_hvac_tadiran_set_setpoint
    name: |
    [[[return ‘ok’;]]]
    size: 100%
    color: |
    [[[ return ‘red’;]]]

not showing the red color. what is wrong?
thanks

Is there a way to display the name of the linked room on the place name? In Jinja we can use area_name but I don’t know what the js template of this is.

I have a question concerning the JavaScript templates in this card.
Configuration excerpt:

tmpl_btn_roll:
  variables:
    preset: open # closed, shade, blinds
    set_width: 7 #6.8 #"rem" will be added later
    enty: null #placeholder
  entity: '[[[ return variables.enty ]]]'
  size: 24px
...and so on

Further down the road I want to access an attribute of the entity.
This attribute’s name is provided via the variable preset.
If I try

  styles:
    grid: # div#container.vertical.no-state
      - grid-template: '"i l" auto'
    card: # ha-card#card.button-card-main.type-custom-button-card
      - border-style: >
          [[[ var v_pos = states[variables.enty].attributes.current_position;
              if (v_pos == states[variables.enty].attributes.${variables.preset}) return 'dashed';
              return 'solid'; ]]]

it produces an error: ButtonCardJSTemplateError: SyntaxError: Unexpected token '{' in 'var v_pos = states[variables.enty].attributes.current_position; if (v_pos == states[variables....'

How do I access an attribute which name is changing?

Dug two hours in SO since I didn’t find the right question (I’m absolutely not into JS).
Once I asked the right question, the following answer came up:
if (v_pos == eval("states[variables.enty].attributes." + variables.preset)) return 'dashed';
works, but it uses evil eval()