Lovelace: Button card

I guess what I was hoping for was something that I would not have to hard code since I use several different devices at different resolutions

All my cards are in a vertical stack. On my 1080p monitor, my 5 button row calculates as 40.89px high. A 3 button row calculates as 70.703px high. If I want all my buttons the same height it can cause things to look disproportionate depending on the devices resolution or if my other button’s are not hard coded.

It would be real nice if width could be specified as a percentage of the row. 2 buttons @ 25% and 1 at 50% for instance. I would imagine that would roughly be the same height as a 4button row, but honestly all this flexbox stuff is new / foreign to me.

Please share the code ?

Follow his reply and you’ll see my example

1 Like

You might want to some of the try other units instead of px maybe: https://www.w3schools.com/cssref/css_units.asp

Here buttons config, it was updated since last post:

6 Likes

For the ones interested, I use this button-card for Homekit style buttons. I have created a dark version as well now just a bit like how ios 13 would handle Homekit:

Find the code here: GitHub - jimz011/homekit-infused: Homekit Infused 5 2023

Hopefully someone can help me with the states functionality.

I have a button that i want to change the MDI Icon as I scroll through the list of “Input_select” options, However the issue i am seeing is that as the button is pressed and the value of the input_select changes, the icon on the button remains the same (I believe, it should change as the value changes with the way i have it configured).

Below is my code, any ideas what i am doing wrong?

      - type: "custom:button-card"
        entity: input_select.game_style
        name: Game
        icon: mdi:numeric-1-box
        color: rgb(30,144,255)
        tap_action:
          action: call-service
          service: input_select.select_next
          service_data:
            entity_id: input_select.game_style
          show_state: true
          state:
            - value: "Game1"
              color: rgb(30,144,255)
              icon: mdi:numeric-1-box
            - value: "Game2"
              color: rgb(30,144,255)
              icon: mdi:numeric-2-box
            - value: "Game3"
              color: rgb(30,144,255)
              icon: mdi:numeric-3-box  
        aspect_ratio: 1.9/1 

The Game1, Game2, Game3 match up exactly to what I have configured in the input_select.yaml and what shows up in the history as I track the states changing.

state is indented too far

That did it… .knew it was something small.

Thanks!!!

:warning: :warning: Read the breaking changes!! :warning: :warning:

Major stuff incoming :slight_smile:

:tada::tada: Version 2.0.0 :tada::tada:

BREAKING CHANGES

  • All the *_template are now deprecated :fearful: but they are replaced with a better way of handling templates. :tada:
    This applies to:

    • name
    • label
    • entity_picture
    • value in the state object when operator: template

    Old style:

    name_template: >
      if (entity.state === 'off') return 'Template is off';
      return 'Template is on';
    

    Becomes for example:

    name: >
      [[[
        if (entity.state === 'off') return 'Template is off';
        return 'Template is on';
      ]]]
    

    Without templating, no change:

    name: This is not a template
    

NEW FEATURES

  • All the states values support templating, it’s optional of course:
    entity: sensor.first_sensor
    state:
      - operator: '<'
        value: '[[[ states["sensor.other_sensor"].state ]]]'
    
  • icon supports templating (use the new templating format [[[ template ]]])
    - type: custom:button-card
      icon: >
        [[[
          if (entity.state === 'on')
            return "mdi:fire";
          return "mdi:lightbulb";
        ]]]
      entity: switch.skylight
    
  • Every styles entry now also supports templating, or plan text of course:
    styles:
      card:
        - background-color: >
            [[[ if (states['input_number.test'].state == 0) return "green"; return "red"; ]]]
    
  • Every field in *_action support templating, or plain text of course, including service_data (fixes #187):
    tap_action:
      action: call-service
      service: >
        [[[
          if (states['input_number.test'].state <= 20)
            return "input_number.increment";
          return "input_number.decrement";
        ]]]
      service_data:
        entity_id: input_number.test
    
  • Custom fields support for your button through the new custom_fields object. This will enable you to define your own fields in the button and apply styles to them without writing hundreds of line of javascript. This is an advanced feature, you’ll have to understand how CSS (and CSS grids) work! You’ll have more control on how to position those fields in the button compared to previously where you only had more or less 2 fields to play with (name and label).
    Your custom field content can be plain text or a template [[[ ]]]
    Your custom element can be styled also using styles.custom_fields.<ELEMENT_NAME>. See below for examples:
    • Placing an element wherever you want (that means bypassing the grid). Set the grid to position: relative and set the element to position: absolute
      Jul-21-2019 16-34-46

        - 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) ]]]
      
    • Or you can use the grid. Each element will have its name positioned as the grid-area (Thanks @iantrich @lbdab and @jimz011 for the inspiration):
      imageimage

        - type: custom:button-card
          entity: 'sensor.raspi_temp'
          icon: 'mdi:raspberry-pi'
          aspect_ratio: 1/1
          name: HassOS
          styles:
            card:
              - background-color: '#000044'
              - border-radius: 10%
              - padding: 10%
              - color: ivory
              - font-size: 10px
              - text-shadow: 0px 0px 5px black
              - text-transform: capitalize
            grid:
              - grid-template-areas: '"i temp" "n n" "cpu cpu" "ram ram" "sd sd"'
              - grid-template-columns: 1fr 1fr
              - grid-template-rows: 1fr min-content min-content min-content min-content
            name:
              - font-weight: bold
              - font-size: 13px
              - color: white
              - align-self: middle
              - justify-self: start
              - padding-bottom: 4px
            img_cell:
              - justify-content: start
              - align-items: start
              - margin: none
            icon:
              - color: >
                  [[[
                    if (entity.state < 60) return 'lime';
                    if (entity.state >= 60 && entity.state < 80) return 'orange';
                    else return 'red';
                  ]]]
              - width: 70%
              - margin-top: -10%
            custom_fields:
              temp:
                - align-self: start
                - justify-self: end
              cpu:
                - padding-bottom: 2px
                - align-self: middle
                - justify-self: start
                - --text-color-sensor: '[[[ if (states["sensor.raspi_cpu"].state > 80) return "red"; ]]]'
              ram:
                - padding-bottom: 2px
                - align-self: middle
                - justify-self: start
                - --text-color-sensor: '[[[ if (states["sensor.raspi_ram"].state > 80) return "red"; ]]]'
              sd:
                - align-self: middle
                - justify-self: start
                - --text-color-sensor: '[[[ if (states["sensor.raspi_sd"].state > 80) return "red"; ]]]'
          custom_fields:
            temp: >
              [[[
                return `<ha-icon
                  icon="mdi:thermometer"
                  style="width: 12px; height: 12px; color: yellow;">
                  </ha-icon><span>${entity.state}°C</span>`
              ]]]
            cpu: >
              [[[
                return `<ha-icon
                  icon="mdi:server"
                  style="width: 12px; height: 12px; color: deepskyblue;">
                  </ha-icon><span>CPU: <span style="color: var(--text-color-sensor);">${states['sensor.raspi_cpu'].state}%</span></span>`
              ]]]
            ram: >
              [[[
                return `<ha-icon
                  icon="mdi:memory"
                  style="width: 12px; height: 12px; color: deepskyblue;">
                  </ha-icon><span>RAM: <span style="color: var(--text-color-sensor);">${states['sensor.raspi_ram'].state}%</span></span>`
              ]]]
            sd: >
              [[[
                return `<ha-icon
                  icon="mdi:harddisk"
                  style="width: 12px; height: 12px; color: deepskyblue;">
                  </ha-icon><span>SD: <span style="color: var(--text-color-sensor);">${states['sensor.raspi_sd'].state}%</span></span>`
              ]]]
      

