Fun with custom:button-card

This thread is for custom:button-card. You only posted a very brief snippit of your card config so I’m only guessing this question should be posted in Custom card: Room Card?

But regardless of that, the room card wiki shows:

type: custom:room-card
entity: sensor.fordpass_ignitionstatus
icon: mdi:car
show_icon: true
info_entities:
  - entity: sensor.fordpass_fuel
    show_icon: true
    icon:
      template:
        styles: >
          if (entity.state >= 70) return 'color: green';  
          if (entity.state >= 20) return 'color: orange';  
          else return 'color: orangered';
        icon: >
          if (entity.state >= 70) return 'mdi:car';  
          if (entity.state >= 20) return 'mdi:carplus';  
          else return 'mdi:carplus2';

Does something like this work?

entity_2:
  entity_id: switch.esph_shelly_1_fr_fireplace_relay
  icon:
    template:
      icon: >
        if (entity.state == 'on') return 'mdi:fireplace-on';  
        else return 'mdi:fireplace';
  templates:
    - red_on
  tap_action:
    action: toggle

I’m trying to use the internal variables of the card to set the variables the card will eventually pass towards a service. I.e. filling out the service_data fields using the button card as a ui, without needing to make helpers whose state would be used to pass the options. Which would also mean the settings are specific for a browser instance, which in the case of some custom scripts I use make more sense, as using helpers for this means the helpers need to be reset after a certain amount of time too.

Anyhow, preamble aside, where I got stuck on was performing javascript code inside custom fields, using the variables of the card itself. custom fields that are html elements are able to perform scripts, however they do not have access to the variables variable, which the card does pass to javascript snippets within configurations. My current test setup is this:

type: custom:button-card
variables:
  test_var: false
custom_fields:
  html-field: |
    [[[ return `<ha-icon
          icon="mdi:mouse-left-click"
          style="height: 40%; margin-bottom: -2.5%;" onclick="console.log('tapped the icon');">
          </ha-icon><p><span style="font-size: 500%;">front html</span>` ]]] 
  frt:
    card:
      type: custom:button-card
      variables:
        c: 42
      name: front card
      icon: mdi:test-tube
      tap_action:
        action: |
          [[[ console.log("tapped the front button?");
              variables.test_var = !(variables.test_var);
              return 'nope';
          ]]]
styles:
  grid:
    - grid-template-areas: '"frt right back left"'
    - grid-template-columns: 1fr 1fr 1fr 1fr
  custom_fields:
    html-field:
      - background-color: steelblue
      - border-radius: 0%
      - position: absolute
      - top: 10%
      - height: 190%
      - width: 100%
      - font-size: 8px
      - line-height: 20px
      - icon: mdi:mouse-left-click
    frt:
      - height: 190%
      - width: 500%
icon: mdi:nuke
name: test
tap_action:
  action: |
    [[[
      console.log(`test_var = ${variables.test_var}`);
      console.log("Tapped the main button!");

      variables.test_var = !(variables.test_var);
    ]]]

