PSA: When testing trigger templates, use namespace

I don’t often use the template editor to create my own automations because I’ve been using appdaemon for years. Well today, I created my own automation because it seemed silly to create it in appdaemon app because it was very basic. Like all automations I create, I tried to make it as generic as possible. This means, anyone can use it or expand it with as few lines of yaml as possible. Typically when doing this we need templates, so that’s what I did.

This lead me to the realization that users don’t have a great way to test triggers in the template editor. So, without further delay, here are some ‘canned’ triggers that can be used when testing trigger templates in actions or conditions:

State Trigger

Equal from_state and to_state

Simply change the name of the entity_id and it will create a ‘fake’ trigger object. Keep in mind that from_state and to_state will always be equal.

{% set entity_id = 'sensor.xxx' %}
{% set fake_state = states | selectattr('entity_id','eq',entity_id) | first %}
{% set trigger = namespace(platform='state', entity_id=entity_id, from_state=fake_state, to_state=fake_state) %}

Emulates:

trigger:
- platform: state
  entity_id: sensor.xxx

Use examples:

{{ trigger.to_state.state }} # returns the state of sensor.xxx
{{ states(trigger.entity_id) }} # returns sensor.xxx

from_state and to_state are not equal

Simply change the name of the entity_id and it will create a ‘fake’ trigger object. Keep in mind that from_state and to_state will not be equal. Also, keep in mind that they are different entities. Try to use entities from the same domain to ‘simulate’ this properly.

{% set entity_id = 'sensor.xxx' %}
{% set entity_id2 = 'sensor.yyy' %}
{% set from_state = states | selectattr('entity_id','eq',entity_id) | first %}
{% set to_state = states | selectattr('entity_id','eq',entity_id2) | first %}
{% set trigger = namespace(platform='state', entity_id=entity_id, from_state=from_state, to_state=to_state) %}

Emulates:

trigger:
- platform: state
  entity_id: sensor.xxx

Use examples:

{{ trigger.from_state.state }} # returns the state of sensor.xxx
{{ trigger.to_state.state }} # returns the state of sensor.yyy
{{ trigger.from_state.state != trigger.to_state.state }} # returns sensor.xxx state does not equal sensor.yyy's state

With a for: minutes: 3 object.

Simply change the name of the entity_id and it will create a ‘fake’ trigger object. Keep in mind that from_state and to_state will always be equal.

{% set entity_id = 'sensor.xxx' %}
{% set entity_id2 = 'sensor.yyy' %}
{% set for_obj = namespace(minutes=3) %} #simply change minutes=3 to hours=1 for hours etc.
{% set from_state = states | selectattr('entity_id','eq',entity_id) | first %}
{% set to_state = states | selectattr('entity_id','eq',entity_id2) | first %}
{% set trigger = namespace(platform='state', entity_id=entity_id, from_state=from_state, to_state=to_state, for=for_obj) %}

Emulates:

trigger:
- platform: state
  entity_id: sensor.xxx
  for:
    minutes: 3

Use examples:

{{ trigger.for.minutes }} # returns 3

If this gets a lot of attention, I’ll gladly add more examples.

24 Likes

That’s good use of namespace! I am too lazy, and I just whip up a sample JSON to test it. I keep this block of JSON handy, and just replace with new values, drop it in the template editor and ready to test my code. Best part is, you can simulate complex object structure without sweating! :slight_smile:

{% set trigger = {
  "entity_id":"sensor.xxx",
  "from_state":{
    "domain":"light",
    "last_updated":"2020-02-10T16:29:05+00:00",
    "last_changed":"2020-02-10T16:29:05+00:00",
    "state":"test!"
  },
  "to_state":{
    "domain":"light",
    "last_updated":"2020-02-10T16:29:05+00:00",
    "last_changed":"2020-02-10T16:29:05+00:00",
    "state":"new test!"
  }
}%}

{{ trigger.entity_id }}
{{ trigger.to_state.last_updated }}
{{ trigger.from_state.state }}
{{ trigger.to_state.state }}
6 Likes

Pretty much what @skalavala said, except his example isn’t JSON, it’s a Python dictionary. :smiley:

1 Like

Odd, I tried this first and failed on the dot notation. I must have made a typo. It’s why I used namespace :man_shrugging:

Now these are really helpful when developing new stuff! Thanks & kudos!

great for beginners! This just saved me a lot of time testing blindly :hugs:

I’m glad that I found this old topic. It helped me to catch some stupid mistakes in my automation.

Now I wondering: can I replace the default template in Developers Tools with this one?

Is there any difference with using dict() instead of namespace()?
I always just create a dictionary with the keys I need.

you can update items in namespace where you can’t in dict. This whole post misleads people into using namespace for testing triggers. I can’t remember why I wasn’t able to make dict work at the time, I can only think it was a typo.

If you don’t need to update the info, just use a dict.

1 Like