Keeping state of Philips Hues

The Philips brain bleeding.

I recently got some Philips Hue lightbulbs. The are very configurabe and the quality of light is very good. Unfortunately they forget their settings every time they loose power. So every time i turn them off and on on the wall-switch, I get a blazing sunlight in my room! What did they think about designing them like that?

Well after looking on the internet, it seemed like philips has no intension of changing this behaviour. It must be a design feature 🙁

My solution

I designed a small python script i have running on my home assistant server (but it could be on any server as long as it has connection to the bridge).

Every second it polls the bridge to get the settings of all my lights. The settings are constantly stored in memory, and if the bulbs become unreachable (if turned off), my script will start sending that last know configuration to the bulbs every second.

My script uses the pip phue library (pip3 install phue). Before running it the first time, press the button on the bridge (max 30 seconds before). This creates a now user on the bridge.

Script:

 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
#!/srv/homeassistant/bin/python

from phue import Bridge
import time

b = Bridge('192.168.xxx.xxx')
b.connect()

db_brightness={}
db_xy={}
db_on={}
db_restoring={}

while True:
    time.sleep(1)
    lights = b.lights
    for light in lights:
        lid=light.light_id
        if not lid in db_brightness: db_brightness[lid]=0
        if not lid in db_xy: db_xy[lid]='nonexist'
        if not lid in db_on: db_on[lid]=False
        if not lid in db_restoring: db_restoring[lid]=False

        if light.reachable:
            if db_restoring[lid]:
                print ("Light {} is online again and should be restored to previous state.".format(light.name))
                db_restoring[lid]=False
            else:
                if light.on!=db_on[lid]:
                    print("Saved state {} for light {}.".format(light.on, light.name))
                    db_on[lid]=light.on
                if light.brightness!=db_brightness[lid]:
                    db_brightness[lid]=light.brightness
                    print ("Saved brightness {} for light {}.".format(light.brightness, light.name))
                if hasattr(light,"xy") and light.xy!=db_xy[lid]:
                    db_xy[lid]=light.xy
                    print ("Saved xy {} for light {}.".format(light.xy, light.name))
        else:
            if db_on[lid]:
                if not db_restoring[lid]:
                    if db_xy[lid] != "nonexist": print ("Light {} is offline. Restoring brightness {}.".format(light.name, db_brightness[lid]))
                    print ("Light {} is offline. Restoring xy {}.".format(light.name, db_xy[lid]))
                    db_restoring[lid]=True
                if db_restoring[lid]:
                    light.brightness=db_brightness[lid]
                    if db_xy[lid] != "nonexist": light.xy=db_xy[lid]
            else:
                if not db_restoring[lid]:
                    print("Light {} is offline. Restoring turned off state for it.".format(light.name))
                    db_restoring[lid]=True
                else:
                    light.on=False

What do i get?

The bridge is very slow at realizing that the bulbs are off. It takes typically around 20 seconds.

When the bulbs get the power restored they will go back to its previous state within few seconds. For some reason it sometimes takes up to 10 seconds. I have no idea why.

If you want to run the code in Appdaemon, I have the rewritten version here Keeping state of Philips Hues in Appdaemon

5 thoughts to “Keeping state of Philips Hues”

  1. is it possible to have a windows exe file that runs on a server machine running windows 10?
    Thanks

      1. i get the following message:
        C:\Users\root>C:\Users\root\AppData\Local\Programs\Python\Python36\python.exe d:\dati\HUE\last_state.py
        Traceback (most recent call last):
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\site-packages\phue.py”, line 736, in connect
        with open(self.config_file_path) as f:
        FileNotFoundError: [Errno 2] No such file or directory: ‘C:\\Users\\root\\.python_hue’

        During handling of the above exception, another exception occurred:

        Traceback (most recent call last):
        File “d:\dati\HUE\last_state.py”, line 6, in
        b = Bridge(‘192.168.000.245’)
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\site-packages\phue.py”, line 629, in __init__
        self.connect()
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\site-packages\phue.py”, line 752, in connect
        self.register_app()
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\site-packages\phue.py”, line 706, in register_app
        response = self.request(‘POST’, ‘/api’, registration_request)
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\site-packages\phue.py”, line 653, in request
        connection.request(mode, address, json.dumps(data))
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 1239, in request
        self._send_request(method, url, body, headers, encode_chunked)
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 1285, in _send_request
        self.endheaders(body, encode_chunked=encode_chunked)
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 1234, in endheaders
        self._send_output(message_body, encode_chunked=encode_chunked)
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 1026, in _send_output
        self.send(msg)
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 964, in send
        self.connect()
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\http\client.py”, line 936, in connect
        (self.host,self.port), self.timeout, self.source_address)
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\socket.py”, line 704, in create_connection
        for res in getaddrinfo(host, port, 0, SOCK_STREAM):
        File “C:\Users\root\AppData\Local\Programs\Python\Python36\lib\socket.py”, line 743, in getaddrinfo
        for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
        socket.gaierror: [Errno 11001] getaddrinfo failed

Leave a Reply

Your email address will not be published. Required fields are marked *