[Guide]Template Fan and Broadlink

Thought I would write a guide as i’ve personally struggled for 2 days to figure this out. Somehow the template fan integration page made no mention of requiring additional entities to keep track of status or how to connect the attributes to the script.

I have an IR controlled fan that I wanted to control using a broadlink mini. The Fan switches on by default to speed 1. Also, it has an oscillating function.

Instead of switches, i created 3 input entities to keep track of its status. (ps: I tried an input_boolean with the oscillate but it didn’t work, so left it as input select)

# Keep track of the fan state
input_boolean:
  bedroom_fan_state:

# Keep track of the fan oscillate
input_select:
  bedroom_fan_osc:
    options:
      - "True"
      - "False"

# Keep track of fan speed
input_number:
  bedroom_fan_percentage:
    name: Bedroom Fan Percentage
    min: 0
    max: 100

Put in the template fan format

fan:
  - platform: template
    fans:
      bedroom_fan:
        friendly_name: "Bedroom Fan"
        unique_id: bedroom_fan
        value_template: "{{ states('input_boolean.bedroom_fan_state') }}"
        percentage_template: "{{ states('input_number.bedroom_fan_percentage') }}"
        oscillating_template: "{{ states('input_select.bedroom_fan_osc') }}"
        turn_on:
          service: script.bedroom_fan_on
        turn_off:
          service: script.bedroom_fan_off
        set_oscillating:
          service: script.fan_oscillating
          data:
            oscillating: "{{ oscillating }}"
        set_percentage:
          service: script.bedroom_fan_set_speed
          data:
            percentage: "{{ percentage }}"
        speed_count: 3

Prepare the scripts

POWER-ON

  • This sends the power on command
  • Updates the boolean state
  • Updates fan percentage entity to 33% (Speed 1)
bedroom_fan_on:
  alias: bedroom_fan_on
  sequence:
  - service: remote.send_command
    target:
      device_id: [YOUR BROADLINK DEVICE]
    data:
      command: 'b64: JgBoAAABJpIVEBMSExISExI3EzcSExITEjcUNhM3EzYUERMSEzcTNhQRExITNxI3FBETEhITEjgTNhQ2FBETEhI3FDYTNxMSEgAFDwABJkoTAAxAAAElShUADD4AASdJEwAMQAABJ0kTAA0F'
  - service: input_boolean.turn_on
    target:
      entity_id: input_boolean.bedroom_fan_state
  - service: input_number.set_value
    target:
      entity_id: input_number.bedroom_fan_percentage
    data:
      value: 33
  mode: single

POWER-OFF

  • This sends the power off command, sets fan state boolean to off, sets the speed to 0, sets oscillate to False
bedroom_fan_off:
  alias: bedroom_fan_off
  sequence:
  - service: remote.send_command
    target:
      device_id: [YOUR BROADLINK DEVICE]
    data:
      command: 'b64: JgBoAAABJpIVEBMSExISExI3EzcSExITEjcUNhM3EzYUERMSEzcTNhQRExITNxI3FBETEhITEjgTNhQ2FBETEhI3FDYTNxMSEgAFDwABJkoTAAxAAAElShUADD4AASdJEwAMQAABJ0kTAA0F'
  - service: input_boolean.turn_off
    target:
      entity_id: input_boolean.bedroom_fan_state
  - service: input_number.set_value
    target:
      entity_id: input_number.bedroom_fan_percentage
    data:
      value: 0
  - service: input_select.select_option
    target:
      entity_id: input_select.bedroom_fan_osc
    data:
      option: 'False'
  mode: single

Fan speed script

  • This script receives the percentage value, updates it in the input_number entity and directs it to another script that sends the actual command. You can add the actual command in this script but i chose to separate them for ease of modification if i get a different fan.
bedroom_fan_set_speed:
  alias: bedroom_fan_set_speed
  sequence:
  - service: input_number.set_value
    target:
      entity_id: input_number.bedroom_fan_percentage
    data:
      value: '{{ percentage }}'
  - delay:
      hours: 0
      minutes: 0
      seconds: 0
      milliseconds: 500
  - choose:
    - conditions:
      - condition: state
        entity_id: input_number.bedroom_fan_percentage
        state: '66.0'
      sequence:
      - service: script.bedroom_fan_inc
    - conditions:
      - condition: state
        entity_id: input_number.bedroom_fan_percentage
        state: '100.0'
      sequence:
      - service: script.bedroom_fan_inc
    - conditions:
      - condition: state
        entity_id: input_number.bedroom_fan_percentage
        state: '33.0'
      sequence:
      - service: script.bedroom_fan_inc
    default: []
  mode: single

