Controlling Template IR Fan Speed with Scripts

I have a fan controlled by IR.
I’m trying to find a good solution for setting the speed of the fan from Home Assistant.
The remote has only a - and + for speed control, as in the picture.


So I can only send commands to step the speed one step in either direction.
It has 8 speeds and if you - when on 1 it goes to 8 or if you + when on 8 it goes to 1.
I’m using a Broadlink RM4 Pro to send commands to the fan.
This is my script for the fan itself:

- platform: template
  fans:
    bedroom_fan:
      friendly_name: "Bedroom Fan"
      value_template: "{{ states('input_boolean.bedroom_fan_state') }}"
      oscillating_template: "{{ states('input_select.bedroom_fan_swivel') }}"
      percentage_template: "{{ states('input_number.bedroom_fan_percentage') }}"
      turn_on:
        - service: script.bedroom_fan_power
      turn_off:
        - service: script.bedroom_fan_power
      set_oscillating:
        - service: script.bedroom_fan_swivel
      speed_count: 8
      set_percentage:
        - service: script.bedroom_fan_set_speed
          data:
            percentage: "{{ percentage }}"

So I have defined that there are 8 speeds and if I change the speed of the fan entity it calls a script and passes the ‘percentage’ value into that script.
Here is the script:

alias: Bedroom Fan Set Speed
sequence:
  - service: input_number.set_value
    target:
      entity_id: input_number.bedroom_fan_percentage
    data:
      value: '{{ percentage }}'
  - service: script.turn_on
    data: {}
    target:
      entity_id: |
        {% if is_state('input_number.bedroom_fan_percentage', '0') %}
          script.delay
        {% elif is_state('input_number.bedroom_fan_percentage', '13') %}
          script.bedroom_fan_slower
        {% elif is_state('input_number.bedroom_fan_percentage', '25') %}
          script.bedroom_fan_faster
        {% elif is_state('input_number.bedroom_fan_percentage', '38') %}
          script.bedroom_fan_faster
        {% elif is_state('input_number.bedroom_fan_percentage', '50') %}
          script.bedroom_fan_faster
        {% elif is_state('input_number.bedroom_fan_percentage', '63') %}
          script.bedroom_fan_faster
        {% elif is_state('input_number.bedroom_fan_percentage', '75') %}
          script.bedroom_fan_faster
        {% elif is_state('input_number.bedroom_fan_percentage', '88') %}
          script.bedroom_fan_faster
        {% elif is_state('input_number.bedroom_fan_percentage', '100') %}
          script.bedroom_fan_faster
        {% else %}
          script.delay
        {% endif %}
mode: single
icon: mdi:fan-auto

The first part of the script sets the value of an input_number helper to the same value as the percentage that the fan has been set to.
The second part of the script calls another script based on the value of the input_number.
I have a script called script.bedroom_fan_slower that steps the speed down one step and another called script.bedroom_fan_faster that steps the speed up one step.
This is where I run into the limit of my ability.
What I want to do is compare the current speed of the fan against the target value of the fan and run the ‘slower’ or ‘faster’ script the correct amount of times to get me from the current speed to the target speed.
For example if the fan is on speed 1 (13%) and I set it to speed 5 (63%) I want it to calculate that it needs to run the script.bedroom_fan_faster 4 times.

Open to ideas and suggestions and appreciate any help on this one.

Just incase it matters or helps here is the codes of the slower and faster scripts. (Note, the if is there becuse the fan ignores the first remote input, it treats it only as a wake from sleep and doesn’t actually change the speed)
script.bedroom_fan_slower

alias: Bedroom Fan Slower
sequence:
  - service: input_boolean.turn_on
    data: {}
    target:
      entity_id: input_boolean.bedroom_fan_slower
  - if:
      - condition: state
        entity_id: timer.bedroom_fan_counter
        state: active
    then:
      - service: remote.send_command
        data:
          device: Bedroom Fan
          command: Slower
        target:
          entity_id: remote.rm4_pro_remote
    else:
      - service: remote.send_command
        data:
          device: Bedroom Fan
          command: Slower
          num_repeats: 2
          delay_secs: 0.3
        target:
          entity_id: remote.rm4_pro_remote
  - service: timer.start
    data: {}
    target:
      entity_id: timer.bedroom_fan_counter
  - delay:
      hours: 0
      minutes: 0
      seconds: 0
      milliseconds: 500
  - service: input_boolean.turn_off
    data: {}
    target:
      entity_id: input_boolean.bedroom_fan_slower
mode: single
icon: mdi:fan-chevron-down

script.bedroom_fan_faster

alias: Bedroom Fan Faster
sequence:
  - if:
      - condition: state
        entity_id: timer.bedroom_fan_counter
        state: active
    then:
      - service: remote.send_command
        data:
          device: Bedroom Fan
          command: Faster
        target:
          entity_id: remote.rm4_pro_remote
    else:
      - service: remote.send_command
        data:
          device: Bedroom Fan
          command: Faster
          num_repeats: 2
          delay_secs: 0.3
        target:
          entity_id: remote.rm4_pro_remote
  - service: timer.start
    data: {}
    target:
      entity_id: timer.bedroom_fan_counter
mode: single
icon: mdi:fan-chevron-up
2 Likes