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

Description
If switching a fan based on the relative humidity difference between two rooms, if there is a temperature differnece, the rule does not provide a consistant behavior. Therefor it is needed to calculate the absoulute 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

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
7 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