Vent-Axia extractor boost on/off when risk of mould

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

Controls a Vent-Axia Pax (Svara/Calima, or compatible) extractor boost switch from dew-point logic. When there is risk of mould for 30 minutes (configurable), boost turns on; when it is no longer warranted for the same delay, boost turns off.

Requires Home Assistant 2023.4 or later. Room sensors and boost switch assume the ha-pax_ble integration (BLE or local API).

Vent warranted formula

Ventilation is warranted when both are true:

  1. Mould floor: room dew point ≥ mould floor (default 16 °C). Below this, extracting heated indoor air usually costs more than the mould risk justifies in winter.
  2. Outdoor delta: room dew point > outdoor dew point + delta (default 1.0 °C). Outdoor air is materially drier, so extraction removes humidity instead of adding it.

Dew point is calculated inside the blueprint (Magnus formula from temperature + humidity), or you can point it at existing dew point sensors.

What it does

  • Warranted for N minutes: turn boost on if it is off.
  • Not warranted for N minutes: turn boost off if it is on.
  • Single automation; thresholds and dew point source are blueprint inputs.

Required entities (calculate mode, default)

Role Example How to get it
Room temperature sensor.top_bathroom_extractor_temperature Pax integration (see link above)
Room humidity sensor.top_bathroom_extractor_humidity Pax integration
Outdoor temperature sensor.met_no_outdoor_temperature Weather integration (Met.no, Met Office, etc.)
Outdoor humidity sensor.met_no_outdoor_humidity Weather integration
Boost switch switch.top_bathroom_extractor_boostmode Pax integration (boost mode, not fan power)

Entity IDs vary by integration and room name; the examples above are from one install.

Sensors mode (optional)

Set Dew point source to Use dew point sensors if you already maintain room and outdoor dew point entities.

Caveats

  • May turn off boost you enabled manually in the Pax app when warranted stays off for the full delay.
  • If Pax temp/RH sensors are unavailable, boost will not change until readings return.

Blueprint

blueprint:
  name: Pax extractor boost when dew-point ventilation warranted
  description: >
    Turn a Vent-Axia Pax (Svara/Calima, or compatible) extractor **boost mode** switch
    **on** or **off** when dew-point ventilation is warranted, with a stability delay
    so boost does not flap.


    **Vent warranted** when both are true:

    1. Room dew point is at or above the mould floor (default 16 °C) - winter heat-loss
       guard so you do not extract expensive heated air unless humidity is mould-relevant.

    2. Room dew point is more than *outdoor dew point + delta* (default 1.0 °C) - outdoor
       air is materially drier, so extraction removes humidity instead of adding it.


    **Dew point source**

    - *Calculate* (default): Magnus formula from room and outdoor temperature + humidity.

    - *Sensors*: use existing room and outdoor dew point `sensor.*` entities.


    **Behaviour**

    - Warranted **on** for *N* minutes → `switch.turn_on` (only if boost is off).

    - Warranted **off** for *N* minutes → `switch.turn_off` (only if boost is on).


    **Caveat:** may turn off boost you enabled manually in the Pax app when warranted
    stays off for the full delay.
  author: Tom
  domain: automation
  homeassistant:
    min_version: 2023.4.0
  input:
    dew_point_source:
      name: Dew point source
      description: Calculate from temperature and humidity, or use existing dew point sensors.
      default: calculate
      selector:
        select:
          options:
            - label: Calculate from temperature and humidity
              value: calculate
            - label: Use dew point sensors
              value: sensors
    room_temperature:
      name: Room temperature
      description: Pax fan or room temperature sensor (calculate mode only).
      selector:
        entity:
          filter:
            - domain: sensor
              device_class: temperature
    room_humidity:
      name: Room humidity
      description: Pax fan or room humidity sensor (calculate mode only).
      selector:
        entity:
          filter:
            - domain: sensor
              device_class: humidity
    outdoor_temperature:
      name: Outdoor temperature
      description: Weather integration outdoor temperature (calculate mode only).
      selector:
        entity:
          filter:
            - domain: sensor
              device_class: temperature
    outdoor_humidity:
      name: Outdoor humidity
      description: Weather integration outdoor humidity (calculate mode only).
      selector:
        entity:
          filter:
            - domain: sensor
              device_class: humidity
    room_dew_point:
      name: Room dew point
      description: Room dew point sensor (sensors mode only).
      selector:
        entity:
          filter:
            - domain: sensor
              device_class: temperature
    outdoor_dew_point:
      name: Outdoor dew point
      description: Outdoor dew point sensor (sensors mode only).
      selector:
        entity:
          filter:
            - domain: sensor
              device_class: temperature
    mould_floor_c:
      name: Mould floor (°C dew point)
      description: Minimum room dew point before boost is considered (UK mould band ~16–18 °C).
      default: 16
      selector:
        number:
          min: 10
          max: 25
          step: 0.5
          unit_of_measurement: "°C"
          mode: box
    outdoor_delta_c:
      name: Outdoor delta (°C)
      description: Room dew point must exceed outdoor dew point by at least this much.
      default: 1.0
      selector:
        number:
          min: 0
          max: 5
          step: 0.1
          unit_of_measurement: "°C"
          mode: box
    boost_switch:
      name: Extractor boost switch
      description: Switch entity for Pax **boost mode** (not the fan power relay).
      selector:
        entity:
          filter:
            - domain: switch
    stable_minutes:
      name: Stability delay
      description: >
        Minutes vent-warranted must stay **on** or **off** before boost changes.
        Filters brief spikes (default 30).
      default: 30
      selector:
        number:
          min: 1
          max: 120
          unit_of_measurement: min
          mode: box

