Lovelace: Button card

Yes, this one. Try to see if you can reproduce it and we’ll go on from there

Unfortunately, I havent been able to reproduce this clicking away over a series of double iterations, on all menu buttons (that all have a double function) in 2 browsers desktop and the mobile app. No issues at all. Just to be sure, should I post it for you to see if there’s an obvious JS error?

Meanwhile, I’ll glob search the navigate action in the config, and you’re saying this could be other cards too?
update
checked all navigate: 's, and all are correct (now, had some incomplete path’s, but they redirected and didn’t throw an error, so I was able to double check that as a. possible cause and eliminate it from the search)

Hi I am trying to setup a multi card custom button.
As a grid 3 by 3 as follows.
As described a few posts above.
However the result is a completely blank card
what is wrong?
Thanks for helping

title: ICBL2
name: ICBL2
path: ICBL2
panel: true
cards:
  - type: custom:button-card
    aspect_ratio: 1/1
    custom_fields:
      g11:
        card:
          type: sensor
          entity: sensor.fibaro_system_fgms001_motion_sensor_luminance
      g21:
        card:
          type: "custom:button-card"
          color_type: blank-card
      g31:
        card:
          type: sensor
          entity: sensor.light_state_cucina
      g12:
        card:
          type: "custom:button-card"
          color_type: blank-card
      g22:
        card:
          type: "custom:button-card"
          color_type: blank-card
      g32:
        card:
          type: "custom:button-card"
          color_type: blank-card
      g13:
        card:
          type: sensor
          entity: sensor.light_state_cucina
      g23:
        card:
          type: "custom:button-card"
          color_type: blank-card
      g33:
        card:
          type: sensor
          entity: sensor.emoncms5_import
    styles:
      custom_fields:
        g11:
          - witdh: 20px
          - height: 20px
        g21:
          - witdh: 20px
          - height: 60px
        g31:
          - witdh: 20px
          - height: 20px
        g12:
          - witdh: 20px
          - height: 60px
        g22:
          - witdh: 60px
          - height: 60px
        g32:
          - witdh: 20px
          - height: 20px
        g13:
          - witdh: 20px
          - height: 20px
        g23:
          - witdh: 60px
          - height: 20px
        g33:
          - witdh: 20px
          - height: 20px
      card:
        - witdh: 100px
        - height: 100px
      grid:
        - grid-template-areas: '"g11 g12 g13" "g21 g22 g23" "g31 g32 g33"'
        - grid-template-columns: 20px  1fr 20px 
        - grid-template-rows: 20px  1fr 20px 
      entity: light.luce_garage
    hold_action:
      action: more-info

please let me put this forward, as a variant of an earlier discussion on the triggers_update. Just found out several buttons with a counter only update on a refresh, and of course, they are based on a group as entity… should have known better of course, because how to trigger that when eg using a counter.

As it happens, I have an automation that gets triggered on each light state change, so I can use that for the button to update. Feels a bit hacky thought, here’s my question:

when a button has a group for entity, couldnt you make the button update on state changes for that group automatically. A bit like the expand('group.outside_lights') in jinja now allows us to do?

  - type: custom:button-card
    entity: group.outside_lights
    triggers_update: input_boolean.run_lights_summary
    template: button_title_outdoors
    label: > #Outside lights
      [[[
      var i;
      var entities = entity.attributes.entity_id;
      var count = 0;
      for (i = 0; i < entities.length; i++) {
        var state = states[entities[i]].state;
        if (state == 'on') {count += 1;}
       }
      if (count == entities.length) return 'All ' + entities.length + ' Outside lights on';
      if (count == 0) return 'No Outside lights on';
      return 'Outside Lights on: ' + count + ' of ' + entities.length;
      ]]]

Has anyone been able to use the built-in weather icons from the weather-forecast card into the button card?

It would be great if i can replace my weather card with this one, because it’s so much more customisable.

Question: which layout were you using here for the covers on the first row (because the 3rd button has a different size). The custom layout-card ?

Seems legit, can you open a feature request on GH please? :slight_smile:

You can, but you’ll need to define them inline in a javascript template. You can find them here

No, I don’t have this setup anymore but if I remember correctly, on the last card I defined the width css property and the other cards would take the remaining space automatically.

thanks, consider it done check have entity group members trigger update · Issue #392 · custom-cards/button-card · GitHub and fiddled in this Need help selecting entities in grouped groups, in Python script - #9 by Mariusthvdb … seems related and useful to the community to have that in the toolbox per design.

I’ve given you the answer on the other thread. It solves partially your problem but will not update if an entity in the group updates until I implement your feature request.
You always have the solution to build sensors in the backend but then you’d have to build one for each group which I can understand… is painful.

1 Like

I’m trying to include a lock icon (which is tied to an input_boolean) in the upperleft position of my light button card. I have a button card for each light and the entity is passed through, this works great as it supposed to. But now I want create an input_boolean for each light, that shows the state on the upper left corner (it’s just as a state, so doesn’t do any action). But I want to incorporate this in my template so I can use the exact same code in my main view and only need to add stuff to my template. Maybe with some extra variables?

This is my code btw

  light:
    deep_press: true
    hold_action:
      action: more-info
      haptic: heavy
    aspect_ratio: 1/1
    show_icon: true
    show_label: true
    show_name: true
    show_state: false
    size: 50%
    label: |
      [[[
        var bri = Math.round(entity.attributes.brightness / 2.55);
        return (bri ? bri : '0');
      ]]]      
    state:
      - styles:
          card:
            - background-color: var(--card-background-light)
            # - transition: all 1s ease
          icon:
            - color: var(--light-entity-color)
            # - transition: all 0.5s ease
          name:
            - color: var(--button-text-color)
          state:
            - color: var(--button-text-color)
        value: 'on'
      - styles:
          label:
            - filter: opacity(0%)
        value: 'off'
    styles:
      card:
        - background-color: var(--card-background-off)
        - font-size: 12px
      grid:
        - grid-template-areas: '"i" "n" "s"'
        - grid-template-columns: 1fr
        - grid-template-rows: 1fr min-content min-content
      img_cell:
        - align-self: start
        - text-align: start
        - position: absolute
        - bottom: 1px
      label:
        - overflow: visible
        - position: absolute
        - right: 13px
        - top: 9px
        - font-weight: bold
        - color: var(--light-entity-color)
      name:
        - padding-bottom: 5px
        - font-weight: bold        
      state:
        - justify-self: start
        - padding-left: 10px
        - text-transform: lowercase
    tap_action:
      action: toggle
      haptic: medium

I hope my question is clear and someone can point me in the right direction.

Edit: just to clarify, this has nothing to do with the lock object that button card supports. I need to tie them to input_booleans for each entity. Users can toggle the input_boolean through the frontend (with a popup card I create). This will then be used in Node-RED to allow/disable lights turning off based on motion. This works fine as is, but now I need to show the lock icon in a way that I can just use one template, instead of writing each button card individually.

HI , May i get your wallpaper , and if you can tell me :slight_smile:Where did you get those icons , and how to create the space in between the culums.

:slight_smile: thanks

Oh, sorry my fault! Thank you!

just for reference in this group, with guidance from @petro ,(tagged to say thank you once more!) this template was created to count the unique members and total members of a group (which can include self references to groups and entities)

  - type: custom:button-card
    entity: group.all_inside_lights
    template: button_title_counter
    group_expand: true
#    triggers_update: input_boolean.run_lights_summary
    label: >
      [[[
        function flatten(entity_id, result=[], searched=[]) {
          var state = states[entity_id];
          if (state) {
            var entities = state.attributes.entity_id;
            if (entities) {
              searched.push(entity_id);
              entities.forEach(entity_id => {
                if (! result.includes(entity_id) && ! searched.includes(entity_id))
                    flatten(entity_id, result, searched);
                });
              }
            else
              result.push(entity_id);
            }
          }
        var light_ids = [];
        flatten(entity.entity_id, light_ids);

        var count = 0;
        light_ids.forEach(entity_id => {
          var state = states[entity_id];
          if (state && state.state === 'on')
              count++;
          });
        if (count == light_ids.length) return 'All ' + light_ids.length + ' lights on';
        if (count == 0) return 'No lights on';
        return 'Lights on: ' + count + ' of ' + light_ids.length;
      ]]]

eg have a group with a double entity, or one of the sibling groups containing an already contained group/entity:

  all_inside_lights:
    name: All inside lights
    icon: mdi:lightbulb-outline
    entities:
      - group.main_inside_lights
      - group.guest_inside_lights
      - group.living_ceiling_spots
      - group.main_inside_lights # <---

HI,

here is the Code. Its a Code from @Petro:

That code uses lovelace gen, it’s also out of date. This is the current version, i’m not sure why it’s still using picture-elements, I thought I switched away from that. There must be a reason (that I can’t remember) why that wasn’t done.

type: picture-elements
image: /local/images/transparent_1to1.png
style: |
  ha-card { 
    border-radius: 15px;
  }