Fan speed command script

  • I have one of those array fans so the commands are sent to each fan 1/2s apart
  • You can of course customize this to however you like them
bedroom_fan_inc:
  sequence:
  - service: remote.send_command
    data:
      command: b64:JgBYAAABJ5EUERQQFRAVEBU0FTUVEBUQFDUVNRU0FTUVEBUQFDUVNRU0FTUVNRQRFBAVEBUQFTQVEBUQFRAVNBU1FTUUNRUQFQAFCAABK0gUAAw7AAEoSBUADQU
    target:
      device_id: [YOUR BROADLINK DEVICE]
  - delay:
      hours: 0
      minutes: 0
      seconds: 0
      milliseconds: 500
  - service: remote.send_command
    data:
      command: b64:JgBYAAABJ5EUERQQFRAVEBU1FDMXEBUQFDUVNRU1FDUVEBUQFDUVNRU1FBEUEBU1FBEUERQQFTUUERQ1FTUUERQ1FTUUNRUQFQAFCwABJ0gUAAw7AAEnSBUADQU=
    target:
      device_id: [YOUR BROADLINK DEVICE]
  - delay:
      hours: 0
      minutes: 0
      seconds: 0
      milliseconds: 500
  - service: remote.send_command
    data:
      command: b64:JgBYAAABJ5AVEBUQFRAUERQ1FTUUEBUQFTUUNRU1FDUVEBUQFTQVNRUQFDUVNRUQFBAVEBUQFTUUNRUQFRAUNRU1FDUVNRQRFAAFCgABKEgUAAw6AAEoSBQADQU
    target:
      device_id: [YOUR BROADLINK DEVICE]
  mode: single
  alias: bedroom_fan_inc
12 Likes

Thank you for this guide. The documentation is indeed quite brief, I struggled on the exact same topics for several hours.

It would be great if Template Fan - Home Assistant (home-assistant.io) was updated with this entry.

2 Likes

Hi, can you please explain the bedroom_fan_inc script?
Does it send the command based on the percentage value(I don’t see a condition) or do you have an increment speed in your remote?
Thank you for this! :pray:t2:

Hey @doronsever, happy to help here.

So here’s the logical flow of the scripts on a high level
The Bedroom Fan entity serves to tie the function of the scripts together
Here, the speed_count is set as 3, which means the percentage value of 100 is divided by 3.
(Speed 1 = 33%, 2=66%, 3=100%)

  1. When set_percentage is called in the entity, it executes bedroom_fan_set_speed script

  2. Bedroom_fan_set_speed then receives the corresponding percentage and first stores the value inside the input_number.bedroom_fan_percentage before conditionally calling script.bedroom_fan_inc based on the value it sees inside input_number.bedroom_fan_percentage.

Since there is no feedback loop, it expects you to increase it in sequence. Therefore the bedroom_fan_inc script is nothing more than a collection of button presses.
(I have an array fan, so I hit 3 buttons to increase the overall speed by 1 step)
You can customise this to your needs as the final action script from the speed interpretation inside the Bedroom_fan_set_speed.

  • In my case the fan always turns on to speed 1 (33%)
  • 66% would mean I need to increase the fan speed by 1 step
  • 100% means one step above 66%

Hope this helps to clarify things :slight_smile:

Most welcome @simon5, glad it helped you!

Thanks! So you are using 3 fans as one entity?
Anyway, thanks to your guide I was able to get this one rolling with few small modifications (start, stop and set percentage are all going to the same set percentage script so I have 1 place that has this logic)

Thank you very much!

Would you mind sharing your updated code?

I have an array fan that has 3 blades built into a single tower. Each one of them has a speed setting which is the reason for the bedroom_fan_inc to include 3 separate commands. I did consider combining the script into the percentage (bedroom_fan_set_speed) script but I figured the modularity would be nice for when I forget how all this works :laughing:

