I’m sure someone one day might find this useful. I have about 140 automations and one of them is doing something funky, but I don’t know which one. This little template helps me narrow down to see which automation just ran in the last x mins so I know which ones to look at. Just paste this into your template editor and change the set mins variable and it will output the automations that just ran within that time period.
{% set mins = 3 %}
{%- for state in states.automation -%}
{%- if loop.first %}{% elif loop.last -%}
{%- else -%}
{%- endif -%}
{%- if (as_timestamp(state.attributes.last_triggered)|int) > (now().strftime("%s")|int - (mins*60)) -%}
{{state.entity_id}}:
last triggered: {{as_timestamp(state.attributes.last_triggered)|timestamp_custom("%H:%M") }}
{% endif %}
{%- endfor -%}
I think the template contains ‘leftovers’ from something else and its those leftovers that are puzzling.
This works without the puzzling bits:
{% set mins = 3 %}
{%- for state in states.automation -%}
{% set last = as_timestamp(state.attributes.last_triggered) %}
{% set current = as_timestamp(now()) - (mins*60) %}
{%- if (last != None) and last > current -%}
{{state.entity_id}}:
last triggered: {{last|timestamp_custom("%H:%M") }}
{% endif %}
{%- endfor -%}
EDIT
Incorporated improvement made by @klogg
Replaced:
the template doesn’t work in my setup, but I track my automations with this automation
- alias: Automation ran
id: 'Automation ran'
# initial_state: 'off'
trigger:
platform: event
event_type: state_changed
condition:
condition: template
value_template: >
{% set skip_list = ['automation_ran', 'count_warnings', 'count_errors',
'activate_map_sensors_actueel', 'call_family_home',
'timed_python_scripts_per_20_secs'] %}
{{ trigger.event.data.entity_id.startswith('automation.') and
trigger.event.data.entity_id.split('.')[1] not in skip_list and
'old_state' in trigger.event.data and 'new_state' in trigger.event.data }}
action:
- condition: template
value_template: >
{{ trigger.event.data.new_state.attributes.last_triggered !=
trigger.event.data.old_state.attributes.last_triggered }}
- service: notify.filed_automations
data_template:
message: >
{{ as_timestamp(trigger.event.data.new_state.last_updated)|timestamp_custom('%d %b: %X') }}: {{ trigger.event.data.new_state.name }}
- service: python_script.last_automation
data_template:
event: '{{ trigger.event }}'
the services in the action block are 2-fold:
the first writes the automation to a file, so I can always check the history,
the second shows a sensor in the frontend, so I can see it happening.
As a kind of double check, I’ve also got the last automation of automations file displayed in the front-end.
There are some great people on this forum but I’m especially loving @123 lately.
This is not the first time in the last few days he/she has been ‘hooked’ by something and decided to look into a solution, apparently just for the fun of it!
Just one question, can you tell me the sensor name that it creates on the front end? Also, I assume that this requires your yaml to be inserted into automations?
sure, but as said there are really 2 files. One made by the python script last_automation.py, called sensor.last_automation:
##############################################################################
# Last automation, to create a sensor for the last automation. It takes as data the trigger.event form the automation.automation_ran
# Take note: an automation's attribute last_triggered is only set when the action part is executed (and not when the trigger gets triggered....)
# @Mariusthvdb
##############################################################################
# Get params
event = data.get('event')
#logger.error("LAST AUTOMATION: " + str(event))
# Sample: <Event call_service[L]: domain=automation, service=trigger, service_data=entity_id=automation.call_service_event_automation, service_call_id=1972124944-486>
# Find the automation name
#** pos_start = event.find('entity_id=')+10
pos_start = event.find('entity_id=')+21
pos_end = event.find(',', pos_start)
# Get the entity_id
#** entity_id = event[pos_start:pos_end]
entity_id = 'automation.' + event[pos_start:pos_end]
# get the state object
state = hass.states.get(entity_id)
# Make a time string in 24 hour format
#time_string = datetime.datetime.now().strftime('%I:%M')
dt = datetime.datetime.now() #state.attributes.get('last_triggered') #
time = "%02d:%02d:%02d" % (dt.hour, dt.minute, dt.second)
# try to get the automation friendly name
msg = []
try:
msg = state.name
except:
msg = None
if msg:
if not msg.startswith('Set '):
# Sensor update
hass.states.set('sensor.last_automation', msg, {
# 'custom_ui_state_card': 'state-card-value_only',
# 'text': sensor_message,
'unit_of_measurement': 'Aut',
'friendly_name': time,
'entity_picture': '/local/buttons/play-mode-repeat.png' })
It’s definitely for the fun of it, certainly not for the Likes which seem to be issued randomly.
There have been cases where I’ve provided almost the entire solution … and get no Likes (zero appreciation). Better yet, the person who requested assistance tags their own post as the ‘solution’.
So, yeah, for the fun of it, definitely not for the Likes.
It didn’t work for me as you have it in that post.
This does work though:
{% set mins = 3 %}
{%- for state in states.automation -%}
{% set last = as_timestamp(state.attributes.last_triggered)|int %}
{% set current = as_timestamp(now()) - (mins*60) %}
{%- if last > current -%}
{{state.entity_id}}:
last triggered: {{last|timestamp_custom("%H:%M") }}
{% endif %}
{%- endfor -%}
I needed to convert the attribute in the “last” line to an “int”.
if the last_triggered is a null value then the template returns an unknown value for “last” then it errors out trying to compare an unknown (or None?) to a float.
if you force the last result to an int then the null becomes a 0 and everything works as expected.