States(trigger.to_state) vs trigger.to_state.state

This post is similar to Trigger sensor: using “trigger” variable - “trigger.to_state.state” vs “states(…)” and others

In this post I am asking why the former of these two seemingly equivalent template variables does not work but the latter does?

The code:

description: ""
mode: single
triggers:
  - type: changed_states
    device_id: 4a8029966d095cd6f6f14ce614044dae
    entity_id: 20a562aa8bcfa10bc11ad335a817974b
    domain: light
    trigger: device
conditions: []
actions:
  - if:
      - condition: template
        value_template: "{{ states('trigger.to_state') == 'on' }}"
    then: []
  - if:
      - condition: template
        value_template: "{{ trigger.to_state.state == 'on' }}"
    then: []

states() takes an entity id as an argument. trigger.to_state is not an entity id.

1 Like

That works for me (but I don't use domain triggers. Shouldn't matter but YMMV)

states(trigger.entity_id)

I would suggest to use trigger.to_state.state like you did in the 2nd if statement.
That will check on the state which caused the trigger.

Technically, the state could have changed between the trigger, and the actual execution of the action sequence. So if you want to be sure you are checking on the actual state, you could use states(trigger.entity_id). But that should only make a difference if you have like delays in your automation before this state is tested.

1 Like

It is not a stretch to think that trigger is an ephemeral entity with a number of states. But, alas, it is not.

After searching the HA documentation I could not find where states() is documented? I did find examples, but examples are just that, examples and not definitive. If it is, indeed, not documented, where should it be docuemented?

What, then, is trigger and where is that documented?

Going forward, I will try to remember your response. I would like the reference, too, because the answers found on the forum are not part of the documentation. In addition, my memory is fallible.

1 Like

In Working with states one finds:

When you write {{ states('sensor.outdoor_temperature') }} , Home Assistant looks up that exact entity ID and gives you back its state. It is that direct.

This is an example. A definition would be:

states( name ), where name is a string which refers to the state entity ID of an existing entity

I see from your reference that:

trigger is a "Home Assistant extension template variable"

So the answer to my original post is:

states() takes the state entity ID of an entity as text and trigger is a special template variable (which is already text).

Did I get that right?

trigger is an object. Specifically a dictionary that changes based on the trigger that occurs in the automation. It's not text. What you're seeing is object oriented code. When text or words are not wrapped in quotes, they are objects, functions, macros, filters, tests, or keywords for Jinja. When words are wrapped in quotes, it is a string. This is the same concept for all coding languages.

1 Like

Ah! yes, of course. So let me rephrase the answer to my origianal post.

states() takes, as text, the state entity ID of an entity. trigger.to_state.state is a special template function, thus 'trigger.to_state' is invalid input to states() because there is no entity trigger

The links to the documentation are an important part of the answer because they provide authoritative supporting details where as replies in the forum, while often helpful, are not documentation.

The function states() requires a valid entity ID string as its first argument. As petro pointed out, most of what you see in a template is text, but not all of that text represent string data.

No, trigger is a built-in variable. Its value is applied when a trigger fires in an automation or trigger-based template entity. The value held by that variable is a dictionary object. The exact structure and contents of that object depend on the type of trigger that generated it.

The to_state property of the variable trigger (trigger.to_state) would return the entire new State Object of the triggering entity at the time the trigger fired. Following that logic and syntax, trigger.to_state.state returns the new state value of the triggering entity.

The string "trigger.to_state" is an invalid argument for the function states() because it is not a valid entity ID string.

A valid entity ID string, for example "light.above_tv", is composed of:

  1. A valid entity domain like "light".
  2. A valid object ID like "above_tv"

There is no entity domain "trigger" in HA, therefor "trigger.to_state" cannot be a valid entity ID string.

4 Likes

So exactly what I said in the first reply.

2 Likes

I thought I had marked post 9 as the solution, which is essentially what tom_l stated but with links and a little more detail.