Turn a fan on and off based on the difference between a humidity sensor and a baseline

The idea here is for a fan to turn on off based on comparing a humidity sensor’s value to a reference humidity.

For example, this could be the humidity in the house at the thermostat. It could be based on the local weather. You can use this automation to have the humidity in your bathroom trend with the humidity outside of the bathroom (which may change with the weather).

Get started

Click the badge to import this Blueprint: (needs Home Assistant Core 2021.3 or higher)

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

blueprint:
  name: Humidity Management
  description: Turn a fan on and off based on the difference between a humidity sensor and a baseline
  domain: automation
  input:
    humidity_sensor:
        name: Humidity Sensor
        description: A sensor that measures the humidity of the area
        selector:
          entity:
            domain: sensor
    reference_humidity:
        name: Reference Humidity
        description: A percentage point value that indicates the baseline humidity if there is no reference sensor available
        default: 60
    reference_humidity_sensor:
        name: Reference Humidity Sensor
        description: A sensor that indicates the baseline humidity of the location
        selector:
          entity:
            domain: sensor
        default: []
    fan_switch:
        name: Fan Switch
        description: A switch that turns the fan on and off
        selector:
          entity:
            domain: switch
    rising_threshold:
        name: Rising Threshold
        description: How many percentage points above the reference humidity the sensor can rise before the fan is turned on
        selector:
          number:
            min: 0
            max: 100
        default: 8
    falling_threshold:
        name: Falling Threshold
        description: How many percentage points above the reference humidity the sensor must fall to before the fan is turned off
        selector:
          number:
            min: 0
            max: 100
        default: 3
    
trigger:
  - entity_id: !input humidity_sensor
    platform: state
  - entity_id: !input reference_humidity_sensor
    platform: state
condition:
  - condition: template
    value_template: '{{ mode != switch_state }}'
action:
  - service: switch.turn_{{mode}}
    entity_id: !input fan_switch
variables:
    reference_humidity: !input reference_humidity
    humidity_sensor: !input humidity_sensor
    reference_humidity_sensor: !input reference_humidity_sensor
    fan_switch: !input fan_switch
    switch_state: '{{ states(fan_switch) }}'
    rising_threshold: !input rising_threshold
    falling_threshold: !input falling_threshold
    difference: '{{ states(humidity_sensor)|float - (states(reference_humidity_sensor)|float
      or reference_humidity|float) }}'
    mode: '{% if switch_state == ''off'' and difference|float > rising_threshold|float %}on{%
      elif switch_state == ''on'' and difference|float > falling_threshold|float %}on{% else %}off{%
      endif %}'
mode: single
17 Likes

Nice. You could use the generic hygrostat component for this, but it hasn’t been merged yet, so you’ll have to add it to your custom_components.

Thank you very much for sharing !

I gave it a try and I get this error message :

Logger: homeassistant.components.automation.salle_de_bain_humidity_management
Source: components/automation/init.py:373
Integration: Automation (documentation, issues)
First occurred: 11:05:32 AM (1 occurrences)
Last logged: 11:05:32 AM

Error rendering variables: AttributeError: ‘list’ object has no attribute ‘lower’

This is the yaml automation created :

alias: Salle de Bain - Humidity Management
description: Blueprint
use_blueprint:
  path: >-
    dondochaka/turn-a-fan-on-and-off-based-on-the-difference-between-a-humidity-sensor-and-a-baseline.yaml
  input:
    falling_threshold: '30'
    humidity_sensor: sensor.aqara_sdb_humidity
    reference_humidity: '60'
    rising_threshold: '35'
    fan_switch: switch.4chpror2_4

This seems to perform the same function as the existing Threshold Binary Sensor.

The threshold binary sensor platform observes the state of another sensor. If the value is below ( lower ) or higher ( upper ) than the given threshold then state of the threshold sensor is changed. It support also a range if lower and upper are given.

1 Like

Ah, that is a brilliant solution, I dig it! I was trying to solve this by checking for a sudden increase, but using a reference sensor is even better.

2 Likes

