Last active
April 29, 2025 19:31
-
-
Save issmirnov/9b10a02b9ab01015cd17afb1e6c4e6da to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
blueprint: | |
name: ZHA - Moes Smart Knob for lights (RGB cycle + optional double‑press) | |
description: > | |
Fork of GonzaloAlbito’s original blueprint, modified to add **hue cycling** on | |
press‑and‑hold and (optionally) a custom **double‑press** action while keeping | |
the original brightness‑dimming logic and reliability work‑arounds (repeat | |
loops, service_template, data_template). | |
• **Rotate** → brightness ±*Light step* % per encoder tick. | |
• **Press & hold** → every `step_color_temp` or `move_hue` event (depends on | |
firmware) steps the hue by ±*Hue step*°. | |
• **Single press** → user‑defined action. | |
• **Double press** *(cluster 6 → command "on")* → optional user‑defined | |
action. | |
Version 2025‑04‑29. | |
domain: automation | |
input: | |
remote: | |
name: Remote | |
description: Moes Knob to use | |
selector: | |
device: | |
integration: zha | |
manufacturer: _TZ3000_qja6nq5z | |
model: TS004F | |
multiple: false | |
light: | |
name: Light(s) | |
description: RGB lights to dim (rotate) and colour‑cycle (press & hold) | |
selector: | |
target: | |
entity: | |
domain: light | |
step_percent: | |
name: Light step | |
description: Brightness % change for each knob step while rotating freely | |
selector: | |
number: | |
mode: slider | |
min: 1 | |
max: 100 | |
unit_of_measurement: "%" | |
default: 20 | |
hue_step: | |
name: Hue step | |
description: Degrees to advance around the colour‑wheel on every hue event | |
selector: | |
number: | |
mode: slider | |
min: 1 | |
max: 60 | |
unit_of_measurement: "°" | |
default: 15 | |
single_press: | |
name: Single press | |
description: Action to run on single press | |
default: [] | |
selector: | |
action: {} | |
double_press: | |
name: Double press (optional) | |
description: Action to run on double press — leave empty to ignore | |
default: [] | |
selector: | |
action: {} | |
mode: restart | |
max_exceeded: silent | |
trigger: | |
- platform: event | |
event_type: zha_event | |
event_data: | |
device_id: !input remote | |
action: | |
- variables: | |
command: "{{ trigger.event.data.command }}" | |
cluster_id: "{{ trigger.event.data.cluster_id }}" | |
endpoint_id: "{{ trigger.event.data.endpoint_id }}" | |
mode: > | |
{% if command not in ['toggle', 'on'] %} | |
{{ trigger.event.data.args[0] }} | |
{% endif %} | |
steps: > | |
{% if command not in ['toggle', 'on'] %} | |
{{ (trigger.event.data.args[1] / 12.5) | int }} | |
{% endif %} | |
step_percent: !input step_percent | |
hue_step: !input hue_step | |
_target: !input light # store the target dict | |
ref_entity: > # first entity_id inside the target | |
{{ _target.entity_id if _target.entity_id is string else _target.entity_id[0] }} | |
current_hue: > # current hue of that entity (0‑360) | |
{{ (state_attr(ref_entity, 'hs_color')[0] if state_attr(ref_entity, 'hs_color') is not none else 0) }} | |
- choose: | |
# ─── Single press ─────────────────────────────────────────────────────── | |
- conditions: | |
- "{{ cluster_id == 6 }}" | |
- "{{ endpoint_id == 1 }}" | |
- "{{ command == 'toggle' }}" | |
sequence: !input single_press | |
# ─── Double press (if configured) ─────────────────────────────────────── | |
- conditions: | |
- "{{ cluster_id == 6 }}" | |
- "{{ endpoint_id == 1 }}" | |
- "{{ command == 'on' }}" | |
- "{{ double_press | length > 0 }}" | |
sequence: !input double_press | |
# ─── Rotate brightness up ─────────────────────────────────────────────── | |
- conditions: | |
- "{{ cluster_id == 8 }}" | |
- "{{ endpoint_id == 1 }}" | |
- "{{ command == 'step' }}" | |
- "{{ mode == 'StepMode.Up' }}" | |
sequence: | |
- repeat: | |
while: | |
- condition: template | |
value_template: '{{ repeat.index < 2 }}' | |
sequence: | |
- service_template: light.turn_on | |
target: !input light | |
data_template: | |
brightness_step_pct: '{{ step_percent * steps }}' | |
transition: 0.5 | |
# ─── Rotate brightness down ───────────────────────────────────────────── | |
- conditions: | |
- "{{ cluster_id == 8 }}" | |
- "{{ endpoint_id == 1 }}" | |
- "{{ command == 'step' }}" | |
- "{{ mode == 'StepMode.Down' }}" | |
sequence: | |
- repeat: | |
while: | |
- condition: template | |
value_template: '{{ repeat.index < 2 }}' | |
sequence: | |
- service_template: light.turn_on | |
target: !input light | |
data_template: | |
brightness_step_pct: '-{{ step_percent * steps }}' | |
transition: 0.5 | |
# ─── Press & hold → cycle hue up ─────────────────────────────────────── | |
- conditions: | |
- "{{ cluster_id == 768 }}" | |
- "{{ endpoint_id == 1 }}" | |
- "{{ command in ['step_color_temp', 'move_hue'] }}" | |
- "{{ mode == 'StepMode.Up' }}" | |
sequence: | |
- repeat: | |
while: | |
- condition: template | |
value_template: '{{ repeat.index < 2 }}' | |
sequence: | |
- service_template: light.turn_on | |
target: !input light | |
data_template: | |
hs_color: | |
- '{{ (current_hue + hue_step) % 360 }}' | |
- 100 | |
transition: 0.1 | |
# ─── Press & hold → cycle hue down ───────────────────────────────────── | |
- conditions: | |
- "{{ cluster_id == 768 }}" | |
- "{{ endpoint_id == 1 }}" | |
- "{{ command in ['step_color_temp', 'move_hue'] }}" | |
- "{{ mode == 'StepMode.Down' }}" | |
sequence: | |
- repeat: | |
while: | |
- condition: template | |
value_template: '{{ repeat.index < 2 }}' | |
sequence: | |
- service_template: light.turn_on | |
target: !input light | |
data_template: | |
hs_color: | |
- '{{ (current_hue - hue_step) % 360 }}' | |
- 100 | |
transition: 0.1 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Fork from https://gist.github.com/gonzaloalbito/3dc06702e941e08298ea9bfade731731, attempting to have the press and hold action cycle through the RGB spectrum.
Currently stable.