Fun with custom:button-card

why do you keep posting in this thread, while there is a huge thread with so many more people to help and get inspiration from? Not saying you shouldn’t, it just that the other thread has all the examples you would need to get you all going.

I know I am doing some basic wrong. I have put this into my raw configuration but am getting this error:

Button-card template 'container' is missing!

This is the config. I am fairly new to dashboards with HA so I am quite certain it is probably something in the wrong place sort of thing. Any help would be appreciated. Of course I truncated the config to just enough to show the error.

Thanks!

title: Home
template:
  button_card_templates:
    container:
      color_type: label-card
      color: dimgray
      styles:
        card:
          - padding: 0
        name:
          - border-radius: 0.4em 0.4em 0 0
          - padding: 0.1em
          - width: 100%
          - font-weight: bold
        grid:
          - grid-template-areas: '"i" "n" "buttons"'
          - grid-template-columns: 1fr
          - grid-template-rows: 1fr min-content min-content
        custom_fields:
          buttons:
            - background-color: 'rgba(0,0,0,0.3)'
            - margin: 0
            - padding: 0.3em
views:
  - path: default_view
    title: Home
    cards:
      - type: 'custom:button-card'
        template: container
        color: '#EDE7B0'
        name: Eating & Patio
        custom_fields:
          buttons:
            card:
              type: horizontal-stack
              cards:
                - entity: switch.ge_14291_in_wall_smart_switch_switch_2
                  name: Kitchen
                  template: standard
                  icon: 'mdi:wall-sconce-flat'
                  type: 'custom:button-card'

Do you have the first section that begins with “button card templates:”? It’s something like this and is at the very beginning of your Lovelace raw config.

