Combined Lock & Door Status in single Entity for Glance Card?

Has anyone figured out a way to combine door open/close status with the lock status for entities in a Glance Card?

It seems so duplicative to require two icons for each door. Both are important data points, but they’re related and it seems like there should be a way to combine them and save precious screen real-estate. For example, there are only four statuses:

  • Door is open and lock is unlocked → door open status is the most important detail since it can be assumed that the lock is unlocked if door is open. Show only that Door is Open if lock is unlocked.
  • Door is closed and lock is unlocked → lock status is the most important detail since it can be assumed that the door is closed if showing unlocked. Show only that lock is unlocked if door is closed.
  • Door is closed and lock is locked → lock status is the most important details since it can be assumed that the door is lcosed if showing locked. Show only that lock is locked if door is closed.
  • Door is open and lock is locked → the issue is the most important detail here since the door cannot be closed if door is locked and therefore will require unlock the lock AND physically close the door (assuming it’s not an automatic or controllable door). Show an error icon of some sort to indicate that attention is needed to resolve.

This seems like something that might be possible through a template sensor, but I’m still learning how to build those with logic like this. So, I’ve been looking for other examples to see if others have solved this or done something similar.

1 Like

I have been looking for this exact solution myself, it should be possible with something like this:

More details here:

So it seems like it is possible. I have not yet figured out how though.

Another good discussion here:

So, update, I still can’t get this working. I am having issues with the templates. I have tried using ‘helpers’ as well as building the templates out in my dedicated ‘sensor.yaml’ file, and in either case, the sensor comes back as ‘unknown’. I have tried so many different permutations of the following I have lost count:

{% if ( (state_attr('lock.front_door', 'Unlocked')) or not (state_attr('binary_sensor.door_front_entry_window_door_is_open', 'Closed'))) %}
  Unlocked
{% elif ( (state_attr('lock.front_door', 'Locked')) or not (state_attr('binary_sensor.door_front_entry_window_door_is_open', 'Open'))) %}
  Open
{% elif ( (state_attr('lock.front_door', 'Locked')) or not (state_attr('binary_sensor.door_front_entry_window_door_is_open', 'Closed'))) %}
  Unlocked
{% else %}
  Unknown
{% endif %}

Tried re-arranging where the terms are, tried fewer parenthesis, tried more, tried using not, tried non not using not. Tried AND. Tried using is_state instead of state_attr.

Same results every time. I am clearly missing something in the templates.

Another good discussion here:

Great discussion here.

With that said, it seems like this went down the path of building custom sensors that still only show one of the two statuses that I was looking to capture in a single entity icon from the original post.

Here’s one of the cards in my dashboard.

Screenshot 2024-01-12 at 20.06.14

  • 2 icons for Front… - the first is door status and the second is lock status
  • 2 icons for Mudr… - the first is door status and second is lock status
  • 2 icons for Outsi… - the first is door status and the second is lock status

The source of these sensors is an August Lock with Door Sense. So it’s providing status for both lock and door, but as two separate sensors. The original intent of this post was to see if I could somehow merge those into a single glance entity icon that could show me both aspects together and take up less space. One thing I realize from the conversation is that I could use a condition to hide door status when it’s closed and the lock is locked, but it’s still not as obvious to the user as the native August Lock icon/control (see below).

How August Smart Locks Work | August Home

This is able to quickly convey the status of open/closed and locked/unlocked, so my goal was to combine the two icons in the glance card into one somehow.

1 Like

I like that.!

I am going to have to combine that with the status template sensor. Basically, it now works that for each door I have:

  • Locked
  • Unlocked
  • Open
  • Locked and Open
  • Unknown

I should be able to turn that into single icons like you did.

I got the combined logic working by resurrecting an old thread here:

Interesting. So what does the icon look like in each state? Is it truly one entity in a glance card? And does it change color with state?

I haven’t yet figured out a single icon card with colours - I will be working on that. Right now, I am using a conditional card such that it is hidden in the GUI until the conditions are met. So the card only appears when all the doors are closed and locked:

type: conditional
conditions:
  - condition: state
    entity: sensor.all_doors_status
    state: All Doors Locked
card:
  type: entity
  entity: sensor.all_doors_status

I got part way there with some custom cards:

The logic in this thread looks very promising, I think it is the full solution as I already have the states working as helpers. However, because icons are needed, I think I need to do this in full YAML, and have the sensor defined with the logic, then the mdi icons defined with the logic again as below:

Ok, I have working code for the icon state and the door. This stanza is only for the front door, I have a stanza for each door, and one specifically to combine all the doors into a single entity. What I am missing now is the ability to colour the icons based on the state, but having seen other posts that do just that, I should be able to figure that out.

Here is the logic for the front door as a single icon showing the state and icons:

  - platform: template
    sensors:
      front_door_status_test:
        friendly_name: "Front Door Status Test"
        value_template: >-
          {% if ( (is_state('lock.front_door','unlocked')) and (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) ) %}
            Unlocked
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','locked')) ) %}
            Locked Open
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) and (is_state('lock.front_door','locked')) ) %}
            Locked
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','unlocked')) ) %}
            Open
          {% else %}
            Unknown
          {% endif %}
        icon_template: >-
          {% if ( (is_state('lock.front_door','unlocked')) and (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) ) %}
            mdi:lock-open
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','locked')) ) %}
            mdi:door-closed-cancel
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) and (is_state('lock.front_door','locked')) ) %}
            mdi:lock
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','unlocked')) ) %}
            mdi:door-open
          {% else %}
            mdi:lock-question
          {% endif %}

The icon changes based on the states, but I still have not figured out how to set the colour properly. This will probably need card-mod I am guessing.

Ok, really close now. First, I have a test sensor that changes the icon and state as per above.

Next, I have an entity card:

type: entities
entities:
  - entity: sensor.front_door_status_sc_2
card_mod:
  style: |
    ha-card {
        {% if states('sensor.front_door_status_sc_2') == 'Locked' %}
        color: green;
        {% elif states('sensor.front_door_status_sc_2') == 'Unlocked' %}
        color: red;
        {% elif states('sensor.front_door_status_sc_2') == 'Open' %}
        color: blue;
        {% elif states('sensor.front_door_status_sc_2') == 'Closed' %}
        color: yellow;
        {% else %}
        color: orange;
        {% endif %}
             } 

This does NOT change the colour of the icon yet, but it does change the colour of the text!


GOT IT:

type: entities
entities:
  - entity: sensor.front_door_status_sc_2
card_mod:
  style: |
    ha-card {
        {% if states('sensor.front_door_status_sc_2') == 'Locked' %}
        --card-mod-icon-color: green;
        {% elif states('sensor.front_door_status_sc_2') == 'Unlocked' %}
        --card-mod-icon-color: red;
        {% elif states('sensor.front_door_status_sc_2') == 'Open' %}
        --card-mod-icon-color: blue;
        {% elif states('sensor.front_door_status_sc_2') == 'Closed' %}
        --card-mod-icon-color: yellow;
        {% else %}
        --card-mod-icon-color: orange;
        {% endif %}
             } 

This changes the colour of the icon based on the state of the sensor, and gives you a single icon for all states of the lock and the door combined.

Will do a few more card edits to see if I can make something cleaner.

This is going to take me some work later, but here is an idea of how it looks:

Still in testing, so kind of ugly, and not perfected, But I think that “All Doors” one will work. Hopefully, with “tap action” I will also be able to lock or unlock the indivdual doors.

Here is the code that powers the “All Doors” display (Its a mess, not for production):

entities:
  - card_type: horizontal-stack
    cards:
      - entity: sensor.all_doors_status
        icon: mdi:lock
        template: menu_button
        type: custom:button-card
      - entity: sensor.front_door_status_sc_2
        card_mod:
          style: |
            ha-card {
              {% if states('sensor.front_door_status_sc_2') == 'Locked' %}
                --card-mod-icon-color: green;
              {% elif states('sensor.front_door_status_sc_2') == 'Unlocked' %}
                --card-mod-icon-color: red;
              {% elif states('sensor.front_door_status_sc_2') == 'Open' %}
                --card-mod-icon-color: blue;
              {% elif states('sensor.front_door_status_sc_2') == 'Closed' %}
                --card-mod-icon-color: yellow;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          service: lock.breezeway
        template: menu_button
        type: custom:button-card
      - entity: sensor.porch_door_status_sc
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.porch_door_status_sc') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.porch_door_status_sc') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.porch_door_status_sc') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.porch_door_status_sc') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        tap_action:
          service: lock.porch
        template: menu_button
        type: custom:button-card
      - entity: lock.breezeway
        icon: mdi:lock
        name: Breezeway
        tap_action:
          service: sensor.front_door_status
        template: menu_button
        type: custom:button-card
      - entity: lock.basement
        icon: mdi:lock
        name: Basement
        tap_action:
          service: script.samsung_upstairs_tv_input_kodi
        template: menu_button
        type: custom:button-card
    type: custom:hui-element
