"Fading" random colour changes

Just sharing this since I couldn’t find anything similar so wrote my own!

Little script blueprint you can then run in a repeat loop within an automation to randomly change xy colour by small values:

blueprint:
  name: Fading Hue/Saturation Changes
  description: Gradually change light colour
  domain: script
  input:
    entities:
      name: Entities
      description: "Which entities to control. Input as YAML list"
      selector:
        object:
    max_value_hue:
      name: Max Hue Value
      description: Max Hue Value
      default: 360.0
      selector:
        number:
          min: 0.0
          max: 360.0
          step: 0.001
          mode: box
    min_value_hue:
      name: Min Hue Value
      description: Min Hue Value
      default: 0.001
      selector:
        number:
          min: 0.0
          max: 360.0
          step: 0.001
          mode: box
    max_value_sat:
      name: Max Saturation
      description: Max Saturation
      default: 100.0
      selector:
        number:
          min: 0.0
          max: 100.0
          step: 0.001
          mode: box
    min_value_sat:
      name: Min Saturation
      description: Min Saturation
      default: 28
      selector:
        number:
          min: 0.0
          max: 100.0
          step: 0.001
          mode: box
    step_value_hue:
      name: Hue Step value
      description: Step value to change each time - is divided by 1000
      default: 30
      selector:
        number:
          min: 0.0
          max: 1000
          step: 1
          mode: box
    step_value_sat:
      name: Saturation Step value
      description: Step value to change each time - is divided by 1000
      default: 30
      selector:
        number:
          min: 0.0
          max: 1000
          step: 1
          mode: box
    use_negatives:
      name: Use negatives
      description: Use negative value changes
      default: true
      selector:
        boolean:
    default_value_hue:
      name: Default Hue Value
      description: Default Starting Hue Value
      default: 240
      selector:
        number:
          min: 0.0
          max: 360
          step: 0.001
          mode: box
    default_value_sat:
      name: Default Saturation
      description: Default Starting Saturation
      default: 69
      selector:
        number:
          min: 0.0
          max: 100
          step: 0.001
          mode: box
sequence:
  - service: light.turn_on
    data:
      entity_id: '{{ entities }}'
      hs_color: >-
        {% set data = namespace(hs_col=[]) %}

        {% if state_attr(entities|first, 'hs_color') == None %}
          {{ default_colour }}
        {% else %}
          {% for hs in ['hue', 'sat'] %}
            {% if hs == 'hue' %}
              {% set step_value = step_value_hue %}
            {% else %}
              {% set step_value = step_value_sat %}
            {% endif %}
            {% if use_negatives %}
              {% set rand_add = ([(range(0, step_value) | random), 0-(range(0, step_value) | random)] | random) / 1000 %}
            {% else %}
              {% set rand_add = (range(0, step_value) | random) / 1000 %}
            {% endif %}
            {% set cur_hs = state_attr(entities|first, 'hs_color') | list %}
            {% if hs == 'hue' %}
              {% set val = cur_hs[0] %}
              {% set max_value_hs = max_value_hue %}
              {% set min_value_hs = min_value_hue %}
              {% set default_value_hs = default_value_hue %}
            {% else %}
              {% set val = cur_hs[1] %}
              {% set max_value_hs = max_value_sat %}
              {% set min_value_hs = min_value_sat %}
              {% set default_value_hs = default_value_sat %}
            {% endif %}
            {% if float(val) + rand_add <= max_value_hs and float(val) + rand_add > min_value_hs %}
              {% set new_val = float(val) + rand_add %}
            {% else %}
              {% set new_val = default_value_hs %}
            {% endif %}
            {% set data.hs_col = data.hs_col + [new_val] %}
          {% endfor %}
        {% endif %}

        {{ data.hs_col or default_colour or [0, 0] }}
      # brightness_pct: 100
variables:
  entities: !input entities
  max_value_hue: !input max_value_hue
  min_value_hue: !input min_value_hue
  max_value_sat: !input max_value_sat
  min_value_sat: !input min_value_sat
  step_value_hue: !input step_value_hue
  step_value_sat: !input step_value_sat
  use_negatives: !input use_negatives
  default_value_hue: !input default_value_hue
  default_value_sat: !input default_value_sat
  default_colour: [!input default_value_hue, !input default_value_sat]
mode: single

Just ask if you want me to explain anything for your own uses :slight_smile:

Open your Home Assistant instance and show the blueprint import dialog with a specific blueprint pre-filled.

So basically a random rainbow effect?

@sparkydave pretty much, did I miss something already doing this? :slight_smile:

It does try to gradually change the colour instead of random values, the biggest changes are just when it gets to a corner of the XY axis. Maybe I’ll build it into a component so I can add some more logic to it though

Not really. I have some LED downlights flashed with ESPhome and I have an effect in there which creates the same gradual random rainbow.

Ah, don’t use ESPHome and none of my lights support effects so this is what I did :slight_smile:

Why not use the hue wheel instead?
You have a 0-360 hue value and a 0-100 saturation value.
So just use [current hue + step % 360] and you have a gradual changing color with no “corners”.

A list selector is supposed to be available with the next release 2022.4 this week, may be a helpful change…
You can also add

  homeassistant:
    min_version: 2022.04.1

To prevent any questions here if that is not back compatible. I don’t know if it is or it isn’t, but I use that in my Blueprints when I adopt a new feature so people don’t complain it’s broken.

Well aren’t you clever sir :slight_smile: I hadn’t seen that before, thanks! Will play with it next

1 Like

Done :slight_smile: thanks for that!

1 Like