Sensor with delay_off has state unknown at startup when off

I deleted the mold indicator and made my own template for dewpoint.

  - sensor:
    - name: "Dewpoint"
      unique_id: "dewpoint"
      unit_of_measurement: "°C"
      icon: mdi:water
      state: >
        {% set a = float(17.271) %}
        {% set b = float(237.7) %}
        {% set dewpoint_tmp =(a *states('sensor.temperature')|float) / (b + states('sensor.temperature')|float) + log(states('sensor.humidity)|float/100) %}
        {% set dewpoint = (b * dewpoint_tmp) / (a - dewpoint_tmp) %}
        {{ dewpoint |float |round(1) }}

Now it works as expected.

Thanks for your help on the way!

That’s not how you set a variable to a number. And you still have not defined defaults.

      state: >
        {% set a = 17.271 %}
        {% set b = 237.7 %}
        {% set dewpoint_tmp = (a * states('sensor.temperature')|float(0)) / (b + states('sensor.temperature')|float(0)) + log(states('sensor.humidity)|float(0)/100) %}
        {% set dewpoint = (b * dewpoint_tmp) / (a - dewpoint_tmp) %}
        {{ dewpoint|round(1) }}

You are right. To be fair it worked.

I don’t really understand the defaults. If I add |float(0) It will default to 0 if the sensor is unknown, right?

I don’t want that. I want the sensor to fail (unknown).

It’s worse than that, the template will not be loaded if it happened during start up. Define your defaults and use an availability template if you want to catch unknown child sensor states.

That makes sense. What do you mean by availability template? I use Watchman to catch unknown devices.

But what values should I use? 0? Division by zero? I don’t like this error management.

Screenshot 2022-04-16 at 12-40-33 Template

https://www.home-assistant.io/integrations/template/#availability

It does not matter (well don’t use division by 0). As long as the default value exists the template will still load if one of the entities is missing.

The availability template will catch this and set the state to unknown.

One way to do this:

      availability: "{{ states('sensor.temperature')|float(0) != 0 and states('sensor.humidity)|float(0) != 0 }}"

The problem with this method is that the sensor states could actually be 0. So put something else as the default, like this:

      availability: "{{ states('sensor.temperature')|float('foo') != 'foo' and states('sensor.humidity)|float('foo') != 'foo' }}"

or this:

      availability: "{{ states('sensor.temperature')|float('bar') != 'bar' and states('sensor.humidity)|float('bar') != 'bar' }}"

or this:

      availability: "{{ states('sensor.temperature')|float(none) != none and states('sensor.humidity)|float(none) != none }}"

Another option is checking the states directly:

      availability: "{{ states('sensor.temperature') not in [unavailable, unknown, none] and states('sensor.humidity) not in [unavailable, unknown, none] }}"

Now I understand. The availability has to be set, otherwise it will just set the sensor to a silly state.

  - sensor:
      - name: "Sonne Höhe"
        unit_of_measurement: "°"
        unique_id: SonneHohe
        availability: "{{ state_attr('sun.sun', 'elevation')|float(none) != none }}"
        state: "{{ state_attr('sun.sun', 'elevation')|float(none) }}"

So I will change all my template sensors like that.

Right now I am just changing template.yaml, but I am using more templates.

What about these templates - are these already fail proof or how should I handle those:

  - platform: template
    switches:
      panasonic_tv:
        friendly_name: "TV"
        unique_id: "switch.panasonic_tv"
        value_template: "{{ states('media_player.panasonic_tv') }}"
  - platform: command_line
    name: Status
    scan_interval: 60
    command: "/Users/server/scripts/status.sh"
    value_template: "{{ value }}"
  - wait_template: '{{ (states(''media_player.receiver'') == ''on'' ) }}'
    timeout: '30'
  - resource: url
    scan_interval: 60
    timeout: 45
    binary_sensor:
      - name: "Service"
        value_template: >-
          {% if value_json is defined %}
            {% if value_json.currentState == 0 %}
              {{'off'}}
            {% else %}
              {{'on'}}
            {% endif %}
          {% else %}
            {{'unknown'}}
          {% endif %}

- platform: template
  covers:
    garage_tor:
      friendly_name: 'Tor'
      unique_id: Tor
      value_template: "
        {% if states('switch.status_tor') == 'off' %}
          {{ True }}
        {% else %}
          {{ False }}
        {% endif %}"

None of those templates are using functions or filters that require a default to be defined.

This one can be simplified:

- platform: template
  covers:
    garage_tor:
      friendly_name: 'Tor'
      unique_id: Tor
      value_template: "
        {% if states('switch.status_tor') == 'off' %}
          {{ True }}
        {% else %}
          {{ False }}
        {% endif %}"

to this:

- platform: template
  covers:
    garage_tor:
      friendly_name: 'Tor'
      unique_id: Tor
      value_template: "{{ is_state('switch.status_tor', 'off') }}"
1 Like

If I set the availability as you said above, do I really have to set float(none) to every value I use in the template?

        availability: "{{ state_attr('sun.sun', 'elevation')|float(none) != none }}"
        state: "{{ state_attr('sun.sun', 'elevation')|float(none) }}"

or

        availability: "{{ state_attr('sun.sun', 'elevation')|float(none) != none }}"
        state: "{{ state_attr('sun.sun', 'elevation') }}"

You don’t need a float filter or an availability template.

Just this:

state: "{{ state_attr('sun.sun', 'elevation') }}"

So, should I only use the availability if I compare or calculate something?

If so is this correct?

        availability: "{{ states('sensor.boen_m_s')|float(none) != none }}"
        state: >
          {% if (states('sensor.boen_m_s')|float(none) < 5) %}
            {{ (10 * 3.6 * states('sensor.boen_m_s')|float(none) )|round(1) }}
          {% else %}
            {{ 11.111 }}
          {% endif %}

or this one:

        availability: "{{ states('sensor.boen_m_s')|float(none) != none }}"
        state: >
          {% if (states('sensor.boen_m_s')|float < 5) %}
            {{ (10 * 3.6 * states('sensor.boen_m_s')|float)|round(1) }}
          {% else %}
            {{ 11.111 }}
          {% endif %}

You need to supply a default value for functions and filters, e.g. |float or log().

You only need to supply an availability template if you want to protect against these templates returning incorrect values when the sensors in the templates are unknown or unavailable.

But it is still required to set the default if I check for availability, right?

Also |round(1) calls for a default value as well.

Yes. I think there is work being done on a PR that prevents the state template being evaluated if the availability template returns false but I’m not sure if it has been merged yet.

Yes.

1 Like

And if I just copy the value to a template it will also copy unknown and therefore not fail.

state: "{{ state_attr('sun.sun', 'elevation') }}"

I think now I have it.

But thinking about condition templates. These will just return false if a sensor is not available, right? Because I do make calculations in these templates as well.

Correct.

As for template conditions, if you are worried about them and they are unreliable put them in their own template sensors.

1 Like

Most sensors are states or state_attr that return a float value. So I did float(none).

How should I handle binary_sensors or strings?

1 Like

Maybe I missed it but if I compare this for on or off in a template I need a default value.

states('binary_sensor.test')

This is obviously wrong:
{{ states('binary_sensor.test')|boolean(none) != none }}

You must have, you’re making up filters boolean is not a filter, test, or keyword. So no, it doesn’t need a default value because it doesn’t exist.