Hey, me again. I’ve updated the blueprint to use EVENT mode instead of COMMAND mode after looking at another blueprint that seemed to have luck with that.
Hopefully it works for you this time.
Hey, me again. I’ve updated the blueprint to use EVENT mode instead of COMMAND mode after looking at another blueprint that seemed to have luck with that.
Hopefully it works for you this time.
Hi
Thank you for the cool blueprint. I watched the youtube video and I like the knob work. But I have zigbee2mqtt and when automation is triggered an error appears
Stopped because an error was encountered at 1 veresnya 2023 p. o 17:59:06 (runtime: 0.01 seconds)
UndefinedError: 'dict object' has no attribute 'to_state'
Tried different command and event modes without success.
Hi, I have tried to use this blueprint to make an automation and I get the error:
Message malformed: Unknown entity registry entry dc2875e62569a54fbbe9bc9ba5c9613f
I can add automations manually but I cannot use the blueprint.
Is there anything I can try?
Greg
Did you solve it?
I just tried this blueprint and I have the same error when trying to create the automation.
Did you managed to find a solution for this?
@nwithan8 , any idea what causes this error?
LE: nevermind, it seems that I found the problem (or at least the source of the problem and a workaround for it)
The problem was with the trigger using the device. So I changed the trigger to be an entity of the Knob and added another input in the blueprint to be able to set the name of the device (fridnely name in z2m - not very nice since is a free text, but still works).
I also changed the order of the modes (seems more natural this way):
Here is the code
# Instructions: https://community.home-assistant.io/t/zha-z2m-control-light-color-hue-brightness-with-ers-dial/595002
blueprint:
name: ERS Rotary Dial - Light Control (Z2M) - COMMAND mode
description: >
Control light brightness, hue and color with an ERS rotary dial.
Device needs to be in COMMAND mode (triple-press the button to switch modes).
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 you wish to use to control the light
selector:
entity:
filter:
domain: sensor
integration: mqtt
knob:
name: Knob
mode_tracker:
name: Mode tracker
description: An input number helper to store the current mode in (1-4)
selector:
entity:
filter:
domain: input_number
color_tracker:
name: Color tracker
description: An input number helper to store the current RGB value in (0-1535)
selector:
entity:
filter:
domain: input_number
hue_tracker:
name: Hue tracker
description: An input number helper to store the current hue in (2000-6500)
selector:
entity:
filter:
domain: input_number
brightness_tracker:
name: Brightness tracker
description: An input number helper to store the current brightness in (0-255)
selector:
entity:
filter:
domain: input_number
# Queued, to ignore non-matched events but capture existing ones
mode: queued
max: 20
max_exceeded: silent
trigger:
- platform: state
entity_id: !input dial
not_to: ""
attribute: action
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"
dial_topic: "zigbee2mqtt/{{ dial }}/action"
# Ref: https://community.home-assistant.io/t/zigbee2mqtt-tuya-moes-smart-knob-ers-10tzbvk-aa/419989/26
command: "{{ trigger.to_state.state }}"
single_pressed: "{{ command == 'toggle' }}"
double_pressed: "{{ command == 'hue_move' }}"
rotated: "{{ command in ['brightness_step_up', 'brightness_step_down', 'color_temperature_step_up', 'color_temperature_step_down'] }}"
positive: "{{ command in ['brightness_step_up', 'color_temperature_step_up'] }}"
step_size: "{{ trigger.to_state.attributes.action_step_size }}"
# How many steps to go full rotation (min 13 per step * 20 steps per full rotation)
full_rotate_step_count: "{{ 13 * 20 | int }}"
current_mode: "{{ states(mode_tracker) | int }}"
min_mode: "{{ state_attr(mode_tracker, 'min') | int }}"
max_mode: "{{ state_attr(mode_tracker, 'max') | int }}"
# always increment, looping
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 }}"
max_hue: "{{ state_attr(hue_tracker, 'max') | int }}"
# How many steps to go full min-max spectrum
hue_steps: "{{ full_rotate_step_count * 2 | int }}"
hue_delta: "{{ (step_size | float(0) / hue_steps) * (max_hue - min_hue) }}"
# don't loop when reached max or min
next_hue: >
{%- set val = states(hue_tracker) | float(0) -%}
{%- set delta = hue_delta -%}
{%- if not positive -%}
{%- set delta = delta * -1 -%}
{%- endif -%}
{%- set val = val + delta | int -%}
{%- if positive and val > max_hue -%}
{%- set val = max_hue -%}
{%- elif not positive and val < min_hue -%}
{%- set val = min_hue -%}
{%- endif -%}
{{ val | int }}
min_brightness: "{{ state_attr(brightness_tracker, 'min') | int }}"
max_brightness: "{{ state_attr(brightness_tracker, 'max') | int }}"
# How many steps to go full min-max spectrum
brightness_steps: "{{ full_rotate_step_count * 2 | int }}"
brightness_delta: "{{ (step_size | float(0) / brightness_steps) * (max_brightness - min_brightness) }}"
# don't loop when reached max or min
next_brightness: >
{%- set val = states(brightness_tracker) | float(0) -%}
{%- set delta = brightness_delta -%}
{%- if not positive -%}
{%- set delta = delta * -1 -%}
{%- endif -%}
{%- set val = val + delta | int -%}
{%- if positive and val > max_brightness -%}
{%- set val = max_brightness -%}
{%- elif not positive and val < min_brightness -%}
{%- set val = min_brightness -%}
{%- endif -%}
{{ val | int }}
min_color: "{{ state_attr(color_tracker, 'min') | int }}"
max_color: "{{ state_attr(color_tracker, 'max') | int }}"
# How many steps to go full min-max spectrum
color_steps: "{{ full_rotate_step_count * 3 | int }}"
color_delta: "{{ (step_size | float(0) / color_steps) * (max_color - min_color) }}"
# loop when reached max or min
next_color: >
{%- set val = states(color_tracker) | float(0) -%}
{%- set delta = color_delta -%}
{%- if not positive -%}
{%- set delta = delta * -1 -%}
{%- endif -%}
{%- set val = val + delta | int -%}
{%- if positive and val > max_color -%}
{%- set val = val % max_color -%}
{%- elif not positive and val < min_color -%}
{%- set diff = min_color - val -%}
{%- set val = max_color - (diff % max_color) -%}
{%- endif -%}
{{ val | int }}
# Process current event
- choose:
- conditions:
- condition: template
value_template: "{{ rotated }}"
alias: Dial turned (0 for right, 1 for left)
sequence:
# Process different actions based on current mode
- choose:
# In Mode 1 (don't do anything; prevent accidental knob rotation)
- conditions:
- condition: template
value_template: "{{ current_mode == 1 }}"
alias: In Mode 1 (Power)
sequence: [ ]
# In Mode 2 (Brightness)
- conditions:
- condition: template
value_template: "{{ current_mode == 2 }}"
alias: In Mode 2 (Brightness)
sequence:
- service: input_number.set_value
entity_id: !input brightness_tracker
data:
value: "{{ next_brightness }}"
alias: Update brightness tracker
- service: light.turn_on
data:
brightness: "{{ states(brightness_tracker) | int }}"
target:
entity_id: !input light
alias: Change light brightness
# In Mode 4 (Hue)
- conditions:
- condition: template
value_template: "{{ current_mode == 4 }}"
alias: In Mode 3 (Hue)
sequence:
- service: input_number.set_value
entity_id: !input hue_tracker
data:
value: "{{ next_hue }}"
alias: Update hue tracker
- service: light.turn_on
data:
kelvin: "{{ states(hue_tracker) | int }}"
target:
entity_id: !input light
alias: Change light hue
# In Mode 3 (Color)
- conditions:
- condition: template
value_template: "{{ current_mode == 3 }}"
alias: In Mode 4 (Color)
sequence:
- service: input_number.set_value
entity_id: !input color_tracker
data:
value: "{{ next_color }}"
alias: Update color tracker
- service: light.turn_on
data:
# Calculate RGB codes based on 0-1535 index (max 2 channels, one always off)
rgb_color: >
{%- set r = 0 -%}
{%- set g = 0 -%}
{%- set b = 0 -%}
{%- set index = states(color_tracker) | int -%}
{%- if index > 0 and index <= 256 -%}
{%- set r = 255 -%}
{%- set g = index -%}
{%- set b = 0 -%}
{%- elif index > 256 and index <= 512 -%}
{%- set r = 512 - index -%}
{%- set g = 255 -%}
{%- set b = 0 -%}
{%- elif index > 512 and index <= 768 -%}
{%- set r = 0 -%}
{%- set g = 255 -%}
{%- set b = index - 512 -%}
{%- elif index > 768 and index <= 1024 -%}
{%- set r = 0 -%}
{%- set g = 1024 - index -%}
{%- set b = 255 -%}
{%- elif index > 1024 and index <= 1280 -%}
{%- set r = index - 1024 -%}
{%- set g = 0 -%}
{%- set b = 255 -%}
{%- elif index > 1280 and index <= 1536 -%}
{%- set r = 255 -%}
{%- set g = 0 -%}
{%- set b = 1536 - index -%}
{%- endif -%}
{%- set r = r | string -%}
{%- set g = g | string -%}
{%- set b = b | string -%}
{{ r + "," + g + "," + b }}
target:
entity_id: !input light
alias: Change light color
alias: Determine action based on mode
# If event was a dial button short push
- conditions:
- condition: template
value_template: "{{ single_pressed }}"
sequence:
# Change mode (cycling back if reached the end)
- service: input_number.set_value
entity_id: !input mode_tracker
data:
value: "{{ next_mode }}"
alias: Switch to next mode
# If event was a dial button long press
- conditions:
- condition: template
value_template: "{{ double_pressed }}"
sequence:
# Toggle light power
- service: light.toggle
data: { }
target:
entity_id: !input light
alias: Toggle light power
When using the blueprint I get the same error, I tried your blueprint with the edits but nothing seems to be working… any ideas how I can fix this, im using the rotary knob through Z2M
Update: Changed the knob naming field to the device name without using capital letters, this made the whole system work, I also changed the single press to toggle the lights and the hold function to switch modes, this makes more sense to my family members who will be using the controller, this prevents accidental mode switching.
Hmm.
Yes unfortunately having the same issues regarding the unknown entity and can’t seem to work out a fix for it. Shame as the YT vid looked great.
Ah well, back to the drawing board.
Hello,
Would you mind sharing your edited blueprint ?
I tried everything to my understanding but I can’t even get a trace on the automation which would help me to debug it. I tried to fix set the state of the knob action entity but it didn’t even work too. So I’m guessing the automation do not succeed to read the entity properly but I can’t understand why.
Here is my automation:
alias: test
description: ""
use_blueprint:
path: nwithan8/ers_rotary_dial_light_control_z2m.yaml
input:
light: light.lb2_bedroom
dial: sensor.klb_bedroom_action
knob: klb-bedroom
mode_tracker: input_number.dial_mode_tracker
color_tracker: input_number.dial_color_tracker
hue_tracker: input_number.dial_hue_tracker
brightness_tracker: input_number.dial_brightness_tracker
The blueprint has been updated with @chelule code above.
Thank you to anyone willing to help, I’m a bit lost on this one.
Okay got it to work, I etited the behavior a little:
Everything should be working by now using the knob action entity.
blueprint:
name: rotary
description: >
Control light brightness, hue and color with an ERS rotary dial.
Device needs to be in COMMAND mode (triple-press the button to switch modes).
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 you wish to use to control the light
selector:
entity:
filter:
integration: mqtt
mode_tracker:
name: Mode tracker
description: An input number helper to store the current mode in (1-4)
selector:
entity:
filter:
domain: input_number
color_tracker:
name: Color tracker
description: An input number helper to store the current RGB value in (0-1535)
selector:
entity:
filter:
domain: input_number
hue_tracker:
name: Hue tracker
description: An input number helper to store the current hue in (2000-6500)
selector:
entity:
filter:
domain: input_number
brightness_tracker:
name: Brightness tracker
description: An input number helper to store the current brightness in (0-255)
selector:
entity:
filter:
domain: input_number
# Queued, to ignore non-matched events but capture existing ones
mode: queued
max: 20
max_exceeded: silent
trigger:
- platform: state
entity_id: !input dial
not_to: ""
- platform: state
entity_id: !input dial
id: inactive
to:
for:
minutes: 3
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"
dial_topic: "{{ base_topic }}/{{ device_attr(dial, 'name') }}/action"
# Ref: https://community.home-assistant.io/t/zigbee2mqtt-tuya-moes-smart-knob-ers-10tzbvk-aa/419989/26
command: "{{ trigger.to_state.state }}"
single_pressed: "{{ command == 'toggle' }}"
double_pressed: "{{ command == 'hue_move' }}"
rotated: "{{ command in ['brightness_step_up', 'brightness_step_down']}}"
positive: "{{ command in ['brightness_step_up'] }}"
press_rotated_up: "{{ command in ['color_temperature_step_up'] }}"
press_rotated_down: "{{ command in ['color_temperature_step_down'] }}"
step_size: "{{ trigger.to_state.attributes.action_step_size }}"
# How many steps to go full rotation (min 13 per step * 20 steps per full rotation)
full_rotate_step_count: "{{ 13 * 20 | int }}"
current_mode: "{{ states(mode_tracker) | int }}"
min_mode: "{{ state_attr(mode_tracker, 'min') | int }}"
max_mode: "{{ state_attr(mode_tracker, 'max') | int }}"
# always increment, looping
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 }}"
max_hue: "{{ state_attr(hue_tracker, 'max') | int }}"
# How many steps to go full min-max spectrum
hue_steps: "{{ full_rotate_step_count * 2 | int }}"
hue_delta: "{{ (step_size | float(0) / hue_steps) * (max_hue - min_hue) }}"
# don't loop when reached max or min
next_hue: >
{%- set val = states(hue_tracker) | float(0) -%}
{%- set delta = hue_delta -%}
{%- if not positive -%}
{%- set delta = delta * -1 -%}
{%- endif -%}
{%- set val = val + delta | int -%}
{%- if positive and val > max_hue -%}
{%- set val = max_hue -%}
{%- elif not positive and val < min_hue -%}
{%- set val = min_hue -%}
{%- endif -%}
{{ val | int }}
min_brightness: "{{ state_attr(brightness_tracker, 'min') | int }}"
max_brightness: "{{ state_attr(brightness_tracker, 'max') | int }}"
# How many steps to go full min-max spectrum
brightness_steps: "{{ full_rotate_step_count * 2 | int }}"
brightness_delta: "{{ (step_size | float(0) / brightness_steps) * (max_brightness - min_brightness) }}"
# don't loop when reached max or min
next_brightness: >
{%- set val = states(brightness_tracker) | float(0) -%}
{%- set delta = brightness_delta -%}
{%- if not positive -%}
{%- set delta = delta * -1 -%}
{%- endif -%}
{%- set val = val + delta | int -%}
{%- if positive and val > max_brightness -%}
{%- set val = max_brightness -%}
{%- elif not positive and val < min_brightness -%}
{%- set val = min_brightness -%}
{%- endif -%}
{{ val | int }}
min_color: "{{ state_attr(color_tracker, 'min') | int }}"
max_color: "{{ state_attr(color_tracker, 'max') | int }}"
# How many steps to go full min-max spectrum
color_steps: "{{ full_rotate_step_count * 3 | int }}"
color_delta: "{{ (step_size | float(0) / color_steps) * (max_color - min_color) }}"
# loop when reached max or min
next_color: >
{%- set val = states(color_tracker) | float(0) -%}
{%- set delta = color_delta -%}
{%- if not positive -%}
{%- set delta = delta * -1 -%}
{%- endif -%}
{%- set val = val + delta | int -%}
{%- if positive and val > max_color -%}
{%- set val = val % max_color -%}
{%- elif not positive and val < min_color -%}
{%- set diff = min_color - val -%}
{%- set val = max_color - (diff % max_color) -%}
{%- endif -%}
{{ val | int }}
# Process current event
- choose:
# Verify that the dial is the one that triggered the event
- conditions:
- "{{ trigger.payload != ''}}"
#- "{{ trigger.topic == dial_topic }}"
sequence:
- choose:
# If event was a dial turn
- conditions:
- condition: template
value_template: "{{ rotated }}"
alias: Dial turned (0 for right, 1 for left)
sequence:
# Process different actions based on current mode
- choose:
# In Mode 1 (don't do anything; prevent accidental knob rotation)
- conditions:
- condition: template
value_template: "{{ current_mode == 1 }}"
alias: In Mode 1 (Power)
sequence: []
# In Mode 2 (Brightness)
- conditions:
- condition: template
value_template: "{{ current_mode == 2 }}"
alias: In Mode 2 (Brightness)
sequence:
- service: input_number.set_value
entity_id: !input brightness_tracker
data:
value: "{{ next_brightness }}"
alias: Update brightness tracker
- service: light.turn_on
data:
brightness: "{{ states(brightness_tracker) | int }}"
target:
entity_id: !input light
alias: Change light brightness
# In Mode 3 (Color)
- conditions:
- condition: template
value_template: "{{ current_mode == 3 }}"
alias: In Mode 3 (Color)
sequence:
- service: input_number.set_value
entity_id: !input color_tracker
data:
value: "{{ next_color }}"
alias: Update color tracker
- service: light.turn_on
data:
# Calculate RGB codes based on 0-1535 index (max 2 channels, one always off)
rgb_color: >
{%- set r = 0 -%}
{%- set g = 0 -%}
{%- set b = 0 -%}
{%- set index = states(color_tracker) | int -%}
{%- if index > 0 and index <= 256 -%}
{%- set r = 255 -%}
{%- set g = index -%}
{%- set b = 0 -%}
{%- elif index > 256 and index <= 512 -%}
{%- set r = 512 - index -%}
{%- set g = 255 -%}
{%- set b = 0 -%}
{%- elif index > 512 and index <= 768 -%}
{%- set r = 0 -%}
{%- set g = 255 -%}
{%- set b = index - 512 -%}
{%- elif index > 768 and index <= 1024 -%}
{%- set r = 0 -%}
{%- set g = 1024 - index -%}
{%- set b = 255 -%}
{%- elif index > 1024 and index <= 1280 -%}
{%- set r = index - 1024 -%}
{%- set g = 0 -%}
{%- set b = 255 -%}
{%- elif index > 1280 and index <= 1536 -%}
{%- set r = 255 -%}
{%- set g = 0 -%}
{%- set b = 1536 - index -%}
{%- endif -%}
{%- set r = r | string -%}
{%- set g = g | string -%}
{%- set b = b | string -%}
{{ r + "," + g + "," + b }}
target:
entity_id: !input light
alias: Change light color
# In Mode 4 (Hue)
- conditions:
- condition: template
value_template: "{{ current_mode == 4 }}"
alias: In Mode 4 (Hue)
sequence:
- service: input_number.set_value
entity_id: !input hue_tracker
data:
value: "{{ next_hue }}"
alias: Update hue tracker
- service: light.turn_on
data:
kelvin: "{{ states(hue_tracker) | int }}"
target:
entity_id: !input light
alias: Change light hue
alias: Determine action based on mode
# If event was a dial button short push
- conditions:
- condition: template
value_template: "{{ double_pressed }}"
sequence:
# Change mode (cycling back if reached the end)
- service: input_number.set_value
entity_id: !input mode_tracker
data:
value: "{{ next_mode }}"
alias: Switch to next mode
# If event was a dial button long press
- conditions:
- condition: template
value_template: "{{ single_pressed }}"
sequence:
# Toggle light power
- service: light.toggle
data: {}
target:
entity_id: !input light
alias: Toggle light power
# If event was a dial button press + rotate right
# Select customized light config
- conditions:
- condition: template
value_template: "{{ press_rotated_up }}"
sequence:
# Toggle light power
- service: light.toggle
data:
brightness: "{{ states(brightness_tracker) | int }}"
kelvin: "{{ states(hue_tracker) | int }}"
color: "{{ states(color_tracker) | int }}"
target:
entity_id: !input light
alias: Toggle light power
# If event was a dial button press + rotate left
# Select default profile
- conditions:
- condition: template
value_template: "{{ press_rotated_down }}"
sequence:
# Toggle light power
- service: light.toggle
data:
kelvin: 2000
brightness: 255
target:
entity_id: !input light
alias: Toggle light power
# Reset to state 1 if button inactive for 3 minutes
- conditions:
condition: trigger
id: inactive
sequence:
- service: input_number.set_value
entity_id: !input mode_tracker
data:
value: "2"
I will probably make another blueprint from this one, thank for your work and inspiration.
Hi there, I’m getting this error. What am I missing? Sorry I’m a noob who only relies on youtube videos lol
hi I tried your blueprint and all it does is on and off. What could be the problem?
Tried both, ZHA and Zigbee2MQTT but none worked! ZHA nothing happens. Zigbee2MQTT the BP doesnt save. I get the error:
“Message malformed: Unknown entity registry entry 093db2abe9da681067b3835b4bbe70eb”
Same with my installation!
I have the same problem here
Hello Nate (@nwithan8 )
Thank you very much for this BluePrint…
Like some of us, I have the same issue related to device ID.
Do you have any idea/suggestion to debug it?
Thanks in advance
Olivier
Hi,
Did someone managed to find a solution for the “Message malformed: Unknown entity registry entry 3f54bf4ca3825e82d62ae23dc093a929” error?
Looks like some nice mods to an already cool project. I was excited to find this stuff after picking up one of these knobs, and plan to do some testing this week.
I was just thinking, would it not be a good feature to have a mode to jump between a list of scenes as well? It seems like it would be a time-saver and a handy feature for many people. Personally, I have a few color setups in each room that I stick to, and I’m unlikely to set all of my lights and LED strips in a room to the same color. Sorry if it’s a dumb idea – just brainstorming.
Thanks
EDIT: Yep. Doesn’t even work. Bummer.