button_card_templates:
  standard:
    color_type: card
    size: 80%
    hold_action:
      action: more-info
    styles:
      card:
        - padding: 0.2em
        - '--mdc-ripple-color': yellow
        - '--mdc-ripple-press-opacity': 0.5
      icon:
        - opacity: 0.75
      name:
        - font-size: 0.5em
        - white-space: normal
      state:
        - font-size: 0.5em
        - white-space: normal
      label:
        - font-size: 0.5em
        - white-space: normal
  wide:
    template: standard
    styles:
      grid:
        - position: relative
        - grid-template-areas: '"i n"'
        - grid-template-columns: 1fr 1fr
        - grid-template-rows: 1fr
  container:
    color_type: label-card
    color: dimgray
    styles:
      card:
        - padding: 0
      name:
        - border-radius: 0.4em 0.4em 0 0
        - padding: 0.0em
        - width: 100%
        - font-weight: bold
        - font-size: 0.6em
      grid:
        - grid-template-areas: '"i" "n" "buttons"'
        - grid-template-columns: 1fr
        - grid-template-rows: 1fr min-content min-content
      custom_fields:
        buttons:
          - background-color: 'rgba(0,0,0,0.3)'
          - margin: 0
          - padding: 0.15em
  standard-button:
    template: standard
    variables:
      value_on: 'on'
      value_off: 'off'
      background_color_on: gold
      background_color_off: slategrey
      text_color_on: blue
      text_color_off: white
    styles:
      label:
        - color: '[[[ return variables.text_color_off ]]]'
    state:
      - id: value_on
        value: '[[[ return variables.value_on ]]]'
        styles:
          card:
            - background-color: '[[[ return variables.background_color_on ]]]'
          name:
            - color: '[[[ return variables.text_color_on ]]]'
          icon:
            - color: '[[[ return variables.text_color_on ]]]'
            - opacity: 1
      - id: value_off
        value: '[[[ return variables.value_off ]]]'
        styles:
          card:
            - background-color: '[[[ return variables.background_color_off ]]]'
          name:
            - color: '[[[ return variables.text_color_off ]]]'
          icon:
            - color: '[[[ return variables.text_color_off ]]]'
            - opacity: 0.5
  option-button:
    template: standard
    show_icon: false
    aspect_ratio: 1/1
    styles:
      card:
        - border-radius: 20%
  dimmer-option:
    template: option-button
    tap_action:
      action: call-service
      service: light.turn_on
      service_data:
        entity_id: entity
        brightness: '[[[ return variables.set_value ]]]'
    state:
      - operator: default
        styles:
          card:
            - background-color: '[[[ return variables.option_button_off_color ]]]'
            - color: '[[[ return variables.option_text_off_color ]]]'
      - operator: template
        value: >-
          [[[ return (entity.attributes.brightness||0) >= variables.range_start
          && (entity.attributes.brightness||0) <= variables.range_stop ]]]
        styles:
          card:
            - background-color: '[[[ return variables.option_button_on_color ]]]'
            - color: '[[[ return variables.option_text_on_color ]]]'
  presets:
    template: standard
    color_type: icon
    tap_action:
      action: none
    styles:
      card:
        - background-color: 'rgba(0,0,0,0.3)'
      icon:
        - color: white
      grid:
        - grid-template-areas: '"i opt1 opt2 opt3 opt4" "n opt1 opt2 opt3 opt4"'
        - grid-template-columns: 1fr 1fr 1fr 1fr 1fr
      custom_fields:
        opt1:
          - margin: 0.1em
          - overflow: visible
        opt2:
          - margin: 0.1em
          - overflow: visible
        opt3:
          - margin: 0.1em
          - overflow: visible
        opt4:
          - margin: 0.1em
          - overflow: visible
    variables:
      option_template: dimmer-option
      option_button_on_color: var(--paper-item-icon-active-color)
      option_text_on_color: white
      option_button_off_color: var(--paper-card-background-color)
      option_text_off_color: white
      option1_name: Low
      option1_set_value: 51
      option1_range_start: 1
      option1_range_stop: 77
      option2_name: Med
      option2_set_value: 102
      option2_range_start: 78
      option2_range_stop: 170
      option3_name: High
      option3_set_value: 255
      option3_range_start: 171
      option3_range_stop: 255
      option4_name: 'Off'
      option4_set_value: 0
      option4_range_start: 0
      option4_range_stop: 0
    custom_fields:
      opt1:
        card:
          type: 'custom:button-card'
          entity: '[[[ return variables.entity ]]]'
          template: '[[[ return variables.option_template ]]]'
          name: '[[[ return variables.option1_name ]]]'
          variables:
            set_value: '[[[ return variables.option1_set_value ]]]'
            range_start: '[[[ return variables.option1_range_start ]]]'
            range_stop: '[[[ return variables.option1_range_stop ]]]'
            option_button_on_color: '[[[ return variables.option_button_on_color ]]]'
            option_button_off_color: '[[[ return variables.option_button_off_color ]]]'
            option_text_on_color: '[[[ return variables.option_text_on_color ]]]'
            option_text_off_color: '[[[ return variables.option_text_off_color ]]]'
      opt2:
        card:
          type: 'custom:button-card'
          entity: '[[[ return variables.entity ]]]'
          template: '[[[ return variables.option_template ]]]'
          name: '[[[ return variables.option2_name ]]]'
          variables:
            set_value: '[[[ return variables.option2_set_value ]]]'
            range_start: '[[[ return variables.option2_range_start ]]]'
            range_stop: '[[[ return variables.option2_range_stop ]]]'
            option_button_on_color: '[[[ return variables.option_button_on_color ]]]'
            option_button_off_color: '[[[ return variables.option_button_off_color ]]]'
            option_text_on_color: '[[[ return variables.option_text_on_color ]]]'
            option_text_off_color: '[[[ return variables.option_text_off_color ]]]'
      opt3:
        card:
          type: 'custom:button-card'
          entity: '[[[ return variables.entity ]]]'
          template: '[[[ return variables.option_template ]]]'
          name: '[[[ return variables.option3_name ]]]'
          variables:
            set_value: '[[[ return variables.option3_set_value ]]]'
            range_start: '[[[ return variables.option3_range_start ]]]'
            range_stop: '[[[ return variables.option3_range_stop ]]]'
            option_button_on_color: '[[[ return variables.option_button_on_color ]]]'
            option_button_off_color: '[[[ return variables.option_button_off_color ]]]'
            option_text_on_color: '[[[ return variables.option_text_on_color ]]]'
            option_text_off_color: '[[[ return variables.option_text_off_color ]]]'
      opt4:
        card:
          type: 'custom:button-card'
          entity: '[[[ return variables.entity ]]]'
          template: '[[[ return variables.option_template ]]]'
          name: '[[[ return variables.option4_name ]]]'
          variables:
            set_value: '[[[ return variables.option4_set_value ]]]'
            range_start: '[[[ return variables.option4_range_start ]]]'
            range_stop: '[[[ return variables.option4_range_stop ]]]'
            option_button_on_color: '[[[ return variables.option_button_on_color ]]]'
            option_button_off_color: '[[[ return variables.option_button_off_color ]]]'
            option_text_on_color: '[[[ return variables.option_text_on_color ]]]'
            option_text_off_color: '[[[ return variables.option_text_off_color ]]]'
  alerter:
    template: standard
    show_last_changed: true
    color_type: icon
    extra_styles: |
      [[[ return `
        @keyframes pulse {
          20% {
            background-color: ${variables.color};
          }
        }
      `]]]
    variables:
      color: var(--paper-item-icon-active-color)
    state:
      - value: 'on'
        id: value_on
        styles:
          card:
            - animation: pulse 1s infinite
  alerter-dual:
    template: standard
    show_last_changed: true
    color_type: icon
    extra_styles: |
      [[[ return `
        @keyframes pulse1 {
          20% {
            background-color: ${variables.color_initial};
          }
        }
        @keyframes pulse2 {
          20% {
            background-color: ${variables.color_extended};
          }
        }
        @keyframes color {
          0% {
            color: unset;
            opacity: 0.5
          }
          99% {
            color: unset;
            opacity: 0.5
          }
          100% {
            color: ${variables.color_extended};
          }
        }
      `]]]
    variables:
      color_initial: var(--paper-item-icon-active-color)
      color_extended: 'rgba(240,52,52, 0.9)'
      color_seconds: 60
    state:
      - value: 'on'
        id: value_on
        styles:
          card:
            - animation: >-
                [[[ return `pulse1 1s ${variables.color_seconds}, pulse2 1s
                ${variables.color_seconds}s infinite` ]]]
          icon:
            - color: '[[[ return variables.color_extended ]]]'
            - opacity: 1
            - animation: '[[[ return `color ${variables.color_seconds}s 1` ]]]'
          name:
            - font-weight: bold

