Some hardware links on this page are affiliate links. As an Amazon Associate I earn from qualifying purchases. We may earn a commission if you buy through them, at no extra cost to you. See the affiliate disclosure.
A fan with off, low, medium, and high does not need four buttons if you only have one. This pack is a script that reads the fan’s current percentage, finds the closest step in a list you write, and sets the next step. Zero means off. A second blueprint calls that script when a button fires.
The list order is the cycle order. 0, 33, 66, 100 walks up and then wraps to off. 100, 66, 33, 0 is a pull chain: high, medium, low, off, then high again.
One button that walks scenes instead of fan speeds is button scene cycling. A touchscreen that already has a fan control on it is CYD touch control panel. Short versus long on one binary sensor, if you want the long press to do something else, is binary sensor short and long press.
What problem it solves
You want one button, or one remote event, to walk a fan through its speeds and back to off, including fans that only expose a percentage.
How it works
- The list. A text input, default
0, 33, 66, 100. Each entry is a percentage. The script splits on commas. - Where you are. If the fan is
off, the current step is 0 even when a percentage attribute is still sitting on the entity. Otherwise it reads thepercentageattribute. - Next step. It picks the list entry closest to that number, then takes the following entry, wrapping to the first. 40 with the default list is closest to 33, so the next call sets 66. 100 wraps to 0, which calls
fan.turn_off. Any other value callsfan.set_percentage. - The button. The automation blueprint’s trigger is a trigger selector. The default is a stand-in state trigger on
binary_sensor.button, so the file has a valid trigger before you edit it. Replace it with a device trigger, an event entity, or the binary sensor that is actually your button. The action turns the script on. - Mashed button. The script is queued (up to 5). Each press is a step, in order.
Snippet
The script input is the fan and the list. The automation only needs the script entity and a trigger.
variables:
fan_entity: !input fan
raw: !input speeds
sequence:
- action: fan.set_percentage
target:
entity_id: !input fan
data:
percentage: "{{ nxt | int }}"
nxt is the next percentage from the list. A result of 0 uses fan.turn_off instead of a percentage.
Setup outline
- Copy
blueprints/script/fan_speed_cycle.yamlintoconfig/blueprints/script/edotdev/andblueprints/automation/fan_speed_cycle_button.yamlintoconfig/blueprints/automation/edotdev/. Reload blueprints. - Create a script from the cycle blueprint. Pick the fan. Leave the list, or set a pull-chain order such as
100, 66, 33, 0. - Run the script from Developer tools a few times. The fan should step, then turn off, then start again at the first non-zero entry (or at 100 if that is first and the fan was off).
- Create an automation from the button blueprint. Pick the script. Replace the default trigger with your button.
- Press the button. Each press should be one step.
Troubleshooting
- It jumps two steps. The button sends two events (press and release, or a doubled click integration). Trigger on one of them, not both. The script will queue whatever the automation sends.
- Off does not stick, and the next press stays on low. The fan entity reports
onat percentage 0, or it ignoresfan.turn_off. Check the state in Developer tools after a step that should be off. Some fans wantfan.turn_onwith a percentage instead. This script usesturn_offfor 0 andset_percentageotherwise. - It always picks the same speed. The percentage attribute is missing, so the current value falls back to 0 and the next step is always the second entry. Confirm the fan exposes
percentage. - Pull chain starts at low. The list is in ascending order. Put 100 first if the first press from off should be high. Off is closest to the 0 entry, and the next entry after 0 is whatever you wrote after it, wrapping to the start if 0 is last.
- The default trigger errors.
binary_sensor.buttonis only a placeholder. Replace the trigger input before you rely on it. The automation will not see a button that does not exist. - Percentage rejected. The fan’s supported speeds are presets, not an arbitrary percentage. Put those preset percentages in the list (some fans only accept 0, 33, 66, and 100, or 0, 25, 50, 75, 100).
Credits
Cycling a fan from a script is the idea in Script: cycle fan speed.