Lovelace: Button card

@kongo09 I don’t know how to include the scripts, so I can’t set those up – in what file should they be added? If I do it straight in configuration.yaml i get a dictionary error and errors about my automations start showing up. Might have something to do with the recent updates changing file locations perhaps?

I was able to install the coap and i’m not getting any errors there. I added the button templates to my raw lovelace config after some tinkering too. I think I’m misunderstanding some basic part of the scripting - it’s all figuring it out as í go for me as i’m not a programmer by trade.

The card itself is wonked out:

yes, thats just the way decluttering cards work. (or maybe we should say the interaction between decluttering and button cards works)

They don’t process templates, but replace a string in a variable. You can write the template in your decluttering card, and in that template use a string you inject in it from the calling card you declare that. Would that field change in every card you use the template for? Because if, not, you wouldn’t even need to use it like that, and could simply use the full template in the decluttering card?

this works:

card:
  type: custom:button-card
  template:
    - button_picture_script_small
    - styles_tooltip
  entity_picture: '/local/flags/[[flag]].png' #fr
  name: '[[name]]' #French
  show_name: false
  tooltip: '[[name]]'
  tap_action:
    action: call-service
    service: script.set_intercom_language
    service_data:
      option: '[[option]]' #'Fr'
  state:
    - operator: template
      value: >
        [[[ return states['input_select.intercom_language'].state === '[[option]]'; ]]]

last line, contains the regular template but only replacing the field [[option]] which is infected from the calling button.

it helps seeing the decluttering cards as one big yaml anchor. Pure string manipulation (copy&paste), no states templating.

I’ve got a quite basic question: Is it possible at all to overlap neighbouring button-cards?
I have some in a horizontal-stack and try to draw a text from the right card over an empty space of the left card (using negative margin or even position: absolute and transform: translate(...)):
button-card3

Whatever I try (even with background: none and background-color: transparent on both cards or using z-index), the overlapping text gets clipped if it “hits” the left card:
button-card4

I’d like to save some space… :cry:

One thing that seems to be missing is the circle for the display. It is not in my Philips icon set, but in a separate one. Maybe I should change that. Did you install this:

Also, are you sure your entities are named consistently, i.e. have the same name in the integration as in the card, like fan.air_ac2729.

On top of the above problem I stumbled upon the following error:
button-card06
while trying to set the initial value for a variable from another variable:

tmpl_btn_heat:
  variables:
    preset: 1
    active: >
      [[[ states[entity.entity_id].attributes.preset_modes[variables.preset] == states[entity.entity_id].attributes.preset_mode ]]]

If I substitute the [variables.preset] with a number all’s well. But that is no option.
What am I doing wrong?

Ah no that one was missing, I did have Philips Air Purifier (PAP) Icon Pack installed.

How did you include the scripts in your setup? I don’t know how to install those and they are needed.

Would it perhaps be an idea for you to create a custom card with your setup which we can install? I’m sure many people would enjoy it. I have other cards installed that make use of the lovelace-button-card, integrating it seems pretty doable. Thanks for your help!

There are several scripts and they go into different places.

I understand that you have the correct script in configuration.yaml? This has nothing to do with the card itself, but it configures the integration of the fan. If you find the fan entities in the developer tools menu, than this part worked.

The most tricky bit is actually the script that starts with button_card_templates: This goes into the lovelace configuration, but not the one where you configure the actual card, but in the raw lovelace configuration file for your whole frontend.

Ok, that sounds cryptic, I know. To find the place, go to your dashboard and click the three dots in the top right corner to select Edit Dashboard. Then you click on the three dots again to select Raw Configuration Editor.

Most probably you find in line 1 views: and below the whole configuration of all your dashboard views. Now, copy the script with button_card_templates: before the views, so that this starts at line 1 and the rest moves down.

Let me know if that helps.

Hi all, i have a group of binary sensors. I would like to see this group in a custom:button-card. I noticed that tap action is completely ignored in it. THere is a reason why tap action doesn’t work on a group entity?

type: custom:button-card
entity: group.sensori_seve
action: more-info

Tap action on groups works with the right code :wink:


tap_action:
  action: more-info

Ok, thank you. Got it

currently i’m using cards like this:
image

But I’m trying to create a button for a light group with the state of a motion sensor and the state of a timer in it, like so: (ms paint skillz!)
image

I’ve been staring real hard at the readme but i just can’t figure out how to use the grid function to create a button like this.

