Posting this here rather than just in Blueprints Exchange, since it’s really a ZHA/Zigbee-specific technique and I know a lot of people hit this exact wall.
The problem: dimming a Zigbee light from a remote by looping light.turn_on with incrementing/decrementing brightness_step works, but it’s visibly jerky — you see each step land instead of a smooth fade, and it hammers the network with repeated commands while a button is held.
The fix: ZHA lights support the Zigbee Level Control cluster’s “Move” command — the same mechanism your remote’s own onboard dimming uses when it’s bound directly to a bulb. Send move on button-down and stop on button-up, and the bulb dims smoothly in hardware, with a single command in each direction:
action: zha.issue_zigbee_cluster_command
data:
cluster_id: 8 # Level Control cluster
cluster_type: in
command: 1 # 1 = move, 5 = move w/ on/off (turns on first if off)
command_type: server
endpoint_id: 1
params:
move_mode: "Up" # or "Down"
rate: 50 # 1/10ths of a second per step
ieee: "{{ device_attr(entity_id, 'identifiers') | selectattr('0', 'eq', 'zha') | first | last }}"
…and to stop:
action: zha.issue_zigbee_cluster_command
data:
cluster_id: 8
cluster_type: in
command: 3 # 3 = stop
command_type: server
endpoint_id: 1
params: {}
ieee: "{{ device_attr(entity_id, 'identifiers') | selectattr('0', 'eq', 'zha') | first | last }}"
Works the same way for a Zigbee group via zha.issue_zigbee_group_command, so one command dims every bulb in the group in sync, instead of firing per-entity.
I wrapped this into two reusable scripts (with proper fields for entity/group/direction/rate/endpoint) plus an optional sensor that remembers each light’s last dim direction, so a single-button remote can toggle up/down on alternating presses. Wiring it up to a remote is just a normal Device trigger in the automation editor (hold → start script, release → stop script) — no need to hand-write zha_event matching.
I mostly use the Switch Manager HACS integration to setup my Zigbee and Z-Wave remotes to control lights. If you haven’t tested it, I recommend giving it a try! Just add the Start Level Change script to the “hold” event of a button, and the Stop Level Change script to the “release” event of the same button.
Full write-up, blueprints, and the drop-in package are in my Blueprints Exchange post: Easy Zigbee Dimming — smooth ZHA dimming scripts, usable from any remote/trigger
Happy to help if anyone can’t get this to work ![]()