Compare commits
3
Commits
96f313e3fb
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08f7332b7e | ||
|
|
fefda42470 | ||
|
|
99ddaa60dc |
@@ -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
|
||||||
@@ -0,0 +1,509 @@
|
|||||||
|
blueprint:
|
||||||
|
name: Z2M - Philips Hue Tap Dial Switch - Light Control (MQTT Direct)
|
||||||
|
description: >
|
||||||
|
Control up to 4 lights and run custom actions with a Philips Hue Tap Dial Switch via Zigbee2MQTT.
|
||||||
|
|
||||||
|
**Why use this version?**
|
||||||
|
Zigbee2MQTT 2.0+ deprecated and removed the legacy `action` sensor. This blueprint connects directly to the MQTT topic, meaning it works flawlessly with the newest Z2M updates without needing legacy workarounds!
|
||||||
|
|
||||||
|
**Features:**
|
||||||
|
- Assign a Light to each button to Toggle it.
|
||||||
|
- Set Custom Actions for Single, Double, and Long Presses on all 4 buttons.
|
||||||
|
- Automatically updates an `input_text` helper to remember the last used light.
|
||||||
|
- Rotating the dial dims the most recently interacted light smoothly.
|
||||||
|
- **No Dropped Clicks:** Uses `mode: parallel` and timestamping so you can press button 1, 2, 3 in rapid succession and *all* of them will register instantly without being blocked by double-click delays.
|
||||||
|
- **Native MQTT:** Connects directly to the MQTT topic (bypassing legacy Z2M action sensors).
|
||||||
|
- **Fallback Light**: A default light to dim if the dial is turned before any buttons are pressed.
|
||||||
|
|
||||||
|
**REQUIREMENT:** Create an `input_text` helper in Home Assistant (Settings > Devices & Services > Helpers) and select it below in the "Last Light Helper" input.
|
||||||
|
domain: automation
|
||||||
|
input:
|
||||||
|
mqtt_topic:
|
||||||
|
name: MQTT Topic
|
||||||
|
description: "The base MQTT topic of the Tap Dial. Usually `zigbee2mqtt/Friendly_Name` (e.g., `zigbee2mqtt/Living Room Dial`). You can find this in Z2M under the device's 'MQTT Info' tab."
|
||||||
|
default: "zigbee2mqtt/Hue Tap Dial"
|
||||||
|
|
||||||
|
helper_last_light:
|
||||||
|
name: Last Light Helper (input_text)
|
||||||
|
description: "Required. An input_text helper to remember the last activated light for the dial to dim."
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: input_text
|
||||||
|
|
||||||
|
fallback_light:
|
||||||
|
name: Fallback Light (Optional)
|
||||||
|
description: "A default light to dim if the dial is rotated before any buttons have been pressed."
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: light
|
||||||
|
|
||||||
|
dial_step_pct:
|
||||||
|
name: Dial Step Size (%)
|
||||||
|
description: Brightness percentage change for a slow/single step rotation.
|
||||||
|
default: 10
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 50
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
dial_fast_pct:
|
||||||
|
name: Dial Fast Step Size (%)
|
||||||
|
description: Brightness percentage change for a fast rotation.
|
||||||
|
default: 25
|
||||||
|
selector:
|
||||||
|
number:
|
||||||
|
min: 1
|
||||||
|
max: 100
|
||||||
|
unit_of_measurement: "%"
|
||||||
|
mode: slider
|
||||||
|
|
||||||
|
# =================
|
||||||
|
# BUTTON 1 (1 Dot)
|
||||||
|
# =================
|
||||||
|
light_1:
|
||||||
|
name: Button 1 - Target Light
|
||||||
|
description: Light to toggle on Single Press and control via the Dial. (Leave empty if only using custom actions).
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: light
|
||||||
|
button_1_single_press:
|
||||||
|
name: Button 1 - Extra Single Press Actions
|
||||||
|
description: Additional custom actions to run alongside the light toggle.
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
button_1_double_press:
|
||||||
|
name: Button 1 - Double Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
button_1_long_press:
|
||||||
|
name: Button 1 - Long Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
# =================
|
||||||
|
# BUTTON 2 (2 Dots)
|
||||||
|
# =================
|
||||||
|
light_2:
|
||||||
|
name: Button 2 - Target Light
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: light
|
||||||
|
button_2_single_press:
|
||||||
|
name: Button 2 - Extra Single Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
button_2_double_press:
|
||||||
|
name: Button 2 - Double Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
button_2_long_press:
|
||||||
|
name: Button 2 - Long Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
# =================
|
||||||
|
# BUTTON 3 (3 Dots)
|
||||||
|
# =================
|
||||||
|
light_3:
|
||||||
|
name: Button 3 - Target Light
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: light
|
||||||
|
button_3_single_press:
|
||||||
|
name: Button 3 - Extra Single Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
button_3_double_press:
|
||||||
|
name: Button 3 - Double Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
button_3_long_press:
|
||||||
|
name: Button 3 - Long Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
# =================
|
||||||
|
# BUTTON 4 (4 Dots)
|
||||||
|
# =================
|
||||||
|
light_4:
|
||||||
|
name: Button 4 - Target Light
|
||||||
|
default: ""
|
||||||
|
selector:
|
||||||
|
entity:
|
||||||
|
domain: light
|
||||||
|
button_4_single_press:
|
||||||
|
name: Button 4 - Extra Single Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
button_4_double_press:
|
||||||
|
name: Button 4 - Double Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
button_4_long_press:
|
||||||
|
name: Button 4 - Long Press Actions
|
||||||
|
default: []
|
||||||
|
selector:
|
||||||
|
action: {}
|
||||||
|
|
||||||
|
# Parallel mode allows rapid sequential button presses across different buttons
|
||||||
|
mode: parallel
|
||||||
|
max: 10
|
||||||
|
|
||||||
|
trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic
|
||||||
|
|
||||||
|
condition:
|
||||||
|
# Verify that the MQTT payload contains a valid action (ignores battery/linkquality pings)
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ trigger.payload_json is not none and trigger.payload_json.action is defined and trigger.payload_json.action != '' }}"
|
||||||
|
|
||||||
|
action:
|
||||||
|
- variables:
|
||||||
|
light_1: !input light_1
|
||||||
|
light_2: !input light_2
|
||||||
|
light_3: !input light_3
|
||||||
|
light_4: !input light_4
|
||||||
|
helper_last_light: !input helper_last_light
|
||||||
|
fallback_light: !input fallback_light
|
||||||
|
dial_step_pct: !input dial_step_pct
|
||||||
|
dial_fast_pct: !input dial_fast_pct
|
||||||
|
|
||||||
|
# Extract action string from MQTT payload for clean condition checks
|
||||||
|
action_type: "{{ trigger.payload_json.action }}"
|
||||||
|
|
||||||
|
# Read helper memory to check for overlapping double-clicks and target lights
|
||||||
|
helper_state: "{{ states(helper_last_light) }}"
|
||||||
|
helper_parts: "{{ helper_state.split('|') if helper_state not in ['unknown', 'unavailable', 'none'] else [] }}"
|
||||||
|
|
||||||
|
prev_light: "{{ helper_parts[0] if helper_parts | length > 0 else 'none' }}"
|
||||||
|
prev_btn: "{{ helper_parts[1] if helper_parts | length > 1 else 'none' }}"
|
||||||
|
prev_time: "{{ helper_parts[2] | float(0) if helper_parts | length > 2 else 0 }}"
|
||||||
|
|
||||||
|
# Identifies if THIS trigger is the second click of an ongoing double-click window
|
||||||
|
is_double_click_secondary: "{{ action_type == prev_btn and (as_timestamp(now()) - prev_time) <= 0.5 }}"
|
||||||
|
|
||||||
|
# Determine which light to dim seamlessly
|
||||||
|
target_dim_light: >-
|
||||||
|
{% if prev_light not in ['none', 'unknown', 'unavailable', ''] %}
|
||||||
|
{{ prev_light }}
|
||||||
|
{% elif fallback_light != '' and fallback_light != none %}
|
||||||
|
{{ fallback_light }}
|
||||||
|
{% else %}
|
||||||
|
none
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
# ==================================
|
||||||
|
# BUTTON 1
|
||||||
|
# ==================================
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_type == 'button_1_press_release' }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_double_click_secondary }}"
|
||||||
|
sequence:
|
||||||
|
- stop: "Secondary click detected. Halting this parallel run to let the primary trace execute Double Click."
|
||||||
|
|
||||||
|
# If not stopped, this is a fresh primary click. Update memory bank.
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ helper_last_light }}"
|
||||||
|
data:
|
||||||
|
value: "{{ (light_1 if light_1 != none else '') ~ '|button_1_press_release|' ~ as_timestamp(now()) }}"
|
||||||
|
|
||||||
|
# Await potential Double-Click via native MQTT
|
||||||
|
- wait_for_trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic
|
||||||
|
payload: "button_1_press_release"
|
||||||
|
value_template: "{{ value_json.action | default('') }}"
|
||||||
|
timeout: "00:00:00.500"
|
||||||
|
continue_on_timeout: true
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ wait.trigger is not none }}"
|
||||||
|
sequence:
|
||||||
|
- choose: []
|
||||||
|
default: !input button_1_double_press
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ wait.trigger is none }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ light_1 != '' and light_1 != none }}"
|
||||||
|
sequence:
|
||||||
|
- service: light.toggle
|
||||||
|
target:
|
||||||
|
entity_id: "{{ light_1 }}"
|
||||||
|
- choose: []
|
||||||
|
default: !input button_1_single_press
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_type == 'button_1_hold' }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ helper_last_light }}"
|
||||||
|
data:
|
||||||
|
value: "{{ (light_1 if light_1 != none else '') ~ '|button_1_hold|0' }}"
|
||||||
|
- choose: []
|
||||||
|
default: !input button_1_long_press
|
||||||
|
|
||||||
|
|
||||||
|
# ==================================
|
||||||
|
# BUTTON 2
|
||||||
|
# ==================================
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_type == 'button_2_press_release' }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_double_click_secondary }}"
|
||||||
|
sequence:
|
||||||
|
- stop: "Secondary click detected."
|
||||||
|
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ helper_last_light }}"
|
||||||
|
data:
|
||||||
|
value: "{{ (light_2 if light_2 != none else '') ~ '|button_2_press_release|' ~ as_timestamp(now()) }}"
|
||||||
|
|
||||||
|
- wait_for_trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic
|
||||||
|
payload: "button_2_press_release"
|
||||||
|
value_template: "{{ value_json.action | default('') }}"
|
||||||
|
timeout: "00:00:00.500"
|
||||||
|
continue_on_timeout: true
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ wait.trigger is not none }}"
|
||||||
|
sequence:
|
||||||
|
- choose: []
|
||||||
|
default: !input button_2_double_press
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ wait.trigger is none }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ light_2 != '' and light_2 != none }}"
|
||||||
|
sequence:
|
||||||
|
- service: light.toggle
|
||||||
|
target:
|
||||||
|
entity_id: "{{ light_2 }}"
|
||||||
|
- choose: []
|
||||||
|
default: !input button_2_single_press
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_type == 'button_2_hold' }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ helper_last_light }}"
|
||||||
|
data:
|
||||||
|
value: "{{ (light_2 if light_2 != none else '') ~ '|button_2_hold|0' }}"
|
||||||
|
- choose: []
|
||||||
|
default: !input button_2_long_press
|
||||||
|
|
||||||
|
|
||||||
|
# ==================================
|
||||||
|
# BUTTON 3
|
||||||
|
# ==================================
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_type == 'button_3_press_release' }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_double_click_secondary }}"
|
||||||
|
sequence:
|
||||||
|
- stop: "Secondary click detected."
|
||||||
|
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ helper_last_light }}"
|
||||||
|
data:
|
||||||
|
value: "{{ (light_3 if light_3 != none else '') ~ '|button_3_press_release|' ~ as_timestamp(now()) }}"
|
||||||
|
|
||||||
|
- wait_for_trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic
|
||||||
|
payload: "button_3_press_release"
|
||||||
|
value_template: "{{ value_json.action | default('') }}"
|
||||||
|
timeout: "00:00:00.500"
|
||||||
|
continue_on_timeout: true
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ wait.trigger is not none }}"
|
||||||
|
sequence:
|
||||||
|
- choose: []
|
||||||
|
default: !input button_3_double_press
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ wait.trigger is none }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ light_3 != '' and light_3 != none }}"
|
||||||
|
sequence:
|
||||||
|
- service: light.toggle
|
||||||
|
target:
|
||||||
|
entity_id: "{{ light_3 }}"
|
||||||
|
- choose: []
|
||||||
|
default: !input button_3_single_press
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_type == 'button_3_hold' }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ helper_last_light }}"
|
||||||
|
data:
|
||||||
|
value: "{{ (light_3 if light_3 != none else '') ~ '|button_3_hold|0' }}"
|
||||||
|
- choose: []
|
||||||
|
default: !input button_3_long_press
|
||||||
|
|
||||||
|
|
||||||
|
# ==================================
|
||||||
|
# BUTTON 4
|
||||||
|
# ==================================
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_type == 'button_4_press_release' }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ is_double_click_secondary }}"
|
||||||
|
sequence:
|
||||||
|
- stop: "Secondary click detected."
|
||||||
|
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ helper_last_light }}"
|
||||||
|
data:
|
||||||
|
value: "{{ (light_4 if light_4 != none else '') ~ '|button_4_press_release|' ~ as_timestamp(now()) }}"
|
||||||
|
|
||||||
|
- wait_for_trigger:
|
||||||
|
- platform: mqtt
|
||||||
|
topic: !input mqtt_topic
|
||||||
|
payload: "button_4_press_release"
|
||||||
|
value_template: "{{ value_json.action | default('') }}"
|
||||||
|
timeout: "00:00:00.500"
|
||||||
|
continue_on_timeout: true
|
||||||
|
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ wait.trigger is not none }}"
|
||||||
|
sequence:
|
||||||
|
- choose: []
|
||||||
|
default: !input button_4_double_press
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ wait.trigger is none }}"
|
||||||
|
sequence:
|
||||||
|
- choose:
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ light_4 != '' and light_4 != none }}"
|
||||||
|
sequence:
|
||||||
|
- service: light.toggle
|
||||||
|
target:
|
||||||
|
entity_id: "{{ light_4 }}"
|
||||||
|
- choose: []
|
||||||
|
default: !input button_4_single_press
|
||||||
|
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_type == 'button_4_hold' }}"
|
||||||
|
sequence:
|
||||||
|
- service: input_text.set_value
|
||||||
|
target:
|
||||||
|
entity_id: "{{ helper_last_light }}"
|
||||||
|
data:
|
||||||
|
value: "{{ (light_4 if light_4 != none else '') ~ '|button_4_hold|0' }}"
|
||||||
|
- choose: []
|
||||||
|
default: !input button_4_long_press
|
||||||
|
|
||||||
|
|
||||||
|
# ==================================
|
||||||
|
# DIAL ROTATE LEFT (DIM DOWN)
|
||||||
|
# ==================================
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_type in ['dial_rotate_left_step', 'dial_rotate_left_slow', 'dial_rotate_left_fast'] }}"
|
||||||
|
sequence:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ target_dim_light != 'none' }}"
|
||||||
|
- service: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ target_dim_light }}"
|
||||||
|
data:
|
||||||
|
brightness_step_pct: >-
|
||||||
|
{% if 'fast' in action_type %}
|
||||||
|
{{ -1 * (dial_fast_pct | int) }}
|
||||||
|
{% else %}
|
||||||
|
{{ -1 * (dial_step_pct | int) }}
|
||||||
|
{% endif %}
|
||||||
|
continue_on_error: true
|
||||||
|
|
||||||
|
|
||||||
|
# ==================================
|
||||||
|
# DIAL ROTATE RIGHT (DIM UP)
|
||||||
|
# ==================================
|
||||||
|
- conditions:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ action_type in ['dial_rotate_right_step', 'dial_rotate_right_slow', 'dial_rotate_right_fast'] }}"
|
||||||
|
sequence:
|
||||||
|
- condition: template
|
||||||
|
value_template: "{{ target_dim_light != 'none' }}"
|
||||||
|
- service: light.turn_on
|
||||||
|
target:
|
||||||
|
entity_id: "{{ target_dim_light }}"
|
||||||
|
data:
|
||||||
|
brightness_step_pct: >-
|
||||||
|
{% if 'fast' in action_type %}
|
||||||
|
{{ dial_fast_pct | int }}
|
||||||
|
{% else %}
|
||||||
|
{{ dial_step_pct | int }}
|
||||||
|
{% endif %}
|
||||||
|
continue_on_error: true
|
||||||
Reference in New Issue
Block a user