Question about template states

Hi Everyone

I don’t know why but i have the following different approaches to compare the value of an attribute, and somehow the top one gives me true, and the bottom both give me false. Does someone know the reason?
Is is_state not intended for what I am doing?

service: notify.mobile_app_mi_mix_3_5g
data_template:
  message: >
            {{trigger.to_state.attributes["battery"] == 100}} --> gives me true
            {{is_state("trigger.to_state.attributes['battery']",100)}} --> gives me false
            {{is_state_attr('trigger.to_state','battery',100)}} --> gives me false
1 Like

The aspect of templates that you are missing is types, you seem to be changing things to strings and not understanding why it’s wrong. There are 7 main object types, here’s a watered down description of them all.

int

a number without a decimal place.

1

float

a number with a decimal place.

1.234234

string

a series of characters. Denoted by characters wrapped in single quotes or double quotes.

'324dalkfsdjlk234'
"32342fsdkj32l4k2j3;523423442kja"

bool

true, false, 1, or 0

True
False
1
0

tuple

a collection of items. It cannot change shape, once it’s defined it will always stay that size. I.e. if I have 4 items, I cannot remove or add an item. Each item is identified by the order it was placed in the collection.

(1,2,3,'a','b','c')

Accessing items:

my_tuple[0] # Returns 1 (first item in tuple)
my_tuple[1] # Returns 2 (second item in tuple)
my_tuple[n] # Returns ? (n+1 item in the tuple)
my_tuple[-1] # Returns 'c' (lastitem in tuple)

list

a collection of items. You can add or remove items from it. You can filter it down. There are also some other operations that happen. Each one is identified by the order it was placed in the collection.

[1,2,3,'a','b','c']

Accessing items:

my_list[0] # Returns 1 (first item in list)
my_list[1] # Returns 2 (second item in list)
my_list[n] # Returns ? (n+1 item in the list)
my_list[-1] # Returns 'c' (last item in list)

dictionary

A collection of items. Each one is identified by a unique identifier, typically a string.

{'foo':1, 'bar':2, 'blah': 3, 'state':'my_state'}

Accessing items:

my_dict['foo'] # returns 1
my_dict.foo # returns 1
my_dict.get('foo') # returns 1
my_dict.get('junk', 74) # returns 'junk's value if it exists, if it does not returns 74

trigger

The trigger object is a bunch of nested dictionaries. It’s not a string. Learn this object through the docs.


Your Code

So with that all being said, the only valid code you have is

{{trigger.to_state.attributes["battery"] == 100}}

The rest seem valid but you’re making small mistakes. So lets look at them.

{{is_state("trigger.to_state.attributes['battery']",100)}}

is_state() accepts an entity_id as it’s first argument, and the state as the second argument. States are always strings unless it comes from an attribute. In the case of an attribute, it can be ANY object type.

Mistakes:

  1. You’re feeding the string "trigger.to_state.attributes['battery']" as the first argument. Is this an entity_id? No. Should trigger even be a string? No.
  2. All states are strings. Is 100 a string? No, there are no quotes around it.

But even if you were to correct those mistakes, it still wouldn’t get the correct answer because you’re trying to get the result of an attribute. is_state only compares the state, not an attribute.


{{is_state_attr('trigger.to_state','battery',100)}}

is_state_attr gets compares an attribute to a result. It’s first argument is an entity_id, the second is the attribute name, and the third is the value you are comparing to.

Mistakes:

  1. You’re feeding the string 'trigger.to_state' as the first argument. Is this an entity_id? No.
  2. Even if you were to correct mistake 1 and remove the quotes, you’re accessing the wrong piece of information. You’re grabbing the trigger.to_state object, which is a dictionary, not a string. And it’s not the entity_id.

Putting it all together

{{ is_state_attr(trigger.to_state.entity_id, 'battery', 100) }}
{{ state_attr(trigger.to_state.entity_id, 'battery') == 100 }}
{{ trigger.to_state.attributes.battery == 100 }}
{{ trigger['to_state']['attributes']['battery'] == 100 }}
... etc ...
4 Likes

Hi Petro

Thanks for the detailed explanation! Seems there are multiple things i misunderstood or didn’t know.

I undestand the differences between integers/float and string, so I tried both, but I didn’t know states are always strings and I thought is_state also accepts values of attributes, or sees the value as the state if I use

trigger.to_state.attributes[‘battery’]

I assumed that trigger.to_state is a normal entity, so when this gave me true:

{{is_state_attr(‘sensor.0x00178801080b5988_action’,‘battery’,100)}}

I just replaced the entity with trigger.to_state.

So the best way is to use one of these two since i want the value when the automation was triggered. When I use the entity_id i would see the current state and not the state when the automation was triggered

{{ trigger.to_state.attributes.battery == 100 }}
{{ trigger[‘to_state’][‘attributes’][‘battery’] == 100 }}