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

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?

if you have a list, you have a list object. It has list properties and only does things that a list does.

If you have an object, like a state object, it has state object properties and only does things that state objects do.

So, if you have a list of state objects:

{% set stuff = [ states.light.mylight ] %}

And you try to do state object things, liek this:

stuff.state

it will fail.

So you have to get the state object from the list like so:

stuff[0].state

or

{% set first_stuff = stuff | first %}
{{ first_stuff.state }}

This is all taught in beginner tutorials btw.

1 Like

I was hoping for the addition of a “user_id” function but using state_attr to get the job done is about as good as it’ll ever get. Thanks for the example.

Of course. that’s a way better idea.

I forgot that the user_id was in the person attributes.

Think of a list as being a container, like a bucket. If I hand you a bucket containing a single apple, you are directly holding the bucket and indirectly holding the apple. To directly hold the apple, you must reach into the bucket and pull it out.

In the same manner, given a list containing a single item, to get the item you first have to pull it out of the list.

Yes, that’s why |list does he same with a single item list :wink:
Funny though we can’t use |last

Not sure I understand what you mean.

If I apply the list filter to a list, the result is a list (not the item within the list).

If I apply first or last filter to a list containing a single item, the result will be the item.

{{ ['hello'] }}
{{ ['hello'] | list }}

{{ ['hello'] | first }}
{{ ['hello'] | last }}

{{ ['hello', 'world'] | last }}

what I meant was that if using |list in my template where posted |first, the exact same output is generated:

{{states.person|selectattr('attributes.user_id','eq','3redacted63')|first}}

renders:

<template state person.marijn=home; editable=False, id=theboss, latitude=5redacted, longitude=4.redacted, gps_accuracy=15, source=device_tracker.life360_marijn, user_id=3redacted63, friendly_name=Marijn, hide_attributes=['templates'], templates=entity_picture=if (entities['sensor.marijn_picture']) return entities['sensor.marijn_picture'].state; return '/local/family/marijn_not_home.png'; @ 2020-07-22T12:03:50.550668+02:00>

there’s only 1 person in the ‘bucket’. using either |list or |first gives the same outcome. of course, the first is not a list, sorry for the confusion. I meant there’s only 1 person…

this turns the generator object into a list.

Generators take less memory and can only be iterated across once. Lists stay in memory and can be iterated on many times. You need | list when you want to use the generator past the currently executing line.