Hello, hoping someone can help me figure out why I am getting the error: “Message malformed: expected str for dictionary value @ data[‘device_id’]” when trying to save a blueprint automation. Here is my code in two files:
File 1:
blueprint:
name: Z-Wave Command Queue
description: >
Safely executes Z-Wave commands with proper delays to prevent
overwhelming the Z-Wave network.
domain: script
input:
device_id:
name: Z-Wave Device
description: The Z-Wave device to send commands to
selector:
device:
filter:
model: ZEN32
commands:
name: Commands
description: List of parameter updates to execute
selector:
object:
command_delay:
name: Command Delay
description: Delay between commands in milliseconds
selector:
number:
min: 50
max: 500
unit_of_measurement: ms
step: 10
default: 150
sequence:
- repeat:
for_each: "{{ commands }}"
sequence:
# Execute the Z-Wave command with proper parameters
- device_id: "{{ device_id }}"
domain: zwave_js
type: set_config_parameter
endpoint: "{{ repeat.item.endpoint | default(0) }}"
parameter: "{{ repeat.item.parameter }}"
bitmask: "{{ repeat.item.bitmask | default }}"
subtype: "{{ repeat.item.subtype | default }}"
value: "{{ repeat.item.value }}"
# Add delay between commands (skip delay after last command)
- if:
- condition: template
value_template: "{{ not loop.last }}"
then:
- delay:
milliseconds: "{{ command_delay }}"
FIle 2:
# File: dimmable_room.yaml
# Location: config/blueprints/automation/
blueprint:
name: Dimmable Room Control
description: >
Controls a room with Off/Dim/Max states using multiple scene controllers.
Supports toggling between states and synchronizes LED indicators across
all controllers to prevent Z-Wave network overload.
domain: automation
input:
room_helper:
name: Room Helper
description: The input_select helper tracking room state (must have Off, Dim, Max options)
selector:
entity:
filter:
domain: input_select
scene_max:
name: Max Scene
description: Scene to activate when room is set to Max brightness
selector:
entity:
filter:
domain: scene
scene_dim:
name: Dim Scene
description: Scene to activate when room is set to Dim
selector:
entity:
filter:
domain: scene
scene_off:
name: Off Scene
description: Scene to activate when room is turned Off
selector:
entity:
filter:
domain: scene
light_toggle_controllers:
name: Light Toggle Buttons
description: >
Controllers and buttons that toggle between Max and Off.
For each entry, select the device and specify which button number (1-5).
selector:
device:
filter:
integration: zwave_js
multiple: true
light_toggle_button_numbers:
name: Light Toggle Button Numbers
description: >
Button numbers for Light toggle (1-5), in same order as devices above.
Separate multiple buttons with commas (e.g., "5,5,5").
selector:
text:
default: "5"
dim_toggle_controllers:
name: Dim Toggle Buttons
description: >
Controllers and buttons that toggle between Dim and Max.
For each entry, select the device and specify which button number (1-5).
selector:
device:
filter:
integration: zwave_js
multiple: true
dim_toggle_button_numbers:
name: Dim Toggle Button Numbers
description: >
Button numbers for Dim toggle (1-5), in same order as devices above.
Separate multiple buttons with commas (e.g., "2,2,2").
selector:
text:
default: "2"
command_delay:
name: Command Delay
description: Delay between Z-Wave commands in milliseconds
selector:
number:
min: 100
max: 500
unit_of_measurement: ms
step: 10
default: 150
mode: queued
max: 2
variables:
# Map button numbers to property_key values for triggers
button_map:
"1": "001"
"2": "002"
"3": "003"
"4": "004"
"5": "005"
# Parse the comma-separated button numbers into lists
light_button_numbers: >-
{% set numbers = (light_toggle_button_numbers | string).split(',') %}
{% set parsed = [] %}
{% for num in numbers %}
{% set parsed = parsed + [num | int] %}
{% endfor %}
{{ parsed }}
dim_button_numbers: >-
{% set numbers = (dim_toggle_button_numbers | string).split(',') %}
{% set parsed = [] %}
{% for num in numbers %}
{% set parsed = parsed + [num | int] %}
{% endfor %}
{{ parsed }}
# Automatically determine all controllers that need LED updates
all_controllers: >-
{% set controllers = [] %}
{% for device in light_toggle_controllers %}
{% if device not in controllers %}
{% set controllers = controllers + [device] %}
{% endif %}
{% endfor %}
{% for device in dim_toggle_controllers %}
{% if device not in controllers %}
{% set controllers = controllers + [device] %}
{% endif %}
{% endfor %}
{{ controllers }}
# LED indicator parameters map button numbers to config parameters
led_param_map:
"1": 2
"2": 3
"3": 4
"4": 5
"5": 6
triggers:
# Room helper state change trigger
- id: room_state_change
trigger: state
entity_id: !input room_helper
# Light toggle button triggers (dynamically added for each controller/button pair)
- id: light_toggle_press
trigger: device
device_id: !input light_toggle_controllers
domain: zwave_js
type: event.value_notification.central_scene
property: scene
property_key: >-
{% set controllers = light_toggle_controllers %}
{% set buttons = light_button_numbers %}
{% set idx = trigger.idx | default(0) %}
{% if idx < buttons | length %}
{{ button_map[buttons[idx] | string] }}
{% else %}
"005" # Default to button 5 if mismatch
{% endif %}
endpoint: 0
command_class: 91
value: 0
# Dim toggle button triggers (dynamically added for each controller/button pair)
- id: dim_toggle_press
trigger: device
device_id: !input dim_toggle_controllers
domain: zwave_js
type: event.value_notification.central_scene
property: scene
property_key: >-
{% set controllers = dim_toggle_controllers %}
{% set buttons = dim_button_numbers %}
{% set idx = trigger.idx | default(0) %}
{% if idx < buttons | length %}
{{ button_map[buttons[idx] | string] }}
{% else %}
"002" # Default to button 2 if mismatch
{% endif %}
endpoint: 0
command_class: 91
value: 0
action:
- choose:
# Light toggle button was pressed
- conditions:
- condition: trigger
id: light_toggle_press
sequence:
- if:
- condition: state
entity_id: !input room_helper
state: "Off"
then:
- action: input_select.select_option
target:
entity_id: !input room_helper
data:
option: "Max"
else:
- action: input_select.select_option
target:
entity_id: !input room_helper
data:
option: "Off"
# Dim toggle button was pressed
- conditions:
- condition: trigger
id: dim_toggle_press
sequence:
- if:
- condition: state
entity_id: !input room_helper
state: "Dim"
then:
- action: input_select.select_option
target:
entity_id: !input room_helper
data:
option: "Max"
else:
- action: input_select.select_option
target:
entity_id: !input room_helper
data:
option: "Dim"
# Room state changed
- conditions:
- condition: trigger
id: room_state_change
sequence:
- choose:
# State changed to Max
- conditions:
- condition: template
value_template: "{{ trigger.to_state.state == 'Max' }}"
sequence:
# Activate scene first (high priority)
- action: scene.turn_on
target:
entity_id: !input scene_max
# Update LED indicators on all controllers
- repeat:
for_each: "{{ all_controllers }}"
sequence:
- action: script.zwave_command_queue
data:
device_id: "{{ repeat.item }}"
command_delay: !input command_delay
commands:
# Light toggle button (usually #5) - white
- parameter: 6
subtype: 6 (LED Indicator Color (Relay)) on endpoint 0
value: 0
# Dim toggle button (usually #2) - off
- parameter: 3
subtype: 3 (LED Indicator (Button 2)) on endpoint 0
value: 2
# State changed to Dim
- conditions:
- condition: template
value_template: "{{ trigger.to_state.state == 'Dim' }}"
sequence:
# Activate scene first (high priority)
- action: scene.turn_on
target:
entity_id: !input scene_dim
# Update LED indicators on all controllers
- repeat:
for_each: "{{ all_controllers }}"
sequence:
- action: script.zwave_command_queue
data:
device_id: "{{ repeat.item }}"
command_delay: !input command_delay
commands:
# Dim toggle button (usually #2) - on
- parameter: 3
subtype: 3 (LED Indicator (Button 2)) on endpoint 0
value: 3
# Light toggle button (usually #5) - white
- parameter: 6
subtype: 6 (LED Indicator Color (Relay)) on endpoint 0
value: 0
# State changed to Off
- conditions:
- condition: template
value_template: "{{ trigger.to_state.state == 'Off' }}"
sequence:
# Activate scene first (high priority)
- action: scene.turn_on
target:
entity_id: !input scene_off
# Update LED indicators on all controllers
- repeat:
for_each: "{{ all_controllers }}"
sequence:
- action: script.zwave_command_queue
data:
device_id: "{{ repeat.item }}"
command_delay: !input command_delay
commands:
# Light toggle button (usually #5) - blue
- parameter: 6
subtype: 6 (LED Indicator Color (Relay)) on endpoint 0
value: 1
# Dim toggle button (usually #2) - off
- parameter: 3
subtype: 3 (LED Indicator (Button 2)) on endpoint 0
value: 2
1 post - 1 participant