Fiddling with Hue and Phue

Posted on di 29 december 2020 in home_automation

Somewhere in 2019 I bought some color capable Hue lights and installed them in the living room. The SO was not impressed. So for most of the time they were just used as normal dimmable lightning. For a brief moment I tried to do some manipulation with python but as soon as I saw this worked fine, the script was 'shelved'

With the X-mas downtime I figured it was a good time to try something. More or less as a practive project for the 'real' work.

It ended up being fairly easy. Lots of people have done this, the module appears to be solid and usable.

After just a small time fiddling, I came up with hue_xmaslights.py which I run from a raspberry pi. It just runs forever, so you have to end it with an interrupt and set the lights to normal with your phone app or switches.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#!/usr/bin/python3
from phue import Bridge
import time

# copy-paste code taken for a random web search
def rgb_to_xy(red, green, blue):
    # Conversion of RGB colors to CIE1931 XY colors
    # Formulas implemented from: https://gist.github.com/popcorn245/30afa0f98eea1c2fd34d
    #Args:
    #    red (float): a number between 0.0 and 1.0 representing red in the RGB space
    #    green (float): a number between 0.0 and 1.0 representing green in the RGB space
    #    blue (float): a number between 0.0 and 1.0 representing blue in the RGB space
    #Returns:
    #    xy (list): x and y
    #

    # gamma correction
    red = pow((red + 0.055) / (1.0 + 0.055), 2.4) if red > 0.04045 else (red / 12.92)
    green = pow((green + 0.055) / (1.0 + 0.055), 2.4) if green > 0.04045 else (green / 12.92)
    blue =  pow((blue + 0.055) / (1.0 + 0.055), 2.4) if blue > 0.04045 else (blue / 12.92)

    # convert rgb to xyz
    x = red * 0.649926 + green * 0.103455 + blue * 0.197109
    y = red * 0.234327 + green * 0.743075 + blue * 0.022598
    z = green * 0.053077 + blue * 1.035763

    # convert xyz to xy
    x = x / (x + y + z)
    y = y / (x + y + z)

    # TODO check color gamut if known

    return [x, y]

# connect to the hue bridge
b = Bridge('192.168.XX.YY')

# If the app is not registered and the button is not pressed, press the button and call connect() (this only needs to be run a single time)
b.connect()


# some simple mapping of human readable names to color values
green = rgb_to_xy(0.0, 1.0, 0.0)
red = rgb_to_xy(1.0, 0.0, 0.0)
white = rgb_to_xy(1.0,1.0,1.0)


# just flip the colors of the four lights in the living room 
# from red to green
while True:

  b.set_light(10, 'xy', green)
  b.set_light(11, 'xy', red)
  b.set_light(4, 'xy', red)
  b.set_light(7, 'xy', green)

  time.sleep(2)

  b.set_light(10, 'xy', red)
  b.set_light(11, 'xy', green)
  b.set_light(4, 'xy', green)
  b.set_light(7, 'xy', red)

  time.sleep(2)

This was fun and easy. And the SO is still not impressed. But our youngest loves it. I also made a small 'disco' variation:

green = rgb_to_xy(0.0, 1.0, 0.0)
red = rgb_to_xy(1.0, 0.0, 0.0)
white = rgb_to_xy(1.0,1.0,1.0)
blue = rgb_to_xy(0.0,0.0,1.0)
yellow = rgb_to_xy(1.0,1.0,0.0)

while True:

  b.set_light(10, 'xy', green)
  b.set_light(11, 'xy', red)
  b.set_light(4, 'xy', blue)
  b.set_light(7, 'xy', yellow)

  time.sleep(0.5)

  b.set_light(10, 'xy', yellow)
  b.set_light(11, 'xy', blue)
  b.set_light(4, 'xy', red)
  b.set_light(7, 'xy', green)

  time.sleep(0.5)

Yes this could have been a lot fancier, using real random settings or even trying to follow the beat of the music. Maybe next time. For now it entertained the kids and me.