Fun with custom:button-card

One more tweak…

image

type: custom:button-card
aspect_ratio: 1/0.6
show_name: true
show_state: true
show_label: true
entity: sensor.moon_phase
styles:
  card:
    - text-transform: capitalize
    - color: |
        [[[
         if (states['sun.sun'].state == 'below_horizon') 
          return "white";
         else return "darkblue";
        ]]]
    - background-color: |
        [[[
         if (states['sun.sun'].state == 'below_horizon') 
          return "black";
         else return "lightblue";
        ]]]
name: Moon Phase
label: |
  [[[
   return states['sensor.moon'].state.replace('_',' ');
  ]]]
entity_picture: |
  [[[ return `/local/images/moon/${entity.state}.jpg`; ]]]
show_entity_picture: true
1 Like

I’m quite enamored with this, and would like to replicate exactly. Can you provide links to the images you used for your card? Thank you!

The zip file is in this post.

1 Like

Thank you very much!

1 Like

If I have a template for a room card that for the sub-buttons takes a bunch of variables can I pass a template as a variable? For example

in variables

          entity_2:
            entity_id: switch.esph_shelly_1_fr_fireplace_relay
            icon: mdi:fireplace
            templates:
              - red_on
            tap_action:
              action: toggle

Is it possible to pass a template into variable? E.g.
if (entity = on) mdi:fireplace-on else mdi-fireplace

Or something like that?

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