Quantcast
Channel: Configuration - Home Assistant Community
Viewing all articles
Browse latest Browse all 106363

Fun with cutom:button-card

$
0
0

I’ve recently discovered the power of custom:button-card (https://github.com/custom-cards/button-card) and want to share some nice layouts I created. Be sure to read the documentation for the button-card at that link if you try to use any of these examples. I make extensive use of its templating feature.

There are a few things going on in that image:

  1. standard and wide button variations
  2. a container that only needs one color setting to theme the header and body
  3. multi-option button
  4. sensors that have color animation when active

Standard & Wide Buttons

The standard and wide button variations are fairly straightforward. I have these defined as templates:

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.5
      name:
        - font-size: 0.65em
        - white-space: normal
      state:
        - font-size: 0.65em
        - white-space: normal
      label:
        - font-size: 0.4em
        - white-space: normal
  wide:
    template: standard
    styles:
      grid:
        - position: relative
        - grid-template-areas: '"i n"'
        - grid-template-columns: 1fr 1fr
        - grid-template-rows: 1fr

I use the standard template to set my common style. The wide template builds on the standard template and just makes the icon and name side by side instead of over/under.

To use them in my dashboard I just supply the desired template and any other relevant properties that aren’t defined by the template or that I want to override:

        - entity: switch.patio_light
          template: standard
          name: Patio
          icon: 'mdi:outdoor-lamp'
          type: 'custom:button-card'

Container with Header

This layout was inspired by a control that I used to use for the same effect, banner-card (https://github.com/nervetattoo/banner-card). I like the look of that, but I wanted more flexibility of the content. Fortunately it was quite easy to make a container with a button card using the custom_fields config.

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

This is a label card that contains a horizontal or vertical stack, which then contains whatever I want, such as buttons to control things. In the template above I defined a custom grid for the layout and set the styles. In the grid-template-areas I have a grid area called buttons that matches the buttons custom field in custom_fields. The custom_fields is defined twice: once in the template styles, and once in my dashboard where I am defining the container. Below is the dashboard yaml for one of my containers in the example image.

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'
        - entity: light.ge_14294_in_wall_smart_dimmer_level_10
          name: Table
          template: standard
          icon: 'mdi:ceiling-light'
          type: 'custom:button-card'
        - entity: light.ge_14294_in_wall_smart_dimmer_level_7
          name: Dining
          template: standard
          icon: 'mdi:ceiling-light'
          type: 'custom:button-card'
        - entity: switch.patio_light
          template: standard
          name: Patio
          icon: 'mdi:outdoor-lamp'
          type: 'custom:button-card'


Multi-option Button

The multi-option button is a bit more involved. It is essentially a button showing its own icon/name and 4 more buttons. In principal it works the same as the container, but it is styled differently and assumes I always want 4 options so that most of it is standard templates and reduces what I have to put in my dashboard. This also has custom javascript templates to detect value ranges when a particular option should be “on”, and it uses service calls to set the desired option value.

This uses several templates, so I will describe each one separately.

Option Button

This defines the basic look of an option button. It builds on the standard button, hides the icon, sets 1/1 aspect ratio to make it square, and sets a nice border radius.

button_card_templates:
  option-button:
    template: standard
    show_icon: false
    aspect_ratio: 1/1
    styles:
      card:
        - border-radius: 20%

Dimmer Option, Blind Option, Fan Option

This builds on the option-button and defines the tap_action and state monitoring. You will notice that is is using the variables feature of the button-card to get some necessary values. Those are provided by the presets template that I will describe in a moment.

I am only showing the dimmer option here because they are all the same definition, but with different service type and service_data for the tap_action, and different attributes to examine in the javascript.

button_card_templates:
  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

This is a big template. It defines the whole layout and all of the variables, with default values.

Special note on overflow: visible: this is to allow the option button’s shadow to appear correctly.

button_card_templates:
  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 ]]]'

Using the multi-option button in the dashboard

For this, you can omit any variables that have defaults that match waht you want. In this example I have set a lot of them, but not all.

            - entity: cover.master_bath_blinds
              type: 'custom:button-card'
              template: presets
              name: Blinds
              state:
                - value: closed
                  color: var(--paper-card-background-color)
                - value: open
                  color: var(--paper-item-icon-active-color)
              variables:
                entity: cover.master_bath_blinds
                option_template: blind-option
                option1_name: ANG
                option1_set_value: 12
                option1_range_start: 2
                option1_range_stop: 35
                option2_name: OPN
                option2_set_value: 50
                option2_range_start: 36
                option2_range_stop: 99
                option3_name: CLN
                option3_set_value: 100
                option3_range_start: 100
                option3_range_stop: 100
                option4_name: CLS
                option4_set_value: 0
                option4_range_start: 9999
                option4_range_stop: 9999

Alerting Sensors

I can explain this in more detail later, but I need to wrap up for now.
The template, with animation:

button_card_templates:
  alerter:
    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

Here is how to use it in the dashboard:

        - entity: binary_sensor.garage_door
          template: alerter
          name: Garage
          type: 'custom:button-card'
          variables:
            color_seconds: 120

Conclusion

I have dumped a lot of config here and fully expect there will be questions. I hope you find this useful :slight_smile:

1 post - 1 participant

Read full topic


Viewing all articles
Browse latest Browse all 106363

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>