check this Lovelace config:

title: Ha Rpi4 Data

button_card_templates: !include lovelace/buttons/button_card_templates.yaml    # <------- this is where you save your templates
decluttering_templates: !include_dir_named lovelace/decluttering_templates
custom_header: !include lovelace/custom_header/custom_header_data.yaml

views:
  - !include lovelace/views/view_Home_assistant.yaml         #0
  - !include lovelace/views/view_Light_data.yaml             #1
  - !etcetcetc

in that file you should copy what you now show below template: (which isnt a valid key in the first place)

safe below code in a button_card_templates.yaml file in the directory of your naming (and reference that in the main lovelace-ui.yaml like I suggested above)

container:
  color_type: label-card
  color: dimgray
  styles:
    card:
      - padding: 0
    name:
      - border-radius: 0.4em 0.4em 0 0
      - padding: 0.1em
      - width: 100%
      - font-weight: bold
    grid:
      - grid-template-areas: '"i" "n" "buttons"'
      - grid-template-columns: 1fr
      - grid-template-rows: 1fr min-content min-content
    custom_fields:
      buttons:
        - background-color: 'rgba(0,0,0,0.3)'
        - margin: 0
        - padding: 0.3em
2 Likes

That decluttering is a good move.

@qoheleth Yes, it is there, it is the third line in the config that I posted.