mode: single

triggers:
  - trigger: template
    id: warranted_on
    value_template: >
      {% if '!input dew_point_source' == 'sensors' %}
      {% set room_dp = states('!input room_dew_point') | float(none) %}
      {% set outdoor_dp = states('!input outdoor_dew_point') | float(none) %}
      {% else %}
      {% set rh_r = states('!input room_humidity') | float(none) %}
      {% set t_r = states('!input room_temperature') | float(none) %}
      {% set room_dp = none if rh_r is none or t_r is none or rh_r <= 0
         else (243.5 * (((rh_r / 100) | log) + (17.67 * t_r) / (243.5 + t_r))
         / (17.67 - ((rh_r / 100) | log) - (17.67 * t_r) / (243.5 + t_r))) | round(1) %}
      {% set rh_o = states('!input outdoor_humidity') | float(none) %}
      {% set t_o = states('!input outdoor_temperature') | float(none) %}
      {% set outdoor_dp = none if rh_o is none or t_o is none or rh_o <= 0
         else (243.5 * (((rh_o / 100) | log) + (17.67 * t_o) / (243.5 + t_o))
         / (17.67 - ((rh_o / 100) | log) - (17.67 * t_o) / (243.5 + t_o))) | round(1) %}
      {% endif %}
      {{ room_dp is not none and outdoor_dp is not none
         and room_dp >= !input mould_floor_c
         and room_dp > outdoor_dp + !input outdoor_delta_c }}
    for:
      minutes: !input stable_minutes
  - trigger: template
    id: warranted_off
    value_template: >
      {% if '!input dew_point_source' == 'sensors' %}
      {% set room_dp = states('!input room_dew_point') | float(none) %}
      {% set outdoor_dp = states('!input outdoor_dew_point') | float(none) %}
      {% else %}
      {% set rh_r = states('!input room_humidity') | float(none) %}
      {% set t_r = states('!input room_temperature') | float(none) %}
      {% set room_dp = none if rh_r is none or t_r is none or rh_r <= 0
         else (243.5 * (((rh_r / 100) | log) + (17.67 * t_r) / (243.5 + t_r))
         / (17.67 - ((rh_r / 100) | log) - (17.67 * t_r) / (243.5 + t_r))) | round(1) %}
      {% set rh_o = states('!input outdoor_humidity') | float(none) %}
      {% set t_o = states('!input outdoor_temperature') | float(none) %}
      {% set outdoor_dp = none if rh_o is none or t_o is none or rh_o <= 0
         else (243.5 * (((rh_o / 100) | log) + (17.67 * t_o) / (243.5 + t_o))
         / (17.67 - ((rh_o / 100) | log) - (17.67 * t_o) / (243.5 + t_o))) | round(1) %}
      {% endif %}
      {% set warranted = room_dp is not none and outdoor_dp is not none
         and room_dp >= !input mould_floor_c
         and room_dp > outdoor_dp + !input outdoor_delta_c %}
      {{ room_dp is not none and outdoor_dp is not none and not warranted }}
    for:
      minutes: !input stable_minutes

actions:
  - choose:
    - conditions:
      - condition: trigger
        id: warranted_on
      - condition: state
        entity_id: !input boost_switch
        state: "off"
      sequence:
      - action: switch.turn_on
        target:
          entity_id: !input boost_switch
    - conditions:
      - condition: trigger
        id: warranted_off
      - condition: state
        entity_id: !input boost_switch
        state: "on"
      sequence:
      - action: switch.turn_off
        target:
          entity_id: !input boost_switch