Using better templates with state

So I have gone through all my configuration and changed things like this:

states.sun.sun.state

To this:

states(‘sun.sun’)

And:

states.sun.sun.attributes.elevation

To this:

state_attr("sun.sun", "elevation")

I did this so that if the state is ‘unknown’ it won’t throw up any errors. But is there a similar way I should use to modify this:

states.light.desk.last_changed

no, last_changed always has to be like that. its not an attributes.

Yeah I had come to that conclusion myself but wondering if I was missing anything.

You can use the default filter.

{{ states.light.desk.last_changed | default(None, True) }}

Will result in None (same as states('') and state_attr('', '') if it does not exist, or display the time if it’s there.

Drop this in the template editor to test:

{{ states.not_a.real_entity.last_changed | default(None, True) }}
{{ states.light.desk.last_changed | default(None, True) }}

The first will say None, and the second (assuming it exists) will show the time.

2 Likes

Thanks. That works.

do we really need that second filter parameter in this case? I can see no difference in my TE

What gets returned if the state is unknown?

None is returned

For this particular case it does not matter.
But it will in other cases, so it’s best to be explicit.
http://jinja.pocoo.org/docs/2.10/templates/#default

2 Likes

Sorry should have been more clear.

What gets returned for:

states.sun.sun.state

vs

states(‘sun.sun’)

when the state is unknown and why is it better?

I’ve used a lot of the first type and wondering why you’ve changed.

Thanks

image

What the 1: really “say” is AttributeError: NoneType has no attribute state.

Thanks for the explanation

Also if you use the first one, you can get errors in your logs when a template_sensor can’t determine the state so using states(‘sensor”) is better than states.sensor.state

which is briefly explained in the docs: https://www.home-assistant.io/components/template/#considerations

it’s even better covered here

well, that’s not quite the case really. It merely mentions it, but the #considerations link explains why this is happening…

well, I don’t mind really so you may count you’ve won :wink:
but my link describes the behaviour in every situation whether yours might be interpreted by some as “at startup only”.
anyway, imho links to 2 resources with information is better than no links (and information) at all, especially if they do not contradict each other :wink:

yes, you’re right. call it a draw :wink:

it’s rather an important aspect of HA templating, so maybe some streamlining the docs could be done. But where to start, and which to replay for the other.
For now we’ll just note both pages.

Thanks for that. I believe it explains why this fails to produce the correct result:

{{ ( states('sensor.does_not_exist') | float | default(1.0) ) < 0.7 }}

The result is True.

However, this produces the correct the result:

{{ ( states('sensor.does_not_exist') | float | default(1.0, true) ) < 0.7 }}

The result is False.

FWIW, an alternative (for this particular template) is to supply the desired default value to the float filter:

{{ ( states('sensor.does_not_exist') | float(default=1.0) ) < 0.7 }}

Excuse my thickness :slightly_smiling_face: but I’m not understanding what the “true” part of the default filter does.

It says in the docs posted above that it’s necessary if the expression would normally return “false” that you have to use “true” in the filter.

None of the examples I’ve seen above, especially the ones posted by @123, would return “false”.

The ones posted by @123 should return a number not a true/false.

Why is the “true” necessary there?