Home Assistant Smart Bathroom Fan

A “smart” bathroom fan should:

  • Turn on automatically when someone showers and humidity rises quickly
  • Allow manual control from a wall switch or dashboard
  • Stay on for a cool-down period after humidity drops, then turn off

Below is a complete Home Assistant implementation that uses:

  • A humidity sensor (for example sensor.bathroom_humidity from an ESP32 + BME280 / SHT45)
  • A fan entity (fan.bathroom_fan or switch.bathroom_fan)
  • An optional manual override (input_boolean.bathroom_fan_manual)

The logic is split into three parts:

  1. Auto ON when humidity rises quickly
  2. Manual override via switch or virtual button
  3. Auto OFF after humidity normalises and a cool-down timer expires

1. Prerequisites: Entities Used

Assumed entities:

sensor.bathroom_humidity     # Bathroom humidity (%)
fan.bathroom_fan             # The fan (or switch.bathroom_fan)

input_boolean.bathroom_fan_manual  # Manual override flag (optional)

If the fan is a switch, just replace fan.bathroom_fan with switch.bathroom_fan in the YAML.

The input_boolean.bathroom_fan_manual can be created in configuration.yaml or via the UI:

input_boolean:
  bathroom_fan_manual:
    name: Bathroom Fan Manual Mode
    icon: mdi:hand

This boolean can be toggled from a wall switch, dashboard or automation when someone presses a “Fan” button.


2. Auto ON – Humidity Rise Percentage

Goal: turn the fan on when:

  • Humidity jumps by a few percentage points in a short time, and
  • Current humidity is above a “normal” threshold (e.g. ≥ 65%)

This avoids the fan turning on every time humidity changes a little.

automation:
  - alias: "Bathroom Fan – Auto ON (Humidity Rise)"
    mode: single
    trigger:
      - platform: state
        entity_id: sensor.bathroom_humidity
    condition:
      - condition: template
        value_template: >
          {% set from = trigger.from_state.state | float(0) %}
          {% set to   = trigger.to_state.state   | float(0) %}
          {% set delta = to - from %}
          {{ to >= 65 and delta >= 5 }}
      # Optional: do not auto start if manual mode is ON
      - condition: state
        entity_id: input_boolean.bathroom_fan_manual
        state: "off"
    action:
      - service: fan.turn_on
        target:
          entity_id: fan.bathroom_fan

Explanation:

  • Trigger fires on any change in humidity
  • Template condition checks that:
    • New value (to) is at least 65 %, and
    • It increased by at least 5 percentage points since the previous reading

Both thresholds can be tuned for each bathroom.


3. Manual Override – Always Respect the User

Two simple behaviours are common:

  • If the user turns on the fan manually → keep it running, even if humidity is low
  • If the user turns off the fan manually → don’t immediately re-start it because of humidity

A simple way to express manual intention is via an input_boolean.

3.1 Manual ON – Set override and start fan

automation:
  - alias: "Bathroom Fan – Manual ON"
    mode: single
    trigger:
      - platform: state
        entity_id: input_boolean.bathroom_fan_manual
        to: "on"
    action:
      - service: fan.turn_on
        target:
          entity_id: fan.bathroom_fan

3.2 Manual OFF – Clear override and stop fan

  - alias: "Bathroom Fan – Manual OFF"
    mode: single
    trigger:
      - platform: state
        entity_id: input_boolean.bathroom_fan_manual
        to: "off"
    action:
      - service: fan.turn_off
        target:
          entity_id: fan.bathroom_fan

The boolean can be bound to a physical wall switch (e.g. ESP32 + relay + button) or a dashboard toggle.


4. Auto OFF – Cool-Down Timer After Shower

Goal: when humidity returns to normal levels, keep the fan running for a cool-down period (e.g. 10–20 minutes), then switch off.

Logic:

  • Only auto-off when:
    • Humidity is below a “safe” threshold (e.g. 60%)
    • Manual mode is OFF
    • Fan has been running for at least X minutes
automation:
  - alias: "Bathroom Fan – Auto OFF (Cool-down)"
    mode: restart
    trigger:
      - platform: numeric_state
        entity_id: sensor.bathroom_humidity
        below: 60
        for: "00:10:00"      # humidity has been low for 10 minutes
    condition:
      # Only auto-off if fan is currently ON
      - condition: state
        entity_id: fan.bathroom_fan
        state: "on"
      # Do not turn off if manual override is active
      - condition: state
        entity_id: input_boolean.bathroom_fan_manual
        state: "off"
    action:
      - service: fan.turn_off
        target:
          entity_id: fan.bathroom_fan

This creates a cool-down timer behaviour:

  • After humidity drops below 60 %
  • And stays there for 10 minutes
  • Fan turns off automatically (unless manual override is on)

below: 60 and for: "00:10:00" are both tunable.


5. Optional: Dashboard Controls

A simple Lovelace card to control and monitor the automation:

type: entities
entities:
  - entity: fan.bathroom_fan
  - entity: sensor.bathroom_humidity
  - entity: input_boolean.bathroom_fan_manual

This shows humidity, the fan state, and allows toggling manual mode from the UI.


Summary

The Smart Bathroom Fan automation combines three ideas:

  1. Humidity rise detection → fan turns on when someone showers
  2. Manual override → user can always take control
  3. Cool-down timer → fan runs long enough to clear steam, then turns off

Together, they create a bathroom fan that feels intelligent instead of annoying, and they are easily adapted to any humidity sensor and fan hardware already integrated with Home Assistant.

Share your love

Leave a Reply

Your email address will not be published. Required fields are marked *