Thank you for @nwithan8
I referred to this article and chat-gpt helped me a lot.
Fixed a blueprint that was originally buggy and wouldn’t run.
blueprint:
name: ERS Rotary Dial - Light Control (Z2M) - COMMAND mode
description: >
Control light brightness, color temperature and color with an ERS rotary dial.
Device needs to be in COMMAND mode.
Needs "Home Assistant legacy entity attributes" checked.
source_url: https://raw.githubusercontent.com/nwithan8/configs/main/home_assistant/blueprints/automations/ers_rotary_dial_light_control_z2m.yaml
domain: automation
input:
light:
name: Light
description: The Light entity or Light Group entity to control
selector:
entity:
filter:
- domain:
- light
- group
multiple: false
dial:
name: Rotary dial
description: Select the rotary dial action entity
selector:
entity:
filter:
integration: mqtt
mode_tracker:
name: Mode tracker
description: Input number helper to store the current mode in (1-4)
selector:
entity:
filter:
domain: input_number
color_tracker:
name: Color tracker
description: Input number helper to store the current RGB wheel value in (0-1535)
selector:
entity:
filter:
domain: input_number
hue_tracker:
name: Hue tracker
description: Input number helper to store the current color temperature in kelvin (2000-6500)
selector:
entity:
filter:
domain: input_number
brightness_tracker:
name: Brightness tracker
description: Input number helper to store the current brightness in (0-255)
selector:
entity:
filter:
domain: input_number
mode: queued
max: 20
max_exceeded: silent
trigger:
- platform: state
entity_id: !input dial
not_to: ""
action:
- variables:
light: !input light
dial: !input dial
mode_tracker: !input mode_tracker
hue_tracker: !input hue_tracker
brightness_tracker: !input brightness_tracker
color_tracker: !input color_tracker
command: "{{ trigger.to_state.state if trigger is defined and trigger.to_state is defined else '' }}"
step_size: "{{ trigger.to_state.attributes.action_step_size | default(13) if trigger is defined and trigger.to_state is defined else 13 }}"
single_pressed: "{{ command == 'toggle' }}"
long_pressed: "{{ command == 'hue_move' }}"
rotated: "{{ command in ['brightness_step_up', 'brightness_step_down'] }}"
pressed_rotated: "{{ command in ['color_temperature_step_up', 'color_temperature_step_down'] }}"
positive: "{{ command in ['brightness_step_up', 'color_temperature_step_up'] }}"
full_rotate_step_count: "{{ 13 * 20 }}"
current_mode: "{{ states(mode_tracker) | int(2) }}"
min_mode: "{{ state_attr(mode_tracker, 'min') | int(1) }}"
max_mode: "{{ state_attr(mode_tracker, 'max') | int(4) }}"
next_mode: >
{% set val = current_mode + 1 %}
{% if val > max_mode %}
{% set val = min_mode %}
{% endif %}
{{ val | int }}
min_hue: "{{ state_attr(hue_tracker, 'min') | int(2000) }}"
max_hue: "{{ state_attr(hue_tracker, 'max') | int(6500) }}"
hue_steps: "{{ full_rotate_step_count * 2 }}"
hue_delta: "{{ ((step_size | float(13)) / (hue_steps | float(1))) * (max_hue - min_hue) }}"
next_hue: >
{% set val = states(hue_tracker) | float(2000) %}
{% set delta = hue_delta | float(0) %}
{% if not positive %}
{% set delta = delta * -1 %}
{% endif %}
{% set val = val + delta %}
{% if val > max_hue %}
{% set val = max_hue %}
{% elif val < min_hue %}
{% set val = min_hue %}
{% endif %}
{{ val | round(0) | int }}
min_brightness: "{{ state_attr(brightness_tracker, 'min') | int(0) }}"
max_brightness: "{{ state_attr(brightness_tracker, 'max') | int(255) }}"
brightness_steps: "{{ full_rotate_step_count * 2 }}"
brightness_delta: "{{ ((step_size | float(13)) / (brightness_steps | float(1))) * (max_brightness - min_brightness) }}"
next_brightness: >
{% set val = states(brightness_tracker) | float(0) %}
{% set delta = brightness_delta | float(0) %}
{% if not positive %}
{% set delta = delta * -1 %}
{% endif %}
{% set val = val + delta %}
{% if val > max_brightness %}
{% set val = max_brightness %}
{% elif val < min_brightness %}
{% set val = min_brightness %}
{% endif %}
{{ val | round(0) | int }}
min_color: "{{ state_attr(color_tracker, 'min') | int(0) }}"
max_color: "{{ state_attr(color_tracker, 'max') | int(1535) }}"
color_steps: "{{ full_rotate_step_count * 3 }}"
color_delta: "{{ ((step_size | float(13)) / (color_steps | float(1))) * (max_color - min_color) }}"
next_color: >
{% set val = states(color_tracker) | float(0) %}
{% set delta = color_delta | float(0) %}
{% if not positive %}
{% set delta = delta * -1 %}
{% endif %}
{% set val = val + delta %}
{% if val > max_color %}
{% set val = val % (max_color + 1) %}
{% elif val < min_color %}
{% set val = (max_color + 1) + val %}
{% endif %}
{{ val | round(0) | int }}
next_rgb: >
{% set r = 0 %}
{% set g = 0 %}
{% set b = 0 %}
{% set index = next_color | int %}
{% if index >= 0 and index <= 255 %}
{% set r = 255 %}
{% set g = index %}
{% set b = 0 %}
{% elif index >= 256 and index <= 511 %}
{% set r = 511 - index %}
{% set g = 255 %}
{% set b = 0 %}
{% elif index >= 512 and index <= 767 %}
{% set r = 0 %}
{% set g = 255 %}
{% set b = index - 512 %}
{% elif index >= 768 and index <= 1023 %}
{% set r = 0 %}
{% set g = 1023 - index %}
{% set b = 255 %}
{% elif index >= 1024 and index <= 1279 %}
{% set r = index - 1024 %}
{% set g = 0 %}
{% set b = 255 %}
{% elif index >= 1280 and index <= 1535 %}
{% set r = 255 %}
{% set g = 0 %}
{% set b = 1535 - index %}
{% endif %}
{{ [r | int, g | int, b | int] }}
- choose:
# click: mode change
- conditions:
- condition: template
value_template: "{{ single_pressed }}"
sequence:
- service: input_number.set_value
target:
entity_id: !input mode_tracker
data:
value: "{{ next_mode }}"
# long press: power toggle
- conditions:
- condition: template
value_template: "{{ long_pressed }}"
sequence:
- service: light.toggle
target:
entity_id: !input light
# normal rotate
- conditions:
- condition: template
value_template: "{{ rotated }}"
sequence:
- choose:
# Mode 1: do nothing
- conditions:
- condition: template
value_template: "{{ current_mode == 1 }}"
sequence: []
# Mode 2: brightness
- conditions:
- condition: template
value_template: "{{ current_mode == 2 }}"
sequence:
- service: input_number.set_value
target:
entity_id: !input brightness_tracker
data:
value: "{{ next_brightness }}"
- service: light.turn_on
target:
entity_id: !input light
data:
brightness: "{{ next_brightness }}"
# Mode 3: color temperature
- conditions:
- condition: template
value_template: "{{ current_mode == 3 }}"
sequence:
- service: input_number.set_value
target:
entity_id: !input hue_tracker
data:
value: "{{ next_hue }}"
- service: light.turn_on
target:
entity_id: !input light
data:
color_temp_kelvin: "{{ next_hue }}"
# Mode 4: color
- conditions:
- condition: template
value_template: "{{ current_mode == 4 }}"
sequence:
- service: input_number.set_value
target:
entity_id: !input color_tracker
data:
value: "{{ next_color }}"
- service: light.turn_on
target:
entity_id: !input light
data:
rgb_color: "{{ next_rgb }}"
# press + rotate: direct color temperature adjust
- conditions:
- condition: template
value_template: "{{ pressed_rotated }}"
sequence:
- service: input_number.set_value
target:
entity_id: !input hue_tracker
data:
value: "{{ next_hue }}"
- service: light.turn_on
target:
entity_id: !input light
data:
color_temp_kelvin: "{{ next_hue }}"
You can use the action entity of the knob.
Please refer to the original article for usage instructions.
I’m also a beginner and Chatgpt helped me with everything related to code, so I may not be able to solve the problems that follow.