Why does this template throw an error every second

using a markdown card with:

{% for state in (states.automation
     |selectattr('attributes.last_triggered')
     |sort(attribute='attributes.last_triggered',reverse=true))
     if (now() - state.attributes.last_triggered).days < 1 -%}
{{state.attributes.last_triggered.timestamp()
  |timestamp_custom('%d-%m %H:%M:%S')}} : {{state.name}}
{% endfor %}

shows a fine card in the frontend.

but, when I use this in the template editor, I see it update every second, and in the HA log:

2022-02-07 15:27:38 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'last_triggered' when rendering '{% for state in (states.automation
     |selectattr('attributes.last_triggered')
     |sort(attribute='attributes.last_triggered',reverse=true))
     if (now() - state.attributes.last_triggered).days < 1 -%}
{{state.attributes.last_triggered.timestamp()
  |timestamp_custom('%d-%m %H:%M:%S')}} : {{state.name}}
{% endfor %}'

why is this?

Not sure if this is the cause but do you have any automations that have never been triggered?

a thats clever indeed!

and yes I do :wink:

Add this filter after states.automation

   | selectattr('attributes.last_triggered', 'ne', None)

I was already in an effort using:

{% for state in states.automation
     |selectattr('attributes.last_triggered')
     |rejectattr('attributes.last_triggered','eq',None)
     |sort(attribute='attributes.last_triggered',reverse=true)
     if (now() - state.attributes.last_triggered).days < 1 -%}
{{state.attributes.last_triggered.timestamp()
  |timestamp_custom('%d-%m %H:%M:%S')}} : {{state.name}}
{% endfor %}

but that doesnt make a difference, and your suggestion:


{% for state in states.automation
| selectattr('attributes.last_triggered', 'ne', None)
     |sort(attribute='attributes.last_triggered',reverse=true)
     if (now() - state.attributes.last_triggered).days < 1 -%}
{{state.attributes.last_triggered.timestamp()
  |timestamp_custom('%d-%m %H:%M:%S')}} : {{state.name}}
{% endfor %}

errors completely:

UndefinedError: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'last_triggered'

never saw ‘null’ in the dev editor:

replacing that (null) in the template results in

TypeError: '<' not supported between instances of 'NoneType' and 'datetime.datetime'
{{state_attr('automation.saver_offline','last_triggered') is none}}

is True

and, to confirm you suspicion, after turning off those non-triggered automations, the template stops being updated each second. So I really need to find out how to reject those automations.

Here’s what I use to list recently triggered automations in a Markup card. I just tested it in the Template Editor without errors.

|D|H|M||Name|
|----:|----:|----:|:--:|:----|
{% 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 days = t.days if t.days > 0 else '&nbsp;' -%}
  {%- set hrs = t.seconds//3600 %}
  {%- set hrs = hrs if hrs > 0 else '&nbsp;' -%}
  |{{days}}|{{hrs}}|{{(t.seconds//60)%60}}||_{{state.name}}_|
{% endfor %}

Copy-paste it into the Template Editor on your system and see if it produces errors.

1 Like

no errors :wink:

BUT, now I enter my old template once again, it doesnt throw errors anymore either…
just to be sure I reject as many issues as possible, I added your ‘ne’ to the markdown:

        content: |
          {% 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))
             if (now() - state.attributes.last_triggered).days < 1 -%}
          {{state.attributes.last_triggered.timestamp()
            |timestamp_custom('%d-%m %H:%M:%S')}} : {{state.name}}
          {% endfor %}

let’s see what a restart will bring (not sure why that would make a change, but apparently something did between the testing of these various templates, a restart might reset that, even though last_triggered is restored at restart)

Magic! :mage:

1 Like

haha, yes, but just so you believe me:

2022-02-07 16:05:21 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'last_triggered' when rendering '{% for state in (states.automation
     |selectattr('attributes.last_triggered')
     |sort(attribute='attributes.last_triggered',reverse=true))
     if (now() - state.attributes.last_triggered).days < 1 -%}
{{state.attributes.last_triggered.timestamp()
  |timestamp_custom('%d-%m %H:%M:%S')}} : {{state.name}}
{% endfor %}'
2022-02-07 16:05:22 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'last_triggered' when rendering '{% for state in (states.automation
     |selectattr('attributes.last_triggered')
     |sort(attribute='attributes.last_triggered',reverse=true))
     if (now() - state.attributes.last_triggered).days < 1 -%}
{{state.attributes.last_triggered.timestamp()
  |timestamp_custom('%d-%m %H:%M:%S')}} : {{state.name}}
{% endfor %}'
2022-02-07 16:05:23 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'last_triggered' when rendering '{% for state in (states.automation
     |selectattr('attributes.last_triggered')
     |sort(attribute='attributes.last_triggered',reverse=true))
     if (now() - state.attributes.last_triggered).days < 1 -%}
{{state.attributes.last_triggered.timestamp()
  |timestamp_custom('%d-%m %H:%M:%S')}} : {{state.name}}
{% endfor %}'
2022-02-07 16:05:24 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'last_triggered' when rendering '{% for state in (states.automation
     |selectattr('attributes.last_triggered')
     |sort(attribute='attributes.last_triggered',reverse=true))
     if (now() - state.attributes.last_triggered).days < 1 -%}
{{state.attributes.last_triggered.timestamp()
  |timestamp_custom('%d-%m %H:%M:%S')}} : {{state.name}}
{% endfor %}'
2022-02-07 16:05:25 WARNING (MainThread) [homeassistant.helpers.template] Template variable warning: 'homeassistant.util.read_only_dict.ReadOnlyDict object' has no attribute 'last_triggered' when rendering '{% for state in (states.automation
     |selectattr('attributes.last_triggered')
     |sort(attribute='attributes.last_triggered',reverse=true))
     if (now() - state.attributes.last_triggered).days < 1 -%}
{{state.attributes.last_triggered.timestamp()
  |timestamp_custom('%d-%m %H:%M:%S')}} : {{state.name}}
{% endfor %}'

Reality! :poop:

Not sure what’s going on there. My test system is running 2022.2.0 and, on restart, I don’t see any errors in the log for the Markup card containing the code I posted above (and the same code is sitting in the Template Editor).

just restarted and no error in sight anymore. Tested my old template, and now with or without your additions.
not a single template error.
how wondrous.

maybe

if state.attributes.last_triggered  and (now() - state.attributes.last_triggered).days < 1

could help too, its what I do in other templates. Or would this be too late in the process and would the error already be thrown in the select section