------------------ 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)