Class: Hue::Hue
- Inherits:
-
Object
- Object
- Hue::Hue
- Defined in:
- lib/hue.rb
Overview
Hue is a class that can interact with and control a Philips Hue base station.
Class Method Summary collapse
-
.discover_ip ⇒ Object
Hue.discover_ip is a convenience class method that will scan the network and attempt to find the Philips base station.
Instance Method Summary collapse
-
#all_lights ⇒ Object
Hue#all_lights is awesome.
-
#authorize ⇒ Object
Hue#authorize authorizes this client (@client + @username combination) with the base station forever.
-
#each_light ⇒ Object
Like Enum’s ‘each`, Hue#each_light takes a block which is called for each light id.
-
#initialize(opts = {}) ⇒ Hue
constructor
Hue can be initialized with a Hash of options.
-
#lights ⇒ Object
Hue#lights returns lights from the cached state, from the poll_state method above.
-
#off(light) ⇒ Object
Hue#off turns off the specified light.
-
#on(light) ⇒ Object
Hue#on turns on the specified light.
-
#poll_state ⇒ Object
Hue#poll_state returns the entire state of the system.
-
#preset ⇒ Object
Hue#preset returns a HuePresetsProxy object, which is meant to be used much like Hue#all_lights.
-
#request(method, path, body = {}) ⇒ Object
Hue#request is makes an authorized request to the Hue backend, relative to the url ‘@ip/api/@user`.
-
#set_bright_color(light, color, opts = {}) ⇒ Object
Hue#set_bright_color is often more useful than its ‘set_color` counterpart, because when converting RGB colors to HSL, a color might not be expected to have full brightness.
-
#set_color(light, color, opts = {}) ⇒ Object
Hue#set_color sets a light to a specified color.
-
#write(light, state) ⇒ Object
Hue#write is the meat of what Hue is all about.
Constructor Details
#initialize(opts = {}) ⇒ Hue
Hue can be initialized with a Hash of options.
45 46 47 48 49 |
# File 'lib/hue.rb', line 45 def initialize(opts = {}) @ip = opts[:ip] || self.class.discover_ip @client = opts[:client] || 'ruby-hue' @username = opts[:username] || Digest::SHA1.hexdigest(`hostname`.strip) end |
Class Method Details
.discover_ip ⇒ Object
Hue.discover_ip is a convenience class method that will scan the network and attempt to find the Philips base station. It may take ~5s to execute.
19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/hue.rb', line 19 def self.discover_ip UPnP::SSDP.log = false # get rid of this pesky debug logging! services = UPnP::SSDP.search('urn:schemas-upnp-org:device:basic:1').map {|s| s[:location] } valid_location = services.find do |l| xml = Curl.get(l).body_str doc = Nokogiri::XML(xml) name = doc.css('friendlyName').first return false unless name name.text =~ /^Philips hue/ end raise 'no hue found on this network' unless valid_location /(([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])\.){3}([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5])/.match(valid_location)[0] end |
Instance Method Details
#all_lights ⇒ Object
Hue#all_lights is awesome. It returns a ‘HueAllLightsProxy` object, which is a simple object that will forward any method calls it gets to this instance of Hue, once for each light, inserting the light id as the first argument.
Imagine we had the following variables:
hue = Hue.new
proxy = hue.all_lights
The following method call:
proxy.write hue: 0, bri: 200
Would essentially be translated to these three method calls (for 3 lights):
hue.write 1, hue: 0, bri: 200
hue.write 2, hue: 0, bri: 200
hue.write 3, hue: 0, bri: 200
Typically, you would simply use this inline, like this:
hue.all_lights.set_bright_color(Color::RGB::Blue)
135 136 137 |
# File 'lib/hue.rb', line 135 def all_lights HueAllLightsProxy.new(self) end |
#authorize ⇒ Object
Hue#authorize authorizes this client (@client + @username combination) with the base station forever. It’s a one-time operation.
#authorize requires manual interation: the method must be called, after which somebody must physically press the button on the base station. Once that is done, the method must be called again and, this time, a success confirmation message will be returned.
72 73 74 |
# File 'lib/hue.rb', line 72 def _request(:post, "http://#{@ip}/api/", devicetype: @client, username: @username) end |
#each_light ⇒ Object
Like Enum’s ‘each`, Hue#each_light takes a block which is called for each light id. For example:
hue.each_light do |l|
hue.set_bright_color(l, Color::RGB::Blue)
end
103 104 105 106 |
# File 'lib/hue.rb', line 103 def each_light lights.each {|k,v| yield k } nil end |
#lights ⇒ Object
Hue#lights returns lights from the cached state, from the poll_state method above. The state of the light themselves is only as current as the last poll_state method call.
90 91 92 93 |
# File 'lib/hue.rb', line 90 def lights poll_state unless @state @state['lights'] end |
#off(light) ⇒ Object
Hue#off turns off the specified light.
173 174 175 |
# File 'lib/hue.rb', line 173 def off(light) write(light, on: false) end |
#on(light) ⇒ Object
Hue#on turns on the specified light.
180 181 182 |
# File 'lib/hue.rb', line 180 def on(light) write(light, on: true) end |
#poll_state ⇒ Object
Hue#poll_state returns the entire state of the system.
79 80 81 82 83 |
# File 'lib/hue.rb', line 79 def poll_state state = request(:get, '/') raise unless state['lights'] # poor man's way of checking for success @state = state end |
#preset ⇒ Object
Hue#preset returns a HuePresetsProxy object, which is meant to be used much like Hue#all_lights. For example:
hue.preset.cycle_thru_colors
219 220 221 |
# File 'lib/hue.rb', line 219 def preset HuePresetsProxy.new(self) end |
#request(method, path, body = {}) ⇒ Object
Hue#request is makes an authorized request to the Hue backend, relative to the url ‘@ip/api/@user`. Include any leading slashes.
This method is mostly used internally, but made avaiable publicly for shits and giggles.
58 59 60 61 |
# File 'lib/hue.rb', line 58 def request(method, path, body = {}) url = "http://#{@ip}/api/#{@username}#{path}" _request(method, url, body) end |
#set_bright_color(light, color, opts = {}) ⇒ Object
Hue#set_bright_color is often more useful than its ‘set_color` counterpart, because when converting RGB colors to HSL, a color might not be expected to have full brightness. But with a known hue & saturation, it’s often desirable to have full brightness. This method uses ‘bri: 255`
207 208 209 210 211 |
# File 'lib/hue.rb', line 207 def set_bright_color(light, color, opts={}) color = color.to_hsl color.l = 1 set_color(light, color, opts) end |
#set_color(light, color, opts = {}) ⇒ Object
Hue#set_color sets a light to a specified color.
set_color expects color to be a color object from the ‘color` gem, or something that implements its interface:
color must implement to_hsl, which must return an object that implements .h, .l, and .s. These methods are expected to return floats in (0.0..1.1)
193 194 195 196 197 198 199 |
# File 'lib/hue.rb', line 193 def set_color(light, color, opts={}) hsl = color.to_hsl opts = opts.merge(bri: (hsl.l * 255).to_i, sat: (hsl.s * 255).to_i, hue: (hsl.h * 360 * 182).to_i) write(light, opts) end |
#write(light, state) ⇒ Object
Hue#write is the meat of what Hue is all about. This is the method that writes a state change to a Hue bulb.
In order to avoid being rate limited at the HTTP api level, this method implements its own rate limiting in which it will block and wait for enough time to elapse when messages are fired too quickly.
State is an object which typically contains a combination of these keys:
:hue => this is a hue value in the range (0..65535)
can be derived from (degrees * 182)
:bri => "brightness" in the range (0..255)
:sat => "saturation" in the range (0..255)
:alert => when set, triggers alert behavior. options:
:select
triggers a flash to the given color, instead of
a permanent change, when set to `true`
:lselect
same as above, except this is a constant flashing,
insead of a one time trigger
:transitiontime => an Integer representing the "transition time," ie. the
amount of time over which the color fade will occur.
this is measured in tenths of seconds. a value of
0 means a hard switch, no fade. defaulys to ~5-ish
165 166 167 168 |
# File 'lib/hue.rb', line 165 def write(light, state) wait_for_rate_limit request(:put, "/lights/#{light}/state", state) end |