Apple Script & Phillis Hue

LXConsole support and feedback
Post Reply
mysecretstache
Posts: 13
Joined: Wed Apr 18, 2012 12:47 am
Location: NYC
Contact:

Apple Script & Phillis Hue

Post by mysecretstache »

Has anyone experimented with Controlling Philips Hue or other "Smart Lamps" through LX Console via Applescript?

I'm thinking it might be an interesting way to control Practicals, in a situation where a traditional dimmer is unavailable.

I''m going to try it when I get some downtime.
admin
Site Admin
Posts: 1643
Joined: Mon Nov 05, 2007 1:26 am
Contact:

Post by admin »

This sounds like an interesting experiment. I'm not sure AppleScript is going to work. It looks as though the Hue has a HTTP based api.

I'll post what I find out.
admin
Site Admin
Posts: 1643
Joined: Mon Nov 05, 2007 1:26 am
Contact:

Post by admin »

Phillips Hue

------------------ Chapter One ------------------

Got the unopened Phillips Hue starter kit box. The goal is to see how these lights can be controlled for use in a performance context.

Apple-like packaging. Comes with Bridge (looks like a white hockey puck) , ethernet cable, power supply and three bulbs.

The first step in the instructions, which are found on a packaging-clever paper wheel on the cover of the box, is to screw in a bulb. It lights like a normal lamp. It looks slightly off-white like a lot of LED bulbs.

Step two is to plug in the bridge and connect to the wifi router. There is a center push button and three indicator LEDs. This router is not connected to the outside internet. So presumably, that's why the blue LED next to the world icon is flashing. The other LEDs/icons are for power and the network connection. (Confirmed that the middle icon was for the network by unplugging the ethernet and the LED goes off.)

The third step is to install the app and follow the instructions. There's a handy QR code on the package so that might work. Trying that with the iPhone, shows a page at meethue.com. But, tapping the install button at the bottom of the screen opens the AppStore to a Karaoke app. Tried again. Really looks like I should tap the install button. But, its an ad! Takes me to a different app. Giving up and searching foe Hue on the AppStore. Searching for "hue" shows "hue app" in the results. Choosing that takes me to the Phillips Hue. Its a free download.

Opened the app after making sure that the phone was connected to the wireless network. Slide to start takes you to another cute splash screen. Tap skip in the lower right corner.

There's a search button to find the bridge on the network. I'll try this. But, the phone's settings for this network are a static 10.2.111.1 IP address (used to connect to the Art-Net and OSC). Sure enough, the app says no bridge found. Switch the phone to DHCP and try again. It found the bridge.

The app says to push the link button in the center of the bridge. Its not just a circular blue LED decoration. It appears that this connects the lamps to the bridge. App switches to a screen labeled "Scenes 1". Tapping the icon labeled "Pencils" causes the lamp to change to red. Good, I can control the lamp with my phone.

The list icon in the upper left of the screen has a red 1. Not sure if this is a notification or telling me that it found one lamp (which is all I have plugged in). Tapping the list lets me select a screen called "Lights". It shows three lights and presumably intensity sliders. Two lights (1 & 3) have a red circle with an i next to them. Trying the #2 slider lets me adjust the intensity of the lamp. It dims down to a point and then abruptly goes off. This might be something that is distracting for performance use.

Looking further down the list of options, it appears that the red notification was probably because there's an update available. I tap the "New software available" line under "notifications". I did the system update by tapping the "update" button on the "New software available screen".

Going back to the "Lights" screen there's a small downward facing arrow. Tapping that opens a color picker. By touching and dragging the little circle marked 2 (the number of my lamp) I am able to select its color.

After playing around with selecting a color, I go back and look at some of the scenes. Touching and holding (or tapping the small pencil in the upper right) allows editing of a scene. Choosing the "Pencils" screen I tried earlier, the icon starts moving like when you rearrange or delete app on the iPhone. Tapping the icon again, options slide up from the bottom. Tapping edit brings up a screen like the color picker with small circles labeled 1, 2, 3. Touching and moving the circle labeled two, I'm able to change the color of the lamp. Its apparent that I'm selecting colors off the image of colored pencils because if I move the circle indicator to the center, the light turns white.

After trying a couple of the scenes and looking at editing them, I notice that there's a small camera icon in the lower left corner. This allows you to change the picture you use to select colors. There's an option to select from the Phillips library or your camera roll. I choose a picture I took of sandstone which has a lot of browns and creams in it. I set my lamp to a nice warm tone from the photo.

