Avoiding 'unavailable' in sensor templating

Hi,

I hope somebody can help me with the following issue. I control my lights based on outside light levels using a NodeMCU with ESPhome on it. A simple setup using a LDR. Before this setup, i done it with the same LDR and MQTT (non ESPHome). The LDR gives a value and with the template sensor i do some math(own mapping calculation) stuff to set the light brightness level.
With my previous setup (MQTT) i didn’t had any problems. With my new setup (ESPHome) Hassio does detect when the sensor isn’t available. That results in a sensor value ‘unavailable’. For now i made a workaround to detect that value and set a sensor to 0 or 1. In the automation script i only set new brightness levels if the sensor is not 0 = ‘unavailable’ using a condition.

I can’t figure out how to handle this in the sensor template itself. If i using INT or FLOAT and the sensor value isn’t numeric it has an outcome. I suspected something else…

Is there a trick to not update a template sensor when the ESPHOME sensor is ‘unavailable’?

My brightness math:

value_template: '{{((((states.sensor.living_room_brightness.state | int - 1) * (1 - (states.input_number.maxbright.state) | int) / (states.input_number.maxldr.state | int -1 ) + (states.input_number.maxbright.state) | int ) | int -1) | float * (states.sensor.brightfactor.state) | float) | int}}

If the room_brightness is a string (no numeric) it will always result in the maxbright state.

Hope you understand my problem.
If any info is needed, let me know.

Can you please read the sticky at the top of the forum.
Trying to read code as you have posted it is near impossible, it should be (as per the sticky) quoted in ‘preformatted text’ (using the </> button above the text box).

Given your problem and a quick scan, it seems because you are using initialisation issues given your use of

states.sensor.living_room_brightness.state | int - 1

Rather than one of the bracketed evaluations, (from memory) something like

states('sensor.living_room_brightness') | int - 1
1 Like

Take a look at the warning in the states part of the templating docs. Try to use the states(xxx) notation instead of states.xxx.

1 Like

Sorry, fixed the text as suggested.

Will try you’re solution.

could you fix your config in the OP as well? :wink:

He means re-parse your evaluations using the preferred notation format.

Hi, yes i fix the config

    sensors:
      lightbrightn:
        friendly_name: "Brightness"
        value_template: "{{((((states('sensor.living_room_brightness') | int - 1) * (1 - (states('input_number.maxbright')) | int) / (states('input_number.maxldr') | int -1 ) + (states('input_number.maxbright')) | int ) | int -1) | float * (states('sensor.brightfactor')) | float) | int}}"

To do testing in the developer tools in template i set a variabele for the brightness so i can fill in a test value like this:

{%set ldr = 'text' %}
{{(((( ldr | int - 1) * 
(1 - (states('input_number.maxbright')) | int) / 
(states('input_number.maxldr') | int -1 ) + 
(states('input_number.maxbright')) | int ) | int -1) | float * 
(states('sensor.brightfactor')) | float) | int}}

What i want to achive… when ldr is not a numeric value the outcomes(result) should not be set.
if that’s not possible can i set the previous value?

if ldr >-255 and <255 then do the math and result new value
if ldr do not match above, do nothing (keep value)

I hope my question is more clear now.

not numeric means unavailable or generally not usable as numeric?
in the first case you can limit yourself by comparing the state to unavailable (and maybe unknown?)
but as you’ll need to convert it to a float anyway, maybe it’s possible to use float’s default set to some “impossible” value like this:

{% set invalid_value = -48 %}
{% set resut = states('sensor.brightfactor') | float(invalid_value) %}
{% if result != invalid_value %}
 # do your maths and return a new value
{% else %}
 {{ states("sensor.this_sensor's_name") }} # i.e return its current value
{% endif %}
2 Likes

EUREKA!

Wow, it was Soooo simple. Thanks AhmadK.

I couldn’t find a way to keep the previous value. But it was so simple, just name the sensor itself. :hugs:

thanks.

Grtx,
Marcel

1 Like

yes, it’s not obvious but as it’s a sensor, its state must be in the state machine and at any time before you change it you can access it :wink: