Is there a way to refer to the current running automation *within* that automation, like "self"?

I’m trying to prevent multiple events from triggering within a certain period of time. Adding this condition works perfectly for doing that, but the name of the automation must be specified. I would like to have a generic version that self-references itself.

  condition:
    condition: template
    value_template: '{{ (as_timestamp(now()) - as_timestamp(states.automation.this_is_the_automation_alias.attributes.last_triggered | default(0)) | int > 300)}}'

Just add a state condition, no need for a template:

condition:
  condition: state
  entity_id: automation.xxxxx
  state: 'off'
  for:
    minutes: 5

and if you want to make it generic, make an anchor:

anchors:
  automation_condition: &automation_condition
    condtion: state
    state: 'off'
    for:
      minutes: 5

then…

condition:
  <<: *automation_condition
  entity_id: automation.xxxxx

Unfortunately, there is no ‘this’ to grab from the trigger because the trigger only holds information on what triggered it, not the object it’s triggering on. I haven’t looked at the code in a while, but there may be hidden trigger properties that exist that have the parent id. But I doubt it. Even then, I’m not sure automations provide access to the parent_id.

this doesn’t check if the automation was triggered does it? It merely checks if a condition is ‘off’, as in ‘not enabled’?

I was under the impression that triggering would turn it on. I don’t use automations so you could be correct. If that’s the case, ignore my response.

No, an automation has to be ‘on’, to be able to be triggered in the first place :wink:

Op must use the suggestion he made himself I fear, which is the regular way of doing that…

depending on the triggers, he might be able to use something like this though:

      - condition: template
        value_template: >
          {{ (now() - trigger.from_state.last_changed | default(0)).total_seconds() > 
                                            states('input_number.presence_timer')|int }}

which checks on the trigger and prevents the automation from firing if that trigger triggered between the given timeframe.

I think we have a way. It’s a pain in the ass and I can’t test it at the moment. It also may change depending on the trigger type.

I’d have to test this with some new automations and I’m currently not at home.

If you have a from_state or a to_state:

{% set id = trigger.to_state.context.parent_id %}
{% set obj = states.automation | selectattr('context.id','eq', id) | list | first %}
{{ (as_timestamp(now()) - as_timestamp(states.automation[obj.object_id].attributes.last_triggered | default(0)) | int > 300)}}

EDIT: I’m assuming that the automation ID gets passed to the trigger object. A value definitely get’s populated in parent_id, I’ve never verified that it’s the id of the automation. I figure an easy way to test this would be to add the following automation into your system:

input_boolean:
  trigger_automation_test:
    name: Trigger any test automation.
    initial: off
    icon: mdi:car
automation:
  - alias: Test Context ID Info
    trigger:
      - platform: state
        entity_id: input_boolean.trigger_automation_test
    action:
      - service: persistent_notification.create
        data_template:
          message: "Context Info"
          title: >
            trigger {{ trigger.to_state.context }}
            automation {{ states.automation.text_context_id_info.context }}

if the parent_id inside the trigger context matches the automation’s context id, then the condition i wrote will work.

I was finally able to try your solution, but unfortunately it doesn’t seem to work :frowning:

I am currently trying everything I can to get this to work. Has anyone found a workable solution to the issue ? Thanks

did you try the testing automation I posted to verify that the id matches the parent_id?

Are all these ‘things’ documented anywhere?

In the dev docs they are. They aren’t really meant for mucking around just yet.

:thinking:

…thanks I’ll keep my ear to the ground.

1 Like

FWIW, I performed an experiment to see if context.user_id could be employed to determine if an automation was triggered by a user or another automation.

Basically, if it was a user then context.user_id contains a value otherwise it does not. The user_id is an identifier (long string of random numbers and alphabetic characters) which represents a specific user account. However, I don’t know of a way to get the user’s name. There must be a way because logbook reports which user triggered something (but might not be accessible for templating purposes).

If you look at the “users” page it gives a list of all users and their user id’s.

You could probably manually create a variable with the attributes as a dictionary of user name:user id then use the variable in a template to find the user name for the associated user id.

Ideally, there ought to be a function to access user account information given its identifier.

What you described would work but, as we both know, because we are duplicating user account information (creating more than one source of truth). In addition, if we were to add a user, we have to remember to duplicate that as well otherwise the next lookup will fail to find the user’s name.

fwiw, I use this to notify me who sent a message:

    action:
      service: notify.filed_intercom_messages
      data_template:
        message: >
          {% set message = states('input_select.intercom_message') %}
          {% set device = states('input_select.intercom') %}
          {% set language = states('input_select.intercom_language') %}
          {% set id = trigger.to_state.context.user_id %}
          {% set time = as_timestamp(now())|timestamp_custom('%d %b: %X') %}
          {% set user = states.person|selectattr('attributes.user_id','eq',id)|first %}
          {% set user = user.attributes.friendly_name %}
          {{time}}: {{user}} played "{{message}}" on {{device}} in {{language}}

still cant find out why I need the |first filter though…

3 Likes

select_attr returns a generator, which is a list of items that it found. first grabs the first one.

fyi, all this is written in the docs for jinja :wink: . And just to put it into perspective, you and I learned jinja at the same starting time. I know I’ve said this 100 times to you, but you REALLY should take a class in this stuff.

of course I’ve read that, over and over. And its not that I dont grasp the generator…using that all over the place.
Still didn’t see why however, when the id is passed, and the person is selected, the |first does what it does. There’s only 1 person with the unique id is there? And there seems to be no difference when using eg |list

or am I to understand this it grabs the first one with this ‘id’ (the template doesn’t ‘know’ it’s unique, and it might just as well be ‘on’…of which many could exist?) and displays that.

In which case the |list does exactly the same, listing the sole person with this id?