Dual-entity flashing button template for custom:button-card

alerter-toggle example

Use a sensor and a switch together as one button with different colors, icons and flashing alert!

  • sensor + lock
  • sensor + light
  • sensor by itself
  • different flashing color if sensor is on too long
  • different color & icon for each of the 4 states

I have created a new template for custom:button-card that I would like to share with everyone. I’m quite pleased with how it came out. This is an improved version of the alerter template in my prior post, plus a delayed flashing color change and a secondary entity to toggle and show state of both the sensor and the secondary entity. This new version is better and simpler than my previous.

The visual example at the top is a snip right off my personal dashboard. You should see two yellow buttons and one flashing blue button.

  • my patio door is closed but unlocked (steady yellow + unlocked icon)
  • one of my garage doors is open (flashing blue + open icon)
  • my house attic hatch is closed but the light is turned on (steady yellow + lightbulb icon)

The colors and flashing are great because I can tell the status from across the room. Colors and icons are easily configurable and can be different for all 4 combined states of the sensor and the switch. Another feature, not visible in the example, is that my doors change to flashing red if open longer than 60 seconds to make it more obvious they need attention.

If you need more depth on using custom:button-card, check my prior post for the link to the documentation and my own explanations of what I’ve done with it. I have some other posts using custom:button-card you might find interesting as well. The custom:button-card is spectacular for making advanced buttons. It is worth the investment of time to learn it if you want complete freedom in designing your dashboards.

Now the important stuff!

Expand the folded sections below to see the templates and examples.

alerter-toggle.yaml (the template we are discussing)
# alerter-toggle.yaml
# Keith Townsend, 3/31/2022
# Based on prior work I did around October 2020, which was inspired by someone's background flash animation. This complete refactor is MUCH cleaner.

variables:
  toggle_entity: null   # optional entity to toggle and watch states
  toggle_state_on: 'on' # optional "on" state to watch for on toggle_entity
  sensor_state_on: 'on' # optional "on" state to watch for on primary entity
  delay_color: null     # optional color to use after delay_seconds
  delay_seconds: 60     # optional seconds to wait before using delay_color

template: standard      # this is my default styles for all my buttons, and includes hold_action to show more_info
color_type: card        # this lets user specify background color by overriding color property on states
show_last_changed: true # user can override this if they want
triggers_update: all    # ensure switch state is detected becuase the card won't auto-monitor entities in variables

extra_styles: |
  [[[ 
    let basecolor = null
    if (variables.delay_color)
      basecolor = Date.parse(entity.last_updated) - new Date() + (variables.delay_seconds * 1000) > 0 ? null : variables.delay_color;
    return `
    @keyframes sharp {
      0% {
        background-color: ${basecolor};
      }
      95% {
        background-color: var(--paper-card-background-color);
        color: var(--paper-card-color);
      }
      100% {
        background-color: ${basecolor};
      }
    }
  `]]]

tap_action:
  action: '[[[ return variables.toggle_entity ? "call-service" : "more-info" ]]]'
  service: homeassistant.toggle
  service_data:
    entity_id: "[[[ return variables.toggle_entity ]]]"

state:
  - id: sensor_off_toggle_off
    operator: default

  - id: sensor_off
    operator: template
    value: '[[[ return entity.state !== variables.sensor_state_on && !variables.toggle_entity ]]]'

  - id: sensor_on
    operator: template
    value: '[[[ return entity.state === variables.sensor_state_on && !variables.toggle_entity ]]]'
    styles:
      card:
        - animation: sharp ease-in-out 1s infinite

  - id: sensor_on_toggle_off
    operator: template
    value: '[[[ return entity.state === variables.sensor_state_on && variables.toggle_entity && states[variables.toggle_entity].state !== variables.toggle_state_on ]]]'
    styles:
      card:
        - animation: sharp ease-in-out 1s infinite

  - id: sensor_off_toggle_on
    operator: template
    value: '[[[ return entity.state !== variables.sensor_state_on && variables.toggle_entity && states[variables.toggle_entity].state === variables.toggle_state_on ]]]'

  - id: sensor_on_toggle_on
    operator: template
    value: '[[[ return entity.state === variables.sensor_state_on && variables.toggle_entity && states[variables.toggle_entity].state === variables.toggle_state_on ]]]'
    styles:
      card:
        - animation: sharp ease-in-out 1s infinite

