hue 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 32b4e4137e61f92f9e4a2033f4b01f5abf57a197
4
+ data.tar.gz: fcd37ed79cb42411e10ac9bc84b4802390b54d5e
5
+ SHA512:
6
+ metadata.gz: 7c72e22fdd17c1065ae118474c03a6aaf9efe2d1cca17b7f27620e2727949b74808795cb729fb2851a1c21ea6e4117f3bb0641940c6a78f954970866cae3b3b2
7
+ data.tar.gz: 6b5ab557a8a00e8ea23fa1f485134ad963052e8b517ed2b969c4895f8adab9ab8b621332997362835f64466064fa88b35acd4204aa5e03849245af3a3510f240
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,19 @@
1
+ ## Submitting a Pull Request
2
+
3
+ 1. [Fork the repository.][fork]
4
+ 2. [Create a topic branch.][branch]
5
+ 3. Add tests for your unimplemented feature or bug fix.
6
+ 4. Run `bundle exec rake`. If your tests pass, return to step 3.
7
+ 5. Implement your feature or bug fix.
8
+ 6. Run `bundle exec rake`. If your tests fail, return to step 5.
9
+ 7. Run `open coverage/index.html`. If your changes are not completely covered
10
+ by your tests, return to step 3.
11
+ 8. Add documentation for your feature or bug fix.
12
+ 9. Run `bundle exec rake doc`. If your changes are not 100% documented, go
13
+ back to step 8.
14
+ 10. Add, commit, and push your changes.
15
+ 11. [Submit a pull request.][pr]
16
+
17
+ [fork]: http://help.github.com/fork-a-repo/
18
+ [branch]: http://learn.github.com/p/branching.html
19
+ [pr]: http://help.github.com/send-pull-requests/
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Sam Soffes
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
@@ -0,0 +1,24 @@
1
+ # Hue
2
+
3
+ Work with Philips Hue light bulbs from Ruby.
4
+
5
+ ## Installation
6
+
7
+ This gem is currently unreleased. For now, simply clone the repository.
8
+
9
+ ## Usage
10
+
11
+ ``` shell
12
+ $ git clone https://github.com/soffes/hue.git
13
+ $ irb -Ihue/lib -rhue
14
+ ```
15
+
16
+ ``` ruby
17
+ > client = Hue::Client.new
18
+ > light = client.lights.first
19
+ > light.on = true
20
+ ```
21
+
22
+ ## Contributing
23
+
24
+ See the [contributing guide](Contributing.markdown).
data/bin/hue ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'hue'
6
+ require 'hue/cli'
7
+
8
+ Hue::Cli.start
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'hue/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'hue'
8
+ spec.version = Hue::VERSION
9
+ spec.authors = ['Sam Soffes']
10
+ spec.email = ['sam@soff.es']
11
+ spec.description = 'Work with Philips Hue light bulbs.'
12
+ spec.summary = 'Work with Philips Hue light bulbs from Ruby.'
13
+ spec.homepage = 'https://github.com/soffes/hue'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.required_ruby_version = '>= 1.8.7'
22
+ spec.add_dependency 'multi_json'
23
+ spec.add_dependency 'thor'
24
+ end
@@ -0,0 +1,8 @@
1
+ require 'hue/version'
2
+ require 'hue/errors'
3
+ require 'hue/client'
4
+ require 'hue/light'
5
+
6
+ module Hue
7
+ USERNAME_RANGE = 10..40
8
+ end
@@ -0,0 +1,26 @@
1
+ require 'thor'
2
+
3
+ module Hue
4
+ class Cli < Thor
5
+ desc 'lights', 'Find all of the lights on your network'
6
+ def lights
7
+ client.lights.each do |light|
8
+ puts light.id.to_s.ljust(6) + light.name
9
+ end
10
+ end
11
+
12
+ desc 'all STATE', 'Send commands to all lights'
13
+ def all(state)
14
+ on = state == 'on'
15
+ client.lights.each do |light|
16
+ light.on = on
17
+ end
18
+ end
19
+
20
+ private
21
+
22
+ def client
23
+ @client ||= Hue::Client.new
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,80 @@
1
+ require 'net/http'
2
+ require 'multi_json'
3
+
4
+ module Hue
5
+ class Client
6
+ attr_reader :username
7
+
8
+ def initialize(username = '1234567890')
9
+ unless USERNAME_RANGE.include?(username.length)
10
+ raise InvalidUsername, "Usernames must be between #{USERNAME_RANGE.first} and #{USERNAME_RANGE.last}."
11
+ end
12
+
13
+ @username = username
14
+ validate_user
15
+ end
16
+
17
+ def base_station
18
+ # Pick the first one for now. In theory, they should all do the same thing.
19
+ base_station = base_stations.first
20
+ raise NoBaseStationFound unless base_station
21
+ base_station
22
+ end
23
+
24
+ def base_stations
25
+ @base_stations ||= MultiJson.load(Net::HTTP.get(URI.parse('http://www.meethue.com/api/nupnp')))
26
+ end
27
+
28
+ def lights
29
+ @lights ||= begin
30
+ ls = []
31
+ json = MultiJson.load(Net::HTTP.get(URI.parse("http://#{bridge_ip}/api/#{@username}/lights")))
32
+ json.each do |key, value|
33
+ ls << Light.new(self, key, value['name'])
34
+ end
35
+ ls
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def validate_user
42
+ response = MultiJson.load(Net::HTTP.get(URI.parse("http://#{bridge_ip}/api/#{@username}")))
43
+ if error = response['error']
44
+ parse_error(error)
45
+ end
46
+ response['success']
47
+ end
48
+
49
+ def register_user
50
+ body = {
51
+ devicetype: 'Ruby',
52
+ username: @username
53
+ }
54
+
55
+ uri = URI.parse("http://#{bridge_ip}/api")
56
+ http = Net::HTTP.new(uri.hostname)
57
+ response = MultiJson.load(http.request_post(uri.path, MultiJson.dump(body)).body).first
58
+
59
+ if error = response['error']
60
+ parse_error(error)
61
+ end
62
+ response['success']
63
+ end
64
+
65
+ def bridge_ip
66
+ base_station['internalipaddress']
67
+ end
68
+
69
+ def parse_error(error)
70
+ # Find error or return
71
+ klass = Hue::ERROR_MAP[error['type']]
72
+ klass = UnknownError unless klass
73
+
74
+ # Raise error
75
+ raise klass.new(error['description'])
76
+ rescue Hue::UnauthorizedUser
77
+ register_user
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,37 @@
1
+ module Hue
2
+ class Error < StandardError; end
3
+
4
+ class UnauthorizedUser < Error; end
5
+ class InvalidJSON < Error; end
6
+ class ResourceNotAvailable < Error; end
7
+ class MethodNotAvailable < Error; end
8
+ class MissingBody < Error; end
9
+ class ParameterNotAvailable < Error; end
10
+ class InvalidValueForParameter < Error; end
11
+ class ParameterNotModifiable < Error; end
12
+ class InternalError < Error; end
13
+ class LinkButtonNotPressed < Error; end
14
+ class ParameterNotModifiableWhileOff < ParameterNotModifiable; end
15
+ class TooManyGroups < Error; end
16
+ class GroupTooFull < Error; end
17
+
18
+ class InvalidUsername < Error; end
19
+ class UnknownError < Error; end
20
+
21
+ # Status code to exception map
22
+ ERROR_MAP = {
23
+ 1 => Hue::UnauthorizedUser,
24
+ 2 => Hue::InvalidJSON,
25
+ 3 => Hue::ResourceNotAvailable,
26
+ 4 => Hue::MethodNotAvailable,
27
+ 5 => Hue::MissingBody,
28
+ 6 => Hue::ParameterNotAvailable,
29
+ 7 => Hue::InvalidValueForParameter,
30
+ 8 => Hue::ParameterNotModifiable,
31
+ 901 => Hue::InternalError,
32
+ 101 => Hue::LinkButtonNotPressed,
33
+ 201 => Hue::ParameterNotModifiableWhileOff,
34
+ 301 => Hue::TooManyGroups,
35
+ 302 => Hue::GroupTooFull
36
+ }
37
+ end
@@ -0,0 +1,66 @@
1
+ module Hue
2
+ class Light
3
+ attr_reader :id
4
+ attr_reader :name
5
+ attr_reader :state
6
+ attr_reader :type
7
+ attr_reader :model
8
+ attr_reader :software_version
9
+ attr_reader :point_symbol
10
+
11
+ def initialize(client, id, name)
12
+ @client = client
13
+ @id = id
14
+ @name = name
15
+ refresh
16
+ end
17
+
18
+ def on?
19
+ @state['on']
20
+ end
21
+
22
+ def on=(new_state)
23
+ self.set_state(new_state)
24
+ end
25
+
26
+ def hsb
27
+ @state.select { |k, v| %w{sat bri hue}.include?(k) }
28
+ end
29
+
30
+ def set_state(on, hue = nil, saturation = nil, brightness = nil)
31
+ body = {
32
+ on: on
33
+ }
34
+
35
+ if on
36
+ body.merge!({
37
+ hue: hue,
38
+ sat: saturation,
39
+ bri: brightness
40
+ })
41
+ end
42
+
43
+ bridge_ip = @client.base_station['internalipaddress']
44
+ uri = URI.parse("http://#{bridge_ip}/api/#{@client.username}/lights/#{self.id}/state")
45
+
46
+ http = Net::HTTP.new(uri.hostname)
47
+ response = http.request_put(uri.path, MultiJson.dump(body))
48
+ MultiJson.load(response.body)
49
+ end
50
+
51
+ private
52
+
53
+ def refresh
54
+ bridge_ip = @client.base_station['internalipaddress']
55
+ uri = URI.parse("http://#{bridge_ip}/api/#{@client.username}/lights/#{self.id}")
56
+ json = MultiJson.load(Net::HTTP.get(uri))
57
+
58
+ @state = json['state']
59
+ @type = json['type']
60
+ @name = json['name']
61
+ @model = json['modelid']
62
+ @software_version = json['swversion']
63
+ @point_symbol = json['pointsymbol']
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,3 @@
1
+ module Hue
2
+ VERSION = '0.0.1'
3
+ end
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hue
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Sam Soffes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-03-19 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: multi_json
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: thor
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Work with Philips Hue light bulbs.
42
+ email:
43
+ - sam@soff.es
44
+ executables:
45
+ - hue
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - .gitignore
50
+ - Contributing.markdown
51
+ - Gemfile
52
+ - LICENSE
53
+ - Rakefile
54
+ - Readme.markdown
55
+ - bin/hue
56
+ - hue.gemspec
57
+ - lib/hue.rb
58
+ - lib/hue/cli.rb
59
+ - lib/hue/client.rb
60
+ - lib/hue/errors.rb
61
+ - lib/hue/light.rb
62
+ - lib/hue/version.rb
63
+ homepage: https://github.com/soffes/hue
64
+ licenses:
65
+ - MIT
66
+ metadata: {}
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: 1.8.7
76
+ required_rubygems_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - '>='
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ requirements: []
82
+ rubyforge_project:
83
+ rubygems_version: 2.0.0
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: Work with Philips Hue light bulbs from Ruby.
87
+ test_files: []