Fan Template Speed - Dyson IR with Broadlink RM Mini

I have a Dyson IR fan which i am trying to setup with a fan template. My broadlink is setup with switches but i can also send IR codes directly.

For the toggle on/off its a single button click and oscillate also has a single click but has the added complication that it can switch on the fan. However the basics work and the template allows me to switch on/off and oscillate.

fan:
  - platform: template
    fans:
      dyson_fan:
        friendly_name: "Dyson Fan"
        value_template: "{{ states('switch.dyson_cool_fan_power') }}"
        oscillating_template: >
            {% if is_state("switch.dyson_cool_fan_sscillate", "on") -%}
              true
            {%- else -%}
              false
            {%- endif %}
        turn_on:
          service: switch.turn_on
          entity_id: switch.dyson_cool_fan_power
        turn_off:
          service: switch.turn_off
          entity_id: switch.dyson_cool_fan_power 
        set_oscillating:
          service: switch.toggle
          entity_id: switch.dyson_cool_fan_sscillate

However i am trying to setup a speed but im lost. The fan supports speeds 1-10 and the increase is a single button up/down press. The fan remembers the last speed set so if it was at 8 when switched off it will be at 8 next time its switched on.

I have created an input select to hold the speed values and have setup scripts to send the IR codes for up and down but i dont know how to now add that to the fan template to make it work for up and down in speed when setting a speed.

Im thinking do i tell the Fan template to adjust my input select which then triggers an automation to run the script? Or should the fan template handle that?

I found this thread which uses an input slider and the automations allow for adjustments but again im struggling to see how to adapt that to the fan template.

Any help appreciated.

About a year ago I helped someone else create a Template Fan with 8 speeds and controlled by a Broadlink device. It should be easy to adapt to your requirements. Let me know if you need help with it.

Hi. Thanks for the link. I’ll check it out. Although my fan has two buttons for increase and decrease. Not sure how to adapt your script to support that.

Does the fan template know if the speed is up or down?

You will have to adapt the python_script. In its current form, it’s designed to control a fan that has a single “increase speed” command. In other words, if the current speed is 4 and you want 2, it must increase the speed to its maximum level (8) and then ‘loop around’ to 1 then 2. Your version of the python_script will be more efficient and will not need to ‘loop around’ because it can decide whether it must send an increase or decrease command to set the target speed.

I don’t understand your question. A Template Fan only executes the commands (on/off, speed level, etc) specified in its template. Because you fan’s speed is set by using increase/decrease commands, some form of logic is needed to:

  • Remember the last-used/current speed.
  • Calculate the difference between the desired speed and the last-used/current speed.
  • Use that difference to transmit the correct number of increase, or decrease, commands to the fan.

In the linked example, the python_script performs all the described logic. That’s the part of your Template Fan that will decide if it must transmit increase or decrease commands, and how many of them, to get from the current speed to the desired speed.

Sorry, i think i was trying to ask if the template had any clever knowledge that it would know if a speed was increased or decreased. As you said its purely a way of merging together different elements into one entity.

I have something working now so thank you. I need to see how to fix the homekit stuff as currently speed 1 is marked as “off” which means i cant drop the speed to 1 instead it goes to 2 which is then out of sync.

I will tinker with my script to see if i can set that up.

So thanks to @123 I have a working fan. Using HomeKit I get a warning because the first entry doesn’t equal “off” but I can’t see to get the python script to notice if the speed = off to not process the change of speed and instead just switch off. Instead get int errors which suggests my code is wrong but I don’t know how to debug it.

Instead I am using a 0 value which will be taken as off (gives warning in the logs but works) which works with the script.

Now my issue is the dyson fan remembers its last position, for example 3. But the 0 (off) now switches the fan off. If I Then switch it on and change my speed to say 3 the fan ends up at 6 because of the script logic.

Fan = 3, fan speed input helper is 0, fan speed is 3 Which puts the fan to 6.

Somehow I need to keep the input text helper as the last speed if zero is selected on the fan template. I don’t know how to do they in the yaml template on the fan configuration.

Then what should happen is

Fan = 3, fan speed input helper is on 3, fan speed = 3 which would equal 3.

I also notice when adjusting the fan speed the fan switches off and then adjusts. It doesn’t do that if I send the same command through a script.

So since the Fan Template changes the python script no longer works. Has anyone got a working solution. I tried to amend the script to work with percentages but i dont know python and it complains about passing incorrect values as integers.