standard.yaml (common for all my templates & buttons)
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
    - max-height: 4.5rem #tweaking the auto-size to prevent vertical inflation of the UI on my wall tablets
  name:
    - font-size: 0.65em
    - white-space: normal
  state:
    - font-size: 0.65em
    - white-space: normal
  label:
    - font-size: 0.4em
    - white-space: normal
excerpt from my dashboard using the alerter-toggle template (same buttons as image at top)
            - type: custom:button-card
              template: alerter-door
              entity: binary_sensor.front_door_open
              name: Front
              variables:
                toggle_entity: switch.front_deadbolt
            - type: 'custom:button-card'
              template: alerter-door
              entity: binary_sensor.patio_door
              name: Patio
              variables:
                toggle_entity: switch.patio_doorlock
            - type: 'custom:button-card'
              template: alerter-door
              entity: binary_sensor.garage_door
              name: Groj
              variables:
                delay_seconds: 120 # 2 minutes
            - type: 'custom:button-card'
              template: alerter-door
              entity: binary_sensor.garage_tilt_single
              name: Single
              state:
                - id: sensor_on
                  icon: 'mdi:garage-open'
              variables:
                delay_seconds: 900 # 15 minutes
            - type: 'custom:button-card'
              template: alerter-door
              entity: binary_sensor.garage_tilt_double
              name: Double
              state:
                - id: sensor_on
                  icon: 'mdi:garage-open-variant'
              variables:
                delay_seconds: 900 # 15 minutes
            - type: 'custom:button-card'
              template: alerter-door
              entity: binary_sensor.front_gate
              name: Front
              state:
                - id: sensor_on
                  color: red
                  icon: 'mdi:gate-arrow-right'
            - type: 'custom:button-card'
              template: alerter-door
              entity: binary_sensor.back_gate
              name: Back
              state:
                - id: sensor_on
                  color: red
                  icon: 'mdi:gate-arrow-right'
            - type: 'custom:button-card'
              template: alerter-light
              entity: binary_sensor.house_attic_hatch
              name: House
              icon: mdi:home-floor-a
              variables:
                toggle_entity: switch.house_attic_light
            - type: 'custom:button-card'
              template: alerter-light
              entity: binary_sensor.garage_attic_hatch
              name: Groj
              icon: mdi:home-floor-a
              variables:
                toggle_entity: switch.garage_attic_light

NOTE: I have organized all my dashboards as yaml files with !include references to achieve multiple-use of the same templates in all my dashboards, so if you’re adding this with the Lovelace UI you will need to nest it under a name property in your button_card_templates section of your dashboard yaml. If you’ve never done custom:button-card templates, refer to the tips in my other post.

Explanations and examples

The minimal behavior is to flash the background of the card with the default “on” color when the entity is on:

  type: custom:button-card
  template: alerter-toggle
  entity: binary_sensor.front_door

If you want to have it switch to a different color after a delay:

  type: custom:button-card
  template: alerter-toggle
  entity: binary_sensor.front_door
  variables:
    delay_color: red
    delay_seconds: 30 # default is 60 if you omit this

To watch for a different state (default is ‘on’), specify the variable sensor_state_on with the state to watch for:

  type: custom:button-card
  template: alerter-toggle
  entity: binary_sensor.front_door
  variables:
    sensor_state_on: 'off' # reverse to alert when off

If you are only using a single entity, there are two state id’s you can configure: sensor_on and sensor_off. Using these id’s you can change the background color, icon, and just about anything else about the button based on the state.

To specify a different “on” color:

  type: custom:button-card
  template: alerter-toggle
  entity: binary_sensor.front_door
  state:
    id: sensor_on
    color: yellow

You can also associate a second entity to include in the button states with the variable toggle_entity. I have two use-cases for this: door sensor + lock, and attic hatch sensor + light. It’s nice to see the combination of status (e.g., flashing when open, custom icon when light is on).

  type: custom:button-card
  template: alerter-toggle
  entity: binary_sensor.front_door
  variables:
    toggle_entity: switch.front_doorlock
    toggle_state_on: 'locked' # optional, state to consider "on"

