Control light color, hue, brightness with ERS dial (Z2M)

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 }}"

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.
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.

Hello tlfqj0719,

Thanks for contributing to the community with a new Blueprint.
I have a suggestion for you. Many people who are not familiar with directory structures will have problems installing this without the Home Assistant MY tools.
Adding a MY link for this Blueprint to your top post would help them a lot.
Here is the link to make that.
Create a link – My Home Assistant
You need to be a trust level ‘member’ to edit a post. Understanding Discourse Trust Levels
If you can’t edit, I would load a link into a second post.

thank you
I edited

1 Like