🪟 Open Window Recommendation | Absolute Humidity Based Blueprint

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

Dynamic Ventilation Recommendation (based on Absolute Humidity)

This blueprint calculates the absolute humidity (AH) indoors and outdoors from temperature and relative humidity sensors. If the AH indoors exceeds the AH outdoors by a configurable threshold (default: 3 g/m³), a ventilation recommendation is triggered.

If the window is still open when the humidity is back to normal, a reminder to close it is sent.

Features

  • Calculates AH from temp & humidity (no external sensor needed)
  • Periodic check every 5 minutes
  • Adjustable threshold
  • Room name for personalized messages
  • Works with any notify service (e.g. mobile app, Alexa)
  • Supports presence-based filtering (only notify if someone is home)

Inputs

  • Indoor & outdoor temperature and humidity sensors
  • Binary sensor for window status
  • Notify service
  • Room name
  • Threshold for AH difference

Example use case
You can set up one automation per room (e.g. bathroom, living room, bedroom) using this blueprint with different sensor inputs.

blueprint:
  name: Dynamic Ventilation Recommendation (based on Absolute Humidity)
  description: >
    Calculates absolute humidity indoors and outdoors based on temperature
    and relative humidity, and recommends ventilation when the difference
    exceeds a defined threshold.
  domain: automation
  input:
    temp_inside:
      name: Indoor temperature sensor
      selector:
        entity:
          domain: sensor
    rh_inside:
      name: Indoor humidity sensor
      selector:
        entity:
          domain: sensor
    temp_outside:
      name: Outdoor temperature sensor
      selector:
        entity:
          domain: sensor
    rh_outside:
      name: Outdoor humidity sensor
      selector:
        entity:
          domain: sensor
    window_sensor:
      name: Window open sensor
      selector:
        entity:
          domain: binary_sensor
    notify_push:
      name: Push notification service (e.g. notify.notify)
      selector:
        text:
    notify_tts:
      name: (Optional) TTS service for Alexa (e.g. notify.alexa_media_kitchen)
      default: ""
      selector:
        text:
    room_name:
      name: Room name (used in messages)
      selector:
        text:
    threshold:
      name: Threshold for AH difference (g/m³)
      default: 3
      selector:
        number:
          min: 0.5
          max: 10
          step: 0.1
          unit_of_measurement: "g/m³"
    message_ventilate:
      name: Message when ventilation is recommended
      default: "{{ room_name }} should be ventilated. (AH indoor {{ af_in | round(1) }} > outdoor {{ af_out | round(1) }} g/m³)"
      selector:
        text:
    message_close:
      name: Message when window can be closed
      default: "Humidity in {{ room_name }} is back to normal (AH indoor {{ af_in | round(1) }} ≤ outdoor + threshold {{ af_out | round(1) + threshold | round(1) }} g/m³). You can close the window."
      selector:
        text:

trigger:
  - platform: time_pattern
    minutes: "/5"

condition:
  - condition: numeric_state
    entity_id: zone.home
    above: 0.5

variables:
  t_in: "{{ states(temp_inside) | float }}"
  rh_in: "{{ states(rh_inside) | float }}"
  t_out: "{{ states(temp_outside) | float }}"
  rh_out: "{{ states(rh_outside) | float }}"

  af_in: >
    {{ (6.112 * exp((17.67 * t_in)/(t_in + 243.5)) * rh_in * 2.1674) / (273.15 + t_in) }}
  af_out: >
    {{ (6.112 * exp((17.67 * t_out)/(t_out + 243.5)) * rh_out * 2.1674) / (273.15 + t_out) }}
  delta_af: "{{ af_in - af_out }}"
  tag_ventilate: "{{ 'ventilate_' ~ room_name | lower | replace(' ', '_') }}"
  tag_close: "{{ 'ventilate_' ~ room_name | lower | replace(' ', '_') }}"

action:
  - choose:
      - conditions:
          - condition: template
            value_template: "{{ delta_af | float > threshold | float }}"
        sequence:
          - service: "{{ notify_push }}"
            data:
              message: "{{ message_ventilate }}"
              data:
                tag: "{{ tag_ventilate }}"
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ notify_tts != '' }}"
                sequence:
                  - service: "{{ notify_tts }}"
                    data:
                      message: "{{ message_ventilate }}"
                      data:
                        type: announce

      - conditions:
          - condition: template
            value_template: "{{ delta_af | float <= threshold | float }}"
          - condition: state
            entity_id: !input window_sensor
            state: "on"
        sequence:
          - service: "{{ notify_push }}"
            data:
              message: "{{ message_close }}"
              data:
                tag: "{{ tag_close }}"
          - choose:
              - conditions:
                  - condition: template
                    value_template: "{{ notify_tts != '' }}"
                sequence:
                  - service: "{{ notify_tts }}"
                    data:
                      message: "{{ message_close }}"
                      data:
                        type: announce
mode: single
1 Like