Lovelace: Button card

You should add 1 button-card on each side:

- type: horizontal-stack
  cards:
    - type: custom:button-card
      color_type: blank-card
    - type: custom:button-card
      [ Your Button Config here ]
    - type: custom:button-card
      color_type: blank-card

Also better use : aspect_ratio: 1/1 if you want square buttons as they will adapt to the screen size :slight_smile:

For YAML mode you have to use a file, so you have to put button_card_templates: at the root of this file (same level as resources before 0.107)

1 Like

Thanks. I was just sitting to down to type that I had figured it out. The button_card_templates: just has to be placed in the particular dashboard’s YAML file.

Would I have to repeat this for each dashboard? I am already using !include so not a big deal.

Thanks for the tip on the additional cards either side. That seems to have worked.

So i changed my cards from width/height 150px to aspect_ratio: 1/1 but now they are small (maybe 75px). Is there a way to increase but keep the aspect ratio?

New user here. @RomRider, thanks for the impressive work!

I’m wondering if what one would really want to solve this and other related layout problems would be a new container entity (call it flexbox-stack or something like that) that placed its child entities inside a CSS flex box. The idea would be to

  • Expose the flex box container style properties via YAML configuration (something similar to what button-card is doing) with some sensible defaults.
  • Allow for arbitrary entities to be provisioned as children (something similar to what entities card does.

For example, paper-buttons-row comes close. It renders button children (using a paper-button web component) in a nice horizontal layout using flex box (without stretching the dimensions of the children), but isn’t flexible enough to allow for arbitrary child entities like entities card (or for that matter lovelace-layout-card).

I’d like to give this a try myself, but not being a frontend developer this is a heavy lift (I’m doing my research). Maybe someone else with frontend chops could provide some insight (hint, hint).

(FWIW, I’ve been looking at boilerplate-card for some wisdom but it currently won’t compile against the latest custom-card-helpers. That, and maybe its a bit too much to get started with. But that is probably a topic for a different thread.)

Again, thanks for the work @RomRider. Any wisdom you or others can shed is greatly appreciated.

ba

That won’t work for the custom button card because the layout/positioning is handled by the front end. The reason it works for the entity_row is because the front end doesn’t really do much with rows in regards to positioning.

EDIT: Unless you’re referring to placing objects in the button when you say layout. Then, you can already do this with the custom_fields and the recent html element handling addition in the latest build.

@petro - No, I am thinking about placing button-card (or other cards) as children in a flex box container. If that is limited to an entity row, so be it. If it can be generalized outside of an entities card, that would be better. I think my naivetĂ© on the UI architecture is showing here
what is rendered by the backend, what the “frontend” does with that. Thanks for the response.

everything in lovelace is done by the frontend, so nothing to think about there.

BTW, if you want to make a flex grid, just use horizontal and vertical stack cards in the entities card. That’s what I do. You can make all sorts of cards

image

that’s a entities card with 2 button cards, 3 bar cards and 1 sensor card using horizontal and vertical stacks.

No need to adjust this card to accomidate.

here’s the full config

  - type: 'custom:hui-entities-card'
    show_header_toggle: off
    style: |
      ha-card { border-radius: 20px; }
    entities:
      - type: section
        label: Synology DS216J
      - type: custom:hui-vertical-stack-card
        cards:
          - type: horizontal-stack
            cards:
              - type: picture
                style: |
                    ha-card { 
                      --paper-card-background-color: 'rgba(0, 0, 0, 0.0)';
                      --ha-card-background: "rgba(0, 0, 0, 0.0)";
                      --ha-card-box-shadow: 'none';
                    }
                image: /local/images/devices/synology_ds216j_2.png
              - type: 'custom:button-card'
                layout: icon_name_state2nd
                show_icon: true
                show_state: true
                size: 100%
                styles:
                  grid:
                    - grid-template-columns: 1fr 2fr
                  icon:
                    - padding: 0px 20px
                    - height: 30px
                    - width: 30px
                  card:
                    - --ha-card-background: "rgba(0, 0, 0, 0.0)"
                    - --ha-card-box-shadow: 'none'
                  state:
                    - padding: 0px 20px
                    - justify-self: start
                    - font-family: Roboto, sans-serif
                    - font-size: 15px
                  name:
                    - padding: 0px 20px
                    - justify-self: start
                    - color: var(--secondary-text-color)
                entity: sensor.synology_uptime
                name: Uptime
                icon: mdi:clock-outline
                  
          - type: custom:config-template-card
            variables:
              - states['sensor.synology_dsm_total_size_volume_1'].state
              - states['sensor.synology_dsm_used_space_volume_1'].state
            entities:
              - sensor.synology_dsm_total_size_volume_1
              - sensor.synology_dsm_used_space_volume_1
            card:
              type: custom:bar-card
              title_position: inside
              show_icon: true
              align: split
              columns: 1
              max: 100
              unit_of_measurement: "%"
              severity:
                - value: 50
                  color: "#3498db"
                - value: 75
                  color: "#f39c12"
                - value: 100
                  color: "#e45e65"
              style: |
                    ha-card { 
                      --paper-card-background-color: 'rgba(0, 0, 0, 0.0)';
                      --ha-card-background: "rgba(0, 0, 0, 0.0)";
                      --ha-card-box-shadow: 'none';
                    }
              entity: sensor.synology_dsm_volume_used_volume_1
              title: "${ 'Disk (' + vars[1] + '/' + vars[0] + ')' }"
          - type: horizontal-stack
            cards:
              - type: custom:bar-card
                title_position: inside
                show_icon: true
                align: split
                columns: 1
                max: 100
                unit_of_measurement: "%"
                severity:
                  - value: 50
                    color: "#3498db"
                  - value: 75
                    color: "#f39c12"
                  - value: 100
                    color: "#e45e65"
                style: |
                    ha-card { 
                      --paper-card-background-color: 'rgba(0, 0, 0, 0.0)';
                      --ha-card-background: "rgba(0, 0, 0, 0.0)";
                      --ha-card-box-shadow: 'none';
                    }
                entity: sensor.synology_dsm_memory_usage_real
                title: RAM
              - type: custom:bar-card
                title_position: inside
                show_icon: true
                align: split
                columns: 1
                max: 100
                unit_of_measurement: "%"
                severity:
                  - value: 50
                    color: "#3498db"
                  - value: 75
                    color: "#f39c12"
                  - value: 100
                    color: "#e45e65"
                style: |
                    ha-card { 
                      --paper-card-background-color: 'rgba(0, 0, 0, 0.0)';
                      --ha-card-background: "rgba(0, 0, 0, 0.0)";
                      --ha-card-box-shadow: 'none';
                    }
                entity: sensor.synology_dsm_cpu_load_total
                title: CPU
          - type: custom:mini-graph-card
            height: 20
            line_width: 2
            font_size: 70
            hours_to_show: 168
            points_per_hour: 1
            show:
              extrema: true
              fill: true
            style: |
              ha-card { 
                --ha-card-background: "rgba(0, 0, 0, 0.0)";
                --ha-card-box-shadow: 'none';
                border-radius: 5px;
              }
            entities: 
              - sensor.synology_dsm_temperature_sda
              - sensor.synology_dsm_temperature_sdb
            name: Temperature
            color_thresholds:
              - value: 90
                color: "#3498db"
              - value: 95
                color: "#f39c12"
              - value: 100
                color: "#E45E65"
5 Likes

Thanks! I’ll have a look!

Hi Alan,

I really like the idea of using the template for the buttons. However, I can’t figure it out where to place the template code. Can you help out, pls?

Well, it depends. I have the default one in UI mode and a second one in YAML mode and I had to copy UI’s templates to the second dashboard’s config file for my moved config to work so in this case the answer is yes.
However, if you have several yaml dashboards, I presume that they all share one lovelace_ui.yaml and it’s enough to add your templates to it just once and it’ll be accessible to all yaml dashboards. Cannot check it though.

The different yaml dashboards do not share the same file. If you want to use the same templates in all your dashboards, use in all your dashboards:

button_card_templates:
  !include path_to/file_with_templates.yaml

maybe I was a bit vague. I meant that if you include button_card_templates in lovelace_ui.yaml, it’ll be available to all your yaml dashboards, but if you include it anywhere lower, it won’t - is that better? :wink:

Hi All,
I recently started using this card and it’s amazing, thanks again @RomRider for creating and keeping it well maintained.
I have the following question/thoughts:

  1. It looks like currently in a card we can use only one template in template: my_template and it limits the card’s flexibility when it is based on another card - could we have a list here?
    The template feature is a great way of creating “building blocks”, but with this limitation it’s a bit painful (or even impossible using template feature only) to create a card that incorporates several non-related cards’ configs (multiple inheritance if you like :wink: ). An easy example: I have a template with global color variables and another one with size variables. I built a hierarchy of cards like base_row -> tweaked_row -> more_tweaked_row -> 
 using template. Then in say, tweaked_row I want to use colours but template is already used for base_row. Currently I do it using anchors/node references - much less readable.
    tl/dr I believe that it’d be great for template to support a list of templates, shouldn’t be too difficult to add.
  2. Variables do not allow anything more than just storing data so they are simply containers. I mean, nothing like templating or things like:
variables:
  a: 'text'
  b: 'another'
  c: a + b

I presume it’s possible to do what I want using custom_field to perform all operations on variables and returning the resulting “compound value” to use in templates later? Or is there a better way?

  1. If in style I terminate a string with ; (as we do in CSS) it seems to make that string (or even the whole section) invalid, it doesn’t work. Something like
styles:
    card:
      - margin-left: 45;

It’s a small niggle but it would be great to allow ; at the end of such strings (by just dropping it).
4. Loosely related to p.3

styles:
    card:
      - margin-left: 45 !important

does not work with or without quotes around the value. If I remove !important, it does - I suspect that most likely I don’t need that bit with this way of styling, is that correct?

Again, thanks the author for the great card and the community for driving it/sharing experience.

@AhmadK, better use github to request features so I can track them :slight_smile:

@Mariusthvdb already asked this, I can see your point. I’ll add this in the next version.

You can use templates in variables. But I don’t see your point about custom fields?

I can drop it but that just requires more compute time :blush:

The style is applied to the element itself, it shouldn’t be required to use !important

1 Like

I surely will, just didn’t want to ask for something that’s already there :wink:

Regarding lists in template - thanks for your understanding. Hope it will accept string or list :wink:

I tried to achieve that c = a+b using templates and it didn’t work as I accessed variable.a and variable.c:

type: custom:button-card
      variables:
        a: 'a'
        b: 'b'
        c: >
          [[[ return variables.a + variables.b ]]]
      name: >
        [[[ return variables.c ]]]

gives me “TypeError: Cannot read property ‘state’ of undefined”.
Forger about custom fields, looks like I cannot use them for this task as they are not accessible as variables.

well, it was just an observation. if it negatively impacts the card’s performance, don’t bother :wink:

that’s why I said “suspect”. I’m not a web designer and many things are new to me :wink:

A yes, that would be really cool, and make it simpler compared to use consecutive templates in the other templates. Thank for this @romrider , much anticipated, and, appreciated!

I’m using a decluttering card and have a problem where the coloring of some custom_fields doesn’t come out right (and I acknowledge this problem may be due to the decluttering card, not the button card)

The card looks like this. I’ve included the relevant section of the decluttering card template below.

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

  - template: info
    type: 'custom:decluttering-card'
    variables:
      - sensor3: sensor.cat_days_since_depooped
      - color_1: '#BDC1C6'
      - color_2: tomato
      - color_3: red
      - colval31: '7'
      - colval32: '40'

For this card, the coloring is all bonkers. What I want to happen (and I think should happen) based on the numerical state value is as follows:

0-6: gray (#BDC1C6)
7-39: tomato
40+: red

But just playing around the the states developer tool to manually set values what I ACTUALLY get doesn’t make sense to me:

0-1: gray
2-4: tomato
5-9: red
10-18: gray
19- 39: tomato
40+: red

The strangest thing is I based the variable config above off of another card that essentially does the same thing, without any problems at all:

        custom_fields:
          stat1:
            - '--text-color-sensor': |
                [[[ 
                  if (states["[[stat1_ent]]"].state < 20) return "lightblue"; 
                  if (states["[[stat1_ent]]"].state >= 20 && states["[[stat1_ent]]"].state < 28) return "mediumaquamarine"; 
                  else return "tomato";
                ]]]                    
            - '--text-color-sensor': |
                [[[ 
                  if (states["[[stat1_ent]]"].state < 20) return "lightblue"; 
                  if (states["[[stat1_ent]]"].state >= 20 && states["[[stat1_ent]]"].state < 28) return "mediumaquamarine"; 
                  else return "tomato";
                ]]]   

For this other card, the colors work exactly as they should:
0-19: lightblue
20-27: mediumaquamarine
28+: tomato

Any ideas
?

Should be numbers, not strings so this should work (I removed the quotes in the variables and in the template):

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

  - template: info
    type: 'custom:decluttering-card'
    variables:
      - sensor3: sensor.cat_days_since_depooped
      - color_1: '#BDC1C6'
      - color_2: tomato
      - color_3: red
      - colval31: 7
      - colval32: 40

Thanks for your reply. I actually added the quotes as part of my troubleshooting; I’ve removed them again.

So I think I made all the changes you suggested (removed single quotes in number values for colval31: and colval32: in the decluttering card, as well as the corresponding quotes in the config.).

It’s definitely better (thanks!), but unfortunately the colors are still a bit wrong, just in a slightly less bonkers way. The color changes from gray to tomato when the value increases to 18 (should be 7).

0-18: gray
19-39: tomato
40+: red.

The revised config looks like:

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

  - template: info
    type: 'custom:decluttering-card'
    variables:
      - sensor3: sensor.cat_days_since_depooped
      - color_1: '#BDC1C6'
      - color_2: tomato
      - color_3: red
      - colval31: 7
      - colval32: 40

Your sensor is probably not a number so maybe try something like this for your state:
Number(states["[[sensor3]]"].state)
Make sure there is no hidden space, or random characters in your state also.