I’m using this code that is still working on 2022.6.0 2022.6.2:
# Automations of the last 8 hours, but do not display more than 40
**Zeit Name**
{% for state in (states.automation
| rejectattr('attributes.last_triggered', 'in', ['None', 'none', 'unknown'])
| selectattr('attributes.last_triggered')
| selectattr('state', 'ne', 'unavailable')
| sort(attribute='attributes.last_triggered', reverse=true)) [0:40] -%}
{% if state.attributes.last_triggered and (now() - state.attributes.last_triggered).total_seconds() < 28800 %}
{%- set t = (as_timestamp(state.attributes.last_triggered) | timestamp_custom('%H:%M', true)) -%}
{{t}} _{{state.name}}_
{% endif -%}
{% endfor %}
Thanks! I tried your code and got no output also. This is my formerly working code.
|H|M||Name|
|----:|----:|:--:|:----|
{% for state in states.automation
|selectattr('attributes.last_triggered')
|sort(attribute='attributes.last_triggered', reverse=true)
if (now() - state.attributes.last_triggered).total_seconds() < 43200 %}
{%- set t = now() - state.attributes.last_triggered -%}
{%- set days = t.days if t.days > 0 else ' ' -%}
{%- set hrs = t.seconds//3600 %}
{%- set hrs = hrs if hrs > 0 else ' ' -%}
|{{hrs}}|{{(t.seconds//60)%60}}||_{{state.name}}_|
{% endfor %}
The state of one of your automations is unknown (go to Developer Tools → States and confirm it) and so it doesn’t have a last_triggered attribute. The existing template doesn’t handle that situation gracefully.
I suggest you add a filter to select only automations that have a defined last_triggered attribute (it’s the same advice parautenbach offered).
{% for state in states.automation
|selectattr('attributes.last_triggered', 'defined')
|selectattr('attributes.last_triggered')
... etc ...
The only significant modification to the original code was described on June 9 (three posts before your post). To prevent an error, it ensures it only references automations that have a last_triggered attribute.
If you want it to be very thorough about which automations are excluded/included, you can add the following three selectattr filters to the template:
{% for state in states.automation
| selectattr('state', 'ne', 'unavailable')
| selectattr('attributes.last_triggered', 'defined')
| selectattr('attributes.last_triggered', 'ne', None)
... etc ...
Hi this isn’t working for me. I am running 2022.11.4 Core and get the error: TypeError: '<' not supported between instances of 'str' and 'datetime.datetime'
The exact same code works fine for sensors though.
The following does work:
{{ states.automation
| selectattr('attributes.last_triggered')
| map(attribute='entity_id')
| list }}
I’m not sure if it is relevant, but when I ran the following, I got 2 different formats of timestamp back - one with a ‘T’ between date and time, and one without.
Fwiw, I use a combination of the auto-entities-card with the multiple-entity-row which has the benefit of being able to directly go into the respective entity dialogue:
Hi folks,
I combined some of the ideas above to show automations and scripts (which may have been called by those automations).
Feel free to adjust how many items are to be used (curently 50 as per … “[:50]”) and how big the time window should be (curerntly 24h … as per " < 86400").
Br
/Fdo.
**Time Name**
{% set ns = namespace(a=[]) %}
{% set ns.a = (states.automation
| selectattr('state', 'ne', 'unavailable')
| selectattr('attributes.last_triggered', 'defined')
| selectattr('attributes.last_triggered', 'ne', None)
| selectattr('attributes.last_triggered')
| sort(attribute='attributes.last_triggered', reverse=true)) -%}
{% set ns2 = namespace(s=[]) %}
{% set ns2.s = (states.script
| selectattr('state', 'ne', 'unavailable')
| selectattr('attributes.last_triggered', 'defined')
| selectattr('attributes.last_triggered', 'ne', None)
| selectattr('attributes.last_triggered')
| sort(attribute='attributes.last_triggered', reverse=true)) -%}
{% for i in ns2.s %}
{% set ns.a = ns.a + [i] %}
{% endfor %}
{%- for state in (ns.a | sort(attribute='attributes.last_triggered', reverse=true))[:50] -%}
{%- if (now() - state.attributes.last_triggered).total_seconds() < 86400 %}
{%- set t = (as_timestamp(state.attributes.last_triggered) | timestamp_custom('%H:%M:%S', true)) -%}
{%- if state.entity_id.startswith("automation") -%}
{{t}} - (a): _{{state.name}}_
{%- else -%}
{{t}} --- (s): _{{state.name}}_
{%- endif %}
{% endif -%}
{%- endfor -%}
These are the ones I ended up using. I lay them out in a 2x2 grid using custom:grid-layout (hence the view_layout: grid-area: x) & happy to share that if anyone is interested).
- type: markdown
view_layout:
grid-area: a
title: Automations last triggered today
content: >
<table>
<tr>
<th> Time </th>
<th align=left>   Automation </th>
</tr>
{% for state in (states.automation
| selectattr('attributes.last_triggered', 'defined')
| rejectattr('attributes.last_triggered', 'in', ['None', 'none', 'unknown'])
| selectattr('attributes.last_triggered')
| selectattr('state', 'ne', 'unavailable')
| sort(attribute='attributes.last_triggered', reverse=true)) [0:40] -%}
{%- set time = state.attributes.last_triggered.timestamp() |timestamp_custom('%X') -%}
{%- if state.attributes.last_triggered > today_at("00:00") -%}
{%- set t = (as_timestamp(state.attributes.last_triggered) | timestamp_custom('%H:%M', true)) -%}
<tr align=left>
<th>   {{time}}   </th>
<td>   {{state.name}} </td>
</tr>
{% endif -%}
{% endfor %}
</table>
- type: markdown
view_layout:
grid-area: b
title: Scripts last ran today
content: >
<table>
<tr>
<th> Time </th>
<th align=left>   Automation </th>
</tr>
{% for state in states.script
|selectattr('attributes.last_triggered')
|sort(attribute='attributes.last_triggered', reverse=true) %}
{%- set time = state.attributes.last_triggered.timestamp() |timestamp_custom('%X') -%}
{%- if state.attributes.last_triggered > today_at("00:00") -%}
<tr align=left>
<th>   {{time}}   </th>
<td>   {{state.name}} </td>
</tr>
{% endif -%}
{% endfor %}
</table>
- type: markdown
view_layout:
grid-area: c
title: Other Automations Last triggered
content: >
<table>
<tr>
<th> Days </th>
<th> Date </th>
<th> Time </th>
<th align=left>   Automation </th>
</tr>
{% for state in (states.automation
|selectattr('state', 'ne', 'unavailable')
|selectattr('attributes.last_triggered', 'ne', None)
|selectattr('attributes.last_triggered')
|sort(attribute='attributes.last_triggered',reverse=true)) %}
{%- set t = now() - state.attributes.last_triggered -%}
{%- set date = state.attributes.last_triggered.timestamp() |timestamp_custom('%d/%m/%Y') -%}
{%- set time = state.attributes.last_triggered.timestamp() |timestamp_custom('%X') -%}
{%- if state.attributes.last_triggered < today_at("00:00") -%}
<tr align=left>
<td align=right> -{{t.days}}   </td>
<th> {{date}}   </th>
<td>   {{time}}   </td>
<td>   {{state.name}} </td>
</tr>
{% endif -%}
{% endfor -%}
</table>
- type: markdown
view_layout:
grid-area: d
title: Other scripts last ran
content: >
<table>
<tr>
<th> Days </th>
<th> Date </th>
<th> Time </th>
<th align=left>   Script </th>
</tr>
{% for state in states.script
|selectattr('attributes.last_triggered')
|sort(attribute='attributes.last_triggered', reverse=true) %}
{%- set t = now() - state.attributes.last_triggered -%}
{%- set date = state.attributes.last_triggered.timestamp() |timestamp_custom('%d/%m/%Y') -%}
{%- set time = state.attributes.last_triggered.timestamp() |timestamp_custom('%X') -%}
{%- if state.attributes.last_triggered < today_at("00:00") -%}
<tr align=left>
<td align=right> -{{t.days}}   </td>
<th> {{date}}   </th>
<td>   {{time}}   </td>
<td>   {{state.name}} </td>
</tr>
{% endif -%}
{% endfor -%}
</table>
edit: updated as accidentally posted an older version.
but… since we can have most of that directly in the Automations UI these days, and set any selector/order you need there, Ive personally moved all of these cards to the trash, and simply add a button that navigates to the automatons dashboard