Assign your own actions to Zigbee2MQTT rotary-knob gestures in Home Assistant. Supports Command/Event modes and includes noise filtering for false “tail” events.
🗺️ How to use 🛠 Installation 🐞 Troubleshooting
✨ Features
- Works with many Zigbee2MQTT rotary knobs (brands such as Moes, Girier, and others — mostly AliExpress-sold models)
- Bind gestures to any HA actions or scripts, with optional helper parameters (gesture, step_size, rate, etc.)
- Supports both Command and Event operation modes (typically switched using a triple-click on most knobs)
- Noise filtering for accidental “tail” events (e.g., unwanted rotation after hold+rotate, or a single click triggered after rotation)
- Allows visual customization of native low-level event mappings if your knob uses different payload values
- Supports configuring automation mode and maximum concurrent runs
- Debug output available via notifications or logs
Core idea of this blueprint — assign actions to gestures instead of handling raw MQTT events.

Out of the box, Zigbee2MQTT rotary knobs only publish raw MQTT events.
You can wire them directly into your automations — but that means:
- spending time inspecting and decoding raw MQTT payloads
- writing and maintaining custom automation logic
- duplicating the same mapping patterns across multiple automations
- mixing low-level device-handling code with your real logic (lights, scenes, etc.)
- debugging false “tail” events and edge-case behaviors
🎯 This blueprint is better because it turns raw MQTT events into clean, human-readable gestures and lets you configure all actions through the UI — with zero YAML and no custom automations. Instead of fighting payloads, you simply choose what each gesture does.
It also cleanly separates concerns:
- works as a reusable gesture-controller layer for any supported knob
- converts unpredictable MQTT events into consistent gestures (single, double, hold, rotate…)
- handles Command/Event modes and noise filtering automatically, in one place
- exposes a simple action interface with optional helper variables when you need more control
Your scripts stay small and focused on behavior, while the knob logic is configured once and reused everywhere.
- Create an automation from this blueprint in your Home Assistant:
- Settings → Automations & Scenes → Automations → Add Automation → Use Blueprint.
- Select: “Z2M Knob — Gesture Action Controller” in the blueprint list.
- Set the MQTT topic of your knob:
- Open Zigbee2MQTT → Devices → choose your knob → copy its Friendly name.
- Replace
your_knob_friendly_namein the blueprint field with the copied value. e.g.: zigbee2mqtt/Bedroom_Knob. - 🥳 Now the automation listens to events from this specific knob.
- Assign your actions to gestures (what each gesture will do).
Without a noise filter, rotating while holding may produce unwanted “tail” events that can trigger actions you didn’t intend (for example, an extra single or toggle event after rotation).
The noise filter window is the period (in milliseconds) during which follow-up events after rotation are ignored.
In most cases 500 ms is good enough, but you can tune it manually. Please, use debugger to test your events and check if filter window has good size for you.
Use Debug mode to test behavior. Set Debug = notification. A new notification will appear in HA. Open it, rotate and click the knob, and observe how events are converted into gestures and filtered.
This helps you:
- see the native event coming from the device
- verify whether an event was filtered as a “tail”
- check the current operation mode (command/event)
If your knob produces different event values — adjust them in the gesture binding table in the blueprint inputs.
If your knob uses a different operation-mode model — copy the debug data and send it to me, I will add support.
If your knob has other events than in blueprint (use debugger to test them), you can re-bind native knob events to gestures. Enter your event names in the right-side field (one per line).
You can select one script that will be triggered on each gesture and will receive all variables:
- gesture: single | double | hold | hold_release | rotate_left | rotate_right | hold_rotate_left | hold_rotate_right | mode_change | unknown
- step_size: action_step_size from payload
- rate: action_rate from payload
- operation_mode: operation_mode from payload
- native_event: action from payload
- topic: MQTT topic of the message
- knob_id: Id of your knob (without "zigbee2mqtt/")
- raw: raw MQTT payload (string)
- payload_json: parsed MQTT payload (dict)
You can pass additional parameters from the automation to your script (if action is script) but it is a bit tricky.
Below is an example of how to use this. First, create a script.
Settings → Automations & Scenes → Scripts → Create Script → Create new script → ⋮ (menu) → Edit as YAML
Example script:
alias: "Debug variables from Lanking blueprint"
mode: parallel
sequence:
- action: persistent_notification.create
data:
title: "Debug variables from Lanking blueprint"
message: >-
gesture={{ gesture }}, native_event={{ native_event }},
operation_mode={{ operation_mode }}, step_size={{ step_size }},
rate={{ rate }}
description: ""Great — now you can call this script from your automation. However, you must explicitly pass every variable that you want to use inside the script.
There are two ways to add a script as a gesture action.
action: script.debug_variables_from_lanking_blueprint
data:
gesture: "{{ gesture | default('') }}"
native_event: "{{ native_event | default('') }}"
operation_mode: "{{ operation_mode | default('unknown') }}"
step_size: "{{ step_size | default(0) }}"
rate: "{{ rate | default(0) }}"
topic: "{{ topic | default('') }}"
raw: "{{ raw | default('') }}"
payload_json: "{{ payload_json | default({}) }}"action: script.turn_on
target:
entity_id: script.debug_variables_from_lanking_blueprint
data:
variables:
gesture: "{{ gesture | default('') }}"
native_event: "{{ native_event | default('') }}"
operation_mode: "{{ operation_mode | default('unknown') }}"
step_size: "{{ step_size | default(0) }}"
rate: "{{ rate | default(0) }}"
topic: "{{ topic | default('') }}"
raw: "{{ raw | default('') }}"
payload_json: "{{ payload_json | default({}) }}"
enabled: trueIn both cases, you need to switch to YAML mode to add the code.
After saving, trigger a gesture on your knob and check the result in the notification.
- No actions trigger → Check correct MQTT topic. Enable Debug mode and check notifications/logs
- Unexpected gestures after rotation → increase noise filter window (ms)
- Sensor unavailable → wait until automation will re-create it. If problem is presistent, please write me.
- Knob uses different payload values → adjust the binding table in inputs
- Knob uses a different operation-mode model → copy the debug data and send it to me, I will add support 🤝
⚠️ If you have unstandard HA url, please change it on the first page (click pencil)
- Copy blueprint to [ Your Home Assistant ]/
config/blueprints/automation/lanking/z2m-knobs-gesture-controller.yaml - Settings → Automations & Scenes → ⋮ (top-right) → Reload Automations
Tested primarily with:
- Moes ZG-101ZD
- Zigbee2MQTT-compatible rotary knobs from Moes / Girier and similar brands
Most similar Z2M knobs should work as long as their events can be mapped to gestures.
MIT — contributions welcome.