The visual behavior of the button, by default, will still be the same, but you can now toggle the second entity (if it’s a type that can be toggled with service homeassistant.toggle). Note, you can override tap_action with a different service call if needed.

When you specify this second entity, you will now get 4 different button state id’s you can extend: sensor_off_toggle_off, sensor_on_toggle_off, sensor_off_toggle_on and sensor_on_toggle_on. Note: the single-entity state id’s are not used when you have two entities.

To make a dual-entity button more useful, you probably want to have different colors and/or icons for some of the states. You can do that by extending the state id’s with your desired settings. Here is an example that sets different state colors & icons and uses a delay color:

  type: custom:button-card
  template: alerter-toggle
  entity: binary_sensor.front_door_open
  variables:
    toggle_entity: switch.front_deadbolt
    delay_color: red
    delay_seconds: 30
  state:
    - id: sensor_off_toggle_on
      color: green
      icon: mdi:door-closed-lock
    - id: sensor_off_toggle_off
      color: darkgoldenrod
      icon: mdi:lock-open

Some future ideas I have for this template are overlays for battery status, light level or fan speed, zone bypass status and “stale” indicator if entity stops reporting updates.

A special note on triggers_update: all

This setting is only needed because the card cannot discover entities in variables when it is parsing the card to register update listeners. We also can’t use javascript with triggers_update, so we can’t dynamically add variable entities to watch for. Using triggers_update: all solves the problem but adds runtime overhead to redraw when any entity changes state. I have discussed the issue with the author of the card (here and here) and there are challenges. I am hopeful that he can find a way to auto-discover from variables, but for now be aware of the extra overhead. If you want to avoid the overhead you can remove the triggers_update: all from the alerter-toggle template and explicitly define triggers_update with a list of entities on every button you configure that uses this alerter-toggle template. Although I’m not a fan of having to repeat the entity names twice each time I use this template, it was worth doing in my dashboards because my wall-tablets are cheap and sensitive to extra overhead. I kept the triggers_update: all in this version described here just to ensure it works out of the box without adding complication to my examples.

2 Likes

neo2angelAngel

21m

Hi everyone
following “template: alerter-dual”
I have managed to make the button blink when it is turned on, but how is it done so that it only blinks when it is “unknown”?

Thank you so much

@neo2angel, you would need to add another state handler to the template to detect the unknown state value and have it set the animation (- animation: sharp ease-in-out 1s infinite)

thank you very much for your prompt response
I’m a little green with the topic of templates
Could you give a quick example please?
Thank you so much

@neo2angel, check my link in first post above to another topic where I explain templates in a little more depth, and the link in that topic to the github repo for custom button card where the official instructions are. It’s a lot to decipher, but well worth it.

I am new to HA and all these templates and toggles hurts my head a little bit. Can you help my setup a simple Card that has 2 buttons and the state of the buttons I get from a binary sensor.

So I want the card that the 2 Buttons are on to go Red when the binary sensor is open if it is closed it will go Green.

The buttons trigger 2 separate actions. switch.gate1 and switch.gate2 and the sensor is binary_sensor.switch2

@n00bster, the button card can contain other cards (including other button cards) using the custom_fields feature. You could have a main button with your binary_sensor.switch2, color_type of “card”, and disable tap_action for it, then use 2 custom fields for your switches. If you haven’t yet, check the documentation for additional tips.

got it working with below code. only thing i dont like is the title is not part of the tile it like sticks out at the top.

example:

image

type: horizontal-stack
title: Gate
cards:
  - type: custom:button-card
    state:
      - value: 'off'
        styles:
          card:
            - background: rgb(255,0,0,50%)
          icon:
            - color: black
    styles:
      card:
        - background: rgb(0,153,0,50%)
      icon:
        - color: black
    tap_action:
      action: call-service
      service: switch.toggle
      service_data:
        entity_id: switch.gate1
    entity: binary_sensor.switch2
    icon: mdi:car
    show_state: false
    show_name: false
    show_icon: true
    size: 80px
    hold_action:
      action: none
  - type: custom:button-card
    state:
      - value: 'off'
        styles:
          card:
            - background: rgb(255,0,0,50%)
          icon:
            - color: black
    styles:
      card:
        - background: rgb(0,153,0,50%)
      icon:
        - color: black
    tap_action:
      action: call-service
      service: switch.toggle
      service_data:
        entity_id: switch.gate2
    entity: binary_sensor.switch2
    icon: mdi:walk
    show_state: false
    show_name: false
    show_icon: true
    size: 80px
    hold_action:
      action: none

