blueprint: name: Z2M - Aqara H2 Rotary Dimmer (KD-R01D) - Light Control (MQTT Direct) description: > Control your lights with the Aqara H2 EU Rotary Dimmer (connected via Zigbee2MQTT). **No Action Sensor Required!** Because modern Zigbee2MQTT setups no longer expose the legacy action sensor, this blueprint listens directly to your device's MQTT topic. This has a major benefit: Home Assistant won't discard identical, rapid rotation events (which typically happens with sensors due to state deduplication), making the dimming feel incredibly smooth and responsive. **Setup:** Find your device's "Friendly name" in Z2M. Your MQTT topic is usually `zigbee2mqtt/` followed by that name (e.g., `zigbee2mqtt/Bedroom dimmer`). domain: automation input: mqtt_topic: name: Device MQTT Topic description: > The base MQTT topic for your dimmer. Typically `zigbee2mqtt/` followed by the Friendly Name of your device. (e.g. `zigbee2mqtt/Bedroom dimmer`) default: zigbee2mqtt/Bedroom dimmer selector: text: {} target_light: name: Target Light(s) description: The light, group, or area of lights to dim when rotating the knob. selector: target: entity: domain: light rotation_sensitivity: name: Rotation Sensitivity description: Multiplier for how much the brightness changes per degree of rotation. (Higher = faster dimming). default: 0.2 selector: number: min: 0.05 max: 2.0 step: 0.05 invert_rotation: name: Invert Rotation description: Enable this to reverse the dimming direction (e.g. right to dim down, left to brighten). default: false selector: boolean: {} dim_transition: name: Dimming Transition (seconds) description: Adds a transition time to smooth out the dimming steps as you turn the dial. default: 0.2 selector: number: min: 0 max: 5 step: 0.1 enable_default_single_press: name: Enable Default Single Press (Toggle) description: If enabled, a single press will automatically toggle the target light on/off. Disable this if you purely want to use the Custom Single Press action below instead. default: true selector: boolean: {} single_press_action: name: Custom Single Press Action description: Additional action(s) to run when the knob is pressed once. default: [] selector: action: {} double_press_action: name: Double Press Action description: Action(s) to run when the knob is double pressed. default: [] selector: action: {} hold_action: name: Long Press (Hold) Action description: Action(s) to run when the knob is held down. default: [] selector: action: {} release_action: name: Release Action description: Action(s) to run when the knob is released after a long press. default: [] selector: action: {} # Parallel mode ensures fast rotational clicks don't interrupt each other mode: parallel max: 15 trigger: - platform: mqtt topic: !input mqtt_topic action: - variables: # Safely extract payload variables directly from the MQTT JSON message payload: "{{ trigger.payload_json if trigger.payload_json is defined else {} }}" action_type: "{{ payload.action | default('') }}" raw_angle: "{{ payload.action_rotation_angle | default(0) | float(0) }}" # Pull inputs into variables so they can be safely evaluated in templates below sens: !input rotation_sensitivity invert: !input invert_rotation enable_toggle: !input enable_default_single_press # Calculate the final brightness step dynamically based on the rotation direction scaled_step: > {% set step = (raw_angle * sens) | int(0) %} {{ (step * -1) if invert else step }} - choose: # --- SINGLE PRESS --- - conditions: - condition: template value_template: "{{ action_type == 'single' or action_type == '' or action_type is none }}" sequence: - choose: - conditions: - condition: template value_template: "{{ enable_toggle }}" sequence: - service: light.toggle target: !input target_light - choose: - conditions: [] sequence: !input single_press_action # --- DOUBLE PRESS --- - conditions: - condition: template value_template: "{{ action_type == 'double' }}" sequence: - choose: - conditions: [] sequence: !input double_press_action # --- HOLD (LONG PRESS) --- - conditions: - condition: template value_template: "{{ action_type == 'hold' }}" sequence: - choose: - conditions: [] sequence: !input hold_action # --- RELEASE (AFTER HOLD) --- - conditions: - condition: template value_template: "{{ action_type == 'release' }}" sequence: - choose: - conditions: [] sequence: !input release_action # --- ROTATION DIMMING --- - conditions: - condition: template value_template: "{{ action_type == 'rotation' }}" sequence: # Only fire the turn_on service if there was a registrable angle change - condition: template value_template: "{{ scaled_step != 0 }}" - service: light.turn_on target: !input target_light data: brightness_step_pct: "{{ scaled_step }}" transition: !input dim_transition