BUGFIXES

  • Fixes #200: Using button-card inside an entities card will not fire more-info anymore automatically.
11 Likes

For those who downloaded between the time of the 2.0.0 post and now, please re-download the file. I messed up the release on github, sorry :blush:

How would I go about converting these to the new format? I only have to change value?

                - type: custom:button-card
                  entity: media_player.main_zone
                  name: RetroPi
                  icon: mdi:gamepad-variant
                  color_type: icon
                  color: "var(--primary-text-color)"
                  tap_action:
                    action: call-service
                    service: media_player.select_source
                    service_data:
                      entity_id:  media_player.main_zone
                      source: RetroPi
                  state:
                    - operator: template
                      value: 
                        return states['media_player.main_zone'].attributes.source === 'RetroPi'
                      color: "var(--primary-color)"            
                - type: custom:button-card
                  entity: media_player.main_zone
                  name: HTPC
                  icon: mdi:server
                  color_type: icon
                  color: "var(--primary-text-color)"
                  tap_action:
                    action: call-service
                    service: media_player.select_source
                    service_data:
                      entity_id:  media_player.main_zone
                      source: Blackbox
                  state:
                    - operator: template
                      value: 
                        return states['media_player.main_zone'].attributes.source === 'Blackbox'
                      color: "var(--primary-color)"

state:
  - operator: template
    value: 
      return states['media_player.main_zone'].attributes.source === 'RetroPi'

Becomes:

state:
  - operator: template
    value: >
      [[[ return states['media_player.main_zone'].attributes.source === 'RetroPi' ]]]

Should this work?

label_template: >
  [[[ return 'PN (' + states['sensor.pn_count'].state + ')' ]]]

It shows nothing.

But as always: Thanks for the new features!
Looks like there will be a weekend with buttons. :slightly_smiling_face:

Did you read the breaking changes? :slight_smile:
label_template doesn’t exist anymore, it’s label only now and works with templates ([[[ ]]]) or without templates

label: >
  [[[ return 'PN (' + states['sensor.pn_count'].state + ')' ]]]

No! Sorry! :man_facepalming:
Works now.

1 Like

Reading is for nerds

8 Likes

This is just ridiculous :sunglasses:
This one card is almost an entire UI in itself.

Brilliant work…

7 Likes

you just screwed my life:cold_sweat::cold_sweat:

someone can help me to fix,this examples:

                  - <<: *custom_button_cerradura
                    entity: switch.cerradura
                    name: Cerradura
                    label_template: >
                      return ' '
                      + (states['switch.cerradura'].state === 'on'
                          ? '<span style="color: #FF0000;">Abierta</span>'
                          : '<span style="color: #00FF00;">Cerrada</span>')

and

          - <<: *custom_button_tracker
            entity: device_tracker.life360_jorge
            entity_picture: /local/jorge.png
            label_template: >
              return states['device_tracker.life360_jorge'].attributes.battery + '% de bateria'  

please someone can help,thanks a lot