Lots to play with here. But I want to know about the IP address because that will be critical for this to work with the rest of the production network. In the list of screens is one called "settings". At the top of this is "My Bridge". Tapping this I find another way to check for system updates. And a line called "Network Settings". Here, I can turn on and off DHCP. Turning off DHCP exposes the network address and allows me to enter a static address and subnet mask.

Ok, I've checked out the basics of the system and next time I'll be ready for some hacking.
admin
Site Admin
Posts: 1643
Joined: Mon Nov 05, 2007 1:26 am
Contact:

Post by admin »

------------------ Chapter Two ------------------

So, it appears if you turn off a hue lamp, turning it back on does not restore the color and brightness. It goes white and then changes to slightly warmer.

On Changing the IP address, it seems like you can enter the address in the App, but that would be to connect to a bridge that matches, rather than changing the IP of the bridge itself. The App won't let me assign a 10.n.n.n address.

So on to hacking. Following the getting started page http://www.developers.meethue.com/docum ... ng-started to get going. You might not be able to change the IP address with the app. But, it is useful to find out what it is.

It appears that the api is composed of url requests similar to a cgi web page. You have to put the IP address in to the URL and then POST a request with a user name to the bridge to gain access. You have to push the button on the bridge after this request. Then you have authorized access. I'm guessing the bridge remembers the IP address of the POST request and authorizes control messages coming from that address. They say this is a security precaution. And, without an exchange of tokens, it seems reasonable that this would work. It's not that hard to spoof an IP address if you have access to a network. So, this is not particularly secure. But, perhaps it is secure enough to keep people from casually messing with your lights.

After following the "getting started" steps, I was able to turn on and off my light from my browser. The light must have a preprogrammed fade because it does not just flash on like a simple LED replacement. It sort of eases into being on in something that's more like an incandescent filament warming up.

Levels of intensity are set 0-255 as in DMX. However, at the lowest level, the light is not completely faded out. So fading these lights from black will have them jump to a low level when they are turned on. Then they will fade smoothly up from that point. From a consumer use perspective, probably not an issue. I assume most people would have preset looks and select from those. Very much like a digital version of the switch controlling the lights in my dining room that has a small dimmer on the edge. So, when you turn the lights on, they go to a preset level, rather than full like a simple switch or requiring a decision on how bright like a typical wall dimmer.
admin
Site Admin
Posts: 1643
Joined: Mon Nov 05, 2007 1:26 am
Contact:

Post by admin »

------------------ Chapter Three ------------------

Finding the IP address of the bridge required using the iPhone app and looking through several layers of screens. I'm interested in how to do this automatically. The API documentation has a complicated flowchart of possible ways to find a bridge, including scanning through all IP addresses to see if a bridge is present. Using the flowchart, is eventually guaranteed to find the bridge now matter what the network is. But, for most practical purposes, it seems good enough to rely on UPnP.

UPnP -Universal Plug and Play- is a really basic protocol for discovering services on a network. When a UPnP device joins a network, it sends out a "I'm Here" message to a multicast address on the network (239.255.255.250 port 1900). This SSDP -Simple Service Discovery Protocol- "Notify" message contains a location URL that points to an XML file on the device that can be queried via HTTP to find out about what it is and what it does.

So that you wouldn't have to be listening and/or plug a device in every time you wanted to discover its address, a UPnP device periodically sends out a Notify message "ssdp-alive". UPnP leaves it open how often this message is sent out to balance network traffic with discovery. It seems like the Hue bridge sends out an "ssdp-alive" about once a minute. So, to find out its IP address, you can just listen to the multicast address on port 1900 and wait for it to send its SSDP Notify to the network.

With a little Python, its not difficult to open a network socket to listen to multicast packets on 239.255.255.250 port 1900. Just printing out these messages over a few minutes shows that the Hue bridge is not the only device sending "ssdp-alive" packets. The wireless router also sends SSDP messages advertising its existence. You can also observe that several SSDP packets are sent in a burst. UDP packets are not guaranteed delivery. So duplicates are used to help insure that the message of the device's existence on the network gets out.

http://lx.claudeheintzdesign.com/downlo ... t_there.py

(Download and move to desktop. Open terminal.app. Type the following command:
python ~/Desktop/upnp_whats_out_there.py)

