hue 0.1.5 → 0.3.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.
- checksums.yaml +5 -5
- data/.github/workflows/main.yml +14 -0
- data/LICENSE +1 -1
- data/{Readme.markdown → README.md} +1 -6
- data/Rakefile +9 -0
- data/bin/hue +5 -1
- data/hue.gemspec +3 -1
- data/lib/hue/bridge.rb +3 -0
- data/lib/hue/client.rb +91 -45
- data/lib/hue/light.rb +6 -6
- data/lib/hue/version.rb +1 -1
- data/test/hue/client_test.rb +25 -0
- data/test/hue/light_test.rb +24 -0
- data/test/test_helper.rb +6 -0
- metadata +44 -12
- data/Contributing.markdown +0 -19
- data/Todo.markdown +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: af74df93c5514679bab0613c9c6c87b0a0dfae19b919fc903ad42a8fafe9b681
|
4
|
+
data.tar.gz: 0afb9bd5b7ee11be0a1dce6b56846c6d13fa7cd9a9b67e2f9c8014c8d03f0fb7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00f64a5fdad18722af090747e6a2dfe2a5fefb556bcd634ee7b498f54df80e23e94975c295a2925a46cf2166e88df0af07dee1999e26446f7e42e66ebbc8778b
|
7
|
+
data.tar.gz: f54f5552bceb7456b0a1d6ccdc29f7ca3cb01636231d83a5f0d7d93b907defce6bfbfcb0e2f96444e49543fbb85f7cda66586f72eedaea912c7a18f5ededb570
|
@@ -0,0 +1,14 @@
|
|
1
|
+
name: Tests
|
2
|
+
on: [push]
|
3
|
+
jobs:
|
4
|
+
test:
|
5
|
+
name: Test Swift Package
|
6
|
+
runs-on: ubuntu-latest
|
7
|
+
timeout-minutes: 5
|
8
|
+
steps:
|
9
|
+
- uses: actions/checkout@v1
|
10
|
+
- uses: actions/setup-ruby@v1
|
11
|
+
- name: 'Install Dependencies'
|
12
|
+
run: sudo apt-get install libcurl4-openssl-dev && gem install bundler && bundle install
|
13
|
+
- name: 'Test'
|
14
|
+
run: bundle exec rake test
|
data/LICENSE
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
Work with Philips Hue light bulbs from Ruby.
|
4
4
|
|
5
|
-
[](https://codeclimate.com/github/soffes/hue) [](https://gemnasium.com/soffes/hue) [](http://badge.fury.io/rb/hue)
|
6
5
|
|
7
6
|
## Installation
|
8
7
|
|
@@ -64,7 +63,7 @@ group = client.group(1)
|
|
64
63
|
|
65
64
|
# Accessing group lights
|
66
65
|
group.lights.first.on!
|
67
|
-
group.lights.each { |light| light.hue = rand(
|
66
|
+
group.lights.each { |light| light.hue = rand(Hue::Light::HUE_RANGE) }
|
68
67
|
|
69
68
|
# Creating groups
|
70
69
|
group = client.group # Don't specify an ID
|
@@ -78,7 +77,3 @@ group.new? # => false
|
|
78
77
|
# Destroying groups
|
79
78
|
client.groups.last.destroy!
|
80
79
|
```
|
81
|
-
|
82
|
-
## Contributing
|
83
|
-
|
84
|
-
See the [contributing guide](Contributing.markdown).
|
data/Rakefile
CHANGED
data/bin/hue
CHANGED
@@ -5,4 +5,8 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
5
5
|
require 'hue'
|
6
6
|
require 'hue/cli'
|
7
7
|
|
8
|
-
|
8
|
+
begin
|
9
|
+
Hue::Cli.start
|
10
|
+
rescue Hue::LinkButtonNotPressed
|
11
|
+
abort("Error: Press the link button on your bridge and then run this command again within 30 seconds of pressing it.")
|
12
|
+
end
|
data/hue.gemspec
CHANGED
@@ -18,9 +18,11 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
spec.require_paths = ['lib']
|
20
20
|
|
21
|
-
spec.required_ruby_version = '>= 1.
|
21
|
+
spec.required_ruby_version = '>= 2.1.0'
|
22
22
|
spec.add_dependency 'thor'
|
23
23
|
spec.add_dependency 'json'
|
24
24
|
spec.add_dependency 'log_switch', '0.4.0'
|
25
25
|
spec.add_dependency 'curb'
|
26
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
27
|
+
spec.add_development_dependency 'webmock'
|
26
28
|
end
|
data/lib/hue/bridge.rb
CHANGED
data/lib/hue/client.rb
CHANGED
@@ -1,28 +1,35 @@
|
|
1
1
|
require 'net/http'
|
2
2
|
require 'json'
|
3
|
+
require 'resolv'
|
3
4
|
require 'curb'
|
4
5
|
|
5
6
|
module Hue
|
6
7
|
class Client
|
7
8
|
attr_reader :username
|
8
9
|
|
9
|
-
def initialize(username =
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
@username = username
|
10
|
+
def initialize(username = nil, use_mdns: true)
|
11
|
+
@bridge_id = nil
|
12
|
+
@username = username || find_username
|
13
|
+
@use_mdns = use_mdns
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
if @username
|
16
|
+
begin
|
17
|
+
validate_user
|
18
|
+
rescue Hue::UnauthorizedUser
|
19
|
+
register_user
|
20
|
+
end
|
21
|
+
else
|
19
22
|
register_user
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
23
26
|
def bridge
|
24
|
-
|
25
|
-
|
27
|
+
@bridge_id = find_bridge_id unless @bridge_id
|
28
|
+
if @bridge_id
|
29
|
+
bridge = bridges.select { |b| b.id == @bridge_id }.first
|
30
|
+
else
|
31
|
+
bridge = bridges.first
|
32
|
+
end
|
26
33
|
raise NoBridgeFound unless bridge
|
27
34
|
bridge
|
28
35
|
end
|
@@ -30,14 +37,8 @@ module Hue
|
|
30
37
|
def bridges
|
31
38
|
@bridges ||= begin
|
32
39
|
bs = []
|
33
|
-
|
34
|
-
|
35
|
-
easy.max_redirects = 10
|
36
|
-
easy.url = 'https://www.meethue.com/api/nupnp'
|
37
|
-
easy.perform
|
38
|
-
JSON(easy.body).each do |hash|
|
39
|
-
bs << Bridge.new(self, hash)
|
40
|
-
end
|
40
|
+
discovery_mdns(bs) if @use_mdns
|
41
|
+
discovery_meethue(bs) if bs.empty?
|
41
42
|
bs
|
42
43
|
end
|
43
44
|
end
|
@@ -75,44 +76,89 @@ module Hue
|
|
75
76
|
scenes.select { |s| s.id == id }.first
|
76
77
|
end
|
77
78
|
|
78
|
-
|
79
|
+
private
|
79
80
|
|
80
|
-
|
81
|
-
|
81
|
+
def find_username
|
82
|
+
return ENV['HUE_USERNAME'] if ENV['HUE_USERNAME']
|
82
83
|
|
83
|
-
|
84
|
-
|
84
|
+
json = JSON(File.read(File.expand_path('~/.hue')))
|
85
|
+
json['username']
|
86
|
+
rescue
|
87
|
+
return nil
|
85
88
|
end
|
86
89
|
|
87
|
-
|
88
|
-
|
90
|
+
def validate_user
|
91
|
+
response = JSON(Net::HTTP.get(URI.parse("http://#{bridge.ip}/api/#{@username}")))
|
92
|
+
|
93
|
+
if response.is_a? Array
|
94
|
+
response = response.first
|
95
|
+
end
|
96
|
+
|
97
|
+
if error = response['error']
|
98
|
+
raise get_error(error)
|
99
|
+
end
|
100
|
+
|
101
|
+
response['success']
|
89
102
|
end
|
90
103
|
|
91
|
-
|
92
|
-
|
104
|
+
def register_user
|
105
|
+
body = JSON.dump({
|
106
|
+
devicetype: 'Ruby'
|
107
|
+
})
|
108
|
+
|
109
|
+
uri = URI.parse("http://#{bridge.ip}/api")
|
110
|
+
http = Net::HTTP.new(uri.host)
|
111
|
+
response = JSON(http.request_post(uri.path, body).body).first
|
112
|
+
|
113
|
+
if error = response['error']
|
114
|
+
raise get_error(error)
|
115
|
+
end
|
93
116
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
})
|
117
|
+
if @username = response['success']['username']
|
118
|
+
File.write(File.expand_path('~/.hue'), JSON.dump({username: @username}))
|
119
|
+
end
|
120
|
+
end
|
99
121
|
|
100
|
-
|
101
|
-
|
102
|
-
response = JSON(http.request_post(uri.path, body).body).first
|
122
|
+
def find_bridge_id
|
123
|
+
return ENV['HUE_BRIDGE_ID'] if ENV['HUE_BRIDGE_ID']
|
103
124
|
|
104
|
-
|
105
|
-
|
125
|
+
json = JSON(File.read(File.expand_path('~/.hue')))
|
126
|
+
json['bridge_id']
|
127
|
+
rescue
|
128
|
+
return nil
|
106
129
|
end
|
107
130
|
|
108
|
-
|
109
|
-
|
131
|
+
def discovery_mdns(bs)
|
132
|
+
resolver = Resolv::MDNS.new
|
133
|
+
resolver.timeouts = 10
|
110
134
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
135
|
+
resolver.each_resource("_hue._tcp.local", Resolv::DNS::Resource::IN::PTR) do |bridge_ptr|
|
136
|
+
bridge_target = resolver.getresource(bridge_ptr.name, Resolv::DNS::Resource::IN::SRV).target
|
137
|
+
|
138
|
+
bridge_hash = {
|
139
|
+
'id' => resolver.getresource(bridge_ptr.name, Resolv::DNS::Resource::IN::TXT).strings[0].split('=')[1],
|
140
|
+
'internalipaddress' => resolver.getresource(bridge_target, Resolv::DNS::Resource::IN::A).address
|
141
|
+
}
|
116
142
|
|
143
|
+
bs << Bridge.new(self, bridge_hash)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
def discovery_meethue(bs)
|
148
|
+
easy = Curl::Easy.new
|
149
|
+
easy.follow_location = true
|
150
|
+
easy.max_redirects = 10
|
151
|
+
easy.url = 'https://discovery.meethue.com/'
|
152
|
+
easy.perform
|
153
|
+
JSON(easy.body).each do |hash|
|
154
|
+
bs << Bridge.new(self, hash)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def get_error(error)
|
159
|
+
# Find error class and return instance
|
160
|
+
klass = Hue::ERROR_MAP[error['type']] || UnknownError unless klass
|
161
|
+
klass.new(error['description'])
|
162
|
+
end
|
117
163
|
end
|
118
164
|
end
|
data/lib/hue/light.rb
CHANGED
@@ -19,16 +19,16 @@ module Hue
|
|
19
19
|
|
20
20
|
# Hue of the light. This is a wrapping value between 0 and 65535.
|
21
21
|
# Both 0 and 65535 are red, 25500 is green and 46920 is blue.
|
22
|
-
|
22
|
+
attr_reader :hue
|
23
23
|
|
24
24
|
# Saturation of the light. 255 is the most saturated (colored)
|
25
25
|
# and 0 is the least saturated (white).
|
26
|
-
|
26
|
+
attr_reader :saturation
|
27
27
|
|
28
28
|
# Brightness of the light. This is a scale from the minimum
|
29
29
|
# brightness the light is capable of, 0, to the maximum capable
|
30
30
|
# brightness, 255. Note a brightness of 0 is not off.
|
31
|
-
|
31
|
+
attr_reader :brightness
|
32
32
|
|
33
33
|
# The x coordinate of a color in CIE color space. Between 0 and 1.
|
34
34
|
#
|
@@ -44,7 +44,7 @@ module Hue
|
|
44
44
|
# are capable of 153 (6500K) to 500 (2000K).
|
45
45
|
#
|
46
46
|
# @see http://en.wikipedia.org/wiki/Mired
|
47
|
-
|
47
|
+
attr_reader :color_temperature
|
48
48
|
|
49
49
|
# The alert effect, which is a temporary change to the bulb’s state.
|
50
50
|
# This can take one of the following values:
|
@@ -58,12 +58,12 @@ module Hue
|
|
58
58
|
# current state in an upcoming patch.
|
59
59
|
#
|
60
60
|
# @see http://developers.meethue.com/coreconcepts.html#some_extra_fun_stuff
|
61
|
-
|
61
|
+
attr_reader :alert
|
62
62
|
|
63
63
|
# The dynamic effect of the light, can either be `none` or
|
64
64
|
# `colorloop`. If set to colorloop, the light will cycle through
|
65
65
|
# all hues using the current brightness and saturation settings.
|
66
|
-
|
66
|
+
attr_reader :effect
|
67
67
|
|
68
68
|
# Indicates the color mode in which the light is working, this is
|
69
69
|
# the last command type it received. Values are `hs` for Hue and
|
data/lib/hue/version.rb
CHANGED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ClientTest < Minitest::Test
|
4
|
+
def before_setup
|
5
|
+
super
|
6
|
+
|
7
|
+
stub_request(:get, "https://discovery.meethue.com/").
|
8
|
+
to_return(:body => '[{"id":"ffa57b3b257200065704","internalipaddress":"192.168.0.1"},{"id":"63c2fc01391276a319f9","internalipaddress":"192.168.0.2"}]')
|
9
|
+
|
10
|
+
stub_request(:get, %r{http://192.168.0.1/api/*}).to_return(:body => '[{"success":true}]')
|
11
|
+
stub_request(:get, %r{http://192.168.0.2/api/*}).to_return(:body => '[{"success":true}]')
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_with_bridge_id
|
15
|
+
client = Hue::Client.new(use_mdns: false)
|
16
|
+
client.stub :find_bridge_id, '63c2fc01391276a319f9' do
|
17
|
+
assert_equal '63c2fc01391276a319f9', client.bridge.id
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_without_bridge_id
|
22
|
+
client = Hue::Client.new(use_mdns: false)
|
23
|
+
assert_equal 'ffa57b3b257200065704', client.bridge.id
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class LightTest < Minitest::Test
|
4
|
+
def before_setup
|
5
|
+
super
|
6
|
+
|
7
|
+
stub_request(:get, "https://discovery.meethue.com/").
|
8
|
+
to_return(:body => '[{"internalipaddress":"localhost"}]')
|
9
|
+
|
10
|
+
stub_request(:get, %r{http://localhost/api/*}).to_return(:body => '[{"success":true}]')
|
11
|
+
stub_request(:post, 'http://localhost/api').to_return(:body => '[{"success":{"username":"ruby"}}]')
|
12
|
+
stub_request(:put, %r{http://localhost/api*}).to_return(:body => '[{}]')
|
13
|
+
end
|
14
|
+
|
15
|
+
%w{on hue saturation brightness color_temperature alert effect}.each do |attribute|
|
16
|
+
define_method "test_setting_#{attribute}" do
|
17
|
+
client = Hue::Client.new(use_mdns: false)
|
18
|
+
light = Hue::Light.new(client, client.bridge, 0, {"state" => {}})
|
19
|
+
|
20
|
+
light.send("#{attribute}=", 24)
|
21
|
+
assert_requested :put, %r{http://localhost/api/.*/lights/0}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Soffes
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -66,6 +66,34 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: minitest
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '5.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: webmock
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
69
97
|
description: Work with Philips Hue light bulbs.
|
70
98
|
email:
|
71
99
|
- sam@soff.es
|
@@ -74,13 +102,12 @@ executables:
|
|
74
102
|
extensions: []
|
75
103
|
extra_rdoc_files: []
|
76
104
|
files:
|
105
|
+
- ".github/workflows/main.yml"
|
77
106
|
- ".gitignore"
|
78
|
-
- Contributing.markdown
|
79
107
|
- Gemfile
|
80
108
|
- LICENSE
|
109
|
+
- README.md
|
81
110
|
- Rakefile
|
82
|
-
- Readme.markdown
|
83
|
-
- Todo.markdown
|
84
111
|
- bin/hue
|
85
112
|
- hue.gemspec
|
86
113
|
- lib/hue.rb
|
@@ -94,11 +121,14 @@ files:
|
|
94
121
|
- lib/hue/scene.rb
|
95
122
|
- lib/hue/translate_keys.rb
|
96
123
|
- lib/hue/version.rb
|
124
|
+
- test/hue/client_test.rb
|
125
|
+
- test/hue/light_test.rb
|
126
|
+
- test/test_helper.rb
|
97
127
|
homepage: https://github.com/soffes/hue
|
98
128
|
licenses:
|
99
129
|
- MIT
|
100
130
|
metadata: {}
|
101
|
-
post_install_message:
|
131
|
+
post_install_message:
|
102
132
|
rdoc_options: []
|
103
133
|
require_paths:
|
104
134
|
- lib
|
@@ -106,16 +136,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
106
136
|
requirements:
|
107
137
|
- - ">="
|
108
138
|
- !ruby/object:Gem::Version
|
109
|
-
version: 1.
|
139
|
+
version: 2.1.0
|
110
140
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
111
141
|
requirements:
|
112
142
|
- - ">="
|
113
143
|
- !ruby/object:Gem::Version
|
114
144
|
version: '0'
|
115
145
|
requirements: []
|
116
|
-
|
117
|
-
|
118
|
-
signing_key:
|
146
|
+
rubygems_version: 3.4.22
|
147
|
+
signing_key:
|
119
148
|
specification_version: 4
|
120
149
|
summary: Work with Philips Hue light bulbs from Ruby.
|
121
|
-
test_files:
|
150
|
+
test_files:
|
151
|
+
- test/hue/client_test.rb
|
152
|
+
- test/hue/light_test.rb
|
153
|
+
- test/test_helper.rb
|
data/Contributing.markdown
DELETED
@@ -1,19 +0,0 @@
|
|
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/
|