show_header_toggle: false
title: All Doors
type: entities

When I have more time, I will try to clean this up. In a nutshell, there are two components. One is creating the sensor that shows the combined state and the mdi icon, the other is setting the colour of the icon in the GUI.

Ok, here is the solution (so far) that does not (yet) use the toggle function. The plan I have is to allow the button to also lock/unlock the door - IF the door is closed.

First, you need the following for each of your doors to build the combined sensor:

  - platform: template
    sensors:
      front_door_status_sc:
        friendly_name: "Front Door Status Test"
        unique_id: front-door-status-9ff7b07a-9d76-48aa-99f8-931126715014
        value_template: >-
          {% if ( (is_state('lock.front_door','unlocked')) and (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) ) %}
            Unlocked
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','locked')) ) %}
            Locked Open
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) and (is_state('lock.front_door','locked')) ) %}
            Locked
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','unlocked')) ) %}
            Open
          {% else %}
            Unknown
          {% endif %}
        icon_template: >-
          {% if ( (is_state('lock.front_door','unlocked')) and (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) ) %}
            mdi:lock-open
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','locked')) ) %}
            mdi:door-closed-cancel
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) and (is_state('lock.front_door','locked')) ) %}
            mdi:lock
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','unlocked')) ) %}
            mdi:door-open
          {% else %}
            mdi:lock-question
          {% endif %}

Then you need an entities card in the GUI (I am using the css mod from above):

entities:
  - card_type: horizontal-stack
    cards:
      - entity: sensor.front_door_status_sc_2
        card_mod:
          style: |
            ha-card {
              {% if states('sensor.front_door_status_sc_2') == 'Locked' %}
                --card-mod-icon-color: green;
              {% elif states('sensor.front_door_status_sc_2') == 'Unlocked' %}
                --card-mod-icon-color: red;
              {% elif states('sensor.front_door_status_sc_2') == 'Open' %}
                --card-mod-icon-color: blue;
              {% elif states('sensor.front_door_status_sc_2') == 'Closed' %}
                --card-mod-icon-color: yellow;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          service: lock.front_door
        name: Front
        template: menu_button
        type: custom:button-card

If you do all your doors like this, you should see:

And each door shows the corresponding state and colours!

Next up… the toggle.


TOGGLE WORKING:
Here is the code for the GUI - no change to the sensor.

IMPORTANT PREREQUISITES
HACS: Add Ons Needed:

  • button-card
  • hui-element
  • card-mod

You also need to build the Multi-States for your sensors (see above).

With this, you can click on the front door icon and lock, or unlock it with a press. The only drawback is that you can lock it while the door is open - the advantage is that you can actually see that state in the icons, so you can see you messed up:

entities:
  - card_type: horizontal-stack
    cards:
      - entity: sensor.front_door_status_sc_2
        card_mod:
          style: |
            ha-card {
              {% if states('sensor.front_door_status_sc_2') == 'Locked' %}
                --card-mod-icon-color: green;
              {% elif states('sensor.front_door_status_sc_2') == 'Unlocked' %}
                --card-mod-icon-color: red;
              {% elif states('sensor.front_door_status_sc_2') == 'Open' %}
                --card-mod-icon-color: blue;
              {% elif states('sensor.front_door_status_sc_2') == 'Closed' %}
                --card-mod-icon-color: yellow;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.front_door
        name: Front
        template: menu_button
        type: custom:button-card
      - entity: sensor.porch_door_status_sc
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.porch_door_status_sc') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.porch_door_status_sc') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.porch_door_status_sc') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.porch_door_status_sc') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.deck
        name: Porch
        template: menu_button
        type: custom:button-card
      - entity: sensor.breezeway_door_status_sc
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.breezeway_door_status_sc') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.breezeway_door_status_sc') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.breezeway_door_status_sc') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.breezeway_door_status_sc') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        name: Breezeway
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.breezeway
        template: menu_button
        type: custom:button-card
      - entity: sensor.basement_door_status_sc
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.basement_door_status_sc') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.basement_door_status_sc') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.basement_door_status_sc') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.basement_door_status_sc') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        name: Basement
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.basement
        template: menu_button
        type: custom:button-card
      - entity: sensor.garage_door_status_sc
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.garage_door_status_sc') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.garage_door_status_sc') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.garage_door_status_sc') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.garage_door_status_sc') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.garage
        template: menu_button
        name: Garage
        type: custom:button-card
    type: custom:hui-element
