Multi speed Fan control based on temperature

This blueprint automates speed control of your fans in relation to your chosen temperature range.

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

It should work with any fans that use percentage step control and allows for fans where the integration shows maximum speed different to 100%.

The speed will be set when first turn the fan on, a customizable delay is used to avoid changing the fan too frequently. Subsequent speed changes are done in steps to allow for temporary manual speed override.

blueprint:
  name: Auto fan speed
  description: "Temperature based Auto fan control.\n\n
    Fan Speed will be set when initially turned on by relating the ambient temperature
    to an equivalant speed setting. \nA time delay is used to eliminate frequent speed changes.\n
    As the temperature changes the fan speed will increase or decrease accordingly,
    rather than being set. \nThis is to allow a manual change of starting speed.\n
    At the minimum temperature setting the fan will be turned off."
  domain: automation
  input:
    fan_switch:
      name: Fan
      description: The fan you wish to speed control.
      selector:
        entity:
          domain: fan
    min_fan_speed:
      name: Minimum Fan Speed
      description: Set the minimum speed at which your fan is still on. This is
        also used to calculate percentage step of your fan.
      default: 16
      selector:
        number:
          min: 1.0
          max: 100.0
          mode: slider
          step: 1.0
          unit_of_measurement: "%"
    max_fan_speed:
      name: Maximum Fan Speed
      description: Set the maximum percentage speed for your fan.
        Just in case the fan integration has the maximum speed different to 100%.
      default: 100
      selector:
        number:
          min: 1.0
          max: 100.0
          mode: slider
          step: 1.0
          unit_of_measurement: "%"
    high_temp_value:
      name: What temperature would you like the fan to run at 100%
      description: Set the high temperture sensor value.
      default: 31
      selector:
        number:
          min: 15
          max: 40.0
          step: 1.0
          mode: slider
    low_temp_value:
      name: What temperature would you like the fan to run at minimum speed.
      description: Set the low temperture sensor value.
      default: 23
      selector:
        number:
          min: 15
          max: 40.0
          step: 1.0
          mode: slider
    off_temp_value:
      name: What temperature would you like the fan to turn off.
      description: Set the fan OFF temperture sensor value.
      default: 21.5
      selector:
        number:
          min: 15
          max: 40.0
          step: 1.0
          mode: slider
    change_time:
      name: Change frequency delay
      description: How long to delay bewteen potential speed adjustments.
      default: 30
      selector:
        number:
          min: 1.0
          max: 120.0
          unit_of_measurement: minutes
          step: 1
          mode: slider
    temp_sensor:
      name: Temperature Sensor
      description: Enter your temperature sensor.
      default: []
      selector:
        entity:
          domain: sensor
          device_class: temperature
          multiple: false
variables:
  change_time: !input change_time
  low_temp_value: !input low_temp_value
  off_temp_value: !input off_temp_value
  high_temp_value: !input high_temp_value
  min_fan_speed: !input min_fan_speed
  max_fan_speed: !input max_fan_speed
  temp_sensor: !input temp_sensor
  fan_switch: !input fan_switch
  current_temp: "{{ states(temp_sensor) |float(0)}}"
  fan_speed: "{{ state_attr(fan_switch,'percentage') |float(0)}}"
  temp_range: "{{high_temp_value|float(0)-low_temp_value|float(0)}}"
  fan_range: "{{max_fan_speed|float(0)-min_fan_speed|float(0)}}"
  percent_per_degree: "{{fan_range|float(0)/temp_range|float(0)}}"
  deg_above_min: "{{current_temp|float(0)-low_temp_value|float(0)}}"
  set_fan_speed: "{{[[min_fan_speed|float(0) + (deg_above_min|float(0)*percent_per_degree|float(0)),min_fan_speed|float(0)]|max,max_fan_speed]|min |float(0)}}"
  speed_diff: "{{(fan_speed - set_fan_speed)|abs}}"
  speed_increase: "{{[(fan_speed + min_fan_speed),max_fan_speed]|min}}"
  speed_decrease: "{{[(fan_speed - (min_fan_speed*1.2))|int,min_fan_speed]|max}}"
trigger:
  - platform: state
    entity_id:
      - !input fan_switch
    id: fanon
    to: "on"
    from: "off"
  - platform: state
    entity_id:
      - !input temp_sensor
  - platform: numeric_state
    entity_id: !input temp_sensor
    below: !input off_temp_value
condition:
  - condition: template
    value_template: "{{ states(fan_switch) == 'on' }}"