@chrislimk In your bedroom_fan_set_speed script, you have separated the speed level into 3 conditions, and based on that you performed the same action (i.e. run the script.bedroom_fan_inc script). I would have imagined that based on the percentage difference (if you’re at speed 2 going to 3 vs speed 1 going to 3) you would configure the script to run once or twice instead.
Are you doing this here, and how are you achieving that?

Hi leoi11, that’s correct.
I have one of these fans with the ability to control speed for each rotor. Typically I just switch all of them to the same speed. On the IR remote the button to change the speed is incremental per fan, and so what the script really only does is blast the IR hex for each fan one increment up.

I’ve only catered for an incremental increase in speed and not for skipping speed 1 to speed 3 for example which is why you see it go to 66, 100 and back to 33. (The fan switches on at a default speed 1 - 33% and so defined in the on script)


t

That’s this script which the bedroom_fan_set_speed script fires off

bedroom_fan_inc:
  sequence:
###Sends to 1st fan, waits 500ms
  - service: remote.send_command
    data:
      command: b64:JgBYAAABJ5EUERQQFRAVEBU0FTUVEBUQFDUVNRU0FTUVEBUQFDUVNRU0FTUVNRQRFBAVEBUQFTQVEBUQFRAVNBU1FTUUNRUQFQAFCAABK0gUAAw7AAEoSBUADQU
    target:
      device_id: [YOUR BROADLINK DEVICE]
  - delay:
      hours: 0
      minutes: 0
      seconds: 0
      milliseconds: 500
###Sends to 2nd fan, waits 500ms
  - service: remote.send_command
    data:
      command: b64:JgBYAAABJ5EUERQQFRAVEBU1FDMXEBUQFDUVNRU1FDUVEBUQFDUVNRU1FBEUEBU1FBEUERQQFTUUERQ1FTUUERQ1FTUUNRUQFQAFCwABJ0gUAAw7AAEnSBUADQU=
    target:
      device_id: [YOUR BROADLINK DEVICE]
  - delay:
      hours: 0
      minutes: 0
      seconds: 0
      milliseconds: 500
###Sends to 3rd fan
  - service: remote.send_command
    data:
      command: b64:JgBYAAABJ5AVEBUQFRAUERQ1FTUUEBUQFTUUNRU1FDUVEBUQFTQVNRUQFDUVNRUQFBAVEBUQFTUUNRUQFRAUNRU1FDUVNRQRFAAFCgABKEgUAAw6AAEoSBQADQU
    target:
      device_id: [YOUR BROADLINK DEVICE]
  mode: single
  alias: bedroom_fan_inc

Hope this helps. Maybe I will rewrite it to be trigger based on percentage jumps in the future if I find myself wanting it as a feature. It could even actually be an add-on automation just to watch for the speed1(33%) to 3(100%) jumps :grinning_face_with_smiling_eyes:

yeah, currently I’m looking for ways to actually do a “jump” instead of a step increment. Part of the reason is that I want to add a slider style component to the UI so it could simply “converge” to a speed.
Another reason is that I’ve purchased this interesting fan that has 24 speed instead of a classic 3 speeds, it seems like a pain to be manually incrementing all the way to the max.

My fan’s spec is like this:

  • 24 speed
  • non-binary swing modes: horizontal, vertical, both horizontal & vertical
  • preset modes: normal, natural breeze, sleeping mode, auto based on temperature

I started without the fan template and just built some trigger based sensors and buttons around it,
but then I learnt about this fan template later, and am trying to evaluate if this would be a simpler solution.
It turns out that it might not really satisfy my use case (given that it is a binary oscillation), and I also could find a good UI that is automatically hooked up nicely with a fan component.

Here’s what I’ve custom built so far using the trigger based sensors and buttons.
Screenshot 2022-04-19 at 9.55.09 PM
The last thing I’m working on is exactly jumping the speed levels, which I’m just going to have a script calculate the current vs the set value and repeat my action as many times as it needs.

Would love to see if anyone else happens to have some similar situations for their fans as well.

(and thanks for sharing yours!)

That’s very nice work, thanks for sharing yours!
If you don’t need a feedback loop then the easy way to do it is probably by watching the speed value.

You could have a sensor that just has numeric values 1 to 24, and then math the difference in script to determine how many times to execute an incremental command or something exact. If I had non binary options and special presets then I would just create additional buttons/switches for them :grin:

Hi @chrislimk ,

I have been searching high and low for something like this and had a few questions please.

I have a broadlink rm4 pro that is integrated and have multiple ceiling fans that are RF. I’ve learnt all the codes and they do work but only as scripts that i have to manually execute.

I have not been able to create a unified button such as a slider that I can execute to make the fans on/ off or set speed/ wind mode etc.

Im just wondering your template, is it suitable for RF ceiling fans?

Im a little bit lost as to how I can make this happen?

Thank you in advance

Hi Sharma, yes it will and the only difference between your fans and mine are that yours is on the ceiling. :laughing:

So hey, all you need to really do is put in those script names into the fan_on, fan_off, fan_set_speed script and you should have a basic working example to improve from there.

Hi @chrislimk ,

Thank you for confirming that. I know I am way over my head on this configuration but would like to get it sorted.

I had some additional questions I hope you can answer.

The first section of your code if I understand correctly are input helpers.

The part im confused is the “template fan format” section. Does this go into the configuration.yaml file? and the remaining power on/ off go into the scripts.yaml page? Am i correct?

Lastly, I took out a set of commands from the codes file and it looks a bit like this:

 "version": 1,
    "key": "broadlink_remote_a043b0b9f50e_codes",
    "data": {
        "Fan": {
            "Speed1": "scCwBM6eBgAJFwsKFwsWCxcXCgsXFwoYChgKFwsXCgABIwwWCxcLFwoXCxcLChcXCxcKCxcKGAoXCxcLFgsXCxcLFhgKCxYYCgsWGAoXCgsXCxcLFhgKCxYYChcKGAoXCxcLAAEjCxcKFwsXCxcLFwoKGBcKFwsKFwsXChgKFwsXCxcKFwsXFwsKFxcKCxcXChgKCxYLFwoXFwsKFxcLFwoYChcLFwoAASQLFwoXCxcLFwoYCgoYFgsXCwoXCxcKGAoXCxcLFwoXCxcXCgsXFwoLFxcKGAoLFgsXCxcXCgsXFwoYChcKGAoYCgABIwwWCxcKGAoXCxcKCxcXChgKChgKFwsXCxcKFwsXCxcLFxcKCxYYCgoXFwsXCgsXCxYLFxcKCxcXChgKFwsXChgKAAEjCxcLFwoXCxcLFwsKFxcLFwoLFwoXCxcLFwoXCxcLFwsWGAoLFhgKChcXCxcKCxcLFwoXGAoLFhcLFwoYChcLFwsAASMLFwoXCxcLFwoYCgoYFgsXCwoXCxcKFwsXCxcLFgsXCxcXCgsXFwoLFxcKGAoLFgsWCxcYCgoXFwoYChgKFwsXCwABIwsZCBgKFwsXChgKChcXCxcLChcLFwoXCxcLFwsXChcLFxcKCxcXCgsXFwoYCgsWCxcLFxcKCxYYChgKFwsXChgKAAEjCxcKGAoXCxcLFwoLFxcKFwsKGAoXCxcKGAoXCxcLFwoXGAoLFhcLChcXCxcKCxcLFgsXFwoLFhgKFwsXChgKGAoAASMLFwoYChcLFwsXCgsXFwoXCwoXCxcLFwoXCxcLFwsXChcYCgoXFwoLFxcLFwoLFwsWCxcXCgsXFwoYChcLFwsXCgABJAsWCxcLFwoYChcLChcXCxcKCxcLFgsXCxcLFwoXCxcLFxcKCxcXCgsWGAoXCwoXCxYLFxcKCxcXChgKFwsXChgKAAEjDBYLFwsXChgKFwsKFxcLFwoLFwoYChcLFwsWCxcLFwsWGAoLFhgKChcYChcLChcLFwsWGAoLFhgKFwoYChcLFwsAASMLFwoYChcLFwsXCgsXFwoXCwoXCxcLFwoXCxcLFwoYChcXCwoXFwoLFxcKGAoLFgsXCxYYCgsWGAoXChgKGAoXCwABIwsXChgKFwsXChgKCxcXChcLChcLFwoYChcLFwsXChcLFxcKCxcXCgsXFwoYCgsWCxcLFxcKCxcXChgKFwsXChgKAAEjDBYLFwsXChcLFwsKFxcKGAoLFwoYChcLFwsWCxcLFwsXFwoLFhgKCxYYChcLChcLFgsXFwoLFxcKGAoXCxcKGAoAASQLFgsXCxcKGAoXCwoXFwsXCgsXChgKFwsXCxYLFwsXCxcXCgsWGAoLFhgKFwoLFwsXCxYYCgsWFwsXCxcKFwsXCwABIwsXChgKFwsXCxcKCxcXChcLChcLFwsXChgKFwsXCxcKFxcLChcXCgsXFwoYCgsXChcLFhgKCxYYChcKGAoYChgKAAEjCxcKGAoXCxcLFwoLFxcKFwsKFwsXCxcKFwsXCxcLFwoXGAoKFxcLChcXCxcKCxcLFgsXFwoLFxcKGAoYChcLFwoAASQLFwoXCxcKGAoXCwoXFw==",

Is the above code in the correct b64 format? Or does it look like conversion is required? Seems super long compared to your example.

Hoping you can help me, thank you in advance.

Hi @Kaushik_Sharma, if your scripts currently work by themselves then there’s no need to think about whether they are b64 or not.

The tracking and template fan entities goes into configuration.yaml, and the rest of the scripts go into scripts.

In short, you need these in config.yaml

# Keep track of the fan state
input_boolean:
  bedroom_fan_state:

# Keep track of the fan oscillate
input_select:
  bedroom_fan_osc:
    options:
      - "True"
      - "False"

# Keep track of fan speed
input_number:
  bedroom_fan_percentage:
    name: Bedroom Fan Percentage
    min: 0
    max: 100

fan:
  - platform: template
    fans:
      bedroom_fan:
        friendly_name: "Bedroom Fan"
        unique_id: bedroom_fan
        value_template: "{{ states('input_boolean.bedroom_fan_state') }}"
        percentage_template: "{{ states('input_number.bedroom_fan_percentage') }}"
        oscillating_template: "{{ states('input_select.bedroom_fan_osc') }}"
        turn_on:
          service: script.bedroom_fan_on
        turn_off:
          service: script.bedroom_fan_off
        set_oscillating:
          service: script.fan_oscillating
          data:
            oscillating: "{{ oscillating }}"
        set_percentage:
          service: script.bedroom_fan_set_speed
          data:
            percentage: "{{ percentage }}"
        speed_count: 3

Scripts:
fan_on
fan_off
fan_set_speed - Receives % input and directs to fan_inc
fan_inc - Sends the commands

1 Like

@chrislimk ,

Thank you for confirming. I’ll get started with configuration and see if I can get it to work :slight_smile:

Will share my findings once Im done.

[quote=“chrislimk, post:1, topic:323488”]Preformatted text
value: '{{ percentage }}'
[/quote]

Having some problems with this, I can’t get the fan speed/percentage working correctly. if I use the following code I get an error: Fan Speed: Error executing script. Invalid data for call_service at pos 1: expected float for dictionary value @ data[‘value’]

fan_speed:
  alias: Fan Speed
  sequence:
  - service: input_number.set_value
    data:
      value: "{{ percentage }}"
    target:
      entity_id: input_number.tower_fan_percentage

I have an input number called: input_number.tower_fan_percentage

My template looks like this:

- platform: template
  fans:
    tower_fan:
      friendly_name: "Tower Fan"
      unique_id: alksdfjlwer008098sdfgsdfkgf
      value_template: "{{ states('binary_sensor.tower_fan_state') }}"
      percentage_template: "{{ states('input_number.tower_fan_percentage') }}"
      oscillating_template: "{{ states('input_select.tower_fan_osc') }}"
      turn_on:
        service: script.fan_power_toggle
      turn_off:
        service: script.fan_power_off
      set_percentage:
        service: script.fan_speed
        data:
          percentage: "{{ percentage }}"
      set_oscillating:
        service: script.fan_oscillating
        data:
          oscillating: "{{ oscillating }}"
      speed_count: 3

Not sure what to do to fix this everything else with the template is working correctly.

@PatrickHASS.io, can you try single quotes for percentage?

service: input_number.set_value
target:
  entity_id: input_number.bedroom_fan_percentage
data:
  value: '{{ percentage }}'

Ok, updated with a single quote, no change.