Lovelace: Button card

:tada::tada: Version 3.3.3 :tada::tada:

Bugfixes

  • Units would be shown even with show_units: false (Fix #321)
  • Card would not work properly with HA < 0.107 (Fix #322)

Is there a way to change the display name of a state on the button-card?

For example: My TV state is “Standby”, but I want it to say “Off” on the card.

Thanks so much!

You need to use the state display option with JavaScript.

Can someone assist with Templating tap actions?

Is it possible to do different actions based on the state?

please allow me this maintenance question, I might have missed an update to the action field:

is this:

hold_action:
  action: call-service
  service: automation.trigger
  service_data:
    entity_id: entity

still correct for firing an automation which is the entity of the button? I ask because it very often doesn’t work (could also be caused by the conditional styling of the card, which is animated: blink 2s ease infinite which makes it a bit more difficult to touch the button on an iPhone…

reason I am expanding on this also, is I have several ‘Alert’ buttons showing on my Home view, in a conditional card, and on their own detailed view for the specific info. Example: a GitHub update is available: ping!, Home view shows the update button.

The same button also shows on my developer view, with all other stuff on the GitHub repos I use.

What I would love to do is, depending on the view I am on, have a hold-action defined.

On my Home view, I would like the hold-action to be a navigate to the developer view,

hold_action:
  action: navigate
  navigation_path: developer

and, on the developer view, the hold action would need to be what I posted above, trigger the automation.

hold_action:
  action: call-service
  service: automation.trigger
  service_data:
    entity_id: entity

I would hope to be able to write a template for that, but of course would need to access view in the JS templates
@RomRider would you allow to do this please?

As I have about 12 alert buttons, for which this scenario would go, it would be amazing if we could:
a) use templates for the actions, that
b) see the view

in Jinja I would be able to write this in a service_template, or maybe even a subscript, but in JS I am not sure how to proceed, so if at all possible would need some help here too…

please have a look? thanks!

Hey there,

is it possible to display to notifications? The example

- type: custom:button-card
    icon: mdi:lightbulb
    aspect_ratio: 1/1
    name: Nb lights on
    styles:
      grid:
        - position: relative
      custom_fields:
        notification:
          - background-color: >
              [[[
                if (states['input_number.test'].state == 0)
                  return "green";
                return "red";
              ]]]
          - border-radius: 50%
          - position: absolute
          - left: 60%
          - top: 10%
          - height: 20px
          - width: 20px
          - font-size: 8px
          - line-height: 20px
    custom_fields:
      notification: >
        [[[ return Math.floor(states['input_number.test'].state / 10) ]]]

shows one notification in the right upper corner. I would like to show another notification in the right corner at the bottom.

Is this possible?

I have the following button set up:

type: 'custom:button-card'
entity: switch.pool_pump
tap_action:
  action: more-info
name: |
  [[[ 
    if (states["timer.clean_cycle"].state == 'idle') return states['sensor.pump_on_today'].state + " h";
    else return "."
  ]]]
show_icon: true
show_name: true
custom_fields:
  timer:
    card:
      type: entities
      entities:
        - timer.clean_cycle
      graph: line
styles:
  grid:
    - position: relative
  custom_fields:
    timer:
      - position: absolute
      - overflow: unset
      - top: 78%
      - left: 15%
      - height: 0px

It shows the state of the pool pump. There are 2 values that I would like to display as the name/label depending on what the pump is doing ie ‘Clean cycle’ or otherwise:
Screenshot 2020-05-07 at 18.25.51 Screenshot 2020-05-07 at 18.09.26

During the Clean cycle the ‘time remaining’ is displayed, otherwise the hours run for the day are displayed.

The only way I know to show a timer counting down in real time is by using an ‘Entities’ card. I therefore embedded it in the button using a custom-field.

Positioning the custom-field was fiddly as I’m not that familiar with CSS styling, but eventually got there. The problem is that the position of the value changes depending on the size of the button.

Any ideas on how to correct this or other ways to do it, would be most welcome.

I get that width: and height: are in px. But, I’m using transparent and non-transparent button-cards as overlays on picture-elements cards to drive actions. Picture-elements’ images scale with the size of the display, but not the custom:button-cards laid on them. Is there a way to scale the button-card dimensions as a percent to keep them in sync with the screen-size?

Yes it’s possible. But what is your question? As a side note, you can do that using a script in homeassistant and call that script from the button-card so no need for templates.

You can access window.location in the JS templates which contains the URL of the current page.

You can already template any property including action in all the *_action fields.

Use vh or vw as units but percent should work too (if not using aspect_ratio)

Don’t use absolute positioning, use the grid to achieve what you want to do. See here

So my idea was to change an action depending on the state for my alarm button. However upon further investigation I’ve gone with conditionals buttons instead.

Thanks.

Ha, I didn’t know that, thanks!
this is the verbose url of course, while I would love to use the view, to make things simpler and easier to read in the templates. Like we can do in Custom header as described on Custom Header
would it be an accepted FR to support some of these builtin variables on Button-card too?

ok thanks, will give it a go. should I use templates on each property individually, like below, or is there a smart way of doing so in short-hand:

hold_action:
  action: >
    [[[ if (window.loaction == 'path.to.home') return 'navigate';
        return 'call-service' ;]]]
  navigation_path: >
    [[[ if (window.loaction == 'path.to.home') return 'developer';
        return none ;]]]
  service: >
    [[[ if (window.loaction == 'path.to.home') return none;
        return 'automation.trigger'; ]]]
  service_data: >
    [[[ if (window.loaction == 'path.to.home') return none;
        return 'entity_id: entity' ;]]]

btw using this to test:

      - type: custom:button-card
        show_label: true
        name: >
          [[[return hass.user]]]
        label: >
          [[[return window.location]]]

returns:
Schermafbeelding 2020-05-08 om 10.34.36

meaning the window.location is displayed alright, but I cant see the user.
Tbh, I am struggling with what’s written at the bottom here button-card/README.md at master · custom-cards/button-card · GitHub on the variables available inside the JS code… How do I use that? I didn’t find any example or documentation about user (or has for that matter…) must be missing the obvious, but in all my button configs, I’ve simply never encountered the need/issue

No, it’s not, you didn’t read the link. You have access to the path also directly.

Yes, you can return a complete object for hold_action. Static example:

hold_action: |
 [[[
    let res = {
      action: "call-service",
      service: "whatever"
   };
   res.service_data = {};
   res.service_data.entity_id = entity.entity_id;
   return res;
 ]]] 

correct, sorry, didnt realize it was a link to the W3school…still, it doesn’t allow finding the view name only, or the Lovelace path, as defined in the view config:

title: Test
icon: mdi:test-tube
path: test
cards:

window.location.pathname coming closest, but still returning “/lovelace/test”
so

label: >
  [[[return window.location.pathname.split('lovelace/')[1] ]]]

is needed for
Schermafbeelding 2020-05-08 om 10.51.23

now how to find the user…

wow, that’s a first for me, have to study what’s done there, and how to use the templates in that.
let and ‘res’ being the great unknowns to me…back to w3schools I fear :wink:

using the template I need, could it be something like:

        hold_action: |
         [[[
             let res = (window.location.pathname.split('lovelace/')[1] == 'home'
             ? {
                 action: "navigate",
                 navigation_path: "developer"
                 }
             : {
                 action: "call_service",
                 service: "automation.trigger",
                 service_data.entity_id: "entity.entity_id"
               }
            return res;
            );
          ]]]

I tried a standard construction with if (window.location.pathname.split('lovelace/')[1] == 'home') but got stuck declaring the let that way.
Now I am stuck returning the res…with the double ‘return’ in the template

You have to convert it to a string :wink: Remember how I always tell you that you need to learn these damn languages so you can do things on your own?

String(window.location.pathname).split('lovelace/')[1]

Petro, he speak with forked tongue

:rofl: :joy: :rofl: :joy:

You are a bit harsh on me here, I am trying to do something I haven’t seen any example of yet…
and btw,

        label: >
          [[[let res = window.location.pathname.split('lovelace/')[1];
             return res ]]]

works just fine…

its the template for the hold action based on this value I cant get right

Lol, CSS is the ONLY exception! Although I’d have to admit that I’ve learned a lot about it in recent months.

That’s the thing here. You’ve been here a LONG time. One basic element of all langauges (doesn’t matter the language) is object typing. If you take a beginner course in ANY language, you learn about this in the first 3 tutorials. I’ve been harping on you for years to take something with the amount of developing that you do and it’s clear you still haven’t.

If you get Object object in js as your returned string, that means you have an OBJECT and not a STRING. I.E. you convert the object to a string with a simple google search “convert window.location.pathname to string”.

EDIT: And just to clarify, I didn’t know how to do this and simply googled that and showed you the first result that I found.

think there is some misunderstanding goin on… what did you think I was asking? because there’s no problem getting the path(name) to the button frontend.

right now, this is my quest: