Lovelace: Button card

I must be missing something really obvious here, but in the docs its says to put your templetes “In ui-lovelace.yaml (or in another file using !import )”

What is and how do you use !import?

I have my lovelace config split and use !include for each view and also for my compact custom header config.

I’d like to put all my button templates in a separate file too. What obvious thing have I missed/do I not know about?

Is the below screenshot the expected outcome of the following card config? The card is significantly taller than 2px.

button_card_templates:
  horizontal-blank-gap:
    styles:
      card:
        - height: 2px

- type: custom:button-card
  template: horizontal-blank-gap

Thanks for this card, great functionality and versatility. Many of us are making remotes so here is one someone can use as a starting point. This one is for Kodi and uses all native methods, so no scripts/automations needed.

Image example:

Template:

button_card_templates:
  remote_button_normal:
    styles:
      icon:
        - color: var(--primary-color)
      card:
        - border-radius: 0px
        - opacity: 0.5
  remote_button_round:
    template: remote_button_normal
    styles:
      card:
        - border-radius: 15px

Remote stack:

cards:
  - cards:
  - type: 'custom:button-card'
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ContextMenu
        entity_id: media_player.theater
    template: remote_button_round
    icon: 'mdi:menu-open'
  - type: 'custom:button-card'
    template: remote_button_round
    hold_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.Up
        entity_id: media_player.theater
      repeat: 100
    icon: 'mdi:menu-up-outline'
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.Up
        entity_id: media_player.theater
  - icon: 'mdi:chevron-double-up'
    type: 'custom:button-card'
    template: remote_button_round
    hold_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ExecuteAction
        entity_id: media_player.theater
        action: pageup
      repeat: 100
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ExecuteAction
        entity_id: media_player.theater
        action: pageup
type: horizontal-stack
  - cards:
  - icon: 'mdi:menu-left-outline'
    type: 'custom:button-card'
    template: remote_button_round
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.Left
        entity_id: media_player.theater
  - icon: 'mdi:alpha-s-circle-outline'
    type: 'custom:button-card'
    template: remote_button_round
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.Select
        entity_id: media_player.theater
  - icon: 'mdi:menu-right-outline'
    type: 'custom:button-card'
    template: remote_button_round
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.Right
        entity_id: media_player.theater
type: horizontal-stack
  - cards:
  - icon: 'mdi:backburger'
    type: 'custom:button-card'
    template: remote_button_round
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.Back
        entity_id: media_player.theater
  - icon: 'mdi:menu-down-outline'
    type: 'custom:button-card'
    template: remote_button_round
    hold_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.Down
        entity_id: media_player.theater
      repeat: 100
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.Down
        entity_id: media_player.theater
  - icon: 'mdi:chevron-double-down'
    type: 'custom:button-card'
    template: remote_button_round
    hold_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ExecuteAction
        entity_id: media_player.theater
        action: pagedown
      repeat: 100
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ExecuteAction
        entity_id: media_player.theater
        action: pagedown
type: horizontal-stack
  - cards:
  - icon: 'mdi:chevron-double-left'
    type: 'custom:button-card'
    template: remote_button_round
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ExecuteAction
        entity_id: media_player.theater
        action: stepback
  - icon: 'mdi:pause'
    type: 'custom:button-card'
    template: remote_button_round
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ExecuteAction
        action: playpause
        entity_id: media_player.theater
  - icon: 'mdi:chevron-double-right'
    type: 'custom:button-card'
    template: remote_button_round
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ExecuteAction
        action: stepforward
        entity_id: media_player.theater
type: horizontal-stack
  - cards:
  - icon: 'mdi:layers-outline'
    type: 'custom:button-card'
    template: remote_button_round
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ExecuteAction
        entity_id: media_player.theater
        action: fullscreen
  - icon: 'mdi:cctv'
    type: 'custom:button-card'
    template: remote_button_round
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ShowPlayerProcessInfo
        entity_id: media_player.theater
  - icon: 'mdi:information-outline'
    type: 'custom:button-card'
    template: remote_button_round
    tap_action:
      service: media_player.kodi_call_method
      action: call-service
      service_data:
        method: Input.ShowOSD
        entity_id: media_player.theater
type: horizontal-stack
type: vertical-stack
1 Like

You’re right, it’s a documentation error, it’s !include.

Add: color_type: blank-card

Ok, I’m definitely missing something. I cannot find a way to have the button card templates in a separate file.

However I do the spacing it either ignores the template or fails entirely and gives the big red box.

I’d like to have all my button templates in one file and then !include it in ui-lovelace.yaml so that it is available for every view which is itself a separate file with an !include.

(I have a feeling this might be something that @Mariusthvdb has done? Or @petro if he is not sticking with his anchors?)

I did that and it works:

button_card_templates:
 !include file.yaml

And then in file.yaml:

template1:
  [stuff]

template2:
  [stuff]

And I also have separate files for each view.

Ah!! thanks!
For some inexplicable reason I had the button_card_templates: in the separate file!!
Doh!

