Lovelace: Button card

I’m surprise to see all works on chrome pc but not on android.
But ok.
:relaxed:

Can anyone help me? if this is possible :slight_smile:
I dont want to change icon. i want the entitys original battery icon that changes by %.

custom_fields:
  battery: |
    [[[
      return `<ha-icon
        icon="mdi:battery-50"
        style="width: 12px; height: 12px; color: deepskyblue;">
        </ha-icon><span> <span style="color: var(--text-color-sensor);">${states['sensor.idlock_battery'].state}%</span></span>`
    ]]]

If i use this i only get the state:

custom_fields:
  battery: |
    [[[
      return `
        </ha-icon><span> <span style="color: var(--text-color-sensor);">${states['sensor.idlock_battery'].state}%</span></span>`
    ]]]

:slight_smile:

Try ${entity.attributes.icon}

Thanks for the quick response! I’m new to this, can you please paste it into the code so I know where to add it?

Like

custom_fields:
  battery: |
    [[[
      return `
        <ha-icon icon="${entity.attributes.icon}" style="width: 12px; height: 12px; color: deepskyblue;"></ha-icon>
        <span style="color: var(--text-color-sensor);">${states['sensor.idlock_battery'].state}%</span>`
    ]]]

Thanks, but the icon disappears completely when I tested it.

How would I go about inserting a if, else statment into motion_icon?

custom_fields:
  motion: |
    [[[
      var motion_icon = states['sensor.basement_motion'].state === 'Motion' ? 'mdi:run' : 'mdi:walk';
      var motion_icon_color = states['sensor.basement_motion'].state === 'Motion' ? 'var(--ha-card-background)' : '#FFFFFF';
      return '<ha-icon icon="' + motion_icon +'" style="width: 20px; height: 20px; color:' + motion_icon_color +';"></ha-icon>'
    ]]]

I have tried the below, but it just returns the mdi: text

custom_fields:
  motion: |
    [[[
      var motion_icon = states['sensor.basement_motion'].state;
      if (motion_icon == 'Motion') 'mdi:run' ; 
      return 'mdi:walk';
      var motion_icon_color = states['sensor.basement_motion'].state === 'Motion' ? 'var(--ha-card-background)' : '#FFFFFF';
      return '<ha-icon icon="' + motion_icon +'" style="width: 20px; height: 20px; color:' + motion_icon_color +';"></ha-icon>'
    ]]]

Trying to learn the syntax so that I can add an additional condition (state of a lightbulb)

It’s most likely not working because your click events are being captured by the button card instead of the picker cards.

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:

  1. 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.
  2. replace both instances of {{ entity }} with your entity_id.
1 Like

Thank you for this clarification. I thought the click was taken since it works on the computer but not on a smartphone …

You’ll have to play around. On PC, click around your button on the button card and see how it reacts. If the actions require precise precision on the PC, then it’s going to be hard on a touch screen. You can disable the button’s button action, but that may not help.

It’s right if I disable tap_action, the time-picker-card action no longer work…

I will realize my card with picture-element-card.

Thanks.

No, this has nothing to do with the yaml configuration. This is a CSS style to enable or disable click events.

Hey Rom,since this was the only post you made in Hover, and Ive really tried just about anything I could think be relevant without any hovering tooltip…:
could you please have a look at my post here, and see what I could do to make a tooltip happen?
thanks if you could spare a moment (or 2…)

Ive been getting help from fellow members here, but haven’t been able to realize what I am looking for: a tooltip hovering a button with only an icon. (a tooltip at all for that matter, but endgoal would be the menubar showing a row of buttons with an icon)

You can try setting the title attribute:

  - type: custom:button-card
    name: >

      [[[
         return `<span title="Calendar">Cal</span>`
      ]]]

well not sure anymore, I have tried a lot of things, up to this:

  - type: custom:button-card
    template: button_shortcut_menu
    extra_styles: |
      /* Tooltip container */
      .tooltip {
        position: relative;
        display: inline-block;
      }

      /* Tooltip text */
      .tooltip .tooltiptext {
        visibility: hidden;
        width: 120px;
        background-color: blue;
        color: red;
        text-align: center;
        padding: 5px 0;
        border-radius: 6px;

        /* Position the tooltip text - see examples below! */
        position: absolute;
        z-index: 1;
      }

      /* Show the tooltip text when you mouse over the tooltip container */
      .tooltip:hover .tooltiptext {
        visibility: visible;
      }
    name: >
       [[[ return `<div class='tooltip'><ha-icon icon='mdi:calendar'</ha-icon>
          <span class='tooltiptext'>Tooltip text</span>
        </div>` ]]]

    tap_action:
      action: navigate
      navigation_path: /lovelace/tijd_agenda

which does give me the icon,


and navigates. It simply refuses to give me a tooltip. Even when I simply use the name: Hover here instead of the icon

(which if course is a trick, but using the icon: field doesn’t show an icon…)

You might need to put your mouse there for longer. Try out:

  - type: custom:button-card
    template: button_shortcut_menu
    name: >
       [[[ return `<ha-icon icon='mdi:calendar' title='Calendar'></ha-icon>` ]]]
    tap_action:
      action: navigate
      navigation_path: /lovelace/tijd_agenda

dont understand this really, where’s the tooltip text in your example? You seem to be mixing name, icon and tooltip in 1 go :wink: ?

in all examples online, the tooltip is immediate…

The tooltip text is the title='Calendar' part.

well I be d…

immediately tried this:

    icon: >
      [[[ return `<ha-icon icon='mdi:calendar' title='Calendar'></ha-icon>` ]]]

but the field icon still doesnt show an icon.;-(

now, next challenge, how to get the tooltip to show in the button:

  - type: custom:button-card
    template: button_shortcut_menu
    icon: mdi:light-switch
    tap_action:
      action: navigate
      navigation_path: /lovelace/lights
    variables:
      path: lights
    styles:
      icon:
        - color: >
            [[[
              return (states['group.all_inside_lights'].state == 'on')
              ? 'gold': 'grey';
            ]]]
[[[ return variables.path.replace('_',' ').toUppercase() ]]]

as tooltip