diff --git a/aqara-h2-eu-dimmer-z2m-light-control.yaml b/aqara-h2-eu-dimmer-z2m-light-control.yaml new file mode 100644 index 0000000..068525f --- /dev/null +++ b/aqara-h2-eu-dimmer-z2m-light-control.yaml @@ -0,0 +1,178 @@ +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' }}" + 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