Lovelace: Button card

So if I understand you correctly there is no way to have the buttons look the same on laptop/phone?

Or would a workaround be to size the card based on the font?

Don’t use em :

em is not an absolute unit - it is a unit that is relative to the currently chosen font size.

so, depending an a state, I either need an icon to spin, or spin anti-clockwise.

since spin is built in, this is easy. However, the anti-clockwise probably needs something like:


@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(-360deg); }
}

as it happens the button itself is already animated when the main entity is ‘on’, so, I would need to combine the 2 animations…

this is the card:

type: custom:button-card
template: button_alarm
variables:
  dst: >
    [[[ return states['input_boolean.dst'].state ]]]
  view: >
    [[[ return (window.location.pathname.split('/')[2] == 'time_settings') ]]]
  adjust: >
    [[[ return states['sensor.dst'].attributes['dst active'] == true ? 'ahead' : 'back'; ]]]

entity: sensor.dst

show_state: true
show_name: false

tap_action:
  action: call-service
  service: input_boolean.toggle
  service_data:
    entity_id: input_boolean.dst

hold_action:
  action: >
    [[[ return variables.view ? 'more-info' : 'navigate'; ]]]
  navigation_path: >
    [[[ return variables.view ? null : '/ui-data/time_settings'; ]]]
  entity: >
    [[[ return variables.view ? entity.entity_id : null; ]]]

state_display: >
  [[[ return 'Dst: ' + variables.adjust ]]]
state:
  - operator: template
    value: >
      [[[ return (variables.dst == 'on'); ]]]
    spin: true
    styles:
      icon:
        - color: maroon
      card:
        - background-color: var(--background-color-on)
        - color: maroon
        - animation: blink 2s ease infinite
  - operator: template
    value: >
      [[[ return (variables.dst == 'off'); ]]]
    styles:
      icon:
        - color: green
      card:
        - background-color: var(--background-color-off)
        - color: grey

and my guess would be to add an additional operator template:

state:
  - operator: template
    value: >
      [[[ return (variables.dst == 'on' && variables.adjust == 'ahead'); ]]]
    spin: true
    styles:
      icon:
        - color: red
      card:
        - background-color: var(--background-color-on)
        - color: maroon
        - animation: blink 2s ease infinite
  - operator: template
    value: >
      [[[ return (variables.dst == 'on' && variables.adjust == 'back'); ]]]
    # spin: true <--- howe to replace this with an anti-clockwise animation
    styles:
      icon:
        - color: green
      card:
        - background-color: var(--background-color-on)
        - color: maroon
        - animation: blink 4s ease infinite

hope this can be done, thanks for having a look
edit
Wait, this seems to do it:

style: |
  @keyframes spin-back {
    0% { transform: rotate(0deg); }
    100% { transform: rotate(-360deg); }
  }

and

  - operator: template
    value: >
      [[[ return (variables.dst == 'on' && variables.adjust == 'back'); ]]]
    # spin: true <--- how to replace this with an anti-clockwise animation
    styles:
      icon:
        - color: green
        - animation: spin-back 4s ease infinite  # <---- like this!
      card:
        - background-color: var(--background-color-on)
        - color: maroon
        - animation: blink 4s ease infinite

Thanks for that! Had the code right, turns out it was an indentation issue stopping my button from showing up.

Final product:

Has anyone implemented any scrolling state/name/label text?

I have a button which displays the Artist - Song Title in the label text but i would like it to scroll rather than … get cut off.

Hi,
I’m trying to pass a variable to a service_data field. Something along the lines of the following MWE of a template:

  media_service:
    variables:
      name: "var_name"
      service: "var_service"
      entity: "var_entity"
      type: "var_type"
      data: "var_data"
      picture: "var_picture"
    name: '[[[ return variables.name ]]]'
    tap_action:
      action: call-service
      service: '[[[ return variables.service ]]]'
      service_data:
        entity_id: '[[[ return variables.entity ]]]'
        '[[[ return variables.type ]]]': '[[[ return variables.data ]]]'
    hold_action:
      action: none
    show_entity_picture: true
    entity_picture: '[[[ return variables.picture ]]]'
    aspect_ratio: 1/1

And the template in use:

      - type: 'custom:button-card'
        template: media_service
        variables:
          name: Bluetooth
          service: media_player.select_source
          entity: media_player.pioneer_avr
          type: source
          data: BT AUDIO
          picture: /local/ui/btns/bluetooth.png

I’m struggling specifically with the “type” variable in this example. Is this even at all possible? Or have I missed something?

Check Scrolling/fading text in Lovelace, is it possible?

1 Like

Also, im sure i have seen it but can you apply a border to the mdi icon itself i.e. not the border container but the SVG?

Im sure i saw someone do it for a TV backlight / hyperion setup?

Thanks for this link, i tried <marquee> tag but its depreciated so wanted to do it in CSS. With a bit of fiddling i used the following code:

On the button card:

extra_styles: |
  @keyframes marquee {
    0%   { transform: translate(0, 0); }
    100% { transform: translate(-100%, 0); }
  }