Is there a code-wizard who van help me set this button up?
if i have the beginning of this i can further adapt it for more buttons i have planned :slight_smile:

Entity info:
Light group: light.woonkamer_group
Timer: sensor.livingroom_timer
Motion Sensor: binary_sensor.huesensor01_occupancy

Thanks for any pointers/help/advice :slight_smile:

Hi,
I was trying to change some style on the button depends on how much the user scroll from the top.
It is working fine, the only problem is that the script is not being refreshed constantly, only once in few seconds, so it is not smooth.
Is there anything can be done here?

Here is the code:

      - background: |
          [[[
            var supportPageOffset = window.pageXOffset !== undefined;
            var y = supportPageOffset ? window.pageYOffset : isCSS1Compat ? document.documentElement.scrollTop : document.body.scrollTop;
            if ( Math.round(y) > 15 ) {
              return 'var(--header-background-color)';
            } else {
              return 'none';
            }
          ]]]

Hi all, I’ve got 2 questions. First one, related to browser mod popup. I’m trying to use the following code to change the border color when playing spotify. The code works, but it’s not updated when i use the code in a browser mod popup, when i re-open the popup the color is changed.

            styles:
              card:
                - border: |
                    [[[    
                       if (states['media_player.spotify_tim'].state == "playing" && states['media_player.spotify_tim'].attributes.source == "Nad T778")
                        return "2px solid gold";
                       else return "2px solid var(--accent-color)"
                    ]]]

second question: How can i change the font size in a custom field? <font size=10></font> is not working. I want to change the first and second line in different fonts.

      custom_fields:
        text1: |
          [[[    
            if (states["media_player.spotify_tim"].state != "idle")
              return states['media_player.spotify_tim'].attributes.media_artist  +"<br/>"+ states['media_player.spotify_tim'].attributes.media_title;
            else if (states["media_player.spotify_tim"].state == "idle")
                  return "";
          ]]]

thanks in advance

The third example should fit: https://github.com/custom-cards/button-card#custom-fields

Use backticks for HTML rendering:


custom_fields:
  text1: |
    [[[ 
      var mp = states["media_player.spotify_tim"];
      if (mp.state != "idle" && mp.state != 'standby' && mp.attributes.media_artist && mp.attributes.media_title)
        return mp.attributes.media_artist +"<br/>"+ mp.attributes.media_title;
      if (mp.state == "idle") return " ";
      return `<span style='font-size: 10px;'>off</span>`
    ]]]

1 Like

Thanks, working perfectly. Another question:
&& mp.attributes.media_artist
what does this part do? Check of the attribute is present or not empty?

Yes, that’s correct. I forgot to adjust the != 'standby' (I have only Echos here to test, and they have no state on or off), so adjust it for your needs.

1 Like

Just wanted to say thank you for this amazing card! I went quite deep with it and designed most of my lovelace UI using variety of button card templates.

The first card I ended up creating is a simple clock card which shows time, date, temperature and current weather.

screenshot-clock

If you fancy it you can check my repo in Github: https://github.com/troinine/hass-config

Thanks again for creating and maintaining this project!

10 Likes

Hi, I have an input_datetime which I like to display on a button card.
So far I do it like follows:

custom_fields:
  left: |
    [[[  
      var date = states['input_datetime.joerg_left_home']; 
      if (states['device_tracker.joerg_s10'].state != 'home') 
      return date.attributes.day + '.' + date.attributes.month + ' - ' + date.attributes.hour + ':' + date.attributes.minute; 
    ]]]

That work but doesn’t look good at least due to the missed leading zeros.
There must be a more efficiant way to do it. In jinja I usually use timestamp_custom(’%H:%M am %d.%m’). I havent found something similar for button_card

I’m not sure if it is more efficient than putting another custom:button-card in your custom field or creating a template sensor, but you can give it a try if you like:


  [[[
    var set = new Date(states['input_datetime.joerg_left_home'].state.split(' ')[0]);
    var date = set.toLocaleString('de-DE', { dateStyle: 'medium' });
    var time = states['input_datetime.test'].state.split(' ')[1].slice(0, -3)
    if (states['device_tracker.joerg_s10'].state == 'home') return date + ', ' + time + ' Uhr'; return '?'
  ]]]

Or, if your input_datetime is feeded by an automation:


  [[[  
    var set = new Date(states['automation.abcdefg'].attributes.last_triggered);
    var d = set.toLocaleString('de-DE', { dateStyle: 'medium', timeStyle: 'short' });
    return d + ' Uhr'
  ]]]

1 Like