1 Like

Thank you, sir! Interesting how I was able to create a vertical “gap card” without needing to declare the color type. Regardless, now I can add spacing in a vertical-stack-in-card! :slight_smile:

Except that (and I’m really sorry about this) why does this work in my ui.lovelace.yaml

button_card_templates:
  haveibeenpwned:
    show_state: true
    show_icon: false
    color: 'var(--paper-card-background-color)'
    size: 70%
    styles:
      name:
        - font-size: 14px
      state:
        - font-size: 14px

but this doesn’t

button_card_templates:
  !include button_card_templates.yaml

Given that my buton-card-templates.yaml file is this

haveibeenpwned:
  show_state: true
  show_icon: false
  color: 'var(--paper-card-background-color)'
  size: 70%
  styles:
    name:
      - font-size: 14px
    state:
      - font-size: 14px

For completeness my button is defined like this

          - type: custom:button-card
            entity: sensor.breaches_myemail_com
            name: [email protected]
            template: haveibeenpwned
            state:
              - value: 0
                operator: '>'
                styles:
                  card:
                    - box-shadow: 0px 0px 8px 2px var(--primary-text-color)
                    - color: red
1 Like

If what you’ve written is what you have, then your include has underscores and your file has hypens and is missing one t. Appart from that your config looks fine.

1 Like

What an idiot!

You could have been so much crueller. I deserved it.
My only excuse is I started this late last night and continued this morning.

No, not an excuse at all.
Sorry for wasting your time.

PS the missing t was typo in this post only :slight_smile:

2 Likes

ah thanks, missed that.

didn’t solve the issue though, it seems to completely ignore the styles bit:

44

mixed test setup, only difference between the buttons is this:

type: horizontal-stack
cards:
  - <<: *custom_button_switch
    entity: switch.sw_multi_purpose_template
    name: Multi purpose

and

  - type: custom:button-card
    template: switch
    entity: switch.sw_audio_auditorium_template
    name: Aud. Audio
    lock: true
    state:

56

To make it really agnostic, I’d add an arbitrary attribute to the entity and use the attribute value in the template:

that is a nice trick indeed! will note that for sure. And somehow I can’t see how to make the templated translation though, so I can use that in the button_card_templates?

I still would need to truncate the switch.sw bit at the beginning and _template at the and, to arrive at sensor.xxx_actueel to go from switch.sw_xxx_template to sensor.xxx_actueel

doing that now with

      var id = entity.entity_id.split('.')[1].slice(3, -9);
      return states['sensor.' + id + '_actueel'].state + ' Watt';

maybe you see another way?

yes i have this too, and the include is found alright, but the templates seem not to work (at all).

button_card_templates:
  !include /config/lovelace/includes/button_card_templates.yaml

type: horizontal-stack
cards:
  - type: custom:button-card
    template: switch
    entity: switch.sw_multi_purpose_template
    name: Multi purpose

etc
etc

Ive copied my anchor into a template, (see post above) but this doesn’t configure the button like it should…

You have both style and styles defined at the same time, style is deprecated you shouldn’t use it anymore.

The path shouldn’t start with /config, as home-assistant’s root is already /config when it looks for files. I think it should be (no / at the beginning either): lovelace/includes/button_card_templates.yaml

really sorry to disagree here, but my experience teaches me differently. Paths should always start with the /, even when referencing a simple image template.

Most of the time these paths start with /local/ when these files reside in the /www folder.

since Ive filed all Lovelace files in /config/lovelace and sub folders there , /includes for includes, /tiles for tiles, /buttons for buttons ;-), this is the correct path for this includes file.

I’ve tried it without the root /config, but this won’t work. I get a popup asking me to take control or let Lovelace be configured automatically… which is a silly way for saying Ive made an error in the path … (filed an issue for that some time ago, don’t knoww if that’s picked up at all)

O I missed that… sorry for that, Ill re-read the docs for that.

Please let me ask, if style is deprecated, how come it is still working when using anchors??

hm, I use this as well I have style: and styles: both in my config and it seems to work fine.
I use this to define an opacity to the card which was (don’t know about now) weirdly a different opacity than if I’d define it in the card style. It is probably fixed but at first the same opacity would look different when using style: or styles:.

Weird stuff :stuck_out_tongue: it is the same with using ‘rgba(x,x,x,0.7)’ which would look different than opacity 0.7 (which it shouldn’t no?). For example if I use the --paper-card-background-color with rgba it will only render opacity on the card and not the text. If I use opacity on the card it will render everything that way including text.

But as I said before I am a noob when it comes to this and as such I just did what worked for me. However it might be that there is something that overrides the stuff I made I wouldn’t know.

Anyways, I will try to use the opacity in styles as style is deprecated you say. I will report back here if my findings happen to be different from last time :smiley:

style is copied to styles.card and style is ignored in the code. Using both at the same time will have unexpected effects (like ignored stuff).

I’ll deprecate style in the next release!