hued 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +57 -0
- data/README.md +149 -0
- data/Rakefile +19 -0
- data/VERSION +1 -0
- data/bin/hued +36 -0
- data/lib/hued.rb +115 -0
- data/resources/api/config +13 -0
- data/resources/api/description.xml +39 -0
- metadata +96 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b5cf08955db23b65793e437c07db14d6b866017b
|
4
|
+
data.tar.gz: 086a26303c15748e74ed137ab8d44e23f25b9590
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d5a4c0d3238d1278a878fc5053f1aa5f6601a00a9f15bfde35c53597d97124a1bc8ea7b2c13a11ad4cfaea34cced002d4e2509acce8494d01eb588b501bfb215
|
7
|
+
data.tar.gz: 1785b51a324ec14fe8e1237177013a217440a583d102f7de2c4797e9eb6fc335a2396c758feb53a0e4222faa2c51b9ec7b8c215830ac35edbef6fd43c2654886
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.4.0)
|
5
|
+
builder (3.2.2)
|
6
|
+
descendants_tracker (0.0.4)
|
7
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
8
|
+
faraday (0.9.2)
|
9
|
+
multipart-post (>= 1.2, < 3)
|
10
|
+
git (1.3.0)
|
11
|
+
github_api (0.13.1)
|
12
|
+
addressable (~> 2.4.0)
|
13
|
+
descendants_tracker (~> 0.0.4)
|
14
|
+
faraday (~> 0.8, < 0.10)
|
15
|
+
hashie (>= 3.4)
|
16
|
+
multi_json (>= 1.7.5, < 2.0)
|
17
|
+
oauth2
|
18
|
+
hashie (3.4.4)
|
19
|
+
highline (1.7.8)
|
20
|
+
jeweler (2.0.1)
|
21
|
+
builder
|
22
|
+
bundler (>= 1.0)
|
23
|
+
git (>= 1.2.5)
|
24
|
+
github_api
|
25
|
+
highline (>= 1.6.15)
|
26
|
+
nokogiri (>= 1.5.10)
|
27
|
+
rake
|
28
|
+
rdoc
|
29
|
+
json (1.8.3)
|
30
|
+
jwt (1.5.1)
|
31
|
+
mini_portile2 (2.0.0)
|
32
|
+
multi_json (1.11.3)
|
33
|
+
multi_xml (0.5.5)
|
34
|
+
multipart-post (2.0.0)
|
35
|
+
nokogiri (1.6.7.2)
|
36
|
+
mini_portile2 (~> 2.0.0.rc2)
|
37
|
+
oauth2 (1.1.0)
|
38
|
+
faraday (>= 0.8, < 0.10)
|
39
|
+
jwt (~> 1.0, < 1.5.2)
|
40
|
+
multi_json (~> 1.3)
|
41
|
+
multi_xml (~> 0.5)
|
42
|
+
rack (>= 1.2, < 3)
|
43
|
+
rack (1.6.4)
|
44
|
+
rake (10.5.0)
|
45
|
+
rdoc (4.2.2)
|
46
|
+
json (~> 1.4)
|
47
|
+
thread_safe (0.3.5)
|
48
|
+
|
49
|
+
PLATFORMS
|
50
|
+
ruby
|
51
|
+
|
52
|
+
DEPENDENCIES
|
53
|
+
jeweler (~> 2.0.1, >= 2.0.1)
|
54
|
+
json (~> 1.8.3, >= 1.8)
|
55
|
+
|
56
|
+
BUNDLED WITH
|
57
|
+
1.11.2
|
data/README.md
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
hued - (?:ab)using the Hue HTTP API
|
2
|
+
====
|
3
|
+
|
4
|
+
- [writeup](#writeup)
|
5
|
+
- [API methods](#api-methods)
|
6
|
+
- [notes](#notes)
|
7
|
+
|
8
|
+
# writeup
|
9
|
+
|
10
|
+
want to talk to your [Philips Hue](http://www2.meethue.com/en-us/) lights directly through an HTTP API without registering an application?
|
11
|
+
|
12
|
+
to turn off the currently-in-use lighting scheme:
|
13
|
+
|
14
|
+
```
|
15
|
+
~/hue $ curl -X PUT http://<hue hub>/api/<token>/groups/0/action -d '{"on":true}'
|
16
|
+
[{"success":{"/groups/0/action/on":true}}]
|
17
|
+
```
|
18
|
+
|
19
|
+
all you need are:
|
20
|
+
- the IP for the Hue Hub plugged in to your network
|
21
|
+
- a 'whitelisted' token to talk to the API
|
22
|
+
|
23
|
+
finding the IP should be pretty straight forward, but the nmap output is not very specific:
|
24
|
+
```
|
25
|
+
~/hue $ nmap 192.168.42.0/24
|
26
|
+
...
|
27
|
+
Nmap scan report for 192.168.42.66
|
28
|
+
Host is up (0.0063s latency).
|
29
|
+
Not shown: 65534 closed ports
|
30
|
+
PORT STATE SERVICE VERSION
|
31
|
+
80/tcp open tcpwrapped
|
32
|
+
...
|
33
|
+
```
|
34
|
+
|
35
|
+
the Hue hub uses DHCP by default, so it likely won't be at that address for you, but you get the idea.
|
36
|
+
|
37
|
+
now, you need to get a token. to do that, trick the Hue app on your phone/tablet/Echo to send it to us.
|
38
|
+
|
39
|
+
- stand up a webserver listening for GET of `http://0.0.0.0:80/api/config` on the same network (0/24) your phone/tablet/Echo is on
|
40
|
+
- `api/config` needs to be JSON that a Hue hub would return (sample included in repo)
|
41
|
+
- from your phone/tablet/Echo, select `Settings->Find Bridge->Search`
|
42
|
+
* this works intermittently, as some times the app found the real hub and the imposter, other times it would only find the real hub, but would mostly end up with a 'Specify IP' button
|
43
|
+
- wait for the app to query your imposter, and you'll have a token
|
44
|
+
|
45
|
+
by the numbers:
|
46
|
+
|
47
|
+
```
|
48
|
+
~/hue $ cat api/config
|
49
|
+
HTTP/1.1 200 OK
|
50
|
+
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
|
51
|
+
Pragma: no-cache
|
52
|
+
Expires: Mon, 1 Aug 2011 09:00:00 GMT
|
53
|
+
Connection: close
|
54
|
+
Access-Control-Max-Age: 3600
|
55
|
+
Access-Control-Allow-Origin: *
|
56
|
+
Access-Control-Allow-Credentials: true
|
57
|
+
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, HEAD
|
58
|
+
Access-Control-Allow-Headers: Content-Type
|
59
|
+
Content-type: application/json
|
60
|
+
|
61
|
+
{"name": "Philips hue","swversion": "01032318","apiversion": "1.13.0","mac": "DE:AD:BE:EF:CA:FE","bridgeid": "001788FFFECAFE","factorynew": false,"replacesbridgeid": null,"modelid": "BSB001"}
|
62
|
+
~/hue $ while true; do sudo nc -l 80 < api/config; done
|
63
|
+
...
|
64
|
+
GET /api/config HTTP/1.1
|
65
|
+
Host: 192.168.42.83
|
66
|
+
Accept: */*
|
67
|
+
Accept-Language: en-us
|
68
|
+
Connection: keep-alive
|
69
|
+
Accept-Encoding: gzip, deflate
|
70
|
+
User-Agent: Hue/1 CFNetwork/758.4.3 Darwin/15.5.0
|
71
|
+
|
72
|
+
GET /api/eKpsfhR9K1u32/config HTTP/1.1
|
73
|
+
Host: 192.168.42.83
|
74
|
+
Accept: */*
|
75
|
+
Accept-Language: en-us
|
76
|
+
Connection: keep-alive
|
77
|
+
Accept-Encoding: gzip, deflate
|
78
|
+
User-Agent: Hue/1 CFNetwork/758.4.3 Darwin/15.5.0
|
79
|
+
|
80
|
+
GET /api/eKpsfhR9K1u32 HTTP/1.1
|
81
|
+
Host: 192.168.42.83
|
82
|
+
Accept: */*
|
83
|
+
Accept-Language: en-us
|
84
|
+
Connection: keep-alive
|
85
|
+
Accept-Encoding: gzip, deflate
|
86
|
+
User-Agent: Hue/1 CFNetwork/758.4.3 Darwin/15.5.0
|
87
|
+
```
|
88
|
+
|
89
|
+
and now we have our token, `eKpsfhR9K1u32`. with that, we can call (all?) API methods
|
90
|
+
|
91
|
+
# API methods
|
92
|
+
|
93
|
+
api|description|GET|PUT
|
94
|
+
----|-----------|---------------|----------------
|
95
|
+
`/config/`|set and query existing settings|without token for unauthenticated, basic registration information, with token for light/device/schedule/sensor configuration|JSON matching schema validation|
|
96
|
+
`/lights/`|scan and query existing lights|JSON scan status|empty body to start a scan
|
97
|
+
`/sensors/`|scan and query existing sensors|JSON scan status|empty body to start a scan
|
98
|
+
`/scenes/`|set and query existing scenes|JSON scene list| /`<uuid>/lights/<id>/state => {"on":true,"xy":[0.5804,0.3995],"bri":253}`
|
99
|
+
`/schedules/`|set and query existing schedules/timers|JSON schedules/timers|`/<uuid> => {"name":"Alarm","autodelete":false,"localtime":"2016-06-20T16:20:00","description":"giants","status":"enabled","command":{"address":"/api/eKpsfhR9K1u32/groups/0/action","body":{"scene":"f55e38250-on-0"},"method":"PUT"}}`
|
100
|
+
`/groups/`|set and query scene (?) groupings|empty JSON|`/<id>/action => {"scene":"2fc89fcdb-on-0"}`
|
101
|
+
|
102
|
+
a few example request/responses:
|
103
|
+
|
104
|
+
```json
|
105
|
+
# http://192.168.42.66/api/eKpsfhR9K1u32/scenes
|
106
|
+
{
|
107
|
+
"f4750b0cf-off-5": {
|
108
|
+
"name": "HIDDEN foff 1452936620159",
|
109
|
+
"lights": [
|
110
|
+
"1",
|
111
|
+
"2",
|
112
|
+
"3",
|
113
|
+
"4",
|
114
|
+
"5",
|
115
|
+
"6",
|
116
|
+
"7",
|
117
|
+
"8",
|
118
|
+
"9",
|
119
|
+
"10"
|
120
|
+
],
|
121
|
+
"owner": "eKpsfhR9K1u32",
|
122
|
+
"recycle": true,
|
123
|
+
"locked": true,
|
124
|
+
"appdata": {
|
125
|
+
|
126
|
+
},
|
127
|
+
"picture": "",
|
128
|
+
"lastupdated": "2016-01-16T09:30:21",
|
129
|
+
"version": 1
|
130
|
+
},
|
131
|
+
...
|
132
|
+
}
|
133
|
+
```
|
134
|
+
|
135
|
+
# notes
|
136
|
+
|
137
|
+
all versions tested are the latest available as of 2016/06/19
|
138
|
+
|
139
|
+
component|version|notes
|
140
|
+
---------|-------|-----
|
141
|
+
Philips Hue Hub|5.23.1.13452|
|
142
|
+
Hue mobile App|1.12.1.0|same version reported on both Android and Apple devices
|
143
|
+
|
144
|
+
TODO
|
145
|
+
* dig further in api/\<token\>/config
|
146
|
+
* determine how the hashes are generated. not concatenation of create time / name in any obvious way. different devices seem to come up with hashes in different ways. older iPhone/iPad apps were [A-Z0-9]{16}, while Android ones seem to always have been [A-Z]{32}
|
147
|
+
* write a client library/binding? or at least some abstraction
|
148
|
+
* determine the truly necessary pieces of the imposter response, think it really only needs content-type and minimal JSON
|
149
|
+
* work on SSDP discovery, see [description.xml](resources/api/description.xml)
|
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'jeweler'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
|
6
|
+
CLEAN.include('pkg/*')
|
7
|
+
|
8
|
+
Jeweler::Tasks.new do |gem|
|
9
|
+
gem.name = 'hued'
|
10
|
+
gem.summary = 'Philips Hue HTTP API bindings'
|
11
|
+
gem.description = 'interact with Philips Hue Hub to control your devices'
|
12
|
+
gem.email = ['conor.code@gmail.com']
|
13
|
+
gem.homepage = 'http://github.com/chorankates/hued'
|
14
|
+
gem.authors = ['Conor Horan-Kates', 'Maureen Long']
|
15
|
+
gem.licenses = 'MIT'
|
16
|
+
|
17
|
+
gem.executables = ['hued']
|
18
|
+
end
|
19
|
+
Jeweler::RubygemsDotOrgTasks.new
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/bin/hued
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# hued - CLI for Hued module
|
3
|
+
|
4
|
+
require 'hued'
|
5
|
+
|
6
|
+
def parse_input
|
7
|
+
options = Hash.new
|
8
|
+
|
9
|
+
parser = OptionParser.new do |o|
|
10
|
+
o.on('--ip <ip>', 'IP address of Phillips Hue Hub') do |p|
|
11
|
+
options[:ip] = p
|
12
|
+
end
|
13
|
+
o.on('--token <token>', 'whitelisted token') do |p|
|
14
|
+
options[:token] = p
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
parser.parse!
|
19
|
+
options
|
20
|
+
end
|
21
|
+
|
22
|
+
options = parse_input
|
23
|
+
|
24
|
+
hub = Hued::Hub.new(options[:ip], options[:token])
|
25
|
+
|
26
|
+
# TODO this should really be a REPL
|
27
|
+
off = hub.all_lights_off
|
28
|
+
puts "off: #{off}"
|
29
|
+
|
30
|
+
sleep 5
|
31
|
+
|
32
|
+
on = hub.all_lights_on
|
33
|
+
puts "on: #{on}"
|
34
|
+
|
35
|
+
off = hub.all_lights_off
|
36
|
+
puts "off(2): #{off}"
|
data/lib/hued.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
## hued.rb Philips Hue HTTP binding
|
3
|
+
|
4
|
+
require 'json'
|
5
|
+
require 'net/http'
|
6
|
+
require 'optparse'
|
7
|
+
require 'yaml'
|
8
|
+
require 'uri'
|
9
|
+
|
10
|
+
module Hued
|
11
|
+
|
12
|
+
class Hub
|
13
|
+
|
14
|
+
attr_accessor :lights, :scenes, :schedules
|
15
|
+
|
16
|
+
def initialize(ip, token)
|
17
|
+
@ip = ip
|
18
|
+
@token = token
|
19
|
+
|
20
|
+
raise "no IP specified" if @ip.nil?
|
21
|
+
raise "no token specified" if @token.nil?
|
22
|
+
|
23
|
+
@config = get_config()
|
24
|
+
|
25
|
+
@lights = get_lights()
|
26
|
+
@scenes = get_scenes()
|
27
|
+
@schedules = get_schedules()
|
28
|
+
end
|
29
|
+
|
30
|
+
def inspect
|
31
|
+
{
|
32
|
+
:ip => @ip,
|
33
|
+
:token => @token,
|
34
|
+
:lights => @lights.size,
|
35
|
+
:scenes => @scenes.size,
|
36
|
+
:schedules => @schedules.size,
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_s
|
41
|
+
inspect.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
def get_config
|
45
|
+
JSON.parse(get_http(get_url('config')).body)
|
46
|
+
end
|
47
|
+
|
48
|
+
def get_lights(input = nil)
|
49
|
+
lights = Array.new
|
50
|
+
response = JSON.parse(get_http(get_url('lights')).body)
|
51
|
+
response.each do |_i, hash|
|
52
|
+
lights << OpenStruct.new(hash)
|
53
|
+
end
|
54
|
+
|
55
|
+
lights
|
56
|
+
end
|
57
|
+
|
58
|
+
def get_scenes(input = nil)
|
59
|
+
scenes = Array.new
|
60
|
+
response = JSON.parse(get_http(get_url('scenes')).body)
|
61
|
+
response.each do |_i, hash|
|
62
|
+
scenes << OpenStruct.new(hash)
|
63
|
+
end
|
64
|
+
|
65
|
+
scenes
|
66
|
+
end
|
67
|
+
|
68
|
+
def get_schedules(input = nil)
|
69
|
+
schedules = Array.new
|
70
|
+
response = JSON.parse(get_http(get_url('schedules')).body)
|
71
|
+
response.each do |_i, hash|
|
72
|
+
schedules << OpenStruct.new(hash)
|
73
|
+
end
|
74
|
+
|
75
|
+
schedules
|
76
|
+
end
|
77
|
+
|
78
|
+
def all_lights_on
|
79
|
+
url = get_url('groups/0/action')
|
80
|
+
payload = { :on => true }
|
81
|
+
put_http(url, payload)
|
82
|
+
end
|
83
|
+
|
84
|
+
def all_lights_off
|
85
|
+
url = get_url('groups/0/action')
|
86
|
+
payload = { :on => false }
|
87
|
+
put_http(url, payload)
|
88
|
+
end
|
89
|
+
|
90
|
+
## helper functions
|
91
|
+
def get_url(method)
|
92
|
+
sprintf('http://%s/api/%s/%s', @ip, @token, method)
|
93
|
+
end
|
94
|
+
|
95
|
+
def get_http(url)
|
96
|
+
uri = URI.parse(url)
|
97
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
98
|
+
http.use_ssl = false
|
99
|
+
request = Net::HTTP::Get.new(uri.request_uri)
|
100
|
+
http.request(request)
|
101
|
+
end
|
102
|
+
|
103
|
+
def put_http(url, body)
|
104
|
+
uri = URI.parse(url)
|
105
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
106
|
+
request = Net::HTTP::Put.new(uri.request_uri)
|
107
|
+
|
108
|
+
request.add_field('Content-Type', 'application.json')
|
109
|
+
request.body = body.to_json
|
110
|
+
http.request(request)
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
|
3
|
+
Pragma: no-cache
|
4
|
+
Expires: Mon, 1 Aug 2011 09:00:00 GMT
|
5
|
+
Connection: close
|
6
|
+
Access-Control-Max-Age: 3600
|
7
|
+
Access-Control-Allow-Origin: *
|
8
|
+
Access-Control-Allow-Credentials: true
|
9
|
+
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE, HEAD
|
10
|
+
Access-Control-Allow-Headers: Content-Type
|
11
|
+
Content-type: application/json
|
12
|
+
|
13
|
+
{"name": "Philips hue","swversion": "01032318","apiversion": "1.13.0","mac": "DE:AD:BE:EF:CA:FE","bridgeid": "001788FFFECAFE","factorynew": false,"replacesbridgeid": null,"modelid": "BSB001"}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
4
|
+
<root xmlns="urn:schemas-upnp-org:device-1-0">
|
5
|
+
<specVersion>
|
6
|
+
<major>1</major>
|
7
|
+
<minor>0</minor>
|
8
|
+
</specVersion>
|
9
|
+
<URLBase>http://192.168.42.66:80/</URLBase>
|
10
|
+
<device>
|
11
|
+
<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>
|
12
|
+
<friendlyName>Philips hue (192.168.42.66)</friendlyName>
|
13
|
+
<manufacturer>Royal Philips Electronics</manufacturer>
|
14
|
+
<manufacturerURL>http://www.philips.com</manufacturerURL>
|
15
|
+
<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>
|
16
|
+
<modelName>Philips hue bridge 2012</modelName>
|
17
|
+
<modelNumber>000</modelNumber>
|
18
|
+
<modelURL>http://www.meethue.com</modelURL>
|
19
|
+
<serialNumber>000</serialNumber>
|
20
|
+
<UDN>000</UDN>
|
21
|
+
<presentationURL>index.html</presentationURL>
|
22
|
+
<iconList>
|
23
|
+
<icon>
|
24
|
+
<mimetype>image/png</mimetype>
|
25
|
+
<height>48</height>
|
26
|
+
<width>48</width>
|
27
|
+
<depth>24</depth>
|
28
|
+
<url>hue_logo_0.png</url>
|
29
|
+
</icon>
|
30
|
+
<icon>
|
31
|
+
<mimetype>image/png</mimetype>
|
32
|
+
<height>120</height>
|
33
|
+
<width>120</width>
|
34
|
+
<depth>24</depth>
|
35
|
+
<url>hue_logo_3.png</url>
|
36
|
+
</icon>
|
37
|
+
</iconList>
|
38
|
+
</device>
|
39
|
+
</root>
|
metadata
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hued
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Conor Horan-Kates
|
8
|
+
- Maureen Long
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2016-06-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: json
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - '>='
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.8'
|
21
|
+
- - ~>
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 1.8.3
|
24
|
+
type: :runtime
|
25
|
+
prerelease: false
|
26
|
+
version_requirements: !ruby/object:Gem::Requirement
|
27
|
+
requirements:
|
28
|
+
- - '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '1.8'
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.8.3
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: jeweler
|
36
|
+
requirement: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.0.1
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 2.0.1
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - '>='
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 2.0.1
|
51
|
+
- - ~>
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 2.0.1
|
54
|
+
description: interact with Philips Hue Hub to control your devices
|
55
|
+
email:
|
56
|
+
- conor.code@gmail.com
|
57
|
+
executables:
|
58
|
+
- hued
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files:
|
61
|
+
- README.md
|
62
|
+
files:
|
63
|
+
- Gemfile
|
64
|
+
- Gemfile.lock
|
65
|
+
- README.md
|
66
|
+
- Rakefile
|
67
|
+
- VERSION
|
68
|
+
- bin/hued
|
69
|
+
- lib/hued.rb
|
70
|
+
- resources/api/config
|
71
|
+
- resources/api/description.xml
|
72
|
+
homepage: http://github.com/chorankates/hued
|
73
|
+
licenses:
|
74
|
+
- MIT
|
75
|
+
metadata: {}
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - '>='
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubyforge_project:
|
92
|
+
rubygems_version: 2.2.2
|
93
|
+
signing_key:
|
94
|
+
specification_version: 4
|
95
|
+
summary: Philips Hue HTTP API bindings
|
96
|
+
test_files: []
|