ah, that was my problem. I removed templates and everything started working. Not sure why I put that in there in the first place. Many thanks!!

@Mariusthvdb One more thing if I may. I tried to move the templates to a separate template file like you did via this:

button_card_templates: !include lovelace/buttons/button_card_templates.yaml

I put that in the Raw configuration editor and when I try to save it I get the following error:

Unable to parse YAML: YAMLException: unknown tag !<!include> at line 3, column 76: ... ttons/button_card_templates.yaml ^

I have used the !include in the main configuration file with no issues. Do I need to do something special here for HA to recognize the macro?

tbh, I dont know, I dont use the Raw config editor, but use yaml mode.

speaking of which, my main setting in configuration.yaml is:

lovelace:
  mode: yaml
  resources: !include /config/lovelace/resources.yaml
  dashboards:
      etcetc

but I don’t think that has anything to do with the error you see. Of course, the folder name and the path need to be exactly the same, are you sure you have done that alright?

Ok, I am going NUTS! I almost have this how I want it. - the fact the Street does not do ST and the STATE does not do a two letter. My malfunction is I CAN NOT get the line after the <br> to justify start like the line before!

so code is this…

  ln1: |
    [[[
      return `<img
        src='https://developers.google.com/maps/images/maps-icon.svg'
          style="width:12px;height:12px">
        </ha-icon> ${states['sensor.g3_1_iphone'].attributes.Street}, ${states['sensor.g3_1_iphone'].attributes.City}<br>${states['sensor.g3_1_iphone'].attributes.State}, ${states['sensor.g3_1_iphone'].attributes['Postal Code']}`
    ]]]

And this code is whats sposta tell it to all align to start.

    ln1:
      - font-size: 11px
      - align-self: start
      - justify-self: start
      - padding-botom: 4px

instead, the outcome is like this…

icon Street Name, City Name
      FullStateName, Zip

This is the whole code incase someone wants to use it. Really nice looking card - the kink above…

type: 'custom:button-card'
entity: person.g3_1
show_icon: false
show_name: true
aspect_ratio: 1/1
styles:
  card:
    - background-color: transparent
    - border-radius: 10%
    - padding: 14%
    - font-size: 10px
    - text-shadow: 0px 0px 5px black
    - text-transform: capitalize
  grid:
    - grid-template-areas: '"n n""i i""zone zone""battery battery""ln1 ln1"'
    - grid-template-columns: 1fr 1fr
    - grid-template-rows: 1fr min-content min-content min-content min-content
  name:
    - font-weight: bold
    - font-size: 12px
    - align-self: start
    - justify-self: middle
  custom_fields:
    zone:
      - font-size: 12px
      - self-start: center
      - align-self: center
      - justify-self: start
      - padding-bottom: 4px
    battery:
      - entity: sensor.g3_1_iphone_12_pro_max_battery_state_2
      - font-size: 12px
      - align-self: center
      - justify-self: start
      - padding-bottom: 4px
      - '--text-color-sensor': >-
          [[[ if (states["sensor.g3_1_iphone_12_pro_max_battery_state_2"].state
          <= 20) return "red"; ]]]
    ln1:
      - font-size: 11px
      - align-self: start
      - justify-self: start
      - padding-botom: 4px
custom_fields:
  i: |
    <img width= 38% src='/local/images/me_g3-1.png'>
  zone: |
    [[[
      if (states['person.g3_1'].state ='Home')
        return `<ha-icon
          icon="mdi:google-maps"
          style="width:12px;height:12px;color:SteelBlue">
          </ha-icon><span> <span style="color: var(--text-color-sensor);">${states['person.g3_1'].state}</span></span>`
       else 
        return `<ha-icon
          icon="mdi:google-maps"
          style="width:12px;height:12px;color:DarkOrange">
          </ha-icon><span> <span style="color: var(--text-color-sensor);">${states['person.g3_1'].state}</span></span>`
    ]]]
  battery: |
    [[[
      if (states['device_tracker.g3_1_iphone_12_pro_max_2'].attributes.battery_status.state =='Charging')
        return `<ha-icon
          icon="mdi:battery-charging"
          style="width:12px;height:12px;color:lime">
          </ha-icon><span> <span style="color: var(--text-color-sensor);">${states['sensor.g3_1_iphone_12_pro_max_battery_state_2'].state}%</span></span>`
       else 
        return `<ha-icon
          icon="mdi:battery"
          style="width:12px;height:12px">
          </ha-icon><span> <span style="color: var(--text-color-sensor);">${states['sensor.g3_1_iphone_12_pro_max_battery_state_2'].state}%</span></span>`
    ]]]
  ln1: |
    [[[
      return `<img
        src='https://developers.google.com/maps/images/maps-icon.svg'
          style="width:12px;height:12px">
        </ha-icon> ${states['sensor.g3_1_iphone'].attributes.Street}, ${states['sensor.g3_1_iphone'].attributes.City}<br>${states['sensor.g3_1_iphone'].attributes.State}, ${states['sensor.g3_1_iphone'].attributes['Postal Code']}`
    ]]]

@portigui, the raw configuration editor does not support !include. You have to do your dashboard in yaml mode for that feature. I don’t know why they don’t support that feature in GUI mode. I wish they did.

@G3GhostTech, have you tried using - text-align: left?
You can also use the browser’s developer pane (usually F12 to turn it on) to examine the styling being applied and experiment with different styling.

Side note, did you intend to have </ha-icon> in your ln1 definition? It may not be causing any problem, but it’s not doing anything. Also, the extra <span>...</span> is redundant and can be removed.

1 Like

Help with variable.

I have some custom fields that i would like to move to an template.

custom_fields:
  sensor_1: "[[[ return `${states['sensor.hallway_mirror_power'].state} W` ]]]"

Is there a way to change the above “return statement” to replace the part “hallway_mirror” with a variable? so i can use the same template for multiple buttons with minimal code in the card.

like a variable i set in the card:

variables:
  var_sensor_name: "hallway_mirror"
custom_fields:
  sensor_1: "[[[ return `${states[ variables.var_sensor_name + '_power' ].state} W` ]]]"
1 Like

Thanks Keith. That coding is also exactly what I need to turn my Thermostat into a template. (I only have one thermostat currently, but I’d hate to have to duplicate all that code if I ever change to a split-level / double-stat system.)

On a completely different aspect, is there anyway to retrieve the icon associated with a zone for display on a card? Of course, if it’s the entity listed on the card, that’s easy and automatic, but on my “family presence” card, the primary entity is our combined status. I’d like to not only show the text of where we are, but also the associated icon.
Any ideas?

I haven’t done anything with zones. If you find out, let me know :slight_smile:

Thank you very much.

I had to add "‘sensor.’ + " to it but your example guided me in the right direction.

sensor_1: "[[[ return `${states[ 'sensor.' + variables.var_sensor_name + '_power' ].state} W` ]]]"

My “status” buttons made with template and variables, makes it easy to add multiple buttons.
Screenshot MCBOOTCAMP 2021-04-19 22_4006

Yaml for the cards:

cards:
  - type: horizontal-stack
    cards:
###################################################################################################
## 
###################################################################################################
      - type: custom:button-card
        template: shelly_plug_s
        entity: light.hallway_mirror
        variables:
          var_name: "Hallway Mirror"
          var_label: "Shelly Plug S - 01"
          var_double_tap_entity: "sensor.hallway_mirror_power"
          var_sensor_name: "hallway_mirror"
###################################################################################################
## 
###################################################################################################
      - type: custom:button-card
        template: shelly_plug_s
        entity: light.bedroom_window
        variables:
          var_name: "Bedroom Window"
          var_label: "Shelly Plug S - 02"
          var_double_tap_entity: "sensor.bedroom_window_power"
          var_sensor_name: "bedroom_window"

Yaml for the template:

button_card_templates:
##################################################################################
  shelly_plug_s:
##################################################################################
    show_label: true
    show_entity_picture: true
    entity_picture: "/local/lovelace/home/shelly_plug_s.png"
    name: '[[[ return variables.var_name ]]]'
    label: '[[[ return variables.var_label ]]]'

    tap_action:
      action: none

    double_tap_action:
      action: more-info
      entity: '[[[ return variables.var_double_tap_entity ]]]'

    hold_action:
      action: toggle

    custom_fields:
      sensor_label_1: '[[[ return "POWER:" ]]]'
      sensor_1: "[[[ return `${states[ 'sensor.' + variables.var_sensor_name + '_power' ].state} W` ]]]"
      sensor_label_2: '[[[ return "CURRENT:" ]]]'
      sensor_2: "[[[ return `${states[ 'sensor.' + variables.var_sensor_name + '_energy' ].state} kWh` ]]]"
      sensor_label_3: '[[[ return "TEMP:" ]]]'
      sensor_3: "[[[ return `${states[ 'sensor.' + variables.var_sensor_name + '_device_temperature' ].state} °C` ]]]"
      sensor_label_4: '[[[ return "FW UPDATE:" ]]]'
      sensor_4: "[[[ return `${states[ 'binary_sensor.' + variables.var_sensor_name + '_firmware_update' ].state}` ]]]"

    styles:
      card:
        - padding: 5px 15px
        - background: 'linear-gradient(rgba(255,255,255,0.1) 25%, rgba(0,0,20,0.3)50%)'
        - border-radius: 15px
        - border: 'solid 3px var(--button-card-light-color)'
        - color: ivory
      name:
        - text-transform: uppercase
        - color: white
        - font-weight: bold
        - font-size: 80%
        - padding: 15px 0px 0px 0px
      label:
        - color: white
        - justify-self: middle
        - font-weight: bold
        - padding: 5px 0px 0px 0px
      img_cell:
        - align-items: middle
        - padding: 5px 0px 0px 0px
      grid:
        - grid-template-areas: '"n n" "i i" "l l" "sensor_label_1 sensor_1" "sensor_label_2 sensor_2" "sensor_label_3 sensor_3" "sensor_label_4 sensor_4"'
        - grid-template-rows: min-content 1fr min-content min-content min-content min-content min-content
      custom_fields:
        sensor_label_1:
          - justify-self: start
          - font-size: 13px
          - padding: 15px 0px 0px 0px
        sensor_1:
          - justify-self: end
          - font-size: 13px
          - padding: 15px 0px 0px 0px
        sensor_label_2:
          - justify-self: start
          - font-size: 13px
          - padding: 5px 0px 0px 0px
        sensor_2:
          - justify-self: end
          - font-size: 13px
          - padding: 5px 0px 0px 0px
        sensor_label_3:
          - justify-self: start
          - font-size: 13px
          - padding: 5px 0px 0px 0px
        sensor_3:
          - justify-self: end
          - font-size: 13px
          - padding: 5px 0px 0px 0px
        sensor_label_4:
          - justify-self: start
          - font-size: 13px
          - padding: 5px 0px 0px 0px
        sensor_4:
          - justify-self: end
          - font-size: 13px
          - padding: 5px 0px 0px 0px
##################################################################################
6 Likes

@Mariusthvdb Many thanks for all the info. I stopped using storage mode and am only using yaml mode. I was able to get everything working with your advise. I even got everything decluttered. :slight_smile: Much obliged for the time you gave me.

1 Like