My Dashboard Card that displays unavailable devices

I finally finished a project I’ve been wanting to do for ages!

I needed some way to see every device that’d gone offline in Home Assistant, and then narrow that down to only the ones I cared about, not “unnamed” devices.

This is the final card view:

I used ChatGPT to help me out with a lot of coaxing. That means the code is pretty awful.

Here’s what I got working:

type: markdown
title: Unavailable Devices
content: >-
  {% set ignore_names = [
    "Christmas Lights",
    "Everything Presence Lite",
    "Home Assistant Voice",
    "IKEA of Sweden TRADFRI",
    "Tagreader",
    "sengled",
    "Signify Netherlands",
    "WLED"
  ] %}


  {% set ns = namespace(devices=[], dates=[]) %}


  {#-- Step 1: Gather unique devices with unavailable entities --#}

  {% for e in states if e.state == 'unavailable' and e.domain in ['sensor',
  'light'] %}
    {% set dev_id = device_id(e.entity_id) %}
    {% set dev_name = device_attr(e.entity_id, 'name') or e.name %}
    {% set is_ignored = ignore_names | select('in', dev_name) | list | count > 0 %}
    {% if not is_ignored and (ns.devices | selectattr('device_id', 'equalto', dev_id) | list | count == 0) %}
      {% set formatted_time = e.last_changed.strftime('%I:%M%p').replace('AM', 'a').replace('PM', 'p') %}
      {% set device_date = e.last_changed.strftime('%m-%d-%Y') %}
      {% set device = {
        'device_id': dev_id,
        'name': dev_name,
        'last_changed': e.last_changed.timestamp(),
        'display_time': formatted_time,
        'date': device_date
      } %}
      {% set ns.devices = ns.devices + [device] %}
    {% endif %}
  {% endfor %}


  {#-- Step 2: Sort devices by time descending --#}

  {% set sorted = ns.devices | sort(attribute='last_changed', reverse=true) %}


  {#-- Step 3: Collect unique dates using a namespace --#}

  {% for item in sorted %}
    {% if item.date not in ns.dates %}
      {% set ns.dates = ns.dates + [item.date] %}
    {% endif %}
  {% endfor %}


  {#-- Step 4: Render one table per date --#}

  {% if ns.dates | length == 0 %}
    No unavailable devices 🎉
  {% else %}

  {% for date in ns.dates %}

  <h3>{{ date }}</h3>

  <table width="100%">

  {% for item in sorted if item.date == date %}
    <tr>
      <td>
        <a href="/config/devices/device/{{ item.device_id }}" target="_blank">
          <strong>{{ item.name }}</strong>
        </a>
      </td>
      <td>{{ item.display_time }}</td>
    </tr>
  {% endfor %}

  </table>

  {% endfor %}

  {% endif %}
text_only: true

Next steps

This is just the card, but getting this list can help in automations as well. Next step is to create an automation that uses this list and notifies me with a fancy email template and a push notification when a device has been offline for 6 hours.

While I have a battery monitor automation, I’ve yet to have it go off. A lot of my devices simply just drop off, and unless I watch the dashboards closely, I wouldn’t know.

This automation will also resolve the issue of battery-powered devices, like the Philips Hue Motion Sensor, always showing 100% battery life until its depletion. I’m stuck wondering why the lights won’t come on or went off suddenly. It’s not easy to find when you have multiple sensors.

4 Likes

@Sawtaytoes /… fyi, the date and time will reset at any system restart, which makes that info not helpful depending. Many users have, rightfully, complained asked devs to fix that but the devs don’t care to - so we have very incorrect info in all our entities, frequently for those that update our systems at all.

btw, this will provide an easy way to get an email notification…

1 Like