This allows you to program up to 4 custom transitions for the Inovelli LED Strip instead of using the pixel effects or the quick strip effects.
Here’s the 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 }}"
Feel free to ask questions about the script.
This is an example service call that blends red -> orange -> yellow -> orange every second indefinitely.
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