elements:
- type: custom:mini-graph-card
  style:
    top: 40%
    left: 50%
    width: 100%
    height: 80%
    translate: translate(-50%, -50%)
    '--paper-card-background-color': 'rgba(0, 0, 0, 0.0)'
    '--ha-card-background': "rgba(0, 0, 0, 0.0)"
    '--ha-card-box-shadow': 'none'
    z-index: 3
    pointer-events: none
  entities:
    - {{ entity }}
  group: true
  points_per_hour: 1
  hour24: true
  line_color: var(--paper-item-icon-active-color)
  line_width: 10
  hours_to_show: 24
  update_interval: 600
  show:
    name: false
    icon: false
    state: false
    points: false
    legend: false
    average: false
    extrema: false
    labels: false
    fill: false
    labels_secondary: false
    name_adaptive_color: false
    icon_adaptive_color: false
- type: custom:button-card
  style:
    top: 50%
    left: 50%
    width: 100%
    translate: translate(-50%, -50%)
  aspect_ratio: 1/1
  entity: {{ entity }}
  color: var(--paper-item-icon-color)
  show_name: true
  show_label: true
  show_icon: true
  show_last_changed: true
  size: 70%
  tap_action:
    action: more-info
    haptic: light
  styles:
    icon:
    - opacity: 0.3
    - width: 100%
    img_cell:
    - top: 0%
    - left: 30%
    - position: absolute
    - z-index: 2
    grid:
    - grid-template-areas: '"info info" "n n" "l l"'
    - grid-template-columns: 40% 1fr
    - grid-template-rows: 1fr min-content min-content
    - position: relative
    card:
    - padding: 10px
    - z-index: 1
    name:
    - justify-self: start
    - align-self: end
    - font-weight: bold
    - font-family: Helvetica 
    - font-size: 12px
    - text-align: start
    - background-image: linear-gradient(to right, white 0%, white 80%, rgba(0,0,0,0))
    - -webkit-background-clip: text
    - -webkit-text-fill-color: transparent
    - position: relative
    - display: inline-block
    - width: 100%
    - align-content: start
    - text-align: start
    - text-overflow: unset
    - z-index: 5
    label:
    - justify-self: start
    - align-self: end
    - font-weight: bold
    - font-family: Helvetica 
    - font-size: 12px
    - text-align: start
    - background-image: linear-gradient(to right, var(--paper-item-icon-color) 0%, var(--paper-item-icon-color) 80%, rgba(0,0,0,0))
    - -webkit-background-clip: text
    - -webkit-text-fill-color: transparent
    - position: relative
    - display: inline-block
    - width: 100%
    - align-content: start
    - text-align: start
    - text-overflow: unset
    - z-index: 5
    custom_fields:
      info:
      - align-self: start
      - width: 40%
      - z-index: 5
  custom_fields:
    info: >
      [[[
        var entity_id = (entity === undefined) ? 'Invalid Entity' : entity.entity_id;
        var statestr = (entity === undefined || entity.state === undefined) ? null : entity.state;
        var units = (statestr && entity.attributes.unit_of_measurement) ? entity.attributes.unit_of_measurement : null;
        var date = (statestr && entity.attributes.device_class === 'timestamp') ? new Date(statestr) : null;
        var value;
        if (statestr && date === null) {
          if (statestr.split('.').length - 1 <= 1){
            var test = parseFloat(parseFloat(statestr).toFixed(2));
            value = (isNaN(test)) ? null : test;
            // test if units are in the state because some sensors are stupid.  Looking
            //   at you synology.
            const expr = /[^-.0-9]+/;
            var has_units = expr.test(statestr.trim());
            // console.log(`${entity_id}: "${statestr}" ${matches}`);
            if (value && has_units)
              units = statestr.replace(/[.0-9]+/, ''); 
          }
        }
        // console.log(`${entity_id}: ${statestr}, ${units}, ${date}, ${value}`);
        const length = 50;
        const width = 3;
        var radius = length / 2;
        if (date){
          let now = new Date();
          var tdelta = Math.floor((now - date)/1000);
          // console.log(`${entity_id}: ${tdelta}`);
          function plural(descriptor, divisor){
            var ret = Math.floor(tdelta/divisor);
            return (ret == 1) ? [ret, descriptor] : [ret, `${descriptor}s`];
          }
          var values;
          if (tdelta < 60)
            values = plural('second', 1);
          else if (tdelta < 60 * 60)
            values = plural('minute', 60);
          else if (tdelta < 60 * 60 * 24)
            values = plural('hour', 60 * 60);
          else if (tdelta < 7 * 60 * 60 * 24)
            values = plural('day', 60 * 60 * 24);
          else
            values = plural('week', 7 * 60 * 60 * 24);
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="var(--paper-item-icon-active-color)" />
              <text x="50%" y="43%" fill="var(--paper-card-background-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${values[0]}<tspan x="50%" dy="1.2em" font-size="10" font-weight="normal" >${values[1]}</tspan>
              </text>
            </svg>
            `;
        }
        else if (value && units && units === '%') {
          radius = (length - 3) / 2;
          const circumference = radius * 2 * Math.PI;
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="none" stroke="var(--paper-item-icon-color)" opacity="0.5" stroke-width="${width}" />
              <circle style="
                  transform: rotate(-90deg);
                  transform-origin: 50% 50%;
                  stroke-dasharray: ${circumference};
                  stroke-dashoffset: ${circumference - value / 100 * circumference};
                "
                id="c_brightness" cx="25" cy="25" r="${radius}" stroke="var(--paper-item-icon-active-color)" stroke-width="${width}" fill="none" stroke-linecap="round" />
              <text x="50%" y="54%" fill="var(--primary-text-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${value}<tspan font-size="10" font-weight="normal" >%</tspan>
              </text>
            </svg>
            `;
          }
        else if (value && units && units.includes('°')) {
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="var(--paper-item-icon-active-color)" />
              <text x="50%" y="54%" fill="var(--paper-card-background-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${value}<tspan font-size="10" font-weight="normal" >${units}</tspan>
              </text>
            </svg>
            `;
        }
        else if (value && units && units.length > 1) {
          var y = (String(value).length > units.length) ? "50%" : "43%";
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="var(--paper-item-icon-active-color)" />
              <text x="50%" y="${y}" fill="var(--paper-card-background-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${value}<tspan x="50%" dy="1.2em" font-size="10" font-weight="normal" >${units}</tspan>
              </text>
            </svg>
            `;
          }
        else if (value) {
          return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="var(--paper-item-icon-active-color)" />
              <text x="50%" y="54%" fill="var(--paper-card-background-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${value}<tspan font-size="10" font-weight="normal" >${units}</tspan>
              </text>
            </svg>
            `;
        }
        return `
            <svg viewBox="0 0 50 50">
              <circle cx="25" cy="25" r="${radius}" fill="var(--paper-item-icon-active-color)" />
              <text x="50%" y="54%" fill="var(--paper-card-background-color)" font-weight="bold" font-size="14" text-anchor="middle" alignment-baseline="middle">${statestr}
              </text>
            </svg>
            `; 
      ]]]

You’ll need to do the following to get it to work on your system:

Make an image that has a 1 to 1 aspect ratio. You’ll need to make sure it’s transparent. I used a 100 x 100 pixel transparent image.
replace both instances of {{ entity }} with your entity_id.

sir how do u create the template file in home assistant for :
button_card_templates:
ceiling-fan-icon-settings:
show_icon: true
show_label: false
show_name: false
styles:
card:
- height: 36px
- width: 50px
grid:
- grid-template-areas: ‘“i”’
- grid-template-columnns: auto
icon:
- height: 26px
- width: 26px
state:
- value: ‘on’
spin: true

Hi
I got three buttons with fan speed, 1 … 3

        - type: horizontal-stack
          cards:
          - type: 'custom:button-card'
            entity: switch.fan_1
            color_type: card
            color: rgb(66, 134, 244)
            icon: mdi:numeric-1-box-outline
            styles:
              card:
                - height: 50px
          - type: 'custom:button-card'
            entity: switch.fan_2
            color_type: card
            color: rgb(66, 134, 244)
            icon: mdi:numeric-2-box-outline
            styles:
              card:
                - height: 50px
          - type: 'custom:button-card'
            entity: switch.fan_3
            color_type: card
            color: rgb(66, 134, 244)
            icon: mdi:numeric-3-box-outline
            styles:
              card:
                - height: 50px

So if I click fan1, status be:
[fan 1 on][fan 2 off][fan 3 off],
so now if I click fan 2 button, I want rest to default to off and and fan 2 to be on.
[fan 1 off][fan 2 on][fan 3 off]
is there a way to update the status of other button?

It would be easier if you made this on the backend with template switches instead of trying to do it with the button card.

how do I update the switch status without doing a service call from a template switches , I know you can do service call, I want to just to update the status. :slight_smile:

value_template handles a switch being on or off. Are all 3 of these switches a single fan? How are they integrated into HA?

Yep all three switches for a single fan and switches are configure as follows

  - platform: broadlink
    mac: abc
    switches:    
      - name: Study room celing fan speed 1
        command_on: sgDYAAkfCR4dCwkfHQs
        command_off: sgDYAAkfCR4dCwkfHQs
      - name: Study room celing fan speed 2
        command_on: shIyAAseCh8
        command_off: shIyAAseCh8LHgsfHwsKHx
      - name: Study room celing fan speed 3
        command_on: shAyAAseCx8LHgsfHgsLHh4LHwofCwseH
        command_off: shAyAAseCx8LHgsfHgsL

And I don’t want to call the device each time I’m updating the status.