Setting up a hue cycler script for RGB lights

Hi all!

I’m trying to set up a script which would slowly change the color of my RGB light bulbs by cycle through a ‘hue wheel’.

I was trying with the following:

alias: Hue cycler
mode: single
sequence:
  - variables:
      hue: 0
  - repeat:
      count: 10
      sequence:
        - service: light.turn_on
          target:
            device_id: 03cfe3b824641e6e54d9c9679b14c9b8
          data:
            hs_color:
              - "{{ hue }}"
              - 100
        - variables:
            hue: "{{ hue + 36 }}"
        - delay:
            hours: 0
            minutes: 0
            seconds: 1
            milliseconds: 0

This is just for testing, I was expecting that my lights will start from red, then in each second a hue change happens, and after 10 steps I’d get back to red (in the real script this would be much slower and the increment would be much smaller).

My issue is that the hue variable seemingly gets incremented once, in the 1st iteration and even this hue change is not showing on my lightbulb; it stays red.

Trace of the call service step:

Changed variables in the variable update step within the repeat block (I can’t upload more than one medi)
Iteration 1
hue: 36

Iteration 2
hue: 36

Iteration 3
hue: 36

I’m incrementing the variable based on this:

What am I missing? Thanks in advance.

It’s due to the variable’s scope.

You have a hue variable defined before the repeat. The hue variable defined within the repeat, is not changing the value of the hue variable outside of the repeat. It’s effectively a separate variable.

Reference

Scope of variables

Solved it. It is a bit disgusting, because I’m not familiar with variables and loops in HA, so the only way I could create an ‘infinite’ loop is by providing an absurdly big number (given the set delay) in the repeat count. I’m open to hear more elegant solutions.

alias: Hue cycler
mode: single
sequence:
  - variables:
      hue_increment: 2
    enabled: true
  - repeat:
      sequence:
        - service: light.turn_on
          target:
            device_id: 03cfe3b824641e6e54d9c9679b14c9b8
          data:
            hs_color:
              - "{{ (hue_increment * (repeat.index - 1) ) % 360 | float }}"
              - 100
        - delay:
            hours: 0
            minutes: 0
            seconds: 5
            milliseconds: 0
      count: 20000000000

I’ll toggle this script for a specific action of one of my buttons.

Refer to the link I posted above for an explanation of variable scope. It applies not only to a variable used in a repeat but also to choose, if, etc.

index is one of the properties of the repeat loop variable present in every repeat loop style. Meaning it isn’t limited to just repeat count but is also available in others such as repeat until.

In other words, you can check the value of repeat.index in until (or while) and have it stop iterating when a certain value is reached (rather than using count with a large number).

Reference

Repeat loop variable


NOTE

For future reference, if you use float and the supplied value is non-numeric it will result in an error message. That’s unlikely to happen in this case because the result of the calculation will always be a number.

For cases where there’s a possibility that the result can be non-numeric, supply float with a default value. For example, float(0) will use 0.

Thank you for your answer! I’ll try these. Right now I’m trying to determine the threshold for the maximum hue increment which I do not perceive as an instantaneous color change, so I can set extended delays while keeping duration of a full cycle constant.

Does it have any added value to have fewer, longer delays rather than many short ones (I’m thinking about CPU utilization, etc.)? I’m not familiar with the underlying behaviour of HA. When a script is running and a delay is in place, the thread is put to sleep, right? So a running script won’t block HA from ‘listening to’ other triggers, or running other scripts, right?

Correct; a running script/automation doesn’t block anything else from running concurrently.

What you should be aware of is that any script/automation that is busy executing its actions (like waiting for a delay to expire or for something to happen in a wait_template or wait_for_trigger) is terminated when Home Assistant is restarted and doesn’t resume on startup from where it left off.

1 Like

You may wish to consider creating a native Hue scene that cycles through all colors. In Home Assistant you would simply turn on the native scene and the bulb takes care of the rest. More efficient than sending a stream of discrete commands to change color.

1 Like