-------------
SERVER: VxWorks/5.4.2 UPnP/1.0 iGateway/1.1
http://192.168.1.1:2869/IGatewayDeviceDescDoc
-------------
-------------
SERVER: VxWorks/5.4.2 UPnP/1.0 iGateway/1.1
http://192.168.1.1:2869/IGatewayDeviceDescDoc
-------------
-------------
SERVER: FreeRTOS/7.4.2, UPnP/1.0, IpBridge/1.7.0
http://192.168.1.100:80/description.xml
-------------
-------------
SERVER: FreeRTOS/7.4.2, UPnP/1.0, IpBridge/1.7.0
http://192.168.1.100:80/description.xml
-------------

With a little extra effort, it is possible to extract the two lines from the SSDP packet that will help identify the IP address of the Hue bridge. The SERVER line contains three elements, OS/Version, UPnP version, and device version. By searching this line for "IpBridge" we can identify which packets come from the Hue.

The location line contains a URL that can be retrieved to provide UPnP information about the device in XML format. In fact, copying and pasting the URL into a browser gives a look at the contents of the "description.xml" file from the Hue bridge.

Even better, we can use urllib2 to get the contents of the url and create a searchable XML ElementTree to extract the URLBase. There's a small bit of tricky python to navigate with probably the least obvious being the fact that in order to find the URLBase, you need to include the appropriate namespace.

http://lx.claudeheintzdesign.com/downlo ... ription.py

(Download and move to desktop. Open terminal.app. Type the following command:
python ~/Desktop/upnp_read_description.py)

Great, now we can get the address of the bridge. But, we have to wait for the ssdp-alive broadcast which could take up to a minute. (And, actually UPnP allows these notices to be sent at even longer intervals.) Fortunately, we can send out a message of our own, which UPnP devices on the network will respond to. This is the third type of UPnP message that begins with "M-SEARCH" (the others are "NOTIFY" and "HTTP/1.1 200 OK")

It takes a bit to figure out exactly what to search for. But, it turns out that we can narrow it down to a urn which is very similar to the xml namespace we used to get the URLBase from description.xml.

http://lx.claudeheintzdesign.com/downlo ... _search.py

(Download and move to desktop. Open terminal.app. Type the following command:
python ~/Desktop/upnp_search.py)
admin
Site Admin
Posts: 1643
Joined: Mon Nov 05, 2007 1:26 am
Contact:

Post by admin »

------------------ Chapter Four ------------------

So, we can now quickly find the address of the Hue Bridge on the network. Let's see if we can control a light. This requires some more urllib2 mojo in order to create and send a request to the bridge. To do this we will start building a class that can send messages to the Hue bridge. We'll make finding the address of the bridge part of this object's __init__ function.

First we need to build the url for setting the state of a light:

url = self.bridgeip + "api/" + self.username + "/lights/" + light + "/state"

Then, we need to add a body with a dictionary of parameters in JSON format:

jbody = '{ "on": ' + value + ' }'

Then, we create a request and add the data. There's a trick to actually sending the request. The Hue api specifies that this should be sent as "PUT" but urllib2 supports only "GET" and "POST" but a little Google and it turns out there's a way to trick urllib2 into sending a PUT request.

Trying this out using "newdeveloper" as the user name (remember the web page from meethue.com back in chapter two) allows success! I've now connected to the bridge and turned on a light. I get a bunch of JSON in return but I can see the word "success" in with all the curly braces and colons. And, the light actually goes on in real life. If I send it { "on" : false } it goes off.

After a bit of experimentation with the json library, I'll add a check_JSON function to look at the results and let me know if it sees an error. I do get an error if I change the user name from "newdeveloper" which I authorized playing with the api getting started documentation. I'm not going to worry about the user name right now because I've got one that works. Eventually, there will have to be a way of authorizing the application which will involve prompting someone to push the link button on the bridge.

http://lx.claudeheintzdesign.com/downlo ... turn_on.py

(Download and move to desktop. Open terminal.app. Type the following command:
python ~/Desktop/py2hue_turn_on.py)
admin
Site Admin
Posts: 1643
Joined: Mon Nov 05, 2007 1:26 am
Contact:

Post by admin »

------------------ Chapter Five ------------------

