[HELP] New Template Fan integration - percentage

yup - I too would like to see what solution you get out of this. please post back when you have solved it. I will post my yaml if I get mine sorted.

fan:
  - platform: template
    fans:
      vent_teto_quarto:
        friendly_name: "Ventilador Quarto"
        value_template: "{{ states('input_boolean.ventteto_quarto') }}"
        percentage_template: "{{ float(states('input_select.ventteto_quarto_velocidades')) * 100 / 6 }}"
        # Uses a fake switch from an input_boolean as the fan has no way of reporting direction back to HA
        direction_template: "{{ 'forward' if is_state('input_boolean.quarto_fan_direction', 'on') else 'reverse' }}"
        turn_on:
          service: script.ventteto_quarto_on
        turn_off:
          service: script.ventteto_quarto_off
        set_percentage:
          - service: script.ventteto_quarto_velocidade
            data_template:
              percentage: "{{ percentage }}"
        set_direction:
          - service: remote.send_command
            data:
              entity_id: remote.rmpro_remote
              command:
                - b64:sgYwABQvFA02DTYvFC+UHyQfJB8kHyQfJB8kHyMfIy8ULxMvFA02DTYvFC8TDTYNNg02LwAAAAAAAAAA
          - service: input_boolean.toggle
            entity_id: input_boolean.quarto_fan_direction
        speed_count: 6

For your ventteto_quarto_velocidade, check the percentage value is between 100*1/6, 100*2/6, 100*3/6, 100*4/6, etc and set the value of the input select based on where it falls similar to how you are doing in ventteto_quarto_on

if percentage <= 0:
  speed=0
elif percentage < 100*1/6:
  speed=1
elif percentage < 100*2/6:
  speed=2
....
1 Like

Hi there. I will try using suggested approach. I have updated to core-2021.3.3 and it’s still working with

fan.set_speed service.

So it’s possible to update without loosing fan controlling, and keep on trying on adding percentage.
Thanks in advance.

The intent was to make fully backwards compatibly to give everyone time to transition as it will likely take a few months for every integration to switch over to the new model. Last time I checked we had 5 integrations still on the old model out of ~26.

Edit: As of April 14th, we are down to 3 that haven’t switched over vallox, wink and xiaomi_miio (in progress - Implement new fan model in Xiaomi Miio by syssi · Pull Request #47897 · home-assistant/core · GitHub)

1 Like

Hi all,

If it helps I updated my old template fan package to allow for the new percentage, it is a little convoluted since it uses RFlink to pickup the status from the 433hz remote and uses broadlink to transmit from home assistant and it is glued together with a bunch of binary sensors etc.

anyhow here is my code which may be helpful for others - for the set percentage if/else check I forgot to switch to an integer as opposed to a sting (i drdnt remove the inverted commas for the percentage).

switch:
  - platform: broadlink
    mac: 'B4:43:0D:AA:9B:6A'
    switches:
      - name: Dining Fan 20
        command_on: 6QACARkzPxAXNRc2Fjc9EDwSFjYVOBU4FTg7EjoUEzoTOhM5FTgTOxI6ORQTOjkVEgACNRM4OxIUOTsTFDkUOBQ6OxE7EhU4FDkUORQ5PBE6EhQ7EzgWNxQ5FDkWODoSFDk6ExQAAjMXNTwRFTg7ExU3FTkVNzsSOxMUOhQ3FDoUODsSPBEUORQ5FDgVOBU4FTg7EhU4OxIUAAIzFjY8EhU3PBIVOBU3FTg7EzsSFDoTOBU4Fjg6EjsSFDkVORQ4FDkUORQ4PRAWNzsSFQACMxY3OxEVODwRFTgVNwwFBDg8EjsSFDgVOBU4FTg7EjsSFTgVOBU4FDkUORY3OxIUODsTFAAF3AAAAAAAAA==
      - name: Dining Fan 40
        command_on: 6QAEAQUXPREWNzsRFjcWNxc2PRA7EhU5FDgUORU4OxI6ExU5EzkVOBQ6EzkUOBU4OxIUORQAAjMVODwRFTg7EhY3FDoTOTkUORYQPBE9EjsQPTcVOBQSPBE7EjsSOhM7EjoTOjkUEzoTAAI0FDk6EhQ5OhQTOhQ4FDo7EToUFDgUOBU5FDg7EjsTFDgVOBU4FDkUOhM5FDk6FBM5FAACMxU3PBEVODwRFTgVOBU4OxM6EhQ5FDgVOhQ3OxI7EhY3FTgVOBU4FDkWNxU5OhIUOBUAAjIWNzwRFTk6EhU4FTgWNzwROxMUORQ4FDoUODsTOhEWOBQ4FTgVOBU4FTgVODsSFTgUAAXcAAAAAA==
      - name: Dining Fan 60
        command_on: 6QAMAQQEBQQEBAQGBAQ+EBY2PREWNxU4FTc8EjsSFTgUORQ5FTg6EzoTFDkUORQ4FDoTOTsTOhI6FRI5FAACMxU4PBEUOToUEjoTOhM6OBc3FRE8ETsSPBI6ORQ5FBI7EjsTORM7Ejo6EzkVORMTOhMAAjMVODsSFjc6ExQ5FDkUOToTOxIUORQ4FTkUODsTOxEUOhQ5FDgUORQ5OxI6EzoTFTcUAAIzFjc7EhU4OxIVOBU4FTg6EzwRFDoUNxU5FTc7EjwRFDkVOBQ6EzkUOTsSOhM6FBM4FQACMhY3OxIVOToSFTgVOBQ4PRI7ERQ4FTgVOBU4OxM6EhU4FTgVOBQ4FTk7EzkTPBEUOBUABdwAAAAAAAAAAAAAAAA=
      - name: Dining Fan 80
        command_on: 6QAKAQQLBAQIBAYEPRAWNj0RFjcVOBU3PBI7EhQ5FDkUORQ5OhM6ExQ5FDkUOBQ5FDk7EhQ5OhU4ExQAAjMVODsSFDk6FBM6EjoUOTkWNxcPPRA7EjwSPDcUORQSOxM6EjsSOhM7ORQSOjoTORYRAAI0FTc7EhU5OhMUOBU4FDk7EzoSFDoTOhM5FDk6EzoTFDkUORQ5FDkTOTwRFTg7EjsSFAACMhY3PBIVODoTFDgVOBU4OxM6EhU4FDkUORU4OxM5FBM5FDkUOBU4FTg9EhM4OxI7EhQAAjQVNjwSFTc8EhQ4FTgVODwRPBEWNxU4FTgVODwROxIUORQ6EzoTOBU4OxIVODsSOxIUAAXcAAAAAAAAAAAAAAAAAAA=
      - name: Dining Fan 100
        command_on: 6QACAT8QFzY8ERc2FjcXNjwSOxEVOBQ5FDkVODsSOhMVOBU4FTcWOBM6FDg7EjoTOhMUAAIzFTg7ExQ3PBQROhM6Ezs5FDgVEjsTOhE7FDk4FTgXEDsSPBE6EzoTOhM7OBQ6EzkUEwACNBQ4OxMTOToTFDkUOhM4OxM6ExQ5FDgVORQ4OxQ5EhU4FDkUORQ5FDkUODsSOxI7EhQAAjQVNzsSFTg7EhU4FTgUODwSOxIUORU3FTgVOjkSOxMUOBU4FTgWNxQ5FTg7EzsROhMUAAIyFjg7ERU4OxIVOhQ3FTk6EjsSFTgWNxQ5FTg7EjoTFDkVOBQ4FTgVOBY4OhI7EjsSFAAF3AAAAAAAAA==
      - name: Dining room Fan Light
        command_on: 6QAAARY2PREWNxU3Fjc8EzoSFTkTOBU4FTg7EjsSFDsUNxQ5FDkUOTsSFDkUORU4FAACMhY3PBEXNjsSFjgUOBU5ORQ5FBI7EzoSOxI7OBU4FRE8EjoTOhI7Ejs5FBM7EToTOhMAAjMXNzoSFTg7FBM4FDkUOToUOhMTORQ4FTkUOjoSOhIUOxM4FDkVOBQ5OxIUORQ4FTgVAAIyFjc8ERU4OxIWNxU5FTc7EjsSFDoTORQ4FzY7EjsSFTgWNxU4FDkUOTsSFDgVOBU4FQACMhc2PREUNz0RFTgVNxY3PBI7EhQ5FTcWNxU4OxI7EhU4FjcVOBQ4FTk7EhQ4FjcVOBUABdwAAAAAAAAAAA==
        command_off: 6QAAARc2PBEXNhY3FTg7EjsSFTgVORQ4FTg7EjoTFDkUORQ5FTcVOhM4FTgUOTwRFAACMxY3OxIVNz0RFjcUOBU4OxM5FBM6EzoUORM6OBY3FhE8ETsSOxI6EzwROhM6Ezo6ExMAAjMVOToSFDk6ExQ5FDkUODsTOhMUOBU4FDsTODsSOxIWOBM5FDkUORU5EzgVOBU4OxIUAAIzFjc8ERU3PBMUOBY2FTk6EzsRFTgVOBU4FTg7EjsSFTgVOBY3FDgVORU3FTgVOToSFgACMRY2PBIVNzwSFTgVNxU5OxE8ERU4FTgWNxU4OxI7EhQ5FTgVOBQ4FTkVNxU5FDg7EhUABdwAAAAAAAAAAA==
      - name: Dining room Fan
        command_on: 6QAYAQ4FBQ8EBwUEBAQECQoFBQQEBAQIDEgQFjc9EBY3FjgUODwROxIUOhM5FDkVODoTOhMUORU4FTcUORQ5PBITORQ5OxITAAI0FTg7EhQ6ORMUORQ5FDg6FDkWEDwROxI7Ejs4FTgWETsTOhI6EzoTOgsuFRI7Ejk6FBIAAjQVODsSFDo5ExU5EzkUODsTOxMSORQ5FDkUOTsSOhMUORQ5FDoTORQ4OxIVOBU4OhMUAAIzFjc8ERU3PBIVORM4Fjc7EjsSFjcVORQ5FDg8ETsSFTgUORQ4FzcUODsSFTgVODsSFAACMxY4OhIVNzwSFTgVNxU4OxM7ERU5FDgVOBY3OxI7EhQ5FTgUOBU4FTg7EhU4Fjc7EhQABdw=
        command_off: 6QAAARc3PBEVOBU3Fjc8EjwRFDgWNxU5FTc8ETsSFDkUOhM5FDkUORQ5FDk6EjwSEwACMxU4OxIVOToSFDkUORQ5ORU4FhE7ETwSOxI7OBU4FBI8ETsSOxI7EjsUOBM6OhM6ExMAAjMWNzsSFTk6EhQ5FDkUOToUOhIUORQ4FTkUOToSOxIVORM5FTgUORQ5FDoTODsSOxIUAAIyGDU8EhQ6OhIUOBU4FTg7EjsTFDgVORM5FTg7EjoTFTkTOBU4FTgVOBU4FTg7EjoTFAACMhY3PBEVODsSFTgVOBU5OhI7ExQ4FDkUOhQ4OhQ5EhU5FDgWNxU4FDoUOBU3OxI7EhUABdwAAAAAAAAAAA==
  - platform: rflink
    devices:
      chuango_ae79fe_02:
        name: Dining room fan light off


        
binary_sensor:
  - platform: rflink
    devices:
      chuango_ae79f6_02:
        name: Dining room fan on
        off_delay: 1
      chuango_ae79fc_02:
        name: Dining room fan off
        off_delay: 1
      chuango_ae79fa_02:
        name: Dining room fan percentage 20
        off_delay: 1
      chuango_ae79fd_02:
        name: Dining room fan percentage 40
        off_delay: 1
      chuango_ae79f1_02:
        name: Dining room fan percentage 60
        off_delay: 1
      chuango_ae79f4_02:
        name: Dining room fan percentage 80
        off_delay: 1
      chuango_ae79f8_02:
        name: Dining room fan percentage 100
        off_delay: 1
      chuango_ae79f7_02:
        name: Dining room fan light on
        off_delay: 1
  - platform: template
    sensors:
      dining_room_fan_light_off:
        value_template: >-
          {{ is_state('switch.dining_room_fan_light_off', 'off') }}    

input_number:
  dining_fan_percentage:
    name: Dining table fan percentage
    initial: 0
    min: 0
    max: 100
    step: 20
input_boolean:
  dining_fan_state:
    name: Dining table fan state 
  dining_fan_light_state:
    name: Dining table fan light state 
    
fan:
  - platform: template
    fans: 
      dining_table_fan:
        friendly_name: "Dining table fan"
        value_template: "{{ states('input_boolean.dining_fan_state') }}"
        percentage_template: "{{ states('input_number.dining_fan_percentage') }}" 
        turn_on:
          service: script.dining_fan_on
        turn_off:
          service: script.dining_fan_off
        set_percentage:
          service: >
            {% if percentage == 20 %}
              script.dining_fan_percentage_20
            {% elif percentage == 40 %}
              script.dining_fan_percentage_40
            {% elif percentage == 60 %}
              script.dining_fan_percentage_60
            {% elif percentage == 80 %}
              script.dining_fan_percentage_80
            {% elif percentage == 100 %}
              script.dining_fan_percentage_100
            {% else %}
              script.dining_fan_off
            {% endif %}
        speed_count: 5

script:
  dining_fan_on:
    sequence:
      - service: switch.turn_on
        data: {}
        entity_id: switch.dining_room_fan
      - service: input_boolean.turn_on
        data: {}
        entity_id: input_boolean.dining_fan_state
  dining_fan_off:
    sequence:
      - service: switch.turn_off
        data: {}
        entity_id: switch.dining_room_fan
      - service: input_boolean.turn_off
        data: {}
        entity_id: input_boolean.dining_fan_state

  dining_fan_light_on:
    sequence:
      - service: switch.turn_on
        data: {}
        entity_id: switch.dining_room_fan_light
      - service: input_boolean.turn_on
        data: {}
        entity_id: input_boolean.dining_fan_light_state
  dining_fan_light_off:
    sequence:
      - service: switch.turn_off
        data: {}
        entity_id: switch.dining_room_fan_light
      - service: input_boolean.turn_off
        data: {}
        entity_id: input_boolean.dining_fan_light_state

  dining_fan_percentage_20:
    sequence:
      - service: switch.turn_on
        data: {}
        entity_id: switch.dining_fan_20
      - service: input_boolean.turn_on
        data: {}
        entity_id: input_boolean.dining_fan_state
    mode: single
  dining_fan_percentage_40:
    sequence:
      - service: switch.turn_on
        data: {}
        entity_id: switch.dining_fan_40
      - service: input_boolean.turn_on
        data: {}
        entity_id: input_boolean.dining_fan_state
    mode: single
  dining_fan_percentage_60:
    sequence:
      - service: switch.turn_on
        data: {}
        entity_id: switch.dining_fan_60
      - service: input_boolean.turn_on
        data: {}
        entity_id: input_boolean.dining_fan_state
    mode: single
  dining_fan_percentage_80:
    sequence:
      - service: switch.turn_on
        data: {}
        entity_id: switch.dining_fan_80
      - service: input_boolean.turn_on
        data: {}
        entity_id: input_boolean.dining_fan_state
    mode: single
  dining_fan_percentage_100:
    sequence:
      - service: switch.turn_on
        data: {}
        entity_id: switch.dining_fan_100
      - service: input_boolean.turn_on
        data: {}
        entity_id: input_boolean.dining_fan_state
    mode: single

    
automation old:
  - alias: '[Fan] - Turn on linker'
    trigger:
      platform: state
      entity_id: binary_sensor.dining_room_fan_on
    action:
      - service: input_boolean.turn_on
        data: {}
        entity_id: input_boolean.dining_fan_state
  - alias: '[Fan] - Turn off linker'
    trigger:
      platform: state
      entity_id: binary_sensor.dining_room_fan_off
    action:
      - service: input_boolean.turn_off
        data: {}
        entity_id: input_boolean.dining_fan_state
  - alias: '[Fan] - Set percentage 20 linker'
    trigger:
      platform: state
      entity_id: binary_sensor.dining_room_fan_percentage_20
    action:
    - service: input_select.select_option
      data_template:
        entity_id: input_select.dining_fan_percentage
        option: '20'
  - alias: '[Fan] - Set percentage 40 linker'
    trigger:
      platform: state
      entity_id: binary_sensor.dining_room_fan_percentage_40
    action:
    - service: input_select.select_option
      data_template:
        entity_id: input_select.dining_fan_percentage
        option: '40'
  - alias: '[Fan] - Set percentage 60 linker'
    trigger:
      platform: state
      entity_id: binary_sensor.dining_room_fan_percentage_60
    action:
    - service: input_select.select_option
      data_template:
        entity_id: input_select.dining_fan_percentage
        option: '60'
  - alias: '[Fan] - Set percentage 80 linker'
    trigger:
      platform: state
      entity_id: binary_sensor.dining_room_fan_percentage_80
    action:
    - service: input_select.select_option
      data_template:
        entity_id: input_select.dining_fan_percentage
        option: '80'
  - alias: '[Fan] - Set percentage 100 linker'
    trigger:
      platform: state
      entity_id: binary_sensor.dining_room_fan_percentage_100
    action:
    - service: input_select.select_option
      data_template:
        entity_id: input_select.dining_fan_percentage
        option: '100'

  - alias: '[Fan Light] - Turn on linker'
    trigger:
      platform: state
      entity_id: binary_sensor.dining_room_fan_light_on
    action:
      - service: input_boolean.turn_on
        data: {}
        entity_id: input_boolean.dining_fan_light_state
  - alias: '[Fan Light] - Turn off linker'
    trigger:
      platform: state
      entity_id: binary_sensor.dining_room_fan_light_off
    action:
      - service: input_boolean.turn_off
        data: {}
        entity_id: input_boolean.dining_fan_light_state

  - alias: '[Fan Light] - binary sensor fix startup'
    trigger:
      - platform: homeassistant
        event: start
    action:
      - service: switch.turn_on
        data: {}
        entity_id: switch.dining_room_fan_light_off
  - alias: '[Fan Light] - binary sensor fix toggle'
    trigger:
      - platform: state
        entity_id: switch.dining_room_fan_light_off
        to: 'off'
    action:
      - service: switch.turn_on
        data: {}
        entity_id: switch.dining_room_fan_light_off

light:
  - platform: template
    lights:
      dining_fan_light:
        friendly_name: "Dining fan light"
        value_template: "{{ states('input_boolean.dining_fan_light_state') }}"
        turn_on:
          service: script.dining_fan_light_on
        turn_off:
          service: script.dining_fan_light_off

2 Likes

granted it could be a bit tidier, i could move the broadling calls into the scripts and try and get the speed calls into a single script using the input numner variable

Where is “percentage” defined in the following template:

        set_percentage:
          service: >
            {% if percentage == 20 %}
              script.dining_fan_percentage_20
            {% elif percentage == 40 %}
              script.dining_fan_percentage_40
            {% elif percentage == 60 %}
              script.dining_fan_percentage_60
            {% elif percentage == 80 %}
              script.dining_fan_percentage_80
            {% elif percentage == 100 %}
              script.dining_fan_percentage_100
            {% else %}
              script.dining_fan_off
            {% endif %}
1 Like

Good question I am not 100% sure but I think it comes from:

input_number:
  dining_fan_percentage:
    name: Dining table fan percentage
    initial: 0
    min: 0
    max: 100
    step: 20

and

        percentage_template: "{{ states('input_number.dining_fan_percentage') }}" 
1 Like

Ok, so it’s some kind of “magical”, “undocumented”, “background” variable that we can use.

Those kinds of things would be good to put in the documentation as an example somewhere. Especially when these kinds of big/breaking changes get implemented.

The docs on this change are pretty darn sparse.

Thanks for the info.

In the meantime I did manage to bang my head against the code wall long enought that I was able to get it wotking another way.

I don’t know if it will help you or not (or somebody else later) but this is my fan package for a dumb fan controlled by a broadlnk:

fan:
  - platform: template
    fans:
      sunroom_fan_percent_template:
        friendly_name: "Sunroom Fan Percent Template"
        value_template: "{{ states('input_boolean.sunroom_fan_state') }}"
        percentage_template: "{{ states('input_number.sunroom_fan_speed_percent') | float }}"
        turn_on:
          service: script.sunroom_fan_on
        turn_off:
          service: script.sunroom_fan_off
        set_percentage:
          service: script.sunroom_fan_set_speed_percent
          data:
            percentage: "{{ percentage }}"
        speed_count: 3

input_number:
  sunroom_fan_speed_percent:
    name: Sunroom Fan Speed Percent
    min: 0
    max: 100
    step: 1

input_boolean:
  sunroom_fan_state:
    name: Sunroom Fan State
    
script:
  sunroom_fan_off:
    alias: Sunroom Fan Off
    sequence:
      - service: switch.turn_on
        entity_id: switch.sunroom_fan_0
      - service: input_boolean.turn_off
        data:
          entity_id: input_boolean.sunroom_fan_state
        
  sunroom_fan_on:
    alias: Sunroom Fan On
    sequence:
      - service: input_boolean.turn_on
        entity_id: input_boolean.sunroom_fan_state
      - service: script.sunroom_fan_set_speed_percent
   
  sunroom_fan_set_speed_percent:
    alias: Sunroom Fan Set Percentage
    sequence:
      - service: input_number.set_value
        entity_id: input_number.sunroom_fan_speed_percent
        data:
          value: "{{ percentage }}"
      - delay:
          milliseconds: 500
      - service: >
          {% if states("input_number.sunroom_fan_speed_percent") | int == 33 %}
            script.sunroom_fan_low
          {% elif states("input_number.sunroom_fan_speed_percent") | int == 66 %}
            script.sunroom_fan_med
          {% elif states("input_number.sunroom_fan_speed_percent") | int == 100 %}
            script.sunroom_fan_high
          {% else %}
            script.sunroom_fan_off
          {% endif %}
      - service: >
          {% if states("input_number.sunroom_fan_speed_percent") | int == 33 %}
            input_boolean.turn_on
          {% elif states("input_number.sunroom_fan_speed_percent") | int == 66 %}
            input_boolean.turn_on
          {% elif states("input_number.sunroom_fan_speed_percent") | int == 100 %}
            input_boolean.turn_on
          {% else %}
            input_boolean.turn_off
          {% endif %}
        entity_id: input_boolean.sunroom_fan_state
   
  sunroom_fan_low:
    alias: Sunroom Fan Low
    sequence:
      - service: switch.turn_on
        entity_id:  switch.sunroom_fan_1

  sunroom_fan_med:
    alias: Sunroom Fan Medium
    sequence:
      - service: switch.turn_on
        entity_id:  switch.sunroom_fan_2

  sunroom_fan_high:
    alias: Sunroom Fan High
    sequence:
      - service: switch.turn_on
        entity_id:  switch.sunroom_fan_3

switch:
  - platform: broadlink
    mac: 34:ea:34:42:f3:be
    switches:
      #sunroom_fan_1:
      - name: "Sunroom Fan 1"
        command_on: sgA8AQ4MDgwODA8MDgwODA4MDg0ODA4MDgwOq........
        command_off: sgA8AQ4MDgwODA8MDgwODA4MDg0ODA4MDgwOqhsMG......  
      #sunroom_fan_2:
      - name: "Sunroom Fan 2"
        command_on: sgDaAQ8MDgwODA8LDwsPDA4MDwsPCw8MDg........
        command_off: sgDaAQ8MDgwODA8LDwsPDA4MDwsPCw8MDg.........
      #sunroom_fan_3:
      - name: "Sunroom Fan 3"
        command_on: sgA8AQ4MDgwODA4NDgwODA4MDg0NDQ4MDgwOqhsMG.........
        command_off: sgA8AQ4MDgwODA4NDgwODA4MDg0NDQ4MDgwOqhsMG...........
      #sunroom_fan_0:
      - name: "Sunroom Fan 0"
        command_on: sgB4Ag4MDgwODQ4MDgwODA4NDQ0ODA4MDgwOqhsMG.......
        command_off: sgB4Ag4MDgwODQ4MDgwODA4NDQ0ODA4MDgwOqhsMGw.........
automation:
  - alias: Toggle Sunroom Fan Low Switch
    initial_state: 'on'
    trigger:
      platform: state
      entity_id: switch.sunroom_fan_1
      to: 'on'
      for:
        seconds: 1
    action:
      service: homeassistant.turn_off
      entity_id: switch.sunroom_fan_1

  - alias: Toggle Sunroom Fan Medium Switch
    initial_state: 'on'
    trigger:
      platform: state
      entity_id: switch.sunroom_fan_2
      to: 'on'
      for:
        seconds: 1
    action:
      service: homeassistant.turn_off
      entity_id: switch.sunroom_fan_2
     
  - alias: Toggle Sunroom Fan High Switch
    initial_state: 'on'
    trigger:
      platform: state
      entity_id: switch.sunroom_fan_3
      to: 'on'
      for:
        seconds: 1
    action:
      service: homeassistant.turn_off
      entity_id: switch.sunroom_fan_3
    
  - alias: Toggle Sunroom Fan Off Switch
    initial_state: 'on'
    trigger:
      platform: state
      entity_id: switch.sunroom_fan_0
      to: 'on'
      for:
        seconds: 1
    action:
      service: homeassistant.turn_off
      entity_id: switch.sunroom_fan_0
      
homeassistant:
  customize:
    switch.sunroom_fan_0:
      friendly_name: Sunroom Fan Off
    switch.sunroom_fan_1:
      friendly_name: Sunroom Fan Low
    switch.sunroom_fan_2:
      friendly_name: Sunroom Fan Medium
    switch.sunroom_fan_3:
      friendly_name: Sunroom Fan High
4 Likes

Thanks @finity for posting this code. It got me most of the way there and I would have really struggled putting it together from scratch, but I was getting an error when I tried to turn the fan on just using the on/off toggle. The error was that a float value (the percentage) was missing. I have a slightly different setup with a Tuya/Smartlife fan that is integrated with the Tuya integration. The fan doesn’t just show up and I had to create “tap to run” actions in the TUYA app, which creates separate scenes for low, medium, high, and off similar to your Broadlink controlled fan. The fan has a QIACHIP so TUYA convert doesn’t look like it will work, so this is the next best thing for control.

The error could have been caused by the slightly different application of using scenes versus switches. I added some more code to the turn on script that basically sets the fan to the previous percentage/speed, unless the prior percentage was 0 which I then have it set to turn the fan to medium using the toggle. My code in case it helps anyone with a similar setup is:

fan:
  - platform: template
    fans:
      lroom_fan_percent_template:
        friendly_name: "Living Room Fan"
        value_template: "{{ states('input_boolean.lroom_fan_state') }}"
        percentage_template: "{{ states('input_number.lroom_fan_speed_percent') | float }}"
        turn_on:
          service: script.lroom_fan_on
        turn_off:
          service: script.lroom_fan_off
        set_percentage:
          service: script.lroom_fan_set_speed_percent
          data:
            percentage: "{{ percentage }}"
        speed_count: 3
input_number:
  lroom_fan_speed_percent:
    name: Living Room Fan Speed Percent
    initial: 0
    min: 0
    max: 100
    step: 33
input_boolean:
  lroom_fan_state:
    name: Living Room Fan State
lroom_fan_off:
  alias: Living room Fan Off
  sequence:
    - service: scene.turn_on
      entity_id: scene.lroomfanoff
    - service: input_boolean.turn_off
      data:
        entity_id: input_boolean.lroom_fan_state       
lroom_fan_on:
  alias: Living room Fan On
  sequence:
    - service: input_boolean.turn_on
      entity_id: input_boolean.lroom_fan_state
    - service: >
        {% if states("input_number.lroom_fan_speed_percent") | int == 33 %}
          script.lroom_fan_low
        {% elif states("input_number.lroom_fan_speed_percent") | int == 66 %}
          script.lroom_fan_med
        {% elif states("input_number.lroom_fan_speed_percent") | int == 100 %}
          script.lroom_fan_high
        {% else %}
          script.lroom_fan_onfromzero
        {% endif %}
lroom_fan_set_speed_percent:
  alias: Living room Fan Set Percentage
  sequence:
    - service: input_number.set_value
      entity_id: input_number.lroom_fan_speed_percent
      data:
        value: "{{ percentage }}"
    - delay:
        milliseconds: 500
    - service: >
        {% if states("input_number.lroom_fan_speed_percent") | int == 33 %}
          script.lroom_fan_low
        {% elif states("input_number.lroom_fan_speed_percent") | int == 66 %}
          script.lroom_fan_med
        {% elif states("input_number.lroom_fan_speed_percent") | int == 100 %}
          script.lroom_fan_high
        {% else %}
          script.lroom_fan_off
        {% endif %}
    - service: >
        {% if states("input_number.lroom_fan_speed_percent") | int == 33 %}
          input_boolean.turn_on
        {% elif states("input_number.lroom_fan_speed_percent") | int == 66 %}
          input_boolean.turn_on
        {% elif states("input_number.lroom_fan_speed_percent") | int == 100 %}
          input_boolean.turn_on
        {% else %}
          input_boolean.turn_off
        {% endif %}
      entity_id: input_boolean.lroom_fan_state   
lroom_fan_low:
  alias: Living Room Fan Low
  sequence:
    - service: scene.turn_on
      entity_id:  scene.lowfan
lroom_fan_med:
  alias: Living Room Fan Medium
  sequence:
    - service: scene.turn_on
      entity_id:  scene.mediumfan
lroom_fan_high:
  alias: Living Room Fan High
  sequence:
    - service: scene.turn_on
      entity_id:  scene.highfan
lroom_fan_onfromzero:
  alias: On from Zero
  sequence:
    - service: input_number.set_value
      entity_id: input_number.lroom_fan_speed_percent
      data:
        value: "66"
    - service: scene.turn_on
      entity_id:  scene.mediumfan
3 Likes

Hi! Help me please. I have two speed fan.
I set it up

cabinet_fan:

      friendly_name: "Cabinet fan"

      unique_id: "cabinet_fan"

      value_template: "{{ states('binary_sensor.cabinet_fan_state') }}"

      percentage_template: "{{ states('input_number.cabinet_fan_speed') }}"

      turn_on:

        service: script.cabinet_fan_on

      turn_off:

        service: script.cabinet_fan_off

      set_percentage:

        service: script.cabinet_fan_set_speed

        data:

          percentage: "{{ percentage  }}"

      speed_count: 2

but I have still 3 speeds. How can I change it?
image

If you’d like to see the old speed list reinstated I’ve requested that the old speed list options should be kept and I’ve had a suggestion from a dev that if a FR gets enough votes they would implement it.

Here is the FR. Please go there and vote it up.

1 Like

like your Idea

I did it this way

- id: b12c44a8-d707-4892-9f75-c84c6927dab4
  alias: Lounge Fan Control
  initial_state: true
  trigger:
    - entity_id: sensor.lounge_fan_status
      platform: state
  action:
    - data_template:
        entity_id: script.lounge_fan_{{ trigger.to_state.state }}
      service: script.turn_on

why is there a percentage slider when most fans run on 3-12 speed modes? this doesnt make sense to me. a dropdown list would be way more convinient to me or am i oversseing something?

1 Like

The percentage slider will work with anything between 2-12+ speeds. It will devide the steps by 100 ie 3 speeds 33, 66, 100. 4 speeds 25, 50, 75, 100 etc.

You also can define preset drop downs. It’s mqtt but take a look at this post from @finity ( aka the fan template guru :grinning:) here to see the percent vs preset drop down options How-to: Using the iFan03/iFan02 running Tasmota on MQTT with the newest updates to the fan control models after HA V2021.3.x

1 Like

Hey,

Maybe you can help me. I implemented this script, but for some reason, i can’t figure out how to add any of it to lovelace, none of the switches are showing up. Am I missing something?

If you successfully created the entity, then you should be able to just add it to Lovelace like in this clip. There are custom fan UI sliders you can get if you search the forum, but this should get you basic control

I have GE ZWave fan controls, and it seems that 33% is ‘Med’ speed, and 32 is ‘Low’. It might be better if the slider used 32, 65, 99 instead of 33, 66, 100.

Hi!
I’ve used and tested using code from here and there and it is done. Thank you all for your help.

Here is my code:

###########################
# Ventilador Teto Quarto
###########################

input_boolean:
  quarto_fan_direction:
    name: Direcao ventilador quarto
  ventteto_quarto:
    name: Ventilador Teto Quarto

input_number:
  ventteto_quarto_percent:
    name: Vent Teto Quarto Percentage
    min: 0
    max: 100
    step: 1
    

###########################
# Ventilador Teto Quarto
###########################

fan:
  - platform: template
    fans:
      vent_teto_quarto:
        friendly_name: "Ventilador Quarto"
        value_template: "{{ states('input_boolean.ventteto_quarto') }}"
        percentage_template: "{{ states('input_number.ventteto_quarto_percent') | float }}"
        # Uses a fake switch from an input_boolean as the fan has no way of reporting direction back to HA
        direction_template: "{{ 'forward' if is_state('input_boolean.quarto_fan_direction', 'on') else 'reverse' }}"
        turn_on:
          service: script.ventteto_quarto_on
        turn_off:
          service: script.ventteto_quarto_off
        set_percentage:
          - service: script.ventteto_quarto_velocidade
            data:
              percentage: "{{ percentage }}"
        set_direction:
          - service: remote.send_command
            data:
              entity_id: remote.rmpro_remote
              command:
                - b64:sgYwABQvFA02DTYvFC+UHyQfJB8kHyQfJB8kHyMfIy8ULxMvFA02DTYvFC8TDTYNNg02LwAAAAAAAAAA
          - service: input_boolean.toggle
            entity_id: input_boolean.quarto_fan_direction
        speed_count: 5
        

script:

  ventteto_quarto_on:
    alias: Ligar ventteto_quarto
    sequence:
      - service: input_boolean.turn_on
        data:
          entity_id: input_boolean.ventteto_quarto
      - delay:
          milliseconds: 500
      - service: >
          {% if states("input_number.ventteto_quarto_percent") | int == 20 %}
            script.ventteto_quarto1
          {% elif states("input_number.ventteto_quarto_percent") | int == 40 %}
            script.ventteto_quarto2
          {% elif states("input_number.ventteto_quarto_percent") | int == 60 %}
            script.ventteto_quarto3
          {% elif states("input_number.ventteto_quarto_percent") | int == 80 %}
            script.ventteto_quarto4
          {% elif states("input_number.ventteto_quarto_percent") | int == 100 %}
            script.ventteto_quarto5
          {% else %}
            script.ventteto_quarto_off
          {% endif %}
      - service: >
          {% if states("input_number.ventteto_quarto_percent") | int == 20 %}
            input_boolean.turn_on
          {% elif states("input_number.ventteto_quarto_percent") | int == 40 %}
            input_boolean.turn_on
          {% elif states("input_number.ventteto_quarto_percent") | int == 60 %}
            input_boolean.turn_on
          {% elif states("input_number.ventteto_quarto_percent") | int == 80 %}
            input_boolean.turn_on
          {% elif states("input_number.ventteto_quarto_percent") | int == 100 %}
            input_boolean.turn_on
          {% else %}
            input_boolean.turn_off
          {% endif %}
        entity_id: input_boolean.ventteto_quarto


  ventteto_quarto_velocidade:
    alias: ventteto_quarto seta velocidade
    sequence:
      - service: input_number.set_value
        data:
          entity_id: input_number.ventteto_quarto_percent
          value: "{{ percentage }}"
      - delay:
          milliseconds: 600
      - service: script.turn_on
        entity_id: script.ventteto_quarto_on

1 Like

Fan toggle missing percentage has been fixed: