so i googled to get help with my template
i trying to do my smoke detectors i made
so for testing i want less then 0.5 is “ok”, > 0.5"problem" and if its not avaliable due to no power to do it that its unavaliable it would show up unavailable, currently i keep getting “unknown” if its plugged in and should be ok
the code i using is
- sensor:
- name: "Smoke Detector 2 By Wood Stove Status"
state: >
{% set val = states('sensor.smoke_detector_2_by_wood_stove') %}
{% if not is_number(val) %}
unavailable
{% elif val < 0.5 %}
ok
{% else %}
problem
{% endif %}
availability: >
{{ is_number(states('sensor.smoke_detector_2_by_wood_stove')) }}
Invalid config for 'template' at yamls/template.yaml, line 372: invalid template (TemplateSyntaxError: unexpected ')') for dictionary value 'sensor->0->availability', got "{{ is_number(states('sensor.smoke_detector_2_by_wood_stove')) | float(-1)) != -1 }}\n"
This gets whatever is in the ‘state’ for the sensor and then pipes that into float. If it is a number that can be converted, float wil return it, if not the default value -1 is returned. Hence I then check against it being equal -1 to get back a true / false value for the availability.
The thing to remember is states() always returns the value as a string. So if you want anything other than ‘text’ you need to cast it. Hence I used ‘raw’ to imply string although there would be nothing wrong using ‘val’.
The float(-1) does the casting. Tries to turn the raw into a numeric float and if it cannot it returns -1. I chose -1 as a default since I do not think your sensor would ever have a state of -1.
Here is a simpler version:
- sensor:
- name: "Smoke Detector 2 By Wood Stove Status"
availability: >
{{ (states('sensor.smoke_detector_2_by_wood_stove') | float(none)) is not none }}
state: >
{% set val = states('sensor.smoke_detector_2_by_wood_stove') | float %}
{% if val < 0.5 %}
ok
{% else %}
problem
{% endif %}
We use the availability attribute to check for ‘unavailable’ and if false (the conversion to numeric is ‘none’) then the template sensor is unavailable. There is no real point to check it again in the state template since it would never get run if it is ‘unavailable’.
If it is available it will either have a state of ‘ok’ or ‘problem’ depending on whether or not sensor.smoke_detector_2_by_wood_stove is below 0.5
note: I don’t have a default value when converting the value since we already did that check in the availability.
ah ok so the “float” is a function program that does the checking if there is something other then whats in the () brackets
the -1 inside the brackets is a value u just make up for unavaliable… so it could be -4598 a value u dont think it can ever be right?
so that simplier so its saying float check for none or check if there is a number and if its none no point in doing the state check… or it would still do it but there is no number to process it
Take the previous sensors value and pipes it into the float function. If the value can be converted to a float then return that, if it cannot then return ‘none’. A bit better than returning -1 which is numeric. We needed to return a numeric value in the previous code as we were testing that value against -1.
This bit then checks to see what the float() function returned. If it returned anything other than ‘none’ the result is true. This happens whenever the float() function can convert the state to a numeric value and hence we can make the sensor available.
There is a very subtle difference using this to the ‘float’ because Home Assistant treats "NaN" and "inf" as strings, and is_number() considers them valid numbers.
So, I use float(none) when I want to guarantee the value is a real numeric value. I only use is_number for loose string checks.
Home assistant does not treat NaN and inf as strings, they are treated as the objects they are, which originate from numpy. In the case of OP, there is no way he will get NaN or inf as those objects because OP is getting the value from the state machine, which means they will be always be strings and they will return False from is_number. You can test this yourself.
Mentioning this is also really really pointless because the only possible way to get NaN or inf as a numerical object is if it comes from a states object attribute and if it comes from one of the 4 integrations that use numpy: compensation, trend, stream, and iqvia. Compensation can only output NaN as the main state (which will always be a string in templates), meaning the coefs will not be NaN, ergo you’ll never get NaN from a compensation attribute. I can’t speak for the other integrations.
So, the “too long didn’t read” is:
using is_number on a states object will always work.
oh ok that sounds easier to understand with home assistant and its float and even the templating they going to need to start a templating code for dummies book… since the templating doc page cant cover all these things specific to home assistant…
i appreciate you guys know what your doing as the template or google AI is great at times but also a problem at the same time…
oh and as you guys talk about NaN etc… since i never tested the MQ2 gas sensor if i pulled it off while home assistant running or so i dunno if it ever produces a NaN and never tested if i ever got a value… ive only made these and just let the values produce i never tricked it that it was broken… so ill never know
i only made it so a value high or low threshold and if esp32 is unplugged… i never seen what happens when you boot up with the mq2 failed or when it fails during esp32 is up and running
Please do not take what he said to heart. He’s leading you down an extremely rare path that you likely will never run into.
For all intents and purposes, you should follow @TheFes’s advice here:
That advice will never run into the NaN / inf issue, regardless which integration it comes from because states are always strings and is_number will return false for both of those.
ok so use has_value or is_number as both mean it has a number… and if if the mq2 is not working it wouldnt produce a number in theory as it could produce 0 if it goes offline… i know i ran into that issue using esphome Ble mode for white square thermomemters… if it doesnt send data it just keeps a value so i had to get help to set if it doesnt produce a value in 10 or 20 min to set it to Nan to show that the devices could have a dead Battery as in the esphome values stay static in that scenario… so far thats the only time i using Nan…
i learn alot… i wish i was 20 years younger i could retain all this info alot better, especially in my coding days…
has_value specifically looks for unknown and unavailable states from the state object itself. It does not check for numerics, it only checks for unknown and unavailable states. It works with all entities, not just numeric sensors.
is_number checks any input and returns True or False if it can be converted to a number.