Hi,
I thought I’d share my code to use a hue, saturation and brightness value to set colored lights. The standard interface only supports XY or RGB, not HSV/HSB. I wanted to be able to chose a random hue value and set my colored lights using this hue and fixed saturation and brightness levels.
First I created 3 sliders to control the amount of saturation and brightness levels to be used as well as my preferred transition speed. Second, I created a script with template code to set the lights (actually requires 2 scripts).
1. Input sliders
movie_night_saturation:
name: Color Saturation
initial: 0.3
min: 0
max: 1
step: 0.05
movie_night_brightness:
name: Color Brightness
initial: 0.8
min: 0
max: 1
step: 0.05
movie_night_transition:
name: Transition
initial: 5
min: 0
max: 30
step: 1
2. The scripts.
The script converts HSV / HSB to RGB and passes that to the colored lights interface. The rgb_color property requires a list of 3 colors like [178,245,32] and not strings. Using any template code before the [] wil make the value a string and not a list (the template returns a strings, which prevents us to set the rgb_color this way). In another post I provided a workaround of putting the RGB colors in a string and simply calling another script that parses out the values and sets the color of the lights.
Script 1: convert HSV / HSB to RGB
movie_night_color:
sequence:
- service: script.set_color
data_template:
id: group.living_room_colored_lights
colors: >-
{%- set h = (range(0, 360)|random)/360 %}
{%- set s = states.input_slider.movie_night_saturation.state|float %}
{%- set v = states.input_slider.movie_night_brightness.state|float %}
{%- set i = (h * 6)|int %}
{%- set f = h * 6 - i %}
{%- set p = v * (1 - s) %}
{%- set q = v * (1 - f * s) %}
{%- set t = v * (1 - (1 - f) * s) %}
{%- if i % 6 == 0 %}
{% set r = v %}
{% set g = t %}
{% set b = p %}
{%- elif i % 6 == 1 %}
{% set r = q %}
{% set g = v %}
{% set b = p %}
{%- elif i % 6 == 2 %}
{% set r = p %}
{% set g = v %}
{% set b = t %}
{%- elif i % 6 == 3 %}
{% set r = p %}
{% set g = q %}
{% set b = v %}
{%- elif i % 6 == 4 %}
{% set r = t %}
{% set g = p %}
{% set b = v %}
{%- elif i % 6 == 5 %}
{% set r = v %}
{% set g = p %}
{% set b = q %}
{%- endif %}
{{ (255*r)|round(0) }}, {{ (255*g)|round(0) }}, {{ (255*b)|round(0) }}, {{ (360*h)|int }}
transition: "{{ states.input_slider.movie_night_transition.state|int }}"
(code was modelled after this code)
You notice that this script calls another script (script.set_color) using a parameter called colors (and id and transition for flexibility).
Script 2: setting the lights to color
set_color:
sequence:
- service: light.turn_on
data_template:
entity_id: '{{ id }}'
rgb_color: [ "{{ colors.split(',')[0]|int }}", "{{ colors.split(',')[1]|int }}", "{{ colors.split(',')[2]|int }}" ]
transition: "{{ transition }}"
This script takes the parameter colors and for each RGB value it extracts the value from the string. Because the value of property rgb_color still starts with a [, it remains a list of values that is being passed to the interface.
I know that using XYZ (CIE 1931) is the proper way to go, but requires somewhat complex math to pick a random color and even crazier math to fix the saturation. This was much easier and works like a charm for my use case, and perhaps someone else’s.