Hey,
I’m looking for a way to make the button flash when the energy at a power plug drops below a value.
Is this possible? in this topic I see only examples for On off etc…

This looks brilliant! However it’s late and i’m tired so i’ll return another time when my brain can process all the info!

Yes, you can override the state settings by specifying the same id that the template uses:

  type: custom:button-card
  template: alerter-toggle
  entity: sensor.thermostat 
  state:
    - id: sensor_on
      operator: '<'
      value: 50
1 Like

THANKS!

Can it also be extended to flash when the power is between 2 values?

Like this?

  type: custom:button-card
  template: alerter-toggle
  entity: sensor.thermostat 
  state:
    - id: sensor_on
      operator: '<'
      value: 50
    - id: sensor_on
      operator: '>'
      value: 30

@fifty889, yes but not that way. Each state id will override the previous one with same id, so if you define it multiple times the last one wins. See here for state config options.

What you need to do in your case is use operator: template and use a javascript template to return a boolean result of the between value comparisons.

My template is already using the template operator for states, so I refer you to this example I copied from the template as an example of how to do the javascript syntax (see here for doc). Obviously you’ll need different logic for your comparison.

  - id: sensor_on
    operator: template
    value: '[[[ return entity.state === variables.sensor_state_on && !variables.toggle_entity ]]]'

There is a lot of power in this custom button card. I highly recommend reading the full documentation a bunch of times. I still have to refer back to it when I work on my templates just because there is so much detail.

1 Like

Struggling with my includes… any chance you can spot the issue.

my directory structure is /config/dashboards …

Within that I have dashboards.yaml, testing.yaml (my dashboard),… and a folder called templates which has button_card.yaml and a folder called button_card which has the templates as individual files…

testing.yaml has

button_card_templates: !include templates/button-card.yaml

templates/button_card.yaml has…

!include_dir_named button-card/

and the templates look like …

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
    - height: "100%"
  icon:
    - opacity: 0.5
    - max-height: 4.5rem #tweaking the auto-size to prevent vertical inflation of the UI on my wall tablets
  name:
    - font-size: 0.65em
    - white-space: normal
  state:
    - font-size: 0.65em
    - white-space: normal
  label:
    - font-size: 0.4em
    - white-space: normal

It’s not working and I’m not sure why… any suggestions?

@efaden, I’m having a hard time visualizing your folder tree, but two things to check:

  • is the folder named button_card or button-card? I see it one way in your description and the other way in your !incluide_dir_named
  • the paths for !include are relative to the file’s location that contains the !include, so sometimes you need to go up to parent directory with .., such as !include_dir_named ../button-card/

Hi,

I am very new to template. Is there any pointer on how to begin with template?

Thanks

@ktownsend-personal awesome work mate! love it. Is there a way to add a condition here, as I would like it to flash red when our occupancy entity is nobody or even between certain times?

Would state styles work?

    - entity: binary_sensor.french_door_sensor
      name: French Doors
      template: alerter-toggle
      type: custom:button-card
      variables:
        color_seconds: 120
      state: 
        - id: sensor_on
          color: red
          icon: mdi:door-open
        - id: sensor_off
          icon: mdi:door-closed`

If you want to check additional conditions you can override the state.value property for the appropriate state.id. You’ll probably want to copy the javascript in the template used by that particular state.id and extend it for your override. The state.color property is exactly what determines the color you want to flash.

I have a switch that calls a REST service to toggle something on or off. That works well EXCEPT that there’s a delay between calling the REST service to toggle the thing, and when Home Assistant receives an updated status for the toggled item.

The effect is that when I toggle the switch on my card, it initially goes to the correct setting but a few seconds later it visually toggles itself back to what it was before I toggled it, then a number of seconds later it toggles itself to the correct new setting once Home Assistant has polled the REST service again.

What I think I’d like as a solution is to have a single push button that changes between red (off) and green (on), but that can also show orange (an intermediate state) for a defined number of seconds when pressed, to indicate that it’s in the process of trying to toggle to a new setting.

Do you know a way to do that please?

@spry-salt, I don’t know of any way to do what you ask.