Template sensor weirdness - Anyone seen this before?

Home Assistant version 229 (from Supervisor->System) installed from image for Raspberry Pi.

This is my first post here, so apologies in advance for any mistakes that I make.

Background:

I have a humidity sensor in a bathroom driving a fan, which is supposed to bring down humidity in the bathroom. The problem I have is that the general humidity (from the weather) is quite variable; triggering the directly from humidity means that I either have to set quite a high threshold before turning on the fan, otherwise, in times of high humidity the fan will run almost constantly. I did discover both template sensors and also filter sensors; From the humidity sensor, I created a filter sensor that does a ā€œtime_simple_moving_averageā€ with quite a large (6 hour) window and then take the difference between the two in order to try to give me a value that I can trigger the fan from that would be something akin to when the bathroom humidity is above ā€œambientā€ (for want of a better term?)

Code:


sensor:

    # Command-line sensor; CPU temperature...

    # <SNIP>    

    # Filter Sensor(s) ...

  - platform: filter
    name: "Middle Bathroom Fan Average Humidity"
    entity_id: sensor.sonoff_1000bed159_humidity
    filters:
      - filter: time_simple_moving_average
        window_size: "06:00"
        precision: 2
        
    # Difference between Bathroom Humidity and rolling Average ...
        
  - platform: template
    sensors:
      middle_bathroom_humidity_diff:
        friendly_name: "Middle Bathroom Humidity Difference"
        value_template: "{{ states('sensor.sonoff_1000bed159_humidity') | float - states('sensor.middle_bathroom_fan_average_humidity') | float }}"

The problem:

What I am seeing is strange; I see quite large negative spikes in the difference periodically that donā€™t match up with the values from the actual sensor and the filter sensor. The following graph should show what I mean:

20200802_173159_Humidity

The negative spikes appear to somewhat be linked to when the the difference reverses (i.e., crosses the zero-line), but not always.

Thanks in advance for any help that you are able to give! :slight_smile:

sensor.sonoff_1000bed159_humidity is intermittenly becoming unavailable. Youā€™re casting the state unavailable to a float. Any string that is not a number that gets cast to a float using | float will turn into the default value of 0.0. So at that time you essentially have 0.0 - sensor.middle_bathroom_fan_average_humidity, which ends up with a negative spike. Fix your humidity sensor and youā€™ll fix your issue.

@petro: Many thanks for that; makes perfect sense once explained.

WRT fixing the sensor; thatā€™s not really a choice for me, at least in the short termā€¦ Do you know if thereā€™s a way to make the result of the calculation be ā€œunavailableā€ if the base sensor is unavailable? ā€¦Sort of like Cā€™s ?: ternary operator?

I did try the following after reading the //Templating section of the docs, but it didnā€™t work:

  - platform: template
    sensors:
      middle_bathroom_humidity_diff:
        friendly_name: "Middle Bathroom Humidity Difference"
        value_template: 
          "{ % if states('sensor.sonoff_1000bed159_humidity') != 'unavailable' % }
             {{ states('sensor.sonoff_1000bed159_humidity') | float - states('sensor.middle_bathroom_fan_average_humidity') | float }}  
           { % else % }
             'unavailable'
           { % endif % }"

I also tried without the enclosing quote-marks, but it wouldnā€™t parse. The result given by the above code is as follows:

{ % if states(ā€˜sensor.sonoff_1000bed159_humidityā€™) != ā€˜unavailableā€™ % } 3.1700000000000017 { % else % } ā€˜unavailableā€™ { % endif % }

Clearly, I donā€™t quite understand how templating works!

Again; thanks for whatever help you all are able to give. :slight_smile:

You could just make an availability template and keep your math the same

  - platform: template
    sensors:
      middle_bathroom_humidity_diff:
        friendly_name: "Middle Bathroom Humidity Difference"
        value_template: >
          {{ states('sensor.sonoff_1000bed159_humidity') | float - states('sensor.middle_bathroom_fan_average_humidity') | float }}"
        availability_template: >
          {% set sensor_states = [
            states('sensor.sonoff_1000bed159_humidity'),
            states('sensor.middle_bathroom_fan_average_humidity') ] %}
          {{ 'unavailable' not in sensor_states }}
1 Like

@petro, Again, thanks. Works perfectly - of course!

I do feel kind of like I got you to do my homework for meā€¦ :slight_smile: Can you recommend a good place to learn how the template stuff works? The docs suggest the Jinja2 website, but I didnā€™t find it easy to follow; possibly because it seems to be HTML oriented, rather than Home-assistant -centric?

Anyhow, thanks for your help; appreciated.

Unfortunately I canā€™t. Iā€™m sure there are some resources out there. I learned by using the docs and having past coding experience.

The docs just cover the code, so itā€™s a bit cryptic. I recommend just playing around in the template editor.