Lovelace: Button card

Hm, I don’t think that’s it unless I’m really not understanding something. The sensor state is an integer value, unit_of_measurement is days. There are no hidden spaces or characters.

I tried using Number(states.sensor.state) as you suggested, both capitalized and uncapitalized, and the card failed to display.

Retroactive Edit 2 placed in front of Edit1: I didn’t understand how to use Number(sensor.state) at first but you were absolutely right - that got it working. THANK YOU.

I don’t understand why my sensor is not recognized as a number though. Is it because unit_of_measurement: is set to days? Even if the unit is days it should still be recognized as an integer… And I don’t want to change the unit of measurement because otherwise HA won’t properly group these day measurements together in history:

      cat_days_since_depooped:
        entity_id:
          - input_datetime.cat_poop
          - sensor.time
        value_template: >
          {% set time = as_timestamp(now()) - as_timestamp(states('input_datetime.cat_poop')) %}
            {{ (time / 86400) | int }}
        unit_of_measurement: "days"

For anyone else who is as confused as I was/am, the proper way to format this is as follows:

            - '--text-color-sensor': |
                [[[ 
                  if (Number(states["[[sensor3]]"].state) < [[colval31]]) return "[[color_1]]"; 
                  if (Number(states["[[sensor3]]"].state) >= [[colval31]] && Number(states["[[sensor3]]"].state) < [[colval32]]) return "[[color_2]]"; 
                  else return "[[color_3]]";
                ]]]

Edit: How can I support you? You’ve helped me and so many people in this thread–and very quickly, i might add. I’m usually able to find donation links for all the great devs in this community but can’t find one for you!

Sorry. I completely missed that option when scanning the github page last night. Thanks

by who if I may ask? the thing is all states of all entities are strings (check out state.state description). that’s probably why HA needs additional hints like unit_of_measurement to handle them correctly (as integers in case of days).
so in your case after declutterer’s substitutions you have JS expression like if (str < number) return str;
obviously it won’t work at all or as you expected.
so basically it boils down to understanding how HA state objects work.
it’s not obvious but hope you get it now :wink:

button card 3.2.1


after upgrade to 3.2.2 or 3.2.3 dont show any button

my button config:

decluttering_templates:
button_1:
default:
- hold_action:
action: none
- tap_action:
action: toggle
- double_tap_action:
action: none
- show_name: true
- spin_1: false
- aspect_ratio: 1/1
card:
type: “custom:button-card”
aspect_ratio: ‘[[aspect_ratio]]’
entity: ‘[[entity_1]]’
tap_action: ‘[[tap_action]]’
double_tap_action: ‘[[double_tap_action]]’
hold_action: ‘[[hold_action]]’
color: rgb(249, 212, 0)
show_state: true
show_icon: true
show_label: true
size: 30%
state:
- value: ‘on’
icon: ‘mdi:[[icon_1]]’
name: ‘[[name_1]]’
spin: ‘[[spin_1]]’
styles:
card:
- background-color: rgba(255,255,255,0.85)
name:
- color: rgba(0, 0, 0, 1)
- font-weight: bold
state:
- color: rgba(0, 0, 0, 1)
- value: ‘off’
icon: ‘mdi:[[icon_2]]’
color: rgb(120, 120, 120)
name: ‘[[name_2]]’
styles:
card:
- background-color: rgba(255,255,255,0.5)
name:
- color: rgb(120, 120, 120)
state:
- color: rgb(120, 120, 120)
icon:
- color: rgb(120, 120, 120)
styles:
card:
- width: 95%
- height: 95%
- border-radius: 10px
- font-size: 110%
grid:
- grid-template-areas: ‘“i” “n” “s”’
- grid-template-columns: 1fr
- grid-template-rows: 1fr min-content min-content
img_cell:
- align-self: start
- text-align: start
name:
- justify-self: start
- padding: 0% 0% 0% 10%
- font-weight: bold
state:
- justify-self: start
- padding: 0% 0% 5% 10%
- text-transform: lowercase
icon:
- padding: 0% 50% 15% 0%

    • List item

Please format your code using ``` ```, I can’t do anything with that.
Also if it’s not already the case, update to the latest version of decluttering-card and clear your cache.

1 Like

Guys, I’ve just created a topic that is related to this card (but it’s a bit wider so I decided to post it separately) about ways to make this card look similar to standard Lovelace cards - please have a look, maybe somebody can help me.

Hi Petro,

I was searching for a way to let the button card “glow”, and this is indeed the solution!

However, when I saw this post, I also noticed the “titles” above the button cards to indicate the room.
Can I ask which card/style that you are using to accomplish this?

I’m creating a harmony hub remote and I’m using the button-card. I had a card for a power button that would show red if the hub was on and clicking on it would send a service call to turn it off. That was all working fine, so I moved the card config to a button-card template. That works, except the state color is not working when it’s a template. I’ve tried overriding the state dictionary in the definition of the card, but it still doesn’t work. I can work around it in other ways, but I’d like to know why this isn’t working. The other functionality is working just like it used to. It still turns off the unit when pressed. Note, I didn’t have the id: in the states before, but tried that when I was trying to override the color.

First, here is the template:

button_card_templates:
  power_button:
    variables:
      var_name: "Power Off"
      var_hub: 'remote.harmony_hub'
    name: '[[[ return variables.var_name ]]]'
    entity: '[[[ return variables.var_hub ]]]'
    color_type: icon
    icon: 'mdi:power'
    layout: icon_name
    state:
      - value: 'on'
        color: 'rgb(249,66,55)'
        id: 1oKHxppjzUCI6hJk/Wa0gQ
      - value: 'off'
        color: 'rgb(239,239,239)'
        id: Dyy0OrYn8EqjmHBJlqpWxQ
    tap_action:
      action: >
        [[[
          return (states[variables.var_hub].state === "off" ? 'none' : 'call-service');
        ]]]
      service: remote.turn_off
      service_data:
        entity_id: '[[[ return variables.var_hub ]]]'
    hold_action:
      action: none
    double_tap_action:
      action: none
    styles:
      grid:
        - grid-template-areas: "i n"
        - grid-template-columns: 1fr 1fr
        - grid-template-rows: min-content

And here is what I’m defining in my lovelace card:

            - type: 'custom:button-card'
              template: power_button
              state:
                - color: 'rgb(249,66,55)'
                  id: 1oKHxppjzUCI6hJk/Wa0gQ
                - color: 'rgb(239,239,239)'
                  id: Dyy0OrYn8EqjmHBJlqpWxQ

In my first attempt, I had no state: section, but added it in an attempt to get it working. I’ve cleared the cache and refreshed the page as well as restarting HA. If I force the color using a styles: section, that works in real time.

fuond problem: in 3.2.2 and 3.2.3 widht and height dont work anymore

issues → Github? :wink:

and it didn’t help, did it?
could you remove quotes around your rgb()?
and have you tried state → value → styles → icon → color, like this

state:
  - value: 'on'
    styles:
      icon:
        - color: rgb(249,66,55)

Width and height still work, but not when you use aspect_ratio: 1/1 :slight_smile:

2 Likes

@AhmadK that did not work. I put this in my template:

    name: '[[[ return variables.var_name ]]]'
    state:
      - value: 'on'
        styles:
          icon:
            - color: 'rgb(249,66,55)'
      - value: 'off'
        styles:
          icon:
            - color: 'rgb(239,239,239)'

Note: I did remove the quotes around the rgb lines, but the raw config editor in lovelace puts them back in. I believe I saw in some docs somewhere that rgb values do need quotes and all the examples in the button-card project use the single quotes around those. I should point out I’m doing this without my own lovelace.yaml and I’m only using the UI to create and edit this stuff.

However, the following does work. I removed the state: block from the template entirely and added the color change to the styles: block. So as I said, there is a way to work around it, but I’m very curious why the state didn’t seem to work in any variation. I’m running HA 0.107.7 and button-card 3.2.3.

    styles:
      grid:
        - grid-template-areas: "i n"
        - grid-template-columns: 1fr 1fr
        - grid-template-rows: min-content
      icon:
        - color: '[[[ return (states[variables.var_hub].state === "on" ? "rgb(249,66,55)" : "rgb(239,239,239)"); ]]]'

the entity field doesn’t support templates that’s why the state object is not doing anything because there is no entity recognized in your button.
replace it with: entity: remote.harmony_hub
and it will work.

