Quick Bathroom Fan Humidity Switch Control

I’ve posted a couple of times over the years my bathroom fan / humidity sensor setup. With some of the HA changes, I’ve updated it a bit and wanted to post the updated version.

This one is simplified a bit, using only an statistics sensor, binary sensor and an automation.

Statistics sensor: Calculates the average humidity in the bathroom over the last 24 hours. This helps to account for seasonal changes and smooths the baseline.

- platform: statistics
  name: Master Bathroom Humidity Average Linear 24h
  entity_id: sensor.master_bathroom_sensor_relative_humidity_measurement
  state_characteristic: average_linear
  max_age:
    hours: 24

Binary Sensor: Determines whether the current humidity is > average humidity - ie. should the fan be on? Worth noting that this can be as complicated or simple as you’d like it to be. The simple one below checks if the current humidity a fixed amount (threshold) greater than the average. [More complicated example at end of post]

master_bath_fan_sb:
  friendly_name: Master Fan S/B Status
  value_template: >-
    {% set humid = states('sensor.master_bathroom_sensor_relative_humidity_measurement')|int(default=0) %}
    {% set avg = states('sensor.master_bathroom_humidity_average_linear_24h')|int(default=0) %}
    {% set thresh = 5 %}
    {{ (humid - avg) > thresh }}

Automation: Turns the bathroom fan on/off based on the value of the binary sensor above.

- id: '1555779101294'
  alias: Master Bath Fan - TOGGLE
  trigger:
  - entity_id: binary_sensor.master_bath_fan_sb
    for: 00:00:30
    platform: state
  condition: []
  action:
  - data:
      entity_id: switch.master_bath_fan
    service_template: switch.turn_{{trigger.to_state.state}}

Additional Options:

  1. Input Number for Threshold. Personally, I use an input_number to hold the threshold value - this makes it changeable w/ out a reboot of HA. Create an input_number:
master_bath_humidity_threshold:
 name: Master Bath Humidity Threshold
 min: 0
 max: 20
 initial: 5
 mode: box
 step: 1

and also, in the binary sensor above, replace

{% set thresh = 5 %}

with

{% set thresh = states('input_number.master_bath_humidity_threshold')|int(default=0) %}
  1. Advanced Binary Sensor. When the AC is on and my humidity is > 45%, I like to reduce the threshold and make the fan more aggressive to remove more moisture. Here’s my actual binary_sensor, which checks for these and cuts the threshold in half under that scenario.
    master_bath_fan_sb:
      friendly_name: Master Fan S/B Status
      value_template: >-
        {% set humid = states('sensor.master_bathroom_sensor_relative_humidity_measurement')|int %}
        {% set avg = states('sensor.master_bathroom_humidity_average_linear_24h')|int(default=0) %}
        {% set thresh = states('input_number.master_bath_humidity_threshold')|int(default=0) %}
        {% if states('climate.6900_master') == 'cool' and avg > 45 %}
          {% set thresh = thresh / 2 %}
        {% endif %}
        {{ (humid - avg) > thresh }}

You can create your own logic and update the binary_sensor accordingly if desired.

Lastly. There are definitely a multitude of other ways to accomplish the desired result, this is only the way that I’m using / works for me.

21 Likes

Followed you from your previous project to here. Looks like you changed from the HACS ave to the statistics? You did this because it is now built in? Seems easy to follow. I’ll let you know how I make out. Thanks for posting your examples.

Yes, the average sensor I was using had some updates needed based on how it was accessing the HA database and the author (last I saw) hadn’t updated yet. Took the opportunity to remove a custom_component and use native HA statistics instead. Equated to better stability for little-to-no tradeoff in functionality (at least for my simple purposes).

FWIW. I’ve also seen a few blueprints floating around for something similar, just haven’t personally gotten around to using blueprints - prefer to hack things together myself :wink:

2 Likes

I have not used binary sensors before (that I know of).
How are they added in the yaml file under platform template or are they added a different way?

