philips_hue 0.1.0
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.
- data/README.md +67 -0
- data/lib/philips_hue.rb +11 -0
- data/lib/philips_hue/bridge.rb +61 -0
- data/lib/philips_hue/light.rb +179 -0
- metadata +49 -0
data/README.md
ADDED
@@ -0,0 +1,67 @@
|
|
1
|
+
## Lights App
|
2
|
+
|
3
|
+
This is a library for accessing and controlling your [Philips Hue](http://www.meethue.com/) lights using Ruby.
|
4
|
+
|
5
|
+
#### TL;DR:
|
6
|
+
|
7
|
+
Check out [bin/example_script.rb](https://github.com/dmerrick/lights_app/blob/master/bin/example_script.rb) for an example of how to use this project and what kind of things you can do.
|
8
|
+
|
9
|
+
|
10
|
+
### Registering a New App
|
11
|
+
|
12
|
+
You need two things to connect with your Hue, a name for your app and the IP address of the white Hue hockeypuck.
|
13
|
+
|
14
|
+
* The IP address can be found on the Hue Community site. Login, [go here](https://www.meethue.com/en-US/user/preferencessmartbridge), click "Show me more," and find the IP under "Internal IP address." Example: `"192.168.1.14"`
|
15
|
+
* The app name can be anything you like. You must register your app with the Hue by running `PhilipsHue#register!` and pressing the button on the hockeypuck. You must do this again for every new app name you create. Example: `"my light app"`
|
16
|
+
|
17
|
+
Full example:
|
18
|
+
```ruby
|
19
|
+
hue = PhilipsHue.new("my light app", "192.168.1.14")
|
20
|
+
hue.register!
|
21
|
+
```
|
22
|
+
|
23
|
+
### Getting the State of a Light
|
24
|
+
|
25
|
+
There are many available status options in the `Light` class.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
light1 = hue.lights.first
|
29
|
+
puts light1.state # returns JSON
|
30
|
+
puts light1.colormode
|
31
|
+
puts light1.xy
|
32
|
+
puts light1
|
33
|
+
# => "Front right is on and reachable"
|
34
|
+
```
|
35
|
+
|
36
|
+
|
37
|
+
### Changing the Color of a Light
|
38
|
+
|
39
|
+
To change the state of a light, simply modify the value of one of the state parameters. For example:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
light1.xy = [0.6446, 0.3289]
|
43
|
+
light1.ct = 200 # note that the colormode changes
|
44
|
+
light1.hue = 25000 # colormode changes again
|
45
|
+
# etc.
|
46
|
+
```
|
47
|
+
|
48
|
+
#### Helper Methods
|
49
|
+
|
50
|
+
Some helper methods, including default color options, are provided. For example:
|
51
|
+
|
52
|
+
```ruby
|
53
|
+
light1.blue
|
54
|
+
light2.red
|
55
|
+
light3.green
|
56
|
+
light1.blip # blink once
|
57
|
+
light2.blink # blink repeatedly
|
58
|
+
light3.flash([0.6446, 0.3289]) # flash red
|
59
|
+
```
|
60
|
+
|
61
|
+
|
62
|
+
### See Also
|
63
|
+
* [Official Philips Hue site](https://www.meethue.com/en-US)
|
64
|
+
* [My original gist](https://gist.github.com/dmerrick/5000839)
|
65
|
+
* [rsmck's hacking guide](http://rsmck.co.uk/hue)
|
66
|
+
* [Hue hackers' community site](http://www.everyhue.com/)
|
67
|
+
* [Thorough API docs](http://blog.ef.net/2012/11/02/philips-hue-api.html)
|
data/lib/philips_hue.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
module PhilipsHue
|
2
|
+
class Bridge
|
3
|
+
|
4
|
+
# creates a new app to talk to a Philips Hue
|
5
|
+
# app_name is used to register with the Hue
|
6
|
+
# api_url is the hostname/IP address of the Hue hockeypuck
|
7
|
+
def initialize(app_name, api_url)
|
8
|
+
@name = app_name
|
9
|
+
@key = Digest::MD5.hexdigest(@name)
|
10
|
+
@api_endpoint = "http://#{api_url}/api"
|
11
|
+
@lights = add_all_lights
|
12
|
+
end
|
13
|
+
|
14
|
+
# provide getter methods for these variables
|
15
|
+
attr_reader :name, :key, :api_endpoint, :lights
|
16
|
+
|
17
|
+
# returns overall system status as JSON
|
18
|
+
def overview
|
19
|
+
request_uri = "#{@api_endpoint}/#{@key}"
|
20
|
+
HTTParty.get(request_uri)
|
21
|
+
end
|
22
|
+
|
23
|
+
# creates a new Light object
|
24
|
+
def add_light(light_id, light_name)
|
25
|
+
Light.new(light_name, light_id, @api_endpoint, @key)
|
26
|
+
end
|
27
|
+
|
28
|
+
# helper method to get light by light_id
|
29
|
+
def light(light_id)
|
30
|
+
@lights[light_id.to_i-1]
|
31
|
+
end
|
32
|
+
|
33
|
+
# registers your app with the Hue
|
34
|
+
# this must be run for every unique app name
|
35
|
+
# FIXME: this needs to be more adequately tested
|
36
|
+
def register!
|
37
|
+
puts "Press the link button on the Hue..."
|
38
|
+
sleep 10
|
39
|
+
json_body = {:username => @key, :devicetype => @name}.to_json
|
40
|
+
response = HTTParty.post(@api_endpoint, :body => json_body)
|
41
|
+
|
42
|
+
if response.first["error"] # should be response.code
|
43
|
+
puts "Press link button and try again."
|
44
|
+
exit
|
45
|
+
else
|
46
|
+
return response
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
# loop through the available lights and make corresponding objects
|
52
|
+
def add_all_lights
|
53
|
+
all_lights = []
|
54
|
+
overview["lights"].each do |id, light|
|
55
|
+
all_lights << add_light(id.to_i, light["name"])
|
56
|
+
end
|
57
|
+
all_lights
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module PhilipsHue
|
2
|
+
class PhilipsHue::Light
|
3
|
+
|
4
|
+
def initialize(light_name, light_id, api_endpoint, key)
|
5
|
+
@name = light_name
|
6
|
+
@id = light_id
|
7
|
+
@api_endpoint = api_endpoint
|
8
|
+
@key = key
|
9
|
+
end
|
10
|
+
|
11
|
+
# query full status for single light
|
12
|
+
def status
|
13
|
+
request_uri = "#{@api_endpoint}/#{@key}/lights/#{@id}"
|
14
|
+
HTTParty.get(request_uri)
|
15
|
+
end
|
16
|
+
|
17
|
+
# change the state of a light
|
18
|
+
# note that colormode will automagically update
|
19
|
+
def set(options)
|
20
|
+
json_body = options.to_json
|
21
|
+
request_uri = "#{@api_endpoint}/#{@key}/lights/#{@id}/state"
|
22
|
+
HTTParty.put(request_uri, :body => json_body)
|
23
|
+
end
|
24
|
+
|
25
|
+
# current state of the light
|
26
|
+
def state
|
27
|
+
status["state"]
|
28
|
+
end
|
29
|
+
|
30
|
+
# determine if the light is on or off
|
31
|
+
def on?
|
32
|
+
state["on"]
|
33
|
+
end
|
34
|
+
|
35
|
+
# turn on the light
|
36
|
+
def on!
|
37
|
+
set(:on => true)
|
38
|
+
end
|
39
|
+
|
40
|
+
# turn off the light
|
41
|
+
def off!
|
42
|
+
set(:on => false)
|
43
|
+
end
|
44
|
+
|
45
|
+
# whether or not the lamp can be seen by the hub
|
46
|
+
def reachable?
|
47
|
+
state["reachable"]
|
48
|
+
end
|
49
|
+
|
50
|
+
# returns the current brightness value
|
51
|
+
# can be 0-254 (and 0 is NOT off)
|
52
|
+
def bri
|
53
|
+
state["bri"]
|
54
|
+
end
|
55
|
+
|
56
|
+
# sets the current brightness value
|
57
|
+
def bri=(value)
|
58
|
+
set(:bri => value)
|
59
|
+
end
|
60
|
+
|
61
|
+
# returns the current colormode
|
62
|
+
def colormode
|
63
|
+
state["colormode"]
|
64
|
+
end
|
65
|
+
|
66
|
+
# returns the current hue value
|
67
|
+
# used in tandem with "sat" to set the color
|
68
|
+
# the 'hue' parameter has the range 0-65535 so represents approximately 182.04*degrees
|
69
|
+
def hue
|
70
|
+
state["hue"]
|
71
|
+
end
|
72
|
+
|
73
|
+
# sets the current hue value
|
74
|
+
def hue=(value)
|
75
|
+
set(:hue => value)
|
76
|
+
end
|
77
|
+
|
78
|
+
# returns the current saturation value
|
79
|
+
# used in tandem with "hue" to set the color
|
80
|
+
# can be 0-254
|
81
|
+
def sat
|
82
|
+
state["sat"]
|
83
|
+
end
|
84
|
+
|
85
|
+
# sets the current saturation value
|
86
|
+
def sat=(value)
|
87
|
+
set(:sat => value)
|
88
|
+
end
|
89
|
+
|
90
|
+
# returns the current color temperature (white only)
|
91
|
+
# in mireds: 154 is the coolest, 500 is the warmest
|
92
|
+
# c.p. http://en.wikipedia.org/wiki/Mired
|
93
|
+
def ct
|
94
|
+
state["ct"]
|
95
|
+
end
|
96
|
+
|
97
|
+
# sets the current color temperature
|
98
|
+
def ct=(value)
|
99
|
+
set(:ct => value)
|
100
|
+
end
|
101
|
+
|
102
|
+
# returns the current xy value
|
103
|
+
# the color is expressed as an array of co-ordinates in CIE 1931 space
|
104
|
+
def xy
|
105
|
+
state["xy"]
|
106
|
+
end
|
107
|
+
|
108
|
+
# sets the current xy value
|
109
|
+
# TODO: consider x() and y() setters/getters
|
110
|
+
def xy=(value)
|
111
|
+
set(:xy => value)
|
112
|
+
end
|
113
|
+
|
114
|
+
# 'select' will flash the lamp once
|
115
|
+
# 'lselect' will flash the lamp repeatedly
|
116
|
+
# 'none' is the default state
|
117
|
+
def alert
|
118
|
+
state["alert"]
|
119
|
+
end
|
120
|
+
|
121
|
+
# set the alert state
|
122
|
+
def alert=(value)
|
123
|
+
set(:alert => value)
|
124
|
+
end
|
125
|
+
|
126
|
+
#TODO: figure out what this does (and if I can change it)
|
127
|
+
def effect
|
128
|
+
state["effect"]
|
129
|
+
end
|
130
|
+
|
131
|
+
# cheap helper method
|
132
|
+
def red
|
133
|
+
self.xy = [0.6446, 0.3289]
|
134
|
+
end
|
135
|
+
|
136
|
+
# cheap helper method
|
137
|
+
def green
|
138
|
+
self.xy = [0.4034, 0.5067]
|
139
|
+
end
|
140
|
+
|
141
|
+
# cheap helper method
|
142
|
+
def blue
|
143
|
+
self.xy = [0.1727, 0.0512]
|
144
|
+
end
|
145
|
+
|
146
|
+
# cheap helper method
|
147
|
+
def yellow
|
148
|
+
self.xy = [0.4447, 0.4918]
|
149
|
+
end
|
150
|
+
|
151
|
+
# flash once
|
152
|
+
def blip
|
153
|
+
self.alert = "select"
|
154
|
+
end
|
155
|
+
|
156
|
+
# flash repeatedly
|
157
|
+
def blink
|
158
|
+
self.alert = "lselect"
|
159
|
+
end
|
160
|
+
|
161
|
+
# flash a specified color
|
162
|
+
# if you're flashing multiple times, specify :old_xy to minimize API calls
|
163
|
+
def flash(xy, options = {})
|
164
|
+
old_xy = options[:old_xy] || self.xy
|
165
|
+
delay = options[:delay] || 1
|
166
|
+
self.xy = xy
|
167
|
+
sleep delay
|
168
|
+
self.xy = old_xy
|
169
|
+
end
|
170
|
+
|
171
|
+
# pretty-print the light's status
|
172
|
+
def to_s
|
173
|
+
pretty_name = @name.to_s.split(/_/).map(&:capitalize).join(" ")
|
174
|
+
on_or_off = on? ? "on" : "off"
|
175
|
+
reachable = reachable? ? "reachable" : "unreachable"
|
176
|
+
"#{pretty_name} is #{on_or_off} and #{reachable}"
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
metadata
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: philips_hue
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dana Merrick
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-26 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A library to control and query Philips Hue lights
|
15
|
+
email: dana.merrick@gmail.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- lib/philips_hue/bridge.rb
|
21
|
+
- lib/philips_hue/light.rb
|
22
|
+
- lib/philips_hue.rb
|
23
|
+
- README.md
|
24
|
+
homepage: https://github.com/dmerrick/lights_app
|
25
|
+
licenses: []
|
26
|
+
post_install_message:
|
27
|
+
rdoc_options: []
|
28
|
+
require_paths:
|
29
|
+
- lib
|
30
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: '0'
|
36
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ! '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
requirements: []
|
43
|
+
rubyforge_project:
|
44
|
+
rubygems_version: 1.8.24
|
45
|
+
signing_key:
|
46
|
+
specification_version: 3
|
47
|
+
summary: Philips Hue
|
48
|
+
test_files: []
|
49
|
+
has_rdoc:
|