- platform: template
  fans:
    dyson_fan:
      friendly_name: "Dyson Fan"
      value_template: "{{ states('switch.dyson_cool_fan_power') | int }}"
      percentage_template: "{{ states('input_text.dyson_fan_speed') | int }}"
      #speeds: ['0','1', '2', '3', '4', '5', '6', '7', '8','9','10']
      oscillating_template: "{{ true if is_state('switch.dyson_cool_fan_sscillate', 'on') else false }}"
      speed_count: 10
      turn_on:
        service: switch.turn_on
        entity_id: switch.dyson_cool_fan_power
      turn_off:
        service: switch.turn_off
        entity_id: switch.dyson_cool_fan_power 
      set_oscillating:
        service: switch.toggle
        entity_id: switch.dyson_cool_fan_osscillate
      set_percentage:
        - service: python_script.dyson_fan_speed_control
          data_template:
            fan_speed: "{{ percentage }}"
        - service: input_number.set_value
          data_template:
            entity_id: input_number.dyson_fan_speed
            value: "{{ percentage }}"

Python Script:

speed = data.get('fan_speed')
status_speed = hass.states.get('input_number.dyson_fan_speed')
save_speed = hass.states.get('input_number.dyson_fan_save_speed')

if speed is not None:
  speed = int(speed)//10
  last_speed = int(status_speed.state) if status_speed.state else 1
  save_speed = int(save_speed.state) if save_speed.state else 1
  if speed == 0:
    loop = last_speed - speed  
    # RF code for increasing speed.
    code = 'b64:JgAkAEgdFzYYGxgcGDQYHBgbGBsYNhg1GDUXNRg1GDQYGxgbGAANBQAAAAA='

    # Set the IP address to match the one used by your Broadlink device
    service_data = {'entity_id':'remote.rm_mini3_remote', 'command':'{}'.format(code)}
    for i in range(loop):
      hass.services.call('remote', 'send_command', service_data, False)
      #hass.services.call('script', name)  
      time.sleep(0.5)

    hass.services.call('switch', 'turn_off', service_data={'entity_id':'switch.dyson_cool_fan_power'} )
  elif 1 <= speed <= 10:
    if speed > last_speed:
      loop = speed - last_speed
      # RF code for decreasing speed.
      code = 'b64:JgBIAEgdGDUYGxgcGDQYHBgbGBsZHBk0GBsYNRgcGDQYNBgbGQAMvEgcGDUYHBgcGDQYGxgcFxsYHRg1GBwYNRkaGDUYNBgbGAANBQ=='

    else:
      loop = last_speed - speed  
      # RF code for increasing speed.
      code = 'b64:JgAkAEgdFzYYGxgcGDQYHBgbGBsYNhg1GDUXNRg1GDQYGxgbGAANBQAAAAA='


    # Set the IP address to match the one used by your Broadlink device
    service_data = {'entity_id':'remote.rm_mini3_remote', 'command':'{}'.format(code)}
    for i in range(loop):
      hass.services.call('remote', 'send_command', service_data, False)
      #hass.services.call('script', name)  
      time.sleep(0.5)
  else:
    logger.warning('<dyson_fan_speed_control> Received fan speed is invalid ({})'.format(fan_speed))
else:
  logger.warning('<dyson_fan_speed_control> Received fan speed is invalid (None)')

divide your percentage by 10 in your set_percentage template and the python script doesn’t change.

Thanks for the heads up. Im trying to fix this but struggling.

I have used:

percentage_template: "{{ (states('input_text.dyson_fan_speed') | int) / 10 }}"

But when i check my input_text helper it showing as a value of 20 if i select 20% instead of 2.

So i adjusted my Python script to divide by 10 instead which seems to work albeit its not massively reliable sending IR commands based on how many steps increase/decrease have been passed.

I also changed the percentage template to just this as the division operator was actually messing up the slider in the UI and homekit.

percentage_template: "{{ (states('input_text.dyson_fan_speed') | int)  }}"

Stil WIP.

You only need to adjust this and divide by 10.

I tried that but then the fan template couldnt be loaded. Maybe my syntax was wrong?

As it stands it sort of works, its flaky and sometimes if the speed changes the speed on the fan gets out of sync. Maybe its easier to just sack off the speed and go back to simple on/off and use the remote. The speed is only adjusted based on the room temp and im normally sat right next to it anyway.

I also have an issue where the power value template is taken from the switch configured in the broadlink integration. Upon a reboot this switch is off however the fan is turned on because the last speed set is above 0%. As such the fan and switch are different and end up getting muddled up with each other.

try to use my python script on hacs.

@eximo84

You seem to be struggling with the new fan speed configs too.

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.

Hey, sorry been a while since i posted about this. Just set up your script using my existing config and it appears to work without giving any errors. I still find its a bit eratic on the slider and gets out of sync quickly. Not sure how to resolve that without making each button press an input rather than using a slider.

Also using HomeKit is odd too, again switching on HomeKit seems to put the speed to 100% but the fan itself remains at the last used speed. Not sure how that is handled really.

Yes voted.
Bring back the set_speed function. This guide works for me my speed can only go up in increment and not down.