I figured it out. Sometimes my split yaml causes me loading issues that takes me awhile to understand my errors :smiley:.

I have it implemented and if I understand it correctly it uses the humid -ave > thresh (5)? To me this means if my ave is 51 it will go on at 56 and then stay on until the humidity drops below 56? Mine went on at 65? Not sure why?

You’d have to check the logs to see when the value of the humidity first registered above 56. Might depend on how frequently your humidity sensor is updating HA. The automation should be instantaneous once the binary_sensor turns to ON or OFF to toggle the fan.

Thanks. The history on both sensors (ave) and the actual sensor getting the data show correct information. Is the (humid - ave) recorded somewhere?

No, it’s not saved anywhere. You’d have to create a template sensor if you wanted to store that value separately. You also can likely use the ‘debug automation’ to see what the automation is doing and/or the Developer Tools → Templates to see what that is doing in real-time.

Thanks for sharing, I just configured this, was in need of an automation that also takes care of humidity changes during the seasons.

When I had set an automation to trigger based on a value it would trigger as soon as the value would hit. I had for example, turn on above 55 and then trigger off when it would start coming back down at say 58.

The last 2 times I ran it with the humid - ave it has triggered at 65 instead of 51 /52. Not seeing any reason why. I am now graphing the delta (humid - ave) as well as the Ave and Humid to try and see where the wrong data is coming from ( most likely something I coded incorrectly).

My issue has to do with the average rising rapidly. Not sure why it does? This is a picture of the ave.
image
I did not expect this as the rest of the data is 24 hours.

What fan are you using to achieve this?

It is not a fan issue. It is my incorrect use of the statistics. I need a lot more samples.
Currently using OPs settings the humidity spikes ( the graph above) as there are a lot of reading taken over a short period of time. I changed the sample size from the default 20 to 2880 and will see what happens after 24 hours.

Personally I’m using the ceiling ventilation fan that came with the house when we purchased. I switched out the wall switch to a ZWave switch that’s tied into HA. My automation toggles this switch on/off.

Ah ok. I have one of them extraction fans that turns on when humidity gets to X. Would love something that I could integrate in to HA

Yeah, if that’s your average graph, def. something amiss there. Almost looks like it (with that vertical change) ingested a super-high / anomalous reading…? If you’re getting the average of the last 24 hours, should def. not spike like that.

Reading some of the other comments on the statistics sensor, it says the default is 20 samples so many high readings over a short time will spike the reading (like my graph above). I changed to once every 30 seconds and will post tomorrow.

A different take if anyone cares. I compare the outside-the-bath-humidity to the inside-the-bath-humidity and turn on the fan if the net difference is too high.

  - sensor:
      - name: "Master Bath Net Humidity"
        device_class: humidity
        unit_of_measurement: "%"
        availability: >
          {{ states('sensor.main_hall_relative_humidity') | int(0) and 
             states('sensor.master_bath_humidity') | int(0)
          }}
        state: >
          {{ (  states('sensor.master_bath_humidity') | float(0)
              - states('sensor.main_hall_relative_humidity') | float(0)
             ) | round(1)
          }}
        attributes:
          Hall: >
            {{ states('sensor.main_hall_relative_humidity') }}
          Bath: >
            {{ states('sensor.master_bath_humidity') }}
5 Likes

Adding more data points to your code above eliminated the spike.

sampling size = 24 hours / 30 sec = 2880

sampling_size: 2880

Looks like it now works correctly for me. Thanks

1 Like

im no coder but this looks like something i need :slight_smile: , but i cant put in the code can you show were to put the codes i have the different files i think

i have automations , statistics and the binary sensor in but were to put the Additional Options: ?? and how i don`t get it can some on please show

master_bath_humidity_threshold:
 name: Master Bath Humidity Threshold
 min: 0
 max: 20
 initial: 5
 mode: box
 step: 1

and also, in the binary sensor above, replace

{% set thresh = 5 %}

with

{% set thresh = states('input_number.master_bath_humidity_threshold')|int(default=0)