The data below was derived from Wireshark on the port where the Philips Hue base station sits.
There is a string 0123456789abdcef0123456789abcdef referred to in the below data. This is a username that the client uses when talking to the base station to identify itself. This username is generated by the client and sent to the base station via POST request.
If the LINK button on the base station has not been pressed, this POST request will result in an error being returned via JSON. Once the LINK button is pressed, the next POST request you make will save the username you sent to the client whitelist.
The client makes a GET request and is returned a JSON error message ...
GET /api/0123456789abdcef0123456789abcdef/lights HTTP/1.1
Host: 10.255.255.44
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
Accept-Language: en-us
Accept: */*
[
{
"error":
{
"type":1,
"address":"/lights",
"description":"unauthorized user"
}
}
]
The client then continually makes POST requests with a username that the client derives and a device type, but until the LINK button is pressed on the base station, an error message is returned.
POST /api HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 86
Accept-Language: en-us
Accept: */*
Connection: keep-alive
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{"username":"0123456789abdcef0123456789abcdef","devicetype":"iPhone 5"}
[
{
"error":
{
"type":101,
"address":"",
"description":"link button not pressed"
}
}
]
After pushing the LINK button on the base station the POST request succeeds.
POST /api HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 86
Accept-Language: en-us
Accept: */*
Connection: keep-alive
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{"username":"0123456789abdcef0123456789abcdef","devicetype":"iPhone 5"}
[
{
"success":
{
"username":"0123456789abdcef0123456789abcdef"
}
}
]
GET /api/0123456789abdcef0123456789abcdef HTTP/1.1
Host: 10.255.255.44
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
Accept-Language: en-us
Accept: */*
{
"lights":
{
"1":
{
"state":
{
"on":false,
"bri":146,
"hue":13234,
"sat":208,
"xy":[0.5090,0.4149],
"ct":459,
"alert":"none",
"effect":"none",
"colormode":"ct",
"reachable":true
},
"type": "Extended color light",
"name": "Living",
"modelid": "LCT001",
"swversion": "65003148",
"pointsymbol":
{
"1":"none",
"2":"none",
"3":"none",
"4":"none",
"5":"none",
"6":"none",
"7":"none",
"8":"none"
}
},
"2":
{
"state":
{
"on":false,
"bri":162,
"hue":2213,
"sat":238,
"xy":[0.6349,0.3413],
"ct":500,
"alert":"none",
"effect":"none",
"colormode":"xy",
"reachable":true
},
"type": "Extended color light",
"name": "Bedroom Far",
"modelid": "LCT001",
"swversion": "65003148",
"pointsymbol":
{
"1":"none",
"2":"none",
"3":"none",
"4":"none",
"5":"none",
"6":"none",
"7":"none",
"8":"none"
}
},
"3":
{
"state":
{
"on":false,
"bri":146,
"hue":13122,
"sat":211,
"xy":[0.3565,0.1775],
"ct":462,
"alert":"none",
"effect":"none",
"colormode":"ct",
"reachable":true
},
"type": "Extended color light",
"name": "Bedroom Near",
"modelid": "LCT001",
"swversion": "65003148",
"pointsymbol":
{
"1":"none",
"2":"none",
"3":"none",
"4":"none",
"5":"none",
"6":"none",
"7":"none",
"8":"none"
}
}
},
"groups": {},
"config":
{
"name": "Philips hue",
"mac": "00:17:88:09:26:9d",
"dhcp": true,
"ipaddress": "10.255.255.44",
"netmask": "255.255.255.0",
"gateway": "10.255.255.254",
"proxyaddress": "",
"proxyport": 0,
"UTC": "2012-11-02T18:34:38",
"whitelist":
{
"0123456789abdcef0123456789abcdef":
{
"last use date": "2012-11-02T18:34:38",
"create date": "2012-11-01T21:04:48",
"name": "iPhone 5"
},
},
"swversion": "01003542",
"swupdate":
{
"updatestate":0,
"url":"",
"text":"",
"notify": false
},
"linkbutton": false,
"portalservices": false
},
"schedules": {}
}
GET /api/0123456789abdcef0123456789abcdef/config HTTP/1.1
Host: 10.255.255.44
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
Accept-Language: en-us
Accept: */*
{
"name": "Philips hue",
"mac": "00:17:88:09:00:00",
"dhcp": true,
"ipaddress": "10.255.255.44",
"netmask": "255.255.255.0",
"gateway": "10.255.255.1",
"proxyaddress": "",
"proxyport": 0,
"UTC": "2012-11-02T18:34:35",
"whitelist":
{
"0123456789abdcef0123456789abcdef":
{
"last use date": "2012-11-02T18:34:35",
"create date": "2012-11-01T21:04:48",
"name": "iPhone 5"
},
},
"swversion": "01003542",
"swupdate":
{
"updatestate":0,
"url":"",
"text":"",
"notify": false
},
"linkbutton": false,
"portalservices": false
}
GET /api/0123456789abdcef0123456789abcdef/lights HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{
"1":
{
"name": "Dining"
},
"2":
{
"name": "Bedroom Far"
},
"3":
{
"name": "Bedroom Near"
}
}
You can specify which group to show by changing the number in the URL.
For example /api/0123456789abdcef0123456789abcdef/groups/1 for group #1.
GET /api/0123456789abdcef0123456789abcdef/groups/0 HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{
"action":
{
"on":false,
"bri":254,
"hue":14922,
"sat":144,
"xy":[0.4595,0.4105],
"ct":369,
"effect":"none",
"colormode":"ct"
},
"lights": ["1","2","3"],
"name": "Lightset 0"
}
GET /api/0123456789abdcef0123456789abcdef/schedules HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{
"1":
{
"name": "Timer on f 649863 "
},
"2":
{
"name": "Timer on 807548 "
},
"3":
{
"name": "Timer on f 996556 "
},
"4":
{
"name": "Timer on 208820 "
},
}
PUT /api/0123456789abdcef0123456789abcdef/config HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 67
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{"name":"New Name","proxyaddress":" ","proxyport":0,"dhcp":true}
[
{
"success":
{
"/config/name":"New Name"
}
},
{
"success":
{
"/config/proxyaddress":" "
}
},
{
"success":
{
"/config/proxyport":0
}
},
{
"success":
{
"/config/dhcp":true
}
}
]
PUT /api/0123456789abdcef0123456789abcdef/lights/0 HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 17
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{"name":"Dining"}
[
{
"success":
{
"/lights/1/name":"Dining"
}
}
]
You can specify which bulb state to change by changing the number in the URL.
For example /api/0123456789abdcef0123456789abcdef/lights/1/state for bulb #1.
PUT /api/0123456789abdcef0123456789abcdef/lights/0/state HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 44
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{"bri":230,"xy":[0.63531,0.34127],"on":true}
[
{
"success":
{
"/lights/0/state/on":true
}
},
{
"success":
{
"/lights/0/state/xy":[0.6353,0.3413]
}
},
{
"success":
{
"/lights/0/state/bri":230
}
}
]
This request turns off all bulbs in group 0. By default all bulbs are in group 0.
PUT /api/0123456789abdcef0123456789abcdef/groups/0/action HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 12
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{"on":false}
[
{
"success":
{
"/groups/0/action/on":false
}
}
]
Schedules are used to turn bulbs on and off at a pre-determined time. You must add a separate schedule for each bulb and each bulb event.
For example, if you have two bulbs and want to turn them on in the morning and off in the evening, you will create four schedules, two schedules to turn the bulbs on and two schedules to turn them off.
You may be able to use schedules with groups but I have not tested that yet.
POST /api/0123456789abdcef0123456789abcdef/schedules HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 240
Accept-Language: en-us
Accept: */*
Connection: keep-alive
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{
"name":"Timer on 807548 ",
"time":"2012-11-30T18:57:02",
"description":" ",
"command":
{
"method":"PUT",
"address":"/api/0123456789abdcef0123456789abcdef/lights/1/state",
"body":
{
"bri":144,
"ct":469,
"transitiontime":1800,
"on":true
}
}
}
DELETE /api/0123456789abdcef0123456789abcdef/schedules/1 HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 0
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
[
{
"success":"/schedules/1 deleted"
}
]
This initiates two distinct requests: first an empty POST request to start the search and subsequent GET requests to get search progress.
POST /api/0123456789abdcef0123456789abcdef/lights HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 0
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
[
{
"success":
{
"/lights":"Searching for new devices"
}
}
]
GET /api/0123456789abdcef0123456789abcdef/lights/new HTTP/1.1
Host: 10.255.255.44
Connection: keep-alive
Accept-Encoding: gzip, deflate
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
Accept-Language: en-us
Accept: */*
{
"lastscan": "active"
}
This makes a light repeatedly turn on and off.
PUT /api/0123456789abdcef0123456789abcdef/lights/0/state HTTP/1.1
Host: 10.255.255.44
Accept-Encoding: gzip, deflate
Accept: */*
Content-Length: 19
Connection: keep-alive
Accept-Language: en-us
User-Agent: hue/1.0.1 CFNetwork/609 Darwin/13.0.0
{"alert":"lselect"}
[
{
"success":
{
"/lights/0/state/alert":"lselect"
}
}
]
require 'rubygems'
require 'mechanize'
require 'json'
basestation = 'http://10.255.255.44'
username = '0123456789abdcef0123456789abcdef'
a = Mechanize.new { |agent|
agent.user_agent = 'hue/1.0.1 CFNetwork/609 Darwin/13.0.0'
}
puts "GET ..."
a.get("#{basestation}/api/#{username}/lights") do |page|
puts page.body
end
success = false
while success == false
puts "POST ..."
page = a.post("#{basestation}/api", {
"username" => username,
"devicetype" => 'iPhone 5',
}.to_json)
puts page.body
json = JSON.parse(page.body)
if not json[0]["error"]
success = true
end
sleep 1
end