Trying to control fan speed by temp

Hi, I am brand new to Home Assistant. I have a Lutron Caseta Fan switch controlling a ceiling fan. I also have a Xaiomi temp sensor (Aqara) reporting the room temperature.

I have figured out how to set up an automation that will turn the fan on when the room hits a certain temperature.

But, I am trying to figure out how to have the fan turn to low at 76 degrees, medium at 79 degrees, medium-high at 82 degrees and high at 85 degrees, but then it would also turn itself off if the temp drops below 76 degrees.

Lastly, would be awesome if the fan doesn’t turn itself off if manually turned on.

Can anyone point me in the right direction? I would greatly appreciate it!!

Thanks,
David

I have a Caseta fan switch and an ecobee temperature sensor in the room I use as an office. Very similar to your set up. This is the automation I created to set my fan to various speeds throughout the day based on the temperature in the room. I have other conditions to limit it so that it runs only if I am home, on weekdays, and during hours where I am typically working.

I’m not sure if/how you can override if you have turned it on manually.

# Office Fan On
- id: office_fan_on
  alias: 'Office Fan On'
  initial_state: true
  trigger:
    - platform: state
      entity_id: sensor.office_temperature_ecobee
  condition:
    condition: and
    conditions:
      - condition: time # Weekdays
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
      - condition: time
        after: '09:00:00'  # Fires after 9:00 am
      - condition: time
        before: '18:00:00'  # Fires before 6:00 pm
      - condition: state
        entity_id: binary_sensor.mike_presence_sensor # Mike is home
        state: 'on'
      - condition: numeric_state
        entity_id: sensor.office_temperature_ecobee
        value_template: "{{ states('sensor.office_temperature_ecobee') | float }}"
        above: 77.2  # Temperature in office is above 77.2

  action:
    - service: fan.set_percentage
      entity_id: fan.office_ceiling_fan
      data:
        percentage: >
          {% if states('sensor.office_temperature_ecobee') | float >= 81 %}
            100
          {% elif states('sensor.office_temperature_ecobee') | float > 79.6 %}
            75
          {% elif states('sensor.office_temperature_ecobee') | float > 78.2 %}
            50
          {% else %}
            25
          {% endif %}

This is a huge help, thank you! I will go though and modify it. I am less worried about the override, so I will start here and will modify it down the road when I know a bit more.

On yours, if the fan kicks on because it hits the trigger temperature, and then the temperature falls below the trigger, will it shut the fan off?

Thank you!
-David

You’re very welcome! I have a separate automation that turns the fan off if the temperature goes below 77.2. It probably could have been written in the same automation, but some of my conditions are a little different.

Ah, ok…that makes sense. Would you mind sharing the code for that automation? Just curious what that includes.

Thanks again!!!

So I am running into an error with the script, and not sure what it means. The error is

Message malformed: required key not provided @ data['trigger'][1]['platform']

And this is the automation:

# Bedroom Fan On
id: bedroom_fan_on
alias: 'Bedroom Fan On'
initial_state: true
trigger:
  - platform: state
    entity_id: sensor.temperature_and_humidity_sensor_f956_temperature
condition:
  - condition: numeric_state
    entity_id: sensor.temperature_and_humidity_sensor_f956_temperature
    value_template: "{{ states('sensor.temperature_and_humidity_sensor_f956_temperature') | float }}"
    above: 77.2  # Temperature in room is above 77.2
  action:
  - service: fan.set_percentage
    target:
    entity_id: fan.molly_s_bedroom_ceiling_fan
    data:
    percentage: 
          {% if states('sensor.temperature_and_humidity_sensor_f956_temperature') | float >= 81 %}
            100
          {% elif states('sensor.temperature_and_humidity_sensor_f956_temperature') | float > 79.6 %}
            75
          {% elif states('sensor.temperature_and_humidity_sensor_f956_temperature') | float > 78.2 %}
            50
          {% else %}
            25
          {% endif %}

Any thoughts as to what is causing the error?

Thank you!

-David

Your indentation looks to be off in a number of places. Yaml is very picky about indentation. I would start with that.

You are also missing the > after percentage: which is needed when you are breaking to multiple lines.

This is my “off” automation. It could probably be rewritten to be included in the “on” automation, but it works fine the way it is.


# Office Fan Off - When below 76.5
- id: office_fan_off_low_temperature
  alias: 'Office Fan Off - Low Temperature'
  initial_state: true
  trigger:
    - platform: numeric_state
      entity_id: sensor.office_temperature_ecobee
      value_template: "{{ states('sensor.office_temperature_ecobee') | float }}"
      below: 76.5
  condition:
    condition: and
    conditions:
      - condition: time # Weekdays
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
      - condition: time
        after: '09:00:00'  # Fires after 9:00 am
      - condition: time
        before: '18:00:00'  # Fires before 6:00 pm

  action:
    - service: fan.turn_off
      entity_id: fan.office_ceiling_fan

I decided to just go ahead and rewrite mine into one automation because the trigger and conditions are so similar to each other. I think I originally wrote these before the choose option was added to HA.

Here is the new automation that include on and off:

# Office Fan On/Off
- id: office_fan_on_off
  alias: 'Office Fan On/Off'
  initial_state: true
  trigger:
    - platform: state
      entity_id: sensor.office_temperature_ecobee
  condition:
    condition: and
    conditions:
      - condition: time # Weekdays
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
      - condition: time
        after: '09:00:00'  # Fires between 9:00 am - 6:00 pm
      - condition: time
        before: '18:00:00'  # Fires between 9:00 am - 6:00 pm

  action:
    - choose:
      - conditions:
          - condition: state
            entity_id: binary_sensor.mike_presence_sensor # Mike is home
            state: 'on'
          - condition: numeric_state
            entity_id: sensor.office_temperature_ecobee
            value_template: "{{ states('sensor.office_temperature_ecobee') | float }}"
            above: 77.2  # Temperature in office is above 77.2
        sequence:
          - service: fan.set_percentage
            entity_id: fan.office_ceiling_fan
            data:
              percentage: >
                {% if states('sensor.office_temperature_ecobee') | float >= 81 %}
                  100
                {% elif states('sensor.office_temperature_ecobee') | float > 79.6 %}
                  75
                {% elif states('sensor.office_temperature_ecobee') | float > 78.2 %}
                  50
                {% else %}
                  25
                {% endif %}

      - conditions:
          - condition: numeric_state
            entity_id: sensor.office_temperature_ecobee
            value_template: "{{ states('sensor.office_temperature_ecobee') | float }}"
            below: 76.5  # Temperature in office is below 76.5
        sequence:
          - service: fan.turn_off
            entity_id: fan.office_ceiling_fan

Hey Mike, this is awesome, thank you!

One huge favor…I am reading online about YAML spacing, since that seems to be the issue here. Any chance you could post a screenshot of yours so I can see how the spacing looks without the copy/paste changes?

I am trying to go through and reformat it in the mean time, but still learning how all this works.

Thanks!
-David

Hi all,

I am having a lot of trouble here…if anyone could point me in the direction of what I am doing wrong, I would greatly appreciate it. This code is all thanks to @_Mike but I am trying to modify it for my use.

The yaml below is giving me a

Message malformed: expected dictionary

This is supposed to turn the bedroom fan on when the temp sensor reports a temp of above 77.2 and then will adjust speed based on actual temp. Once the temp gets below 76.5, it should shut the fan off.

Thank you for your help!!
-David

# Bedroom Fan On/Off
- id: molly_fan_on_off
  alias: 'Molly Fan On/Off'
  initial_state: true
  trigger:
    - platform: state
      entity_id: sensor.temperature_and_humidity_sensor_f956_temperature

  condition:

  action:
    - choose:
      - conditions:
          - condition: numeric_state
            entity_id: sensor.temperature_and_humidity_sensor_f956_temperature
            value_template: "{{ states('sensor.temperature_and_humidity_sensor_f956_temperature') | float }}"
            above: 77.2  # Temperature in bedroom is above 77.2
        sequence:
          - service: fan.set_percentage
            entity_id: fan.molly_s_bedroom_ceiling_fan
            data:
              percentage: >
                {% if states('sensor.temperature_and_humidity_sensor_f956_temperature') | float >= 81 %}
                  100
                {% elif states('sensor.temperature_and_humidity_sensor_f956_temperature') | float > 79.6 %}
                  75
                {% elif states('sensor.temperature_and_humidity_sensor_f956_temperature') | float > 78.2 %}
                  50
                {% else %}
                  25
                {% endif %}

      - conditions:
          - condition: numeric_state
            entity_id: sensor.temperature_and_humidity_sensor_f956_temperature
            value_template: "{{ states('sensor.temperature_and_humidity_sensor_f956_temperature') | float }}"
            below: 76.5  # Temperature in bedroom is below 76.5
        sequence:
          - service: fan.turn_off
            entity_id: fan.molly_s_bedroom_ceiling_fan

There’s really no need for a screen shot. Using the code/preformatted text button keeps the exact formatting. You could copy and paste my example and it would retain all of the original spacing. But you may need to view it in a computer browser rather than mobile or email.

The issue I see right away here is that you have condition: with nothing following it. If you have no condition, you can completely omit condition: or add empty brackets after it like condition: []

But having said that, I would add some kind of condition. Whether time-based or anything else. As it is now, your automation will fire 24/7 every time your sensor value changes. Your choose statement will ensure that only the intended actions will happen, but the trigger will still be firing. Not a HUGE deal, but still adding some unneeded load on HA.

Thanks, Mike. I just tried copying your code directly (with the preformatted text button) on a computer browser and pasted into my blank automation, but I am still getting the Message malformed: expected dictionary error. So there is something going on with the copy/paste.

Did you remove the empty condition: ?

I am using your code exactly. I realize I would get an error when it can’t find the entity, but I can’t even get past the expected dictionary error

# Office Fan On/Off
- id: office_fan_on_off
  alias: 'Office Fan On/Off'
  initial_state: true
  trigger:
    - platform: state
      entity_id: sensor.office_temperature_ecobee
  condition:
    condition: and
    conditions:
      - condition: time # Weekdays
        weekday:
          - mon
          - tue
          - wed
          - thu
          - fri
      - condition: time
        after: '09:00:00'  # Fires between 9:00 am - 6:00 pm
      - condition: time
        before: '18:00:00'  # Fires between 9:00 am - 6:00 pm

  action:
    - choose:
      - conditions:
          - condition: state
            entity_id: binary_sensor.mike_presence_sensor # Mike is home
            state: 'on'
          - condition: numeric_state
            entity_id: sensor.office_temperature_ecobee
            value_template: "{{ states('sensor.office_temperature_ecobee') | float }}"
            above: 77.2  # Temperature in office is above 77.2
        sequence:
          - service: fan.set_percentage
            entity_id: fan.office_ceiling_fan
            data:
              percentage: >
                {% if states('sensor.office_temperature_ecobee') | float >= 81 %}
                  100
                {% elif states('sensor.office_temperature_ecobee') | float > 79.6 %}
                  75
                {% elif states('sensor.office_temperature_ecobee') | float > 78.2 %}
                  50
                {% else %}
                  25
                {% endif %}

      - conditions:
          - condition: numeric_state
            entity_id: sensor.office_temperature_ecobee
            value_template: "{{ states('sensor.office_temperature_ecobee') | float }}"
            below: 76.5  # Temperature in office is below 76.5
        sequence:
          - service: fan.turn_off
            entity_id: fan.office_ceiling_fan

I don’t understand. You should still be able to paste it in, and then change the entities to what you have. Here is the screen shot…

It looks just like what I have…no clue why I am getting the error!!

Then I would try taking out almost everything until it works, then add back once piece at a time.

Do you have other automations that work?

No, this is my first automation. I first created one using the automation tool which worked, but I couldn’t add in the fan speeds based on temps, so I trashed that one.