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 usingcustom:button-card
you might find interesting as well. Thecustom: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 yourbutton_card_templates
section of your dashboard yaml. If you’ve never donecustom: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 thetriggers_update: all
from thealerter-toggle
template and explicitly define triggers_update with a list of entities on every button you configure that uses thisalerter-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 thetriggers_update: all
in this version described here just to ensure it works out of the box without adding complication to my examples.