Now that you have defined properly the entity, you can do this for your tap action for example:

    tap_action:
      action: >
        [[[
          return (entity.state === "off" ? 'none' : 'call-service');
        ]]]

entity in templates maps to the button’s declared entity object, so no need for variables to handle that :slight_smile:

2 Likes

That’s a markdown card with card mod removing the shadow and background.

@RomRider removing the entity id from the template and defining it solved my color issue. Thanks. So that was the power button on the remote and it works fine now. I’ve moved on to the activity buttons and I’m experiencing something weird there.

Here’s how it works. There are buttons for Watch TV, Watch Mi Box, and Watch OTA. The current activity has a blue color. Pressing another activity switches to that activity and the new button turns blue. This all worked fine, but of course the button code was mostly identical, so I wanted to move them to templates. The weird part is that if I make 2 of the buttons use the template, everything still works fine, but if I then make the third button use the template, it will switch activities, but the buttons don’t get updated unless I refresh the page.

For example:
I’m currently using the “Watch TV” activity. I press the “Watch OTA” button. The TV and components switch properly so the service was called, but the “Watch TV” button is still blue and pressing “Watch TV” does nothing. In the code for the card, I make it so the service won’t be called if you press the current activity. It seems to think the current activity is still “Watch TV”. I refresh the page and the “Watch OTA” button is now blue and I can switch back to watching TV.

Again, this only happens if all three buttons are using the button template. If any of them still have all the config in the card itself, all the buttons work like they should.

Here’s the button template:

  activity_button:
    variables:
      var_name: "Activity Name"
      var_activity: Activity
    entity: remote.harmony_hub
    name: '[[[ return variables.var_name; ]]]'
    color_type: icon
    icon: 'mdi:remote'
    state:
      - value: 'on'
        styles:
          icon:
            - color: '[[[ return (entity.attributes.current_activity === variables.var_activity ? "rgb(59,66,249)" : "rgb(239,239,239)"); ]]]'
      - value: 'off'
        styles:
          icon:
            - color: 'rgb(239,239,239)'
    tap_action:
      action: >
        [[[
          return (entity.attributes.current_activity === variables.var_activity ? 'none' : 'call-service' );
        ]]]
      service: remote.turn_on
      service_data:
        entity_id: '[[[ return entity.entity_id; ]]]'
        activity: '[[[ return variables.var_activity; ]]]'
    hold_action:
      action: none
    double_tap_action:
      action: none

And here is what is in the card config for this row of buttons:

        - cards:
            - type: 'custom:button-card'
              template: activity_button
              variables:
                var_name: Watch TV
                var_activity: Watch TV
              entity: remote.harmony_hub
            - type: 'custom:button-card'
              template: activity_button
              variables:
                var_name: Watch Mi Box
                var_activity: Watch Mi Box
              entity: remote.harmony_hub
            - type: 'custom:button-card'
              template: activity_button
              variables:
                var_name: Watch OTA
                var_activity: Watch OTA
              entity: remote.harmony_hub

There’s no difference on how the button works with and without templates.
However, there’s a delay for the current_activity attribute to update with Harmony Hub (at least 5-10seconds). Did you wait that long?

@RomRider Yes, I waited but it never updated. When it’s working, it only takes a couple seconds to update. Another odd thing is that as long as I have the lovelace card in the UI editor, the buttons work correctly as well but as soon as I click “Save” and return to the page, I get the bad behavior I described

To try and debug further, I moved the color change to a “styles:” block instead of trying to associate it with state. Since the state of the hub doesn’t really change when the activity changes, I thought maybe it just wasn’t picking up the change. I also added some logging to the console. This is what my style block looks like (after the raw ui editor gets done with it):

    styles:
      icon:
        - color: >-
            [[[ console.log(entity); return (entity.attributes.current_activity
            === variables.var_activity ? "rgb(59,66,249)" : "rgb(239,239,239)");
            ]]]

That’s in the activity_button template. What I see is that when I refresh the page, I see 9 dumps of the object (I have 3 activity buttons). Then I see no more updates if I just sit there for awhile. I then press another activity button and the TV switches, but I see no additional output in the console and I see no update in the UI. If I have the card opened in the UI editor and I click another activity button, I see 3 more outputs to the console and everything works.

If I put one of the activity buttons back to having all the config in the card, then I also see the console updating when I change activities even if I’m not choosing the button that has the full code in the card.

