Execute script only if the device Who call It Is at home

Hello, i Need help to understand how I can do this.

I have a simple script who execute a playlist on a specific device (Google home mini).
All is working but I accidentally called it while I was outside the home from my Android device and I wake up my little baby .
So I modified the script to check first if my Android phone is registered at home or note.

Since this script is used by 4 users, I would like to not create 4 different script (one from each user) to check if their devices (android) are at home.

How can I template the if condition to check if the device that is calling the script is at home or not? Any hint?

The trigger variable should have the user that triggered it. Check automation docs.

If it really is a script, something like this should work:

condition: "{{ states.person | selectattr('attributes.user_id', 'eq', context.user_id) | selectattr('state', 'eq', 'home') | list | count > 0 }}"

If it is not a script, I’m not sure how to get the user_id of whomever triggered it as for automations it seems to always be null.

OP says script. Not automation. Automation user ID is generally null.

Hi! Yes it’s a script and not an automation. I’ve tried your code but it get always evaluted as false in my script, i think.

So i check on the model editor, replacing context.user_id with the string of my user_id, and i get this error:

TemplateRuntimeError: No test named 'states'.

I’m not an expert of Jinja and the datamodels of HA, but i’ve removed the select(‘states’,‘home’) part and the count to access the array data and i get this:

[<template TemplateState(<state person.federico=home; editable=True, id=federico, device_trackers=['device_tracker.redmi_note_8_pro', 'device_tracker.pixel_8_2'], latitude=XX.XXXXXX, longitude=YY.YYYYYYY, gps_accuracy=100, source=device_tracker.pixel_8_2, user_id=*******************, friendly_name=federico @ 2025-01-06T18:19:20.480603+01:00>)>]

Btw, this is the full script i’m using for test:

sequence:
  - condition: >-
      {{ states.person | selectattr('attributes.user_id', 'eq', context.user_id)
      | select('states', 'home') | list | count > 0 }}

  - action: notify.mobile_app_pixel_6
    metadata: {}
    data:
      message: Test OK!
alias: Riproduci Relax e Nanna su Google Home mini
description: Riproduce Relax e Nanna da Spotify sul google home mini

Does it seems correct?

Doh. Error is correct, in this case it shouldn’t be states (which is a filter) but instead is_state (which is a test). I’ve updated my code above.

Thank you but with the new code i get this error:

TypeError: unhashable type: 'TemplateState'

But, having started to learn Ansible that use Jinja2 i had encountered before a command that help to serialize to string an array me so i made this code:

{{ states.person | selectattr('attributes.user_id', 'eq', 'ce374c274e4840ef82fe98e223efde03') | map(attribute='state') | list |  join(" ") == 'home' }}

I’ve converted the array of ‘state’ in a simple string and compared with the string home.
I think that the state cannot have more than one location, right? The array will have always one element.

Sigh. I keep forgetting the difference of dealing with entity objects rather than only entity ids! If whatever you’ve come up with now works, great, but here is how I’d rewrite the condition.

condition: "{{ states.person | selectattr('attributes.user_id', 'eq', context.user_id) | selectattr('state', 'eq', 'home') | list | count > 0 }}"

This one really, really should work! (Assuming execution in a script, if your dashboard button triggers an automation then context.user_id will unfortunately always be null as already mentioned above…)

1 Like