action:
  - choose:
      - conditions:
          - condition: trigger
            id: fanon
          - condition: template
            value_template: "{{ speed_diff|float(0) > min_fan_speed|float(0) }}"
        sequence:
          - service: homeassistant.turn_on
            data:
              percentage: "{{set_fan_speed}}"
            target:
              entity_id: "{{fan_switch}}"
          - delay:
              minutes: !input change_time
      - conditions:
          - condition: template
            value_template: "{{ speed_diff|float(0) > min_fan_speed|float(0) }}"
          - condition: template
            value_template: "{{ fan_speed |float(0) < set_fan_speed|float(0) }}"
          - condition: template
            value_template: "{{ current_temp|float(0) > off_temp_value|float(0) }}"
          - condition: template
            value_template: "{{ states(fan_switch) == 'on' }}"
        sequence:
          - service: homeassistant.turn_on
            target:
              entity_id: "{{fan_switch}}"
            data:
              percentage: "{{speed_increase}}"
          - delay:
              minutes: !input change_time
      - conditions:
          - condition: template
            value_template: "{{ speed_diff|float(0) > min_fan_speed|float(0) }}"
          - condition: template
            value_template: "{{ set_fan_speed|float(0) < fan_speed|float(0) }}"
          - condition: template
            value_template: "{{ current_temp|float(0) > off_temp_value|float(0) }}"
          - condition: template
            value_template: "{{ states(fan_switch) == 'on' }}"
        sequence:
          - service: homeassistant.turn_on
            target:
              entity_id: "{{fan_switch}}"
            data:
              percentage: "{{speed_decrease}}"
          - delay:
              minutes: !input change_time
      - conditions:
          - condition: not
            conditions:
              - condition: trigger
                id: fanon
          - condition: numeric_state
            entity_id: !input temp_sensor
            below: !input off_temp_value
        sequence:
          - service: homeassistant.turn_off
            target:
              entity_id: "{{fan_switch}}"
mode: single

Update:
Added an extra temp selection for minimum speed / turn off temp.
Added a condition to check fan is on to eliminate a log error.

2 Likes

Hiya,
I wish I could get this working, it’s EXACTLY what I’ve been looking for.
I’ve got two Whisper Flex Smart fans. They just arrived today.
I’ve got the automation setup from your blueprint.
Doesn’t seem to be working tho.
I’m seeing ‘option 2 executed’ in the trace.
Fan.increase_speed is working in a script and so is fan.set_percentage
Any ideas to why it might not be working?
Cheers,
Michael

Can you give me some ideas as to the numbers your working with.
How many speed options do your fans have?
What is the max and min %?
And maybe what temp range you have entered for the blueprint.

hiya,
The fans have 26 speeds, min is 3% and max 100%
however, looking further at the logs and traces it appeared that it should have been working, I never worked out why it wasn’t. I decided to try another way and In the end I went down a different route, as below. But thanks all the same.

 alias: Adjust Whisper Flex Fan Speed
  trigger:
    - platform: state
      entity_id: fan.whisper_flex
      to: 'on'
    - platform: state
      entity_id: sensor.net2main_temperature
  condition:
    - condition: state
      entity_id: person.michael_j  # Replace with your presence entity
      state: 'home'
    - condition: time
      after: '09:00:00'
      before: '23:59:59'
    - condition: state
      entity_id: input_boolean.whisper_fan_1_auto  # Replace with your input boolean entity
      state: 'on'
  action:
    - service: fan.set_percentage
      target:
        entity_id: fan.whisper_flex
      data_template:
        percentage: "{{ (states('sensor.net2main_temperature') | float - 20) * 4.5 }}"

Definitely much more basic than yours but at least I’ve got them up and running for now.
May have to adjust the figures once it gets warmer over here in the UK.

I guess my other question is what version of not working happened?
Did the fan turn on at all?
Also note, I don’t actually use fan.increase_speed or fan.set_percentage in the blueprint, I think I read something somewhere to say perhaps using the homeassistant.turn_on would be more suitable as a generic command.

I can’t see any reason why it shouldn’t work, my fans are about 1 speed change per degree. With 26 speeds you might end up getting many speed adjustments as the temperature changes by small amounts.

I didn’t see any action from the fans while testing the blueprint. It didn’t turn on and the speed didn’t get set after I manually turned it on and let it run for a number of hours.
The automation appeared to be working however, it was triggering and generating the numbers when I checked the trace. The temperatures that I set were 20c turn off, 21c lowest speed and 30c highest. I did measure temp changes in the room from 22-25.
fan.set_percentage seems to work with these Whisper Flex Smart fans.

@MickW69 some good work put in here and it looks like the perfection solution for my network cabinet fan (controlled via an esp32 via espHome). However, for whatever reason, I havn’t been able to get the blueprint to work. No matter what the temperature is, the traces for the automation show that no changes were needed.

What unit does the temp sensor need to return? Mine is currently in degC.

I’ve added to this blueprint to suit my needs. Some improvments were made to both the equation for set_fan_speed and I also included a blocking entity and a minimum_change_threshold selector. Great work on this initial blueprint @MickW69! I couldn’t have done it without your inspiration :clap:

Updated blueprint here

1 Like