So, here is my current activity template:

  activity_button:
    variables:
      var_name: Activity Name
      var_activity: Activity
    entity: remote.harmony_hub
    name: '[[[ return variables.var_name; ]]]'
    color_type: icon
    icon: 'mdi:remote'
    styles:
      icon:
        - color: >-
            [[[ console.log(entity); return (entity.attributes.current_activity
            === variables.var_activity ? "rgb(59,66,249)" : "rgb(239,239,239)");
            ]]]
    tap_action:
      action: |
        [[[
          return (entity.attributes.current_activity === variables.var_activity ? 'none' : 'call-service' );
        ]]]
      service: remote.turn_on
      service_data:
        entity_id: '[[[ return entity.entity_id; ]]]'
        activity: '[[[ return variables.var_activity; ]]]'
    hold_action:
      action: none
    double_tap_action:
      action: none

And this is the code in the card definition:

        - cards:
            - type: 'custom:button-card'
              template: activity_button
              variables:
                var_name: Watch TV
                var_activity: Watch TV
              entity: remote.harmony_hub
            - type: 'custom:button-card'
              entity: remote.harmony_hub
              name: Watch Mi Box
              state: null
              styles:
                icon:
                  - color: |-
                      [[[
                        if (states['remote.harmony_hub'].attributes.current_activity === "Watch Mi Box")
                          return 'rgb(59,66,249)';
                        else
                          return 'rgb(239,239,239)';
                      ]]]
              tap_action:
                action: |
                  [[[
                    var is_on = (states['remote.harmony_hub'].attributes.current_activity === 'Watch Mi Box');
                    return (is_on ? 'none' : 'call-service' );
                  ]]]
                service: remote.turn_on
                service_data:
                  entity_id: remote.harmony_hub
                  activity: Watch Mi Box
              hold_action:
                action: none
              double_tap_action:
                action: none
            - type: 'custom:button-card'
              template: activity_button
              variables:
                var_name: Watch OTA
                var_activity: Watch OTA
              entity: remote.harmony_hub

One difference between the card definition and the template is that for some reason, I find the entity object is never defined within the card configuration, so I have to use the states object to determine the current activity. That was going to be a separate question after I sorted all this out.

At this point I’m pretty baffled. I don’t understand why having just one button defined directly in the card makes everything work perfectly. I see no exceptions or errors in the console. Next I think I’ll try removing the variables from the template. Since I’m only using 2, I think I can easily override those values in the card without using variables.

Ok, I have a thought on this. I’m wondering if it has something to do with when certain javascript templates are evaluated. I’m guessing that what happens when using these config templates is something like this:

  • Upon loading of the lovelace card (button-card), the config template is read into memory.
  • variables are merged
  • states are merged
  • ??? javascript templates within the config template are evaluated and the results substituted
  • card is rendered

I’m wondering about the 4th step above. Let’s look at an example, shall we? :slight_smile:

If in my config template like activity_button, I have the following code in the tap_action block:

    tap_action:
      action: >
        [[[
          return (entity.attributes.current_activity === variables.var_activity ? 'none' : 'call-service' );
        ]]]
      service: remote.turn_on
      service_data:
        entity_id: '[[[ return entity.entity_id; ]]]'
        activity: '[[[ return variables.var_activity; ]]]'

I’ve been assuming that those javascript templates get carried over as-is to the final version of the card source so they remain dynamic. But now I’m wondering if those actually get evaluated and substituted so that after loading the template, what’s left is:

    tap_action:
      action: none
      service: remote.turn_on
      service_data:
        entity_id: 'remote.harmony_hub'
        activity: 'Watch TV'

So, if “Watch TV” was the current activity when I reloaded the page, I can click on another activity button and the service for that button gets called but my Watch TV button stays blue since the color was hard coded by the already evaluated javascript code. Trying to go back to “Watch TV” would result in nothing happening because as we can see the service action is set to “none” and doesn’t change dynamically anymore.

So, if I’m correct, that would mean any javascript templating that I need to remain dynamic needs to be in the actual card config and not the config template. Does any of that sound reasonable?

How can I define the color of both the icon and the button? It seems it’s either one or the other. The first post in this thread shows a gray button with pink icon, so it looks possible, but I just can’t seen to get there. I need a gray button with a red icon.