To experiment with controlling the bridge from other interfaces, I'll use a python class that I already have called osclistener. This class functions a lot like the ssdplistener in that it opens a network connection and listens on a specific port. It parses an incoming message as osc and calls a delegate with the address pattern and arguments. Its not too hard to hook this up to listen for messages from TouchOSC and send messages to the bridge in response. I'll add an application class and a hook to press a key when I'm done to properly close the socket and cleanup.

http://lx.claudeheintzdesign.com/downlo ... hue_osc.py

(Download and move to desktop. Open terminal.app. Type the following command:
python ~/Desktop/py2hue_osc.py)

I've mapped the first three faders of the TouchOSC Simple layout to the intensity, saturation and hue of light 1. I can now control the light through my phone. Of course, I could do that before through the hue app... So, the next step will be to listen to Art-Net and map dimmers to these functions.

Its not that difficult to modify either the ssdplistener or osclistener classes to be a antnetlistener class. It can function largely the same way but listening to a different port (0x1936 for Art-Net). Minimal checking of an incoming packet identifies it as Art-Net, confirms that it is Art-DMX and matches a target universe. The artnetlistener class then calls a delegate with the packet data that can be read for individual dimmer levels.

An improvement over the OSC test is to package levels for intensity, hue and saturation into a single JSON dictionary and send them in a single PUT request to the bridge. And this is successful, I can convert Art-Net into messages and control a Hue light with LXConsole just like a regular fixture!

In experimenting with this, it is apparent that the Hue does not fade smoothly. It does for a bit and then seems to "bunch up" and then jump to a level. And, it seems to lag behind control from LXConsole a bit. I thought I noticed this with TouchOSC, but I wasn't sure. Checking with the Hue developer documentation confirms a recommendation not to send more than 10 commands ber second. Art-Net can be considerably faster. And LXConsole sends at approximately the maximum DMX rate of 40 times a second while fading. Because each PUT request to the Hue bridge needs to accept an incoming connection, sending too many messages delays things and causes a backup.

To fix this, it is necessary to handoff the outgoing messages to a separate thread. Otherwise a delay in sending will delay listening and messages will pile up and be processed later causing the output to lag noticeably. This results in a smoother fade for the most part. Fades are not quite as smooth as a DMX LED fixture. There're more in the neighborhood of what you'd get with a regular light and a wall dimmer--which shouldn't be a surprise.

http://lx.claudeheintzdesign.com/downlo ... t_trial.py

(Download and move to desktop. Open terminal.app. Type the following command:
python ~/Desktop/py2hue_artnet_trial.py)

The final big test is to see if the python app can run with two wireless network interfaces, one a static 10.n.n.n going to an Art-Net to DMX converter to run theatre lights and also to a DHCP assigned 192.168.1.n address for the Hue bridge. And this works on the first try. Experience dictates that this might not always be so easy. The network sockets in the python are bound to 0.0.0.0 or "any address". The system does not always choose what you want it to and there may be a need to specify which address goes with which socket. But, for now, it all works. We are still using the "newdeveloper" username that was authorized with the first meethue debug web page. So, that will need to have a way to automatically configure for the python app to be generally useful.
admin
Site Admin
Posts: 1643
Joined: Mon Nov 05, 2007 1:26 am
Contact:

Post by admin »

------------------ Chapter Six ------------------

Added some more user friendly features to the Art-Net to Hue Bridge python script. It still needs to run in a terminal window. But, it works pretty reliably other than having a minimal interface.

Download:

http://lx.claudeheintzdesign.com/downlo ... _artnet.py

move py2hue_artnet.py to Desktop

open Applications/Utilities/Terminal.app

Type the following command:

python ~/Desktop/py2hue_artnet.py

You'll get prompted to enter the universe and starting address.

DMX addresses are:
start "1" intensity
+1 "1" hue
+2 "1" hue (fine)
+3 "1" saturation
+4 "2" intensity
+5 "2" hue
+6 "2" hue (fine)
+7 "2" saturation
+8 "3" intensity
+9 "3" hue
+10 "3" hue (fine)
+11 "3" saturation

The first time you run the script, you'll need to press the Link button on the Hue bridge to authorize the username. Later, it should just start running, listening for Art-Net and
sending messages to the Hue bridge when something changes.

You'll get error messages on startup saying "parameter, hue, is not modifiable. Device is set to off". You can safely ignore these. They won't repeat unless you attempt to change the level of the DMX associated with a light that is not plugged in.
Post Reply