Checking the console log in my browser shows that upon loading, all javascript codes are performed. However, afterwards, only clicking on the html field triggers the on click action in the html element, as well as the tap_action of the main button. This shows that test_var does indeed toggle on each click. However, clicking on the frt custom field does not trigger the javascript code. It does read out the returned value, however (i.e. setting it to return "more-info"; throws an error saying no entity-id has been specified. However the other parts of the script are not performed. Nothing is logged in the console, nor is the variable changed. Is it possible for the action to still perform these parts of the code as well?

I’m not sure if what I’m trying is even possible, as it may be a bit too hacky (which would explain why it won’t work), but maybe someone here actually has an idea of what to do.

Sorry. Not talking about room card, but talking about a template for button card. I thought I included more of the template. Here is a fuller example. Notice how the icon for the i1 custom field is passed through as a variable? I am trying to figure out if I can pass through a template instead of just a single icon. If the entity is on, then one icon and if it is off another. But it doesn’t really seem to work. So my question was if it is possible to pass a template like that as a variable to a custom field. Does that make more sense?

My end goal is to make a room card style template and then use that template. But for something like the fireplace I want to have an icon with the flame if its on and without if it is off. But I am struggling to pass the if/else through as a variable to a template.

Template:

example_template:
  icon: "mdi:sofa-single"
  ....
  custom_fields:
    i1:
      card:
        type: "custom:button-card"
        template: >
          [[[
            let templates = [ 'widget_icon_room_8' ];
            if (variables?.entity_1?.templates?.length) {
              templates.push(...variables.entity_1.templates);
            }
            return templates;
          ]]]
        variables: "[[[ return variables?.entity_1; ]]]"
        state:
          - operator: "template"
            value: "[[[ return !variables.entity_1; ]]]"
            styles:
              card:
                - display: "none"
        entity: "[[[ return variables?.entity_1?.entity_id; ]]]"
        icon: "[[[ return variables?.entity_1?.icon; ]]]"
        styles:
          mwc-ripple:
            - display: "none"

Usage:

      - type: "custom:button-card"
        template:
         - example-template
        ....
        variables:
          label_use_temperature: true
          label_use_brightness: false
          label_use_temperature_entity: "sensor.family_room_temperature"
          entity_1:
            entity_id: switch.zb_family_room_lamps
            icon: mdi:lamps
            tap_action:
              action: toggle
          entity_2:
            entity_id: switch.esph_shelly_1_fr_fireplace_relay
            icon: mdi:fireplace
            tap_action:
              action: toggle

Have you considered using custom-ui to customize the icons?

show_name: true
show_icon: true
type: custom:button-card
tap_action:
  action: toggle
entity: switch.2ch_relay_right

imageimage

configuration.yaml:

homeassistant:
  customize: !include customize.yaml

customize.yaml:

switch.2ch_relay_right:
  templates:
    icon: "return state === 'off' ? 'mdi:fireplace-off' : 'mdi:fireplace';"
    icon_color: "return state === 'off' ? 'grey' : 'gold';"

Note: custom:button-card uses my custom-ui templated icon but does not use my templated icon_color which is likely related to this note in the docs:

By default, if the entity state is off , the color will be var(--paper-item-icon-color) , for on it will be var(--paper-item-icon-active-color) and for any other state it will be var(--primary-text-color).

The standard button card applies both custom-ui templates:
imageimage

Honestly no, I hadn’t because I had never heard of it. Lol. That looks like a very interesting way to go though. Thanks I’ll do some reading tonight. Although it seems development has stopped…

@efaden No, not @Mariusthvdb’s version!

You can find the repository here.

There are numerous references to it here in the community but not sure if there’s a primary topic for it.

Thanks! I’ll check it out. I’m also thinking of just notifying the template to include an on and off icon.

Interesting update, was able to solve my own issue.

This doesn’t work.

        variables:
          entity_1:
            entity_id: switch.zb_family_room_lamps
            icon: mdi:lamps
            tap_action:
              action: toggle
          entity_2:
            entity_id: switch.esph_shelly_1_fr_fireplace_relay
            icon: >
              [[[
                let state = states['variables.entity_2_entity_id'].state; // BAD
                if (state == "on")
                  return "mdi:fireplace";
                else
                  return "mdi:fireplace-off";
              ]]]

but this does…


         variables:
          entity_1:
            entity_id: switch.zb_family_room_lamps
            icon: mdi:lamps
            tap_action:
              action: toggle
          entity_2:
            entity_id: switch.esph_shelly_1_fr_fireplace_relay
            icon: >
              [[[
                let state = states['switch.esph_shelly_1_fr_fireplace_relay'].state;
                if (state == "on")
                  return "mdi:fireplace";
                else
                  return "mdi:fireplace-off";
              ]]]
            tap_action:
              action: toggle
let state = states['variables.entity_1_entity_id'].state;

Also works within entity_2 (not useful, but interesting). So it looks like entity_2 is evaluated all at one go, and nothing within it is available within the sub items.

Turns out even though entity_id is alphabetically before icon in the above example it is still undefined in the icon field. This was my issue.

Interesting. I understand now.

I wonder if variables can reference other variables though?
Like this…

variables:
          switch_1: switch.zb_family_room_lamps
          switch_2: switch.esph_shelly_1_fr_fireplace_relay

          entity_1:
            entity_id: variables.switch_1
            icon: mdi:lamps
            tap_action:
              action: toggle

          entity_2:
            entity_id: variables.switch_2
            icon: 
              [[[
                let state = states['variables.switch_2'].state;
                if (state == "on")
                  return "mdi:fireplace";
                else
                  return "mdi:fireplace-off";
              ]]]

I think you would have to use a_switch1, etc. Reason is that they are processed alphabetically. …

Maybe this then?

variables:
          a1: switch.zb_family_room_lamps
          a2: switch.esph_shelly_1_fr_fireplace_relay

          entity_1:
            entity_id: variables.a1
            icon: mdi:lamps
            tap_action:
              action: toggle

          entity_2:
            entity_id: variables.a2
            icon: 
              [[[
                let state = states['variables.a2'].state;
                if (state == "on")
                  return "mdi:fireplace";
                else
                  return "mdi:fireplace-off";
              ]]]

Yeah. That should work. I’ll test it later…

If it’s alphabetical AND you can use the alphabetically earlier ones in later variables, then there are a lot of possibilities. It’s a matter of what would make sense to you looking at the code later. I’m thinking something short like this maybe?

variables:
          _id1: switch.zb_family_room_lamps
          _id2: switch.esph_shelly_1_fr_fireplace_relay

          entity_1:
            entity_id: variables._id1
            icon: mdi:lamps
            tap_action:
              action: toggle

          entity_2:
            entity_id: variables._id2
            icon: 
              [[[
                let state = states['variables._id2'].state;
                if (state == "on")
                  return "mdi:fireplace";
                else
                  return "mdi:fireplace-off";
              ]]]

Hi there
Can someone help me how to make grids like this?
grids
I need to edit these lines:

styles:
  grid:
    - grid-template-columns: 1fr 1fr
    - grid-template-rows: 1fr 2fr 1fr
    - grid-template-areas: ' "grid1" "grid2 grid3"' "grid4 grid5"'

This isn’t perfect, but might point you in the right direction

type: custom:button-card
tap_action:
  action: toggle
styles:
  card:
    - background-color: blue
  grid:
    - grid-template-areas: |
        "light1 light1 "
        "light2 light3 "
        "light4 light5 "
    - grid-template-columns: 1fr 1fr
    - grid-template-rows: 5em 1fr 1fr
    - grid-gap: 0
custom_fields:
  light1:
    card:
      type: custom:button-card
      entity: light.pc_lights
      aspect_ratio: 5/1
      show_name: true
      name: Card 1
      icon: mdi:lamp
      tap_action:
        action: toggle
      styles:
        card:
          - background-color: blue

  light2:
    card:
      type: custom:button-card
      entity: light.bathroom_lights
      show_name: true
      name: Card 2
      icon: mdi:lamp
      aspect_ratio: 2/1
      tap_action:
        action: toggle
      styles:
        grid:
          - grid-template-areas: |
              "i"
              "n"
          - grid-template-columns: 1fr
          - grid-template-rows: 3em 1fr
        icon:
          - height: 100%
          - color: orange
        card:
          - background-color: blue
  light3:
    card:
      type: custom:button-card
      entity: light.bathroom_lights
      show_name: true
      name: Card 3      
      icon: mdi:lamp
      aspect_ratio: 2/1
      tap_action:
        action: toggle
      styles:
        grid:
          - grid-template-areas: |
              "i"
              "n"
          - grid-template-columns: 1fr
          - grid-template-rows: 3em 1fr
        icon:
          - height: 100%
          - color: orange
        card:
          - background-color: blue
  light4:
    card:
      type: custom:button-card
      entity: light.bathroom_lights
      show_name: true
      name: Card 4      
      icon: mdi:lamp
      aspect_ratio: 2/1
      tap_action:
        action: toggle
      styles:
        grid:
          - grid-template-areas: |
              "i"
              "n"
          - grid-template-columns: 1fr
          - grid-template-rows: 3em 1fr
        icon:
          - height: 100%
          - color: orange
        card:
          - background-color: blue
  light5:
    card:
      type: custom:button-card
      entity: light.bathroom_lights
      show_name: true
      name: Card 5     
      icon: mdi:lamp
      aspect_ratio: 2/1
      tap_action:
        action: toggle
      styles:
        grid:
          - grid-template-areas: |
              "i"
              "n"
          - grid-template-columns: 1fr
          - grid-template-rows: 3em 1fr
        card:
          - background-color: blue
        icon:
          - height: 100%
          - color: orange

Is it Possible to change the size of the entity picture?

    name: Network
    entity_picture: /local/PNGS/net.png
    show_name: true
    show_entity_picture: true
    styles:
      card:
        - padding: 5px
        - border: 0px
      grid:
        - grid-template-areas: '"n i"'
        - grid-template-columns: 3fr 1fr
      name:
        - justify-self: start
        - padding-left: 20px
        - font-size: 30px
        - font-weight: 300

Yes just add width and height to entity _picture under styles

styles:
  card:
        - padding: 5px
        - border: 0px
  grid:
        - grid-template-areas: '"n i"'
        - grid-template-columns: 3fr 1fr
  entity_picture:
        - height: 10px
        - width: 20px

image

1 Like

Thank you!!!

Happy to assist!

Here is an odd one. I have a button I want to use to select a preset of some lights in my house. So basically I need to use call service to set multiple select with a bunch of options… but if that preset is enabled when the button is pressed I actually want it to call light.turn_off on the main light…


                  - type: custom:button-card
                    entity: select.parker_wled_preset
                    name: Reading
                    icon: mdi:book-open-page-variant
                    tap_action:
                      action: call-service
                      service:  |
                        [[[ 
                          if (entity.state == "Reading") return 'light.turn_off'; 
                          return 'select.select_option'; 
                        ]]]
                      target:
                        entity_id:  |
                          [[[ 
                            if (entity.state == "Reading") return 'light.parker_wled_master; 
                            return 'select.parker_wled_preset'; 
                          ]]]
                      data: 
                        option: "Reading"

Something like this. But it is complaining that option is present for light.turn_off. So basically I need no data in one case and some data in the other. That’s what I’m struggling with. Any help appreciated.