Good day, Thank you for sharing this blueprint. Great work, however I get the following error:

Logger: homeassistant.components.automation.humidity_management
Source: components/automation/__init__.py:373
Integration: Automation (documentation, issues)
First occurred: 3:39:43 AM (122 occurrences)
Last logged: 11:23:48 AM

Error rendering variables: TypeError: '>' not supported between instances of 'float' and 'str'

This is the yaml created:

alias: Main Bathroom Humidity Management
description: Manage the bathroom humidity with the extractor fan.
use_blueprint:
  path: >-
    dondochaka/turn-a-fan-on-and-off-based-on-the-difference-between-a-humidity-sensor-and-a-baseline.yaml
  input:
    falling_threshold: '3'
    humidity_sensor: sensor.sonoff_1000bec77f_humidity
    reference_humidity: '80'
    reference_humidity_sensor: sensor.ble_temperature_a4c138349488
    fan_switch: switch.sonoff_1000bec77f
    rising_threshold: '8'

The numbers shouldn’t be strings ('3' is incorrect, 3 is)

That appears to be the way the input selector’s value is stored. The input selector’s default value is an integer:

default: 3

Yet when stored in the generated automation, it’s a string. Not sure why the system makes that conversion. :thinking:

Maybe they forgot to use a number selector?

falling_threshold is a Number selector.

But reference_humidity isn’t. I understand what you’re saying though, it’s a number selector, it should be stored as a number.

True, that one isn’t a Number selector but its default value is also an integer (60). If you look at Tibuski’s post, the default integer value is, yet again, converted to string.

It seems to ignore the value’s type and always stores it as string. Maybe it’s assuming automatic type conversion will take care of it later, when the value is consumed at runtime. :man_shrugging:

Or it’s a bug …

Hey all, thanks for the heads up. I just fixed the bug by editing the blueprint in the original post.

Although the thresholds are selected as numbers, they become strings in the variable definitions. They must be cast to numbers for the comparisons to work properly.

That part was understood (evident from the error message). What KTibow and I were discussing was a blueprint’s preference to store numeric values as strings (as seen in the automation generated by the blueprint). Seems like a curious design decision.

Good work. I noticed that it does not take into account if its started the fan or not and that I think would make it more versatile. For example I tried to turn my electrical floorheating on when the humidity was raised but that will not work since it will for the moment also turn off the heating during hours when I want it on all the time.

It would also be nice if the reference sensor could be the same sensor but with an averaged value over time (when NOT triggered), then most of us wouldnt need an extra sensor.

nice!

but my fan isnt a switch…

"

fan:
    - platform: mqtt
      name: Fan
      unique_id: "b5f92e68-a4b2-463d-8816-26a0fa340d9b"
      command_topic: "itho/cmd"
      speed_command_topic: "itho/cmd"
      state_topic: "itho/state"
      speed_state_topic: "itho/state"
      state_value_template: >
        {% if value_json == 0 -%}0{%- elif value_json > 0 -%}254{%- endif %}
      speed_value_template: "{{value.json}}"
      payload_off: "0"
      payload_on: "254"
      payload_low_speed: "65"
      payload_medium_speed: "127"
      payload_high_speed: "254"

this is the code for my fan, how would i get it working with this script ?

1 Like

Change the word switch in the action to fan.
That is also a service, fan.turn_off / fan.turn_on under action
Then use your fan entity. It will use the default fan speed. If you want to change fan speeds, you will have to get into a little more coding.
Also change the domain in the top from switch to fan.

1 Like

tnx ive editted the blueprint in \config\blueprints\automation\dondochaka

edit 2x the word switch to fan, that seemed to work

1 Like

Thanks, great contribution.

Is it possible to make the Humidity sensor a multi device selector. I have two bathrooms that use the one fan. So I want to turn the fan on if one of the Humidity Sensor matches the criteria.

1 Like

Can you make this turn on a Fan when the outside temperature is above a certain degree?
Like if its 25c outside, turn on a loft fan?
Turn back off once outside temp comes down to like 22c or something?