Switch a fan based on absolute humidity difference between two humid/temp sensors

Description
If switching a fan based on the relative humidity difference between two rooms, if there is a temperature difference, the rule does not provide a consistent behavior. Therefor it is needed to calculate the absolute humidity in g/m3 based on the temperature and relative humidity.

Based on the blueprint of ride4sun (sorry for the missing Link, new users can only post two links…)

Requirements:

  • switch for the fan
  • temperature
  • humidity
  • reference temperature
  • reference humidity

Blueprint with an additional light switch which blocks the fan if the light is on: Switch a fan based on absolute humidity difference between two humid/temp sensors, with blocking Light Switch

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

blueprint:
  name: Humidity Management based on abs. humidity (g/m3)
  description:
    Turn a fan on and off based on the difference between a humidity sensor
    and a baseline, based on absolute humidity
  domain: automation
  input:
    humidity_sensor:
      name: Humidity Sensor
      description: A sensor that measures the humidity of the area to be vented, for example the shower
      selector:
        entity:
          domain: sensor
    temperature_sensor:
      name: Temperature Sensor
      description: A sensor that measures the temperature of the area to be vented, for examle the shower
      selector:
        entity:
          domain: sensor
    reference_humidity_sensor:
      name: Reference Humidity Sensor
      description: A sensor that indicates the baseline humidity of the area outside of the vented, for example the walkway outside the shower
      selector:
        entity:
          domain: sensor
      default: []
    reference_temperature_sensor:
      name: Reference Temperature Sensor
      description: A sensor that indicates the baseline temperature of the area outside of the vented, for example the walkway outside the shower
      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 (in g/m3)
      description: How many gram/m3 above the reference humidity the sensor
        can rise before the fan is turned on
      selector:
        number:
          min: 0.0
          max: 3.0
          mode: slider
          step: 0.1
      default: 1.1
    falling_threshold:
      name: Falling Threshold
      description: How many gram/m3 above the reference humidity the sensor
        must fall to before the fan is turned off
      selector:
        number:
          min: 0.0
          max: 3.0
          mode: slider
          step: 0.1
      default: 0.9
  #source_url: https://community.home-assistant.io/t/turn-a-fan-on-and-off-based-on-the-difference-between-a-humidity-sensor-and-a-baseline/255999
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:
  temperature_sensor: !input "temperature_sensor"
  humidity_sensor: !input "humidity_sensor"
  reference_temperature_sensor: !input "reference_temperature_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"
  abs_humid_ref: >-
    {% set h, t = states(reference_humidity_sensor)|float, states(reference_temperature_sensor) %}
    {% if not h or t == 'unknown' -%}
      'unknown'
    {%- else %}
    {% set t = t | float %}
    {{ (h*6.112*2.1674*e**((t*17.67)/(t+243.5))/(t+273.15))|round(2) }}
    {% endif %}

  abs_humid: >-
    {% set h, t = states(humidity_sensor)|float, states(temperature_sensor) %}
    {% if not h or t == 'unknown' -%}
      'unknown'
    {%- else %}
    {% set t = t | float %}
    {{ (h*6.112*2.1674*e**((t*17.67)/(t+243.5))/(t+273.15))|round(2) }}
    {% endif %}
  difference: "{{ abs_humid|float - abs_humid_ref|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
8 Likes

I use an input_boolean as a switch for my fan, is there a way to use it instead of a domain: switch?

Just change the domain in the blueprint and the service for the action in the lower part. @ski_maniac

1 Like

Hello
First of all sry for the stupid questions :sweat_smile:, but I don’t understand the difference between area and location.

I would like to use this blueprint to get the height humidity out of my basement.

The area sensor is that one who is inside the basement and the location sensor is that on in the garden?

Thanks :wink:
Rudi

Reference / Location would be what you want to drive the Area in question to be like.
(Assuming I’ve read your question and the blueprint correctly…)

Thx for the answer, but I don’t understand it.
So I have to declare two sensors in this automation.
The area and the location sensor. My question was what sensor is mounted inside and what outside?

Inside the room = location sensor
Outside the building = area sensor

I have adjusted the descriptions a bit to be more precise. The reference_* sensor values should come from the place where the air is attracted. So if the fan has exchanged all the air, they should be identical to the values inside the room that is being ventilated. Since there may be differences in temperature, the relative humidity will of course be different.

In the case of the basement, humidity_sensor and temperature_sensor in the basement, reference_* sensors where the air comes from, in your case from outside, so the values in the garden, as close as possible to the house, but without direct sunlight.

Hi, wish i had seen this before i spend my time ( and friends) making my own .
Excellent job!
I would like to ask if there is a rule of thumb of a good threshold of abs humidity difference before starting ventilating . I can see that you have 1.1 as default. How you come up with this value?

Awesome! But can you increase to max thresholds (now 3)?

1.1 is my current setting, with this, i have no mold in the shower. I would start with 1.1 and in-/decrease it by 0.1 steps

1 Like

as the threashold is in g/m3 3 is already very high. I would not increase it further.

Converter for humidity of air for the records.

I’m now seeing the following warning related to this blueprint. Any idea how to go about fixing it?

Logger: homeassistant.helpers.template
Source: helpers/template.py:1210
First occurred: October 16, 2021, 3:22:35 PM (18 occurrences)
Last logged: 6:05:20 PM

Template warning: 'float' got invalid input 'unknown' when rendering template '{% set h, t = states(reference_humidity_sensor)|float, states(reference_temperature_sensor) %} {% if not h or t == 'unknown' -%} 'unknown' {%- else %} {% set t = t | float %} {{ (h*6.112*2.1674*e**((t*17.67)/(t+243.5))/(t+273.15))|round(2) }} {% endif %}' but no default was specified. Currently 'float' will return '0', however this template will fail to render in Home Assistant core 2021.12
Template warning: 'float' got invalid input ''unknown'' when rendering template '{{ abs_humid|float - abs_humid_ref|float }}' but no default was specified. Currently 'float' will return '0', however this template will fail to render in Home Assistant core 2021.12

Would you do the same if you wanted to change from a switch to a light?

Yes. you also need to check that the usage syntax in the body of the blueprint matches the entity. The service needs to match the entity it’s calling or it won’t work.

This has replaced my previous logic, which was just two simple automations, one to turn on the fan if RH > high setpoint, and one to turn off the fan if RH < low setpoint for some time delay.

However, it doesn’t do the time delay aspect, and I’ve found that this causes the fan to cycle on and off a bit. It obviously pulls out enough moisture to be < turn off point… but then when the fan stops, the humidity slowly rises again until it turns on again (and so on for a while).

I’ve added in a delay element to the automation, but I’m not sure if this is the nicest way to do it. Any ideas on this? I’ve added my updated blueprint below…

blueprint:
  name: Humidity Management based on abs. humidity (g/m3)
  description:
    Turn a fan on and off based on the difference between a humidity sensor
    and a baseline, based on absolute humidity
  domain: automation
  input:
    humidity_sensor:
      name: Humidity Sensor
      description:
        A sensor that measures the humidity of the area to be vented, for
        example the shower
      selector:
        entity:
          domain: sensor
    temperature_sensor:
      name: Temperature Sensor
      description:
        A sensor that measures the temperature of the area to be vented,
        for example the shower
      selector:
        entity:
          domain: sensor
    reference_humidity_sensor:
      name: Reference Humidity Sensor
      description:
        A sensor that indicates the baseline humidity of the area outside
        of the vented, for example the walkway outside the shower
      selector:
        entity:
          domain: sensor
      default: []
    reference_temperature_sensor:
      name: Reference Temperature Sensor
      description:
        A sensor that indicates the baseline temperature of the area outside
        of the vented, for example the walkway outside the shower
      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 (in g/m3)
      description:
        How many gram/m3 above the reference humidity the sensor can rise
        before the fan is turned on
      selector:
        number:
          min: 0.0
          max: 3.0
          mode: slider
          step: 0.1
      default: 1.1
    rising_delay:
      name: Rising Delay
      description: Time delay once rising threshold is met prior to the fan turning on
      selector:
        number:
          min: 0
          max: 60
          unit_of_measurement: "min"
          mode: slider
      default: 0
    falling_threshold:
      name: Falling Threshold
      description:
        How many gram/m3 above the reference humidity the sensor must fall
        to before the fan is turned off
      selector:
        number:
          min: 0.0
          max: 3.0
          mode: slider
          step: 0.1
      default: 0.9
    falling_delay:
      name: Falling Delay
      description: Time delay once falling threshold is met prior to the fan turning off
      selector:
        number:
          min: 0
          max: 60
          unit_of_measurement: "min"
          mode: slider
      default: 5
  source_url: https://community.home-assistant.io/t/switch-a-fan-based-on-absolute-humidity-differnece-between-two-humid-temp-sensors/305686
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:
  - delay:
      minutes: "{%if mode == 'on' %}{{rising_delay | int}}{% else %}{{falling_delay | int}}{% endif %}"
  - service: homeassistant.turn_{{mode}}
    entity_id: !input "fan_switch"
variables:
  temperature_sensor: !input "temperature_sensor"
  humidity_sensor: !input "humidity_sensor"
  reference_temperature_sensor: !input "reference_temperature_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"
  rising_delay: !input "rising_delay"
  falling_delay: !input "falling_delay"
  abs_humid_ref:
    "{% set h, t = states(reference_humidity_sensor)|float, states(reference_temperature_sensor)\
    \ %} {% if not h or t == 'unknown' -%}\n  'unknown'\n{%- else %} {% set t = t\
    \ | float %} {{ (h*6.112*2.1674*e**((t*17.67)/(t+243.5))/(t+273.15))|round(2)\
    \ }} {% endif %}"
  abs_humid:
    "{% set h, t = states(humidity_sensor)|float, states(temperature_sensor)\
    \ %} {% if not h or t == 'unknown' -%}\n  'unknown'\n{%- else %} {% set t = t\
    \ | float %} {{ (h*6.112*2.1674*e**((t*17.67)/(t+243.5))/(t+273.15))|round(2)\
    \ }} {% endif %}"
  difference: "{{ abs_humid|float - abs_humid_ref|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

Excellent blueprint. Works great for me.

Would it be possible to add an optional condition? If the bathroom light is on => fan does not turn on
Reason: If I’m in the bath the sound of the fan is disturbing and the temperature in the bathroom drops.

Excellent work, good explain i just aim the g/m3 for my purpose and it work well
Thanks a lot

Late but… see here: Switch a fan based on absolute humidity difference between two humid/temp sensors, with blocking Light Switch

I can’t seem to get this blue print to work, it exclusively turns my bath fan on no matter what changes I make to the thresholds. Disclaimer, I wont pretend that I understand the math underlying the blueprint, but I think I understand the overall function (turn up rising threshold and it allows for more moisture before activating the fan, turn up falling threshold and it allows for more moisture to linger after deactivating the fan).

That said, I’ve tried having both rising and falling at opposite and same extremes (pretty much every possible combo unless I missed something) of the slider and every time I run the automation it always turns my bath fan on.

A little about my setup, I have temp/humidity sensors in every room of my house, I averaged them together (less the bathroom) and am comparing the bathroom to the house average. They compare such that usually the bathroom reads 10% higher humidity and ~+0.5 degrees to the house average. This makes sense, its a small room and we keep the door closed (we simply don’t have the budget for replacing toilet paper if we always let the cat in there), so I would expect to see higher humidity and near the same temperature as the rest of the house.

See below for the current yaml of the automation (again, I was just playing with the thresholds in an attempt to get this to work, the values are nonsense)

alias: Bath Fan Humidity Switch Control
description: Turns fan on/off based on humidity sensor values
use_blueprint:
  path: >-
    W6Es3QEa/switch-a-fan-based-on-absolute-humidity-difference-between-two-humid-temp-sensors.yaml
  input:
    humidity_sensor: sensor.bathroom_temp_humid_humidity
    temperature_sensor: sensor.bathroom_temp_humid_temperature
    reference_humidity_sensor: sensor.house_humidity_minus_bathroom
    reference_temperature_sensor: sensor.house_temperature
    fan_switch: switch.bathroom_fan_light_switch_bottom
    falling_threshold: 2.5
    rising_threshold: 0.3