Then within the state_display field:

state_display: |
  [[[
    var active_speaker_state = (states[variables.active_speaker].state);
    var active_speaker_media_artist = (states[variables.active_speaker].attributes.media_artist);
    var active_speaker_media_title = (states[variables.active_speaker].attributes.media_title);
    if (active_speaker_state === 'playing') return `<div style="animation: marquee 8s linear infinite;display: inline-block;padding-left: 100%;">${active_speaker_media_title}</div>`;
    else return "&nbsp;";
  ]]]

I now have scrolling song title - this will always scroll now though even if the text fits on the card. Not sure how i implement an IF width greater than clause within the CSS.

1 Like

marquee still works, if it doesnt in your config, you’ve made a mistake:

type: custom:button-card
template: button_default_title
styles:
  card:
    - padding: 5px
name: >
  [[[ var phrase = states['sensor.count_alerts_notifying'].state == 1
                   ? 'Alert:' : 'Alerts:';
      return `<div style='display: inline-flex;'>
      <div>${states['sensor.count_alerts_notifying'].state} ${phrase}&nbsp</div>
      <marquee>
      <span style='align-items: center;font-weight:normal;font-size:18px;'>
      ${states['sensor.marquee_alerts'].state}&nbsp</span>
      </marquee>`; ]]]

or

type: custom:button-card
template: button_summary_picture
entity: sensor.next_alarm
hold_action:
  action: navigate
  navigation_path: /lovelace/alarmclock
label: >
  [[[ var caption = 'Next:&nbsp';
      var alarm = states['sensor.next_alarm_day_only'].state;
      if (entity.state != 'Not set')
      return `<div style='display: flex;
                         padding: 0px 5px 0px 5px;
                         align-items: center;
                         background: transparent;'>
      <div>${caption}</div>
      <marquee>
      <span style='color: var(--primary-color);align-items: center;'>${alarm} at ${entity.state}</span>
      </marquee>`;
      return entity.state; ]]]
entity_picture: >
  [[[ if (entity.state != 'Not set') return hass.hassUrl('/local/badges/alarm.png');
      return hass.hassUrl('/local/badges/alarm_off.png'); ]]]
styles:
  label:
    - color: >
        [[[ if (entity.state != 'Not set') return 'crimson';
            return 'green'; ]]]

work just fine, even posted that some time ago in this thread: Lovelace: Button card - #3133 by Mariusthvdb

that might be rather difficult, given the fact these buttons adapt to the device and screen size, so you’d need to consider that in the logic.

I didnt say it didnt work, it did work but its a depreciated tag. Also the tag itself has some odd margin/padding which i couldnt be bothered to fix so i went the other route after looking at your examples.

ok cool, thanks for letting me know.

hello together,

i am very new to the custom button card, but i like it a lot.
One Question i have at the moment is, is it possible to “call” a different card with double-tap for example.

What i want to achieve is the following:
tap_action: => Open or Close a Cover (that works great)
double_tap_action: => call different card to set the postion (that does not work :frowning: )
The option more-info is not the thing i like at this point :frowning:

Perhaps anybody can share how he/she has achieved something like that

thx.

You can open popups or replace the more-info dialog with:

Hi, is it possible to use a custom icon like gif or svg instead of mdi?

Is it possible to set an entity name as an var and use it in template. I got an card it already partially templated but want to move the rest over to the template side, because all the setting is the same with the exception of entity name.

############## Picture Element Main Light Entities ##############
  - type: "custom:button-card"
    entity: light.hall_way_walkway
    template: light_element_button
    style:
      left: 54.5%
      top: 33%
    ######### want to move this section into template #########
    entity_picture: |
      [[[
        if (states['light.hall_way_walkway'].state == 'off')
          return "/local/photos/lovelace_photos/general/recessed_light_off.png";
        return "/local/photos/lovelace_photos/general/recessed_light_on.png";
      ]]]
    custom_fields:
      light_bri: |
        [[[
          var bri = states['light.hall_way_walkway'].attributes.brightness;
          if (bri > 0) 
            return Math.floor(bri/255 * 100) + '%';
          return
        ]]]
    ######### want to move this section into template ######### 
############## Button Card Template ##############
##### main light button
light_element_button:
  hold_action:
      action: more-info
  show_entity_picture: true
  show_name: false
  styles:
    grid:
      - position: relative
    entity_picture:
      - width: 21px
    custom_fields:
      light_bri:
        - position: absolute
        - height: 21px
        - width: 21px
        - font-size: 8px
        - line-height: 21px
        - align-self: middle
        - justify-self: start
        - color: 'red'

entity.state

perfect thank.

Yes, using the entity_picture (or for more options, the custom_fields)

Hello
Do you know how can I achieve circular brightness indicator like implemented in homekit card?
I’m going to migrate from hk to button card, but I like this “circles”.
Author of hk card mentions he got idea from other source, but link he provided directs to an image.

obrazek

1 Like