show_header_toggle: false
title: All Doors
type: entities

I was working on some zwave configs, and because of that, I was also able to verify the “unknown” state for these icons while the zwave was down:


Ok, I think I have what can be considered the solution. First, here is what the card looks like, I have it stacked with two rows. Also, each button will toggle and lock/unlock locks or open/close garages. The color and icon of each will change according to the state:

Here is the GUI side code to make that work:

entities:
  - card_type: horizontal-stack
    cards:
      - entity: sensor.front_door_status_sc_2
        card_mod:
          style: |
            ha-card {
              {% if states('sensor.front_door_status_sc_2') == 'Locked' %}
                --card-mod-icon-color: green;
              {% elif states('sensor.front_door_status_sc_2') == 'Unlocked' %}
                --card-mod-icon-color: red;
              {% elif states('sensor.front_door_status_sc_2') == 'Open' %}
                --card-mod-icon-color: blue;
              {% elif states('sensor.front_door_status_sc_2') == 'Closed' %}
                --card-mod-icon-color: yellow;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.front_door
        name: Front
        template: menu_button
        type: custom:button-card
      - entity: sensor.porch_door_status_sc
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.porch_door_status_sc') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.porch_door_status_sc') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.porch_door_status_sc') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.porch_door_status_sc') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.deck
        name: Porch
        template: menu_button
        type: custom:button-card
      - entity: sensor.breezeway_door_status_sc
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.breezeway_door_status_sc') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.breezeway_door_status_sc') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.breezeway_door_status_sc') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.breezeway_door_status_sc') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.breezeway
        name: Breezeway
        template: menu_button
        type: custom:button-card
      - entity: sensor.basement_door_status_sc
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.basement_door_status_sc') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.basement_door_status_sc') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.basement_door_status_sc') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.basement_door_status_sc') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        name: Basement
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.basement
        template: menu_button
        type: custom:button-card
    type: custom:hui-element
  - card_type: horizontal-stack
    cards:
      - entity: sensor.garage_door_status_sc
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.garage_door_status_sc') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.garage_door_status_sc') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.garage_door_status_sc') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.garage_door_status_sc') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.garage
        template: menu_button
        name: Garage
        type: custom:button-card
      - entity: sensor.garage_east_door_status_sc
        card_mod:
          style: |
            ha-card {
              {% if states('cover.garage_door_2') == 'open' %}
                --card-mod-icon-color: red;
              {% elif states('cover.garage_door_2') == 'closed' %}
                --card-mod-icon-color: green;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          action: call-service
          service: cover.toggle
          target:
            entity_id: cover.garage_door_2
        name: East
        template: menu_button
        type: custom:button-card
      - entity: sensor.garage_west_door_status_sc
        card_mod:
          style: |
            ha-card {
              {% if states('cover.garage_door') == 'open' %}
                --card-mod-icon-color: red;
              {% elif states('cover.garage_door') == 'closed' %}
                --card-mod-icon-color: green;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          action: call-service
          service: cover.toggle
          target:
            entity_id: cover.garage_door
        name: East
        template: menu_button
        type: custom:button-card
      - entity: sensor.garage_shop_door_status_sc
        card_mod:
          style: |
            ha-card {
              {% if states('cover.sgarage') == 'open' %}
                --card-mod-icon-color: red;
              {% elif states('cover.sgarage') == 'closed' %}
                --card-mod-icon-color: green;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          action: call-service
          service: cover.toggle
          target:
            entity_id: cover.sgarage
        name: Shop
        template: menu_button
        type: custom:button-card
    type: custom:hui-element
show_header_toggle: false
title: All Doors
type: entities 

Within my sensor.yaml I have created some entities that change to power the GUI component:


###############################################
# TEMPLATES For Door States and Garage States #
###############################################

  - platform: template
    sensors:
      front_door_status_sc:
        friendly_name: "Front Door Status"
        unique_id: front-door-status-9ff7b07a-9d76-48aa-99f8-931126715014
        value_template: >-
          {% if ( (is_state('lock.front_door','unlocked')) and (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) ) %}
            Unlocked
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','locked')) ) %}
            Locked Open
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) and (is_state('lock.front_door','locked')) ) %}
            Locked
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','unlocked')) ) %}
            Open
          {% else %}
            Unknown
          {% endif %}
        icon_template: >-
          {% if ( (is_state('lock.front_door','unlocked')) and (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) ) %}
            mdi:lock-open
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','locked')) ) %}
            mdi:door-closed-cancel
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','off')) and (is_state('lock.front_door','locked')) ) %}
            mdi:lock
          {% elif ( (is_state('binary_sensor.door_front_entry_window_door_is_open','on')) and (is_state('lock.front_door','unlocked')) ) %}
            mdi:door-open
          {% else %}
            mdi:lock-question
          {% endif %}

  - platform: template
    sensors:
      porch_door_status_sc:
        friendly_name: "Porch Door Status"
        unique_id: porch-door-status-8ac9a06a-2d77-48aa-99f8-941226715014
        value_template: >-
          {% if ( (is_state('lock.deck','unlocked')) and (is_state('binary_sensor.door_porch_window_door_is_open','off')) ) %}
            Unlocked
          {% elif ( (is_state('binary_sensor.door_porch_window_door_is_open','on')) and (is_state('lock.deck','locked')) ) %}
            Locked Open
          {% elif ( (is_state('binary_sensor.door_porch_window_door_is_open','off')) and (is_state('lock.deck','locked')) ) %}
            Locked
          {% elif ( (is_state('binary_sensor.door_porch_window_door_is_open','on')) and (is_state('lock.deck','unlocked')) ) %}
            Open
          {% else %}
            Unknown
          {% endif %}
        icon_template: >-
          {% if ( (is_state('lock.deck','unlocked')) and (is_state('binary_sensor.door_porch_window_door_is_open','off')) ) %}
            mdi:lock-open
          {% elif ( (is_state('binary_sensor.door_porch_window_door_is_open','on')) and (is_state('lock.deck','locked')) ) %}
            mdi:door-closed-cancel
          {% elif ( (is_state('binary_sensor.door_porch_window_door_is_open','off')) and (is_state('lock.deck','locked')) ) %}
            mdi:lock
          {% elif ( (is_state('binary_sensor.door_porch_window_door_is_open','on')) and (is_state('lock.deck','unlocked')) ) %}
            mdi:door-open
          {% else %}
            mdi:lock-question
          {% endif %}

  - platform: template
    sensors:
      breezeway_door_status_sc:
        friendly_name: "Breezeway Door Status"
        unique_id: breezeway-door-status-2ad4a16a-3d68-48bb-11f8-491226726111
        value_template: >-
          {% if ( (is_state('lock.breezeway','unlocked')) and (is_state('binary_sensor.door_breezeway_window_door_is_open','off')) ) %}
            Unlocked
          {% elif ( (is_state('binary_sensor.door_breezeway_window_door_is_open','on')) and (is_state('lock.breezeway','locked')) ) %}
            Locked Open
          {% elif ( (is_state('binary_sensor.door_breezeway_window_door_is_open','off')) and (is_state('lock.breezeway','locked')) ) %}
            Locked
          {% elif ( (is_state('binary_sensor.door_breezeway_window_door_is_open','on')) and (is_state('lock.breezeway','unlocked')) ) %}
            Open
          {% else %}
            Unknown
          {% endif %}
        icon_template: >-
          {% if ( (is_state('lock.breezeway','unlocked')) and (is_state('binary_sensor.door_breezeway_window_door_is_open','off')) ) %}
            mdi:lock-open
          {% elif ( (is_state('binary_sensor.door_breezeway_window_door_is_open','on')) and (is_state('lock.breezeway','locked')) ) %}
            mdi:door-closed-cancel
          {% elif ( (is_state('binary_sensor.door_breezeway_window_door_is_open','off')) and (is_state('lock.breezeway','locked')) ) %}
            mdi:lock
          {% elif ( (is_state('binary_sensor.door_breezeway_window_door_is_open','on')) and (is_state('lock.breezeway','unlocked')) ) %}
            mdi:door-open
          {% else %}
            mdi:lock-question
          {% endif %}

  - platform: template
    sensors:
      basement_door_status_sc:
        friendly_name: "Basement Door Status"
        unique_id: breezeway-door-status-2bb6c26a-3a72-44bc-42f5-495256726115
        value_template: >-
          {% if ( (is_state('lock.basement','unlocked')) and (is_state('binary_sensor.door_basement_window_door_is_open','off')) ) %}
            Unlocked
          {% elif ( (is_state('binary_sensor.door_basement_window_door_is_open','on')) and (is_state('lock.basement','locked')) ) %}
            Locked Open
          {% elif ( (is_state('binary_sensor.door_basement_window_door_is_open','off')) and (is_state('lock.basement','locked')) ) %}
            Locked
          {% elif ( (is_state('binary_sensor.door_basement_window_door_is_open','on')) and (is_state('lock.basement','unlocked')) ) %}
            Open
          {% else %}
            Unknown
          {% endif %}
        icon_template: >-
          {% if ( (is_state('lock.basement','unlocked')) and (is_state('binary_sensor.door_basement_window_door_is_open','off')) ) %}
            mdi:lock-open
          {% elif ( (is_state('binary_sensor.door_basement_window_door_is_open','on')) and (is_state('lock.basement','locked')) ) %}
            mdi:door-closed-cancel
          {% elif ( (is_state('binary_sensor.door_basement_window_door_is_open','off')) and (is_state('lock.basement','locked')) ) %}
            mdi:lock
          {% elif ( (is_state('binary_sensor.door_basement_window_door_is_open','on')) and (is_state('lock.basement','unlocked')) ) %}
            mdi:door-open
          {% else %}
            mdi:lock-question
          {% endif %}

  - platform: template
    sensors:
      garage_door_status_sc:
        friendly_name: "Garage Door Status"
        unique_id: garage-door-status-1bbbc85a-2cf2-444f-42f6-405056726105
        value_template: >-
          {% if ( (is_state('lock.garage','unlocked')) and (is_state('binary_sensor.door_garage_window_door_is_open','off')) ) %}
            Unlocked
          {% elif ( (is_state('binary_sensor.door_garage_window_door_is_open','on')) and (is_state('lock.garage','locked')) ) %}
            Locked Open
          {% elif ( (is_state('binary_sensor.door_garage_window_door_is_open','off')) and (is_state('lock.garage','locked')) ) %}
            Locked
          {% elif ( (is_state('binary_sensor.door_garage_window_door_is_open','on')) and (is_state('lock.garage','unlocked')) ) %}
            Open
          {% else %}
            Unknown
          {% endif %}
        icon_template: >-
          {% if ( (is_state('lock.garage','unlocked')) and (is_state('binary_sensor.door_garage_window_door_is_open','off')) ) %}
            mdi:lock-open
          {% elif ( (is_state('binary_sensor.door_garage_window_door_is_open','on')) and (is_state('lock.garage','locked')) ) %}
            mdi:door-closed-cancel
          {% elif ( (is_state('binary_sensor.door_garage_window_door_is_open','off')) and (is_state('lock.garage','locked')) ) %}
            mdi:lock
          {% elif ( (is_state('binary_sensor.door_garage_window_door_is_open','on')) and (is_state('lock.garage','unlocked')) ) %}
            mdi:door-open
          {% else %}
            mdi:lock-question
          {% endif %}

  - platform: template
    sensors:
      garage_east_door_status_sc:
        friendly_name: "Garage Door East Status"
        unique_id: garage-door-east-status-1ffac45a-2bf2-d44e-32f6-411156726102
        value_template: >-
          {% if ( (is_state('cover.garage_door_2','open')) ) %}
            Open
          {% elif ( (is_state('cover.garage_door_2','closed')) ) %}
            Closed
          {% elif ( (is_state('cover.garage_door_2','closing')) ) %}
            Closing
          {% elif ( (is_state('cover.garage_door_2','opening')) ) %}
            Opening
          {% else %}
            Unknown
          {% endif %}
        icon_template: >-
          {% if ( (is_state('cover.garage_door_2','open')) ) %}
            mdi:garage-open-variant
          {% elif ( (is_state('cover.garage_door_2','closed')) ) %}
            mdi:garage-variant
          {% elif ( (is_state('cover.garage_door_2','closing')) ) %}
            mdi:arrow-down-box
          {% elif ( (is_state('cover.garage_door_2','opening')) ) %}
            mdi:arrow-up-box
          {% else %}
            mdi:garage-alert-variant
          {% endif %}

  - platform: template
    sensors:
      garage_west_door_status_sc:
        friendly_name: "Garage Door West Status"
        unique_id: garage-door-west-status-2baac34a-5aa3-d44b-3bf7-400151726002
        value_template: >-
          {% if ( (is_state('cover.garage_door','open')) ) %}
            Open
          {% elif ( (is_state('cover.garage_door','closed')) ) %}
            Closed
          {% else %}
            Unknown
          {% endif %}
        icon_template: >-
          {% if ( (is_state('cover.garage_door','open')) ) %}
            mdi:garage-open-variant
          {% elif ( (is_state('cover.garage_door','closed')) ) %}
            mdi:garage-variant
          {% elif ( (is_state('cover.garage_door','closing')) ) %}
            mdi:arrow-down-box
          {% elif ( (is_state('cover.garage_door','opening')) ) %}
            mdi:arrow-up-box
          {% else %}
            mdi:garage-alert-variant
          {% endif %}

  - platform: template
    sensors:
      garage_shop_door_status_sc:
        friendly_name: "Garage Door Shop Status"
        unique_id: garage-door-shop-status-3abbd45b-6bc5-b37a-2bf7-400151726002
        value_template: >-
          {% if ( (is_state('cover.sgarage','open')) ) %}
            Open
          {% elif ( (is_state('cover.sgarage','closed')) ) %}
            Closed
          {% else %}
            Unknown
          {% endif %}
        icon_template: >-
          {% if ( (is_state('cover.sgarage','open')) ) %}
            mdi:garage-open-variant
          {% elif ( (is_state('cover.sgarage','closed')) ) %}
            mdi:garage-variant
          {% elif ( (is_state('cover.sgarage','closing')) ) %}
            mdi:arrow-down-box
          {% elif ( (is_state('cover.sgarage','opening')) ) %}
            mdi:arrow-up-box
          {% else %}
            mdi:garage-alert-variant
          {% endif %}

