Link to Home Assistant forum post.
This script creates a custom effect.
Zwave 1.4 & Open Zwave
Script
lzw45_custom_effect:
alias: LZW45 Custom Effect
description: Sets the custom effects for the Inovelli LZW45 LED Strip
mode: restart
fields:
service:
description:
(required) The name of the service.
OpenZwave (Beta) -> 'ozw.set_config_parameter'
OpenZwave (1.4) -> 'zwave.set_config_parameter'
Zwave JS -> 'zwave_js.set_config_parameter'
example: ozw.set_config_parameter
lzw45:
description: (required) The entity_id for the lzw45 LED Strip.
example: light.lzw45_light_strip_level
colors:
description: (required) A list of colors, (1 to 4 colors). Color choices are off, 2700k, 4500k, 6500k, red, orange, yellow, yellow-green, green, spring-green, cyan, azure, blue, violet, magenta, and random.
example: "[ 'red', 'orange', 'yellow', 'off' ]"
effects:
description: (required) A list of colors (1 to 4 effects). Color choices are fade, fade-blend, flash, chase, and chase-blend.
example: "[ 'fade', 'fade-blend', 'fade', 'chase' ]"
brightness_pcts:
description: (optional) A list of brightness percents, 0 - 99. Defaults to 99 if omitted.
example: "[ 99, 99, 99, 99 ]"
duration_units:
description: (required) The units of the duration. Choices are 100ms, seconds, minutes, hours.
example: 100ms
durations:
description: (required) A list of durations (1-60).
example: "[ 10, 10, 10, 10 ]"
finish_behavior:
description: (optional) The behavior when the effect reaches the max number of iterations. Choices are off, previous-color, last-color-in-program. Default is previous-color.
example: previous-color
iterations:
description: (optional) The number of times the custom effect repeats (1-254). 255 is forever. Default is 255.
example: 255
variables:
service: >
{{ service | default('ozw.set_config_parameter') }}
node_id: >
{%- if lzw45 is not defined %}
0
{%- else %}
{%- set node_id = state_attr(lzw45, 'node_id') %}
{{ node_id if node_id else 0 }}
{%- endif %}
transitions: >
{%- set ns = namespace(counts=[]) %}
{%- for item in [ colors, effects, brightness_pcts, durations ] %}
{%- set ns.counts = ns.counts + [ item | length ] %}
{%- endfor %}
{{ ns.counts | min }}
levels: >
{%- set levels = brightness_pcts | default([]) %}
{%- if not levels %}
{{ [ 99 ] * transitions }}
{%- else %}
{%- set ns = namespace(levels = []) %}
{%- for i in range(transitions) %}
{%- set pct = levels[i] | int %}
{%- set pct = pct if pct >= 0 else 0 %}
{%- set pct = pct if pct <= 99 else 99 %}
{%- set ns.levels = ns.levels + [ pct ] %}
{%- endfor %}
{{ ns.levels }}
{%- endif %}
parameter22: >
{%- macro byte(color, effect) %}
{%- set colors = [
'off',
'2700k',
'4500k',
'6500k',
'red',
'orange',
'yellow',
'yellow green',
'green',
'spring green',
'cyan',
'azure',
'blue',
'violet',
'magenta',
'random'
] %}
{% set effects = [
'fade',
'fade-blend',
'flash',
'chase',
'chase-blend'
] %}
{%- if color in colors and effect in effects %}
{%- set ci = colors.index(color) %}
{%- set ei = effects.index(effect) %}
{{- '{0:05b}{1:03b}'.format(ci, ei) }}
{%- else %}
{{- '00000000' }}
{%- endif %}
{%- endmacro %}
{%- set ns = namespace(bytes=[]) %}
{%- for i in range(transitions) %}
{%- set ns.bytes = ns.bytes + [ byte(colors[i], effects[i]) | int('', 2) * 2**(i * 8) ] %}
{%- endfor %}
{{ ns.bytes | sum }}
parameter23: >
{%- set ns = namespace(bytes=[]) %}
{%- for i in range(transitions) %}
{%- set ns.bytes = ns.bytes + [ '{0:08b}'.format(levels[i]) | int('', 2) * 2**(i * 8) ] %}
{%- endfor %}
{{ ns.bytes | sum }}
parameter24: >
{%- set ns = namespace(bytes=[]) %}
{%- for i in range(transitions) %}
{%- set duration = durations[i] | int %}
{%- set duration = duration if duration >= 1 else 1 %}
{%- set duration = duration if duration <= 60 else 60 %}
{%- set ns.bytes = ns.bytes + [ '{0:08b}'.format(duration) | int('', 2) * 2**(i * 8) ] %}
{%- endfor %}
{{ ns.bytes | sum }}
parameter30: >
{%- set iterations = iterations | default(255) | int %}
{%- set iterations = iterations if iterations >= 0 else 0 %}
{%- set byte1 = iterations if iterations <= 255 else 255 %}
{%- set behaviors = [ 'off', 'previous-color', 'last-color-in-program' ] %}
{%- set units = ['100ms', 'seconds', 'minutes', 'hours'] %}
{%- set byte2 = behaviors.index(behavior) if behavior in behaviors else 1 %}
{%- set byte3 = units.index(duration_units) if duration_units in units else 0 %}
{{ '{0:08b}{1:08b}{2:08b}'.format(byte3, byte2, byte1) | int('', 2) }}
sequence:
- condition: template
value_template: "{{ node_id != 0 and transitions > 0 }}"
- service: "{{ service }}"
data:
node_id: "{{ node_id }}"
parameter: 22
value: "{{ parameter22 }}"
- service: "{{ service }}"
data:
node_id: "{{ node_id }}"
parameter: 23
value: "{{ parameter23 }}"
- service: "{{ service }}"
data:
node_id: "{{ node_id }}"
parameter: 24
value: "{{ parameter24 }}"
- service: "{{ service }}"
data:
node_id: "{{ node_id }}"
parameter: 30
value: "{{ parameter30 }}"
Service
service: script.lzw45_custom_effect
data:
service: ozw.set_config_parameter
lzw45: light.lzw45_light_strip_level
colors:
- red
- orange
- yellow
- orange
effects:
- fade-blend
- fade-blend
- fade-blend
- fade-blend
brightness_pcts:
- 99
- 99
- 99
- 99
duration_units: 100ms
durations:
- 10
- 10
- 10
- 10
finish_behavior: previous-color
iterations: 255
ZwaveJS
Currently there is a bug (Home Assistant side) with parameter 23 that is under investigation. This will error out on param 23!
EDIT: The investigation found an issue with the config file in my system, it should work for everyone else. If it does not, there may be an issue with caching in ZwaveJS2MQTT. Please report any issues that you find.
Script
lzw45_custom_effect_zwave_js:
alias: LZW45 Custom Effect
description: Sets the custom effects for the Inovelli LZW45 LED Strip
mode: restart
fields:
lzw45:
description: (required) The entity_id for the lzw45 LED Strip.
example: light.lzw45_light_strip_level
colors:
description: (required) A list of colors, (1 to 4 colors). Color choices are off, 2700k, 4500k, 6500k, red, orange, yellow, yellow-green, green, spring-green, cyan, azure, blue, violet, magenta, and random.
example: "[ 'red', 'orange', 'yellow', 'off' ]"
effects:
description: (required) A list of colors (1 to 4 effects). Color choices are fade, fade-blend, flash, chase, and chase-blend.
example: "[ 'fade', 'fade-blend', 'fade', 'chase' ]"
brightness_pcts:
description: (optional) A list of brightness percents, 0 - 99. Defaults to 99 if omitted.
example: "[ 99, 99, 99, 99 ]"
duration_units:
description: (required) The units of the duration. Choices are 100ms, seconds, minutes, hours.
example: 100ms
durations:
description: (required) A list of durations (1-60).
example: "[ 10, 10, 10, 10 ]"
finish_behavior:
description: (optional) The behavior when the effect reaches the max number of iterations. Choices are off, previous-color, last-color-in-program. Default is previous-color.
example: previous-color
iterations:
description: (optional) The number of times the custom effect repeats (1-254). 255 is forever. Default is 255.
example: 255
variables:
service: >
{{ service | default('ozw.set_config_parameter') }}
node_id: >
{%- if lzw45 is not defined and node is not defined %}
0
{%- else %}
{%- if node is not defined %}
{%- set node_id = state_attr(lzw45, 'node_id') %}
{%- else %}
{%- set node_id = node %}
{%- endif %}
{{ node_id if node_id else 0 }}
{%- endif %}
transitions: >
{%- set ns = namespace(counts=[]) %}
{%- for item in [ colors, effects, brightness_pcts, durations ] %}
{%- set ns.counts = ns.counts + [ item | length ] %}
{%- endfor %}
{{ ns.counts | min }}
levels: >
{%- set levels = brightness_pcts | default([]) %}
{%- if not levels %}
{{ [ 99 ] * transitions }}
{%- else %}
{%- set ns = namespace(levels = []) %}
{%- for i in range(transitions) %}
{%- set pct = levels[i] | int %}
{%- set pct = pct if pct >= 0 else 0 %}
{%- set pct = pct if pct <= 99 else 99 %}
{%- set ns.levels = ns.levels + [ pct ] %}
{%- endfor %}
{{ ns.levels }}
{%- endif %}
parameter22: >
{%- macro byte(color, effect) %}
{%- set colors = [
'off',
'2700k',
'4500k',
'6500k',
'red',
'orange',
'yellow',
'yellow green',
'green',
'spring green',
'cyan',
'azure',
'blue',
'violet',
'magenta',
'random'
] %}
{% set effects = [
'fade',
'fade-blend',
'flash',
'chase',
'chase-blend'
] %}
{%- if color in colors and effect in effects %}
{%- set ci = colors.index(color) %}
{%- set ei = effects.index(effect) %}
{{- '{0:05b}{1:03b}'.format(ci, ei) }}
{%- else %}
{{- '00000000' }}
{%- endif %}
{%- endmacro %}
{%- set ns = namespace(bytes=[]) %}
{%- for i in range(transitions) %}
{%- set ns.bytes = ns.bytes + [ byte(colors[i], effects[i]) | int('', 2) * 2**(i * 8) ] %}
{%- endfor %}
{{ ns.bytes | sum }}
parameter23: >
{%- set ns = namespace(bytes=[]) %}
{%- for i in range(transitions) %}
{%- set ns.bytes = ns.bytes + [ '{0:08b}'.format(levels[i]) | int('', 2) * 2**(i * 8) ] %}
{%- endfor %}
{{ ns.bytes | sum }}
parameter24: >
{%- set ns = namespace(bytes=[]) %}
{%- for i in range(transitions) %}
{%- set duration = durations[i] | int %}
{%- set duration = duration if duration >= 1 else 1 %}
{%- set duration = duration if duration <= 60 else 60 %}
{%- set ns.bytes = ns.bytes + [ '{0:08b}'.format(duration) | int('', 2) * 2**(i * 8) ] %}
{%- endfor %}
{{ ns.bytes | sum }}
parameter30: >
{%- set iterations = iterations | default(255) | int %}
{%- set iterations = iterations if iterations >= 0 else 0 %}
{%- set byte1 = iterations if iterations <= 255 else 255 %}
{%- set behaviors = [ 'off', 'previous-color', 'last-color-in-program' ] %}
{%- set units = ['100ms', 'seconds', 'minutes', 'hours'] %}
{%- set byte2 = behaviors.index(behavior) if behavior in behaviors else 1 %}
{%- set byte3 = units.index(duration_units) if duration_units in units else 0 %}
{{ '{0:08b}{1:08b}{2:08b}'.format(byte3, byte2, byte1) | int('', 2) }}
sequence:
- condition: template
value_template: "{{ lzw45 is defined and transitions > 0 }}"
- service: zwave_js.bulk_set_partial_config_parameters
target:
entity_id: "{{ lzw45 }}"
data:
parameter: 22
value: "{{ parameter22 }}"
- service: zwave_js.bulk_set_partial_config_parameters
target:
entity_id: "{{ lzw45 }}"
data:
parameter: 23
value: "{{ parameter23 }}"
- service: zwave_js.bulk_set_partial_config_parameters
target:
entity_id: "{{ lzw45 }}"
data:
parameter: 24
value: "{{ parameter24 }}"
- service: zwave_js.bulk_set_partial_config_parameters
target:
entity_id: "{{ lzw45 }}"
data:
parameter: 30
value: "{{ parameter30 }}"
Service
service: script.lzw45_custom_effect
data:
lzw45: light.lzw45_light_strip_level
colors:
- red
- orange
- yellow
- orange
effects:
- fade-blend
- fade-blend
- fade-blend
- fade-blend
brightness_pcts:
- 99
- 99
- 99
- 99
duration_units: 100ms
durations:
- 10
- 10
- 10
- 10
finish_behavior: previous-color
iterations: 255