You need both of these components for it to function. As I mentioned above:
HACS: Add Ons Needed:

  • button-card
  • hui-element
  • card-mod

Some things that I have not done, but you could do:

  • add in a hold-action to do something like lock all doors
  • add logic to not lock a door if it is open
  • maybe fix the closed status in my templates that never gets called
2 Likes

@Mr_Flibble I want to implement your cards here but lovelace is barking at me about

Button-card template ‘menu_button’ is missing!

Can you tell me how to find that?

Have you added the HACS addons listed, and restarted Home Assistant? If I remember correctly menu_button is part of one of those packages, and you need to restart for it to load. Been a while since I made it (they still work today).

Yes, I do have them installed and I have restarted HA. Still no joy.

What does your code look like at the moment?

Sorry it took so long, I was otherwise occupied. So here’s just a single card with the “template: menu_button” line in it:

entities:
  - card_type: horizontal-stack
    cards:
      - entity: sensor.front_door_status
        card_mod:
          style: |
            ha-card {
              {% if states('sensor.front_door_status') == 'Locked' %}
                --card-mod-icon-color: green;
              {% elif states('sensor.front_door_status') == 'Unlocked' %}
                --card-mod-icon-color: red;
              {% elif states('sensor.front_door_status') == 'Open' %}
                --card-mod-icon-color: blue;
              {% elif states('sensor.front_door_status') == 'Closed' %}
                --card-mod-icon-color: yellow;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.front_door
        name: Front
        template: menu_button
        type: custom:button-card
    type: custom:hui-element
show_header_toggle: false
title: All Doors
type: entities

and it blows up just like this

but if I comment out that line then I get this card

so it’s definitely something it doesn’t like trying to use that template that should be there and should work.

I just manually entered the card with your code in Home Assistant by going to Edit → Add Card → Manual and pasted in your code. I then changed the name of the sensor to match mine, but otherwise left everything the same. It works for my door, but has the wrong icon:

entities:
  - card_type: horizontal-stack
    cards:
      - entity: sensor.front_door_status
        card_mod:
          style: |
            ha-card {
              {% if states('sensor.front_door_status_sc_2') == 'Locked' %}
                --card-mod-icon-color: green;
              {% elif states('sensor.front_door_status_sc_2') == 'Unlocked' %}
                --card-mod-icon-color: red;
              {% elif states('sensor.front_door_status_sc_2') == 'Open' %}
                --card-mod-icon-color: blue;
              {% elif states('sensor.front_door_status_sc_2') == 'Closed' %}
                --card-mod-icon-color: yellow;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.front_door
        name: Front
        template: menu_button
        type: custom:button-card
    type: custom:hui-element
show_header_toggle: false
title: All Doors
type: entities

This is probably because I have components directly in my sensor.yaml file, and as they don’t match, I am not loading the right image in this case. I think it might just be a formatting issue with the YAML? I can’t really see anything else amiss?

Ok, I have mine fully working - I had the name out a bit for my sensors:

Here is the code:

entities:
  - card_type: horizontal-stack
    cards:
      - entity: sensor.front_door_status_sc_2
        card_mod:
          style: |
            ha-card {
              {% if states('sensor.front_door_status_sc_2') == 'Locked' %}
                --card-mod-icon-color: green;
              {% elif states('sensor.front_door_status_sc_2') == 'Unlocked' %}
                --card-mod-icon-color: red;
              {% elif states('sensor.front_door_status_sc_2') == 'Open' %}
                --card-mod-icon-color: blue;
              {% elif states('sensor.front_door_status_sc_2') == 'Closed' %}
                --card-mod-icon-color: yellow;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.front_door
        name: Front
        template: menu_button
        type: custom:button-card
    type: custom:hui-element
show_header_toggle: false
title: All Doors
type: entities

My guess is that you need something in there like my sensor.yaml? Thats doing half the work for me.

Yeah it’s weird. I have the sensor.yaml set up and when I build out my entire card it works just fine as you can see in the image below. The colors and icons are being accurately reflected but as soon as I add the “template: menu_button” line it blows up. To be perfectly honest I don’t know what I’m not getting out of not having it so maybe it doesn’t really even matter.

Here’s my working YAML without that one line

type or paste code hereentities:
  - card_type: horizontal-stack
    cards:
      - entity: sensor.front_door_status
        card_mod:
          style: |
            ha-card {
              {% if states('sensor.front_door_status') == 'Locked' %}
                --card-mod-icon-color: green;
              {% elif states('sensor.front_door_status') == 'Unlocked' %}
                --card-mod-icon-color: red;
              {% elif states('sensor.front_door_status') == 'Open' %}
                --card-mod-icon-color: blue;
              {% elif states('sensor.front_door_status') == 'Closed' %}
                --card-mod-icon-color: yellow;
              {% else %}
                --card-mod-icon-color: orange;
              {% endif %}
                 } 
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.front_door
        name: Front
        type: custom:button-card
      - entity: sensor.back_door_status
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.back_door_status') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.back_door_status') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.back_door_status') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.back_door_status') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        tap_action:
          action: call-service
          service: |
            [[[
              return (entity.state === 'Locked') ? 'lock.unlock' : 'lock.lock';
            ]]]
          service_data:
            entity_id: lock.back_door
        name: Back
        type: custom:button-card
      - entity: sensor.garage_door_status
        card_mod:
          style: |
            ha-card {
                {% if states('sensor.garage_door_status') == 'Locked' %}
                --card-mod-icon-color: green;
                {% elif states('sensor.garage_door_status') == 'Unlocked' %}
                --card-mod-icon-color: red;
                {% elif states('sensor.garage_door_status') == 'Open' %}
                --card-mod-icon-color: blue;
                {% elif states('sensor.garage_door_status') == 'Closed' %}
                --card-mod-icon-color: yellow;
                {% else %}
                --card-mod-icon-color: orange;
                {% endif %}
                     }
        tap_action:
          action: call-service
          service: cover.toggle
          service_data:
            entity_id: cover.msg100_38be_garage_door
        name: Garage
        type: custom:button-card
    type: custom:hui-element
show_header_toggle: false
title: All Doors
type: entities

The card looks good and accurately reflects the states of the locks and cover. I even tested open/close of the garage door, and got the up and down arrows.

So I’m not really sure what the actual issue is unless you can tell me what that template: menu_button does?

Anyway thanks for all your help so far.

I mean, if it does what you want, and works without it, then don’t use it! I totally forget why I used it for mine now, been a few months since I figured out how to make it work, and is has been working perfectly ever since.

Thanks again…now I have to get the YAML formatting so I can embed this inside another series of cards…yuck.