hue 0.3.0 → 0.3.2
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 +4 -4
- data/.github/workflows/main.yml +21 -6
- data/.gitignore +1 -0
- data/.ruby-version +1 -0
- data/Gemfile +5 -2
- data/LICENSE +1 -1
- data/Rakefile +8 -6
- data/bin/console +7 -0
- data/hue.gemspec +17 -22
- data/lib/hue/bridge.rb +32 -24
- data/lib/hue/cli.rb +30 -30
- data/lib/hue/client.rb +38 -38
- data/lib/hue/editable_state.rb +42 -5
- data/lib/hue/errors.rb +22 -8
- data/lib/hue/group.rb +37 -37
- data/lib/hue/http_client.rb +12 -0
- data/lib/hue/light.rb +46 -35
- data/lib/hue/scene.rb +6 -8
- data/lib/hue/translate_keys.rb +1 -1
- data/lib/hue/version.rb +1 -1
- data/lib/hue.rb +10 -9
- data/test/hue/client_test.rb +9 -8
- data/test/hue/light_test.rb +30 -10
- data/test/test_helper.rb +5 -5
- metadata +9 -53
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a93b5e3363bf3af0a578de606c2d061c44db405f77ec3d88dacbbae9ac01b420
|
|
4
|
+
data.tar.gz: 3e5e17cd8438264c403ffab5292d813c08ab9ccff39e4a3b680fe912e56fab3d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 05103d25ba76ff79bfbf7655009d818a4425fc0d20dce2146473fe1c93b8d99dcaabe8ebaeed90e8bab88d75ed7679667941ae40d3c1eb181a2f0e39f0869e84
|
|
7
|
+
data.tar.gz: ca26e94b2d5ed62af06038da96a832f9694bc1b09065bdd161be6c222bd4c872397114b7565a89e4669d02cc2c7925907cdae6cb84db67d077fb9d638e7c27a5
|
data/.github/workflows/main.yml
CHANGED
|
@@ -2,13 +2,28 @@ name: Tests
|
|
|
2
2
|
on: [push]
|
|
3
3
|
jobs:
|
|
4
4
|
test:
|
|
5
|
-
name: Test
|
|
5
|
+
name: Test
|
|
6
6
|
runs-on: ubuntu-latest
|
|
7
7
|
timeout-minutes: 5
|
|
8
8
|
steps:
|
|
9
|
-
-
|
|
10
|
-
|
|
11
|
-
- name:
|
|
12
|
-
|
|
13
|
-
|
|
9
|
+
- name: Checkout
|
|
10
|
+
uses: actions/checkout@v6
|
|
11
|
+
- name: Setup Ruby
|
|
12
|
+
uses: ruby/setup-ruby@v1
|
|
13
|
+
with:
|
|
14
|
+
bundler-cache: true
|
|
15
|
+
- name: Test
|
|
14
16
|
run: bundle exec rake test
|
|
17
|
+
lint:
|
|
18
|
+
name: Lint
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
timeout-minutes: 5
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout
|
|
23
|
+
uses: actions/checkout@v6
|
|
24
|
+
- name: Setup Ruby
|
|
25
|
+
uses: ruby/setup-ruby@v1
|
|
26
|
+
with:
|
|
27
|
+
bundler-cache: true
|
|
28
|
+
- name: Test
|
|
29
|
+
run: bundle exec rake standard
|
data/.gitignore
CHANGED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.4.7
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
data/Rakefile
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
1
|
+
require "bundler/gem_tasks"
|
|
2
|
+
require "rake/testtask"
|
|
3
3
|
|
|
4
4
|
Rake::TestTask.new(:test) do |t|
|
|
5
|
-
t.libs <<
|
|
6
|
-
t.libs <<
|
|
7
|
-
t.test_files = FileList[
|
|
5
|
+
t.libs << "test"
|
|
6
|
+
t.libs << "lib"
|
|
7
|
+
t.test_files = FileList["test/**/*_test.rb"]
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
require "standard/rake"
|
|
11
|
+
|
|
12
|
+
task default: :test
|
data/bin/console
ADDED
data/hue.gemspec
CHANGED
|
@@ -1,28 +1,23 @@
|
|
|
1
|
-
|
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
-
require
|
|
3
|
+
require "hue/version"
|
|
5
4
|
|
|
6
5
|
Gem::Specification.new do |spec|
|
|
7
|
-
spec.name
|
|
8
|
-
spec.version
|
|
9
|
-
spec.authors
|
|
10
|
-
spec.email
|
|
11
|
-
spec.description
|
|
12
|
-
spec.summary
|
|
13
|
-
spec.homepage
|
|
14
|
-
spec.license
|
|
6
|
+
spec.name = "hue"
|
|
7
|
+
spec.version = Hue::VERSION
|
|
8
|
+
spec.authors = ["Sam Soffes"]
|
|
9
|
+
spec.email = ["sam@soff.es"]
|
|
10
|
+
spec.description = "Work with Philips Hue light bulbs."
|
|
11
|
+
spec.summary = "Work with Philips Hue light bulbs from Ruby."
|
|
12
|
+
spec.homepage = "https://github.com/soffes/hue"
|
|
13
|
+
spec.license = "MIT"
|
|
15
14
|
|
|
16
|
-
spec.files
|
|
17
|
-
spec.executables
|
|
18
|
-
spec.
|
|
19
|
-
spec.require_paths = ['lib']
|
|
15
|
+
spec.files = `git ls-files`.split($/)
|
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
|
17
|
+
spec.require_paths = ["lib"]
|
|
20
18
|
|
|
21
|
-
spec.required_ruby_version =
|
|
22
|
-
spec.add_dependency
|
|
23
|
-
spec.add_dependency
|
|
24
|
-
spec.add_dependency
|
|
25
|
-
spec.add_dependency 'curb'
|
|
26
|
-
spec.add_development_dependency 'minitest', '~> 5.0'
|
|
27
|
-
spec.add_development_dependency 'webmock'
|
|
19
|
+
spec.required_ruby_version = ">= 2.1.0"
|
|
20
|
+
spec.add_dependency "thor"
|
|
21
|
+
spec.add_dependency "json"
|
|
22
|
+
spec.add_dependency "color_conversion"
|
|
28
23
|
end
|
data/lib/hue/bridge.rb
CHANGED
|
@@ -46,21 +46,21 @@ module Hue
|
|
|
46
46
|
# Current time stored on the bridge.
|
|
47
47
|
def utc
|
|
48
48
|
json = get_configuration
|
|
49
|
-
DateTime.parse(json[
|
|
49
|
+
DateTime.parse(json["utc"])
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# Indicates whether the link button has been pressed within the last 30
|
|
53
53
|
# seconds.
|
|
54
54
|
def link_button_pressed?
|
|
55
55
|
json = get_configuration
|
|
56
|
-
json[
|
|
56
|
+
json["linkbutton"]
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
# This indicates whether the bridge is registered to synchronize data with a
|
|
60
60
|
# portal account.
|
|
61
61
|
def has_portal_services?
|
|
62
62
|
json = get_configuration
|
|
63
|
-
json[
|
|
63
|
+
json["portalservices"]
|
|
64
64
|
end
|
|
65
65
|
|
|
66
66
|
def refresh
|
|
@@ -73,8 +73,10 @@ module Hue
|
|
|
73
73
|
|
|
74
74
|
def lights
|
|
75
75
|
@lights ||= begin
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
uri = URI.parse(base_url)
|
|
77
|
+
http = HttpClient.create(uri)
|
|
78
|
+
json = JSON(http.get(uri.path).body)
|
|
79
|
+
json["lights"].map do |key, value|
|
|
78
80
|
Light.new(@client, self, key, value)
|
|
79
81
|
end
|
|
80
82
|
end
|
|
@@ -82,14 +84,16 @@ module Hue
|
|
|
82
84
|
|
|
83
85
|
def add_lights
|
|
84
86
|
uri = URI.parse("#{base_url}/lights")
|
|
85
|
-
http =
|
|
87
|
+
http = HttpClient.create(uri)
|
|
86
88
|
response = http.request_post(uri.path, nil)
|
|
87
|
-
|
|
89
|
+
response.body.first
|
|
88
90
|
end
|
|
89
91
|
|
|
90
92
|
def groups
|
|
91
93
|
@groups ||= begin
|
|
92
|
-
|
|
94
|
+
uri = URI.parse("#{base_url}/groups")
|
|
95
|
+
http = HttpClient.create(uri)
|
|
96
|
+
json = JSON(http.get(uri.path).body)
|
|
93
97
|
json.map do |id, data|
|
|
94
98
|
Group.new(@client, self, id, data)
|
|
95
99
|
end
|
|
@@ -98,43 +102,47 @@ module Hue
|
|
|
98
102
|
|
|
99
103
|
def scenes
|
|
100
104
|
@scenes ||= begin
|
|
101
|
-
|
|
105
|
+
uri = URI.parse("#{base_url}/scenes")
|
|
106
|
+
http = HttpClient.create(uri)
|
|
107
|
+
json = JSON(http.get(uri.path).body)
|
|
102
108
|
json.map do |id, data|
|
|
103
109
|
Scene.new(@client, self, id, data)
|
|
104
110
|
end
|
|
105
111
|
end
|
|
106
112
|
end
|
|
107
113
|
|
|
108
|
-
|
|
114
|
+
private
|
|
109
115
|
|
|
110
116
|
KEYS_MAP = {
|
|
111
|
-
:
|
|
112
|
-
:
|
|
113
|
-
:
|
|
114
|
-
:
|
|
115
|
-
:
|
|
116
|
-
:
|
|
117
|
-
:
|
|
118
|
-
:
|
|
119
|
-
:
|
|
120
|
-
:
|
|
121
|
-
:
|
|
117
|
+
id: :id,
|
|
118
|
+
ip: :internalipaddress,
|
|
119
|
+
name: :name,
|
|
120
|
+
proxy_port: :proxyport,
|
|
121
|
+
software_update: :swupdate,
|
|
122
|
+
ip_whitelist: :whitelist,
|
|
123
|
+
software_version: :swversion,
|
|
124
|
+
proxy_address: :proxyaddress,
|
|
125
|
+
mac_address: :macaddress,
|
|
126
|
+
network_mask: :netmask,
|
|
127
|
+
portal_services: :portalservices
|
|
122
128
|
}
|
|
123
129
|
|
|
124
130
|
def unpack(hash)
|
|
125
131
|
KEYS_MAP.each do |local_key, remote_key|
|
|
126
132
|
value = hash[remote_key.to_s]
|
|
127
133
|
next unless value
|
|
128
|
-
instance_variable_set("@#{local_key}", value)
|
|
134
|
+
instance_variable_set(:"@#{local_key}", value)
|
|
129
135
|
end
|
|
130
136
|
end
|
|
131
137
|
|
|
132
138
|
def get_configuration
|
|
133
|
-
|
|
139
|
+
uri = URI.parse("#{base_url}/config")
|
|
140
|
+
http = HttpClient.create(uri)
|
|
141
|
+
JSON(http.get(uri.path).body)
|
|
134
142
|
end
|
|
135
143
|
|
|
136
144
|
def base_url
|
|
137
|
-
"
|
|
145
|
+
"https://#{ip}/api/#{@client.username}"
|
|
138
146
|
end
|
|
139
147
|
end
|
|
140
148
|
end
|
data/lib/hue/cli.rb
CHANGED
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
require
|
|
1
|
+
require "thor"
|
|
2
2
|
|
|
3
3
|
module Hue
|
|
4
4
|
class Cli < Thor
|
|
5
|
-
desc
|
|
5
|
+
desc "lights", "Find all of the lights on your network"
|
|
6
6
|
def lights
|
|
7
7
|
client.lights.each do |light|
|
|
8
8
|
puts light.id.to_s.ljust(6) + light.name
|
|
9
9
|
end
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
desc
|
|
12
|
+
desc "add LIGHTS", "Search for new lights"
|
|
13
13
|
def add(thing)
|
|
14
14
|
case thing
|
|
15
|
-
when
|
|
15
|
+
when "lights"
|
|
16
16
|
client.add_lights
|
|
17
17
|
end
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
desc
|
|
20
|
+
desc "light ID STATE [COLOR]", "Access a light"
|
|
21
21
|
long_desc <<-LONGDESC
|
|
22
22
|
Examples: \n
|
|
23
23
|
hue all on \n
|
|
24
24
|
hue all off \n
|
|
25
25
|
hue all --hue 12345 \n
|
|
26
|
-
hue all --
|
|
27
|
-
hue all --hue 50000 --
|
|
26
|
+
hue all --brightness 25 \n
|
|
27
|
+
hue all --hue 50000 --brightness 200 --saturation 240 \n
|
|
28
28
|
hue all --alert lselect \n
|
|
29
29
|
LONGDESC
|
|
30
|
-
option :hue, :
|
|
31
|
-
option :sat, :
|
|
32
|
-
option :bri, :
|
|
33
|
-
option :alert, :
|
|
34
|
-
desc
|
|
35
|
-
def all(state =
|
|
30
|
+
option :hue, type: :numeric
|
|
31
|
+
option :sat, type: :numeric, aliases: "--saturation"
|
|
32
|
+
option :bri, type: :numeric, aliases: "--brightness"
|
|
33
|
+
option :alert, type: :string
|
|
34
|
+
desc "all STATE", "Send commands to all lights"
|
|
35
|
+
def all(state = "on")
|
|
36
36
|
body = options.dup
|
|
37
|
-
body[:on] = state ==
|
|
37
|
+
body[:on] = state == "on"
|
|
38
38
|
client.lights.each do |light|
|
|
39
39
|
puts light.set_state body
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
desc
|
|
43
|
+
desc "light ID STATE [COLOR]", "Access a light"
|
|
44
44
|
long_desc <<-LONGDESC
|
|
45
45
|
Examples: \n
|
|
46
46
|
hue light 1 on --hue 12345 \n
|
|
47
|
-
hue light 1 --
|
|
47
|
+
hue light 1 --brightness 25 \n
|
|
48
48
|
hue light 1 --alert lselect \n
|
|
49
49
|
hue light 1 off
|
|
50
50
|
LONGDESC
|
|
51
|
-
option :hue, :
|
|
52
|
-
option :sat, :
|
|
53
|
-
option :
|
|
54
|
-
option :alert, :
|
|
51
|
+
option :hue, type: :numeric
|
|
52
|
+
option :sat, type: :numeric, aliases: "--saturation"
|
|
53
|
+
option :bri, type: :numeric, aliases: "--brightness"
|
|
54
|
+
option :alert, type: :string
|
|
55
55
|
def light(id, state = nil)
|
|
56
56
|
light = client.light(id)
|
|
57
57
|
puts light.name
|
|
58
58
|
|
|
59
59
|
body = options.dup
|
|
60
|
-
body[:on] = (state ==
|
|
60
|
+
body[:on] = (state == "on" || !(state == "off"))
|
|
61
61
|
puts light.set_state(body) if body.length > 0
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
desc
|
|
64
|
+
desc "groups", "Find all light groups on your network"
|
|
65
65
|
def groups
|
|
66
66
|
client.groups.each do |group|
|
|
67
67
|
puts group.id.to_s.ljust(6) + group.name
|
|
@@ -71,28 +71,28 @@ module Hue
|
|
|
71
71
|
end
|
|
72
72
|
end
|
|
73
73
|
|
|
74
|
-
desc
|
|
74
|
+
desc "group ID STATE [COLOR]", "Update a group of lights"
|
|
75
75
|
long_desc <<-LONGDESC
|
|
76
76
|
Examples: \n
|
|
77
77
|
hue groups 1 on --hue 12345
|
|
78
|
-
hue groups 1 --
|
|
78
|
+
hue groups 1 --brightness 25
|
|
79
79
|
hue groups 1 --alert lselect
|
|
80
80
|
hue groups 1 off
|
|
81
81
|
LONGDESC
|
|
82
|
-
option :hue, :
|
|
83
|
-
option :sat, :
|
|
84
|
-
option :
|
|
85
|
-
option :alert, :
|
|
82
|
+
option :hue, type: :numeric
|
|
83
|
+
option :sat, type: :numeric, aliases: "--saturation"
|
|
84
|
+
option :bri, type: :numeric, aliases: "--brightness"
|
|
85
|
+
option :alert, type: :string
|
|
86
86
|
def group(id, state = nil)
|
|
87
87
|
group = client.group(id)
|
|
88
88
|
puts group.name
|
|
89
89
|
|
|
90
90
|
body = options.dup
|
|
91
|
-
body[:on] = (state ==
|
|
91
|
+
body[:on] = (state == "on" || !(state == "off"))
|
|
92
92
|
puts group.set_state(body) if body.length > 0
|
|
93
93
|
end
|
|
94
94
|
|
|
95
|
-
|
|
95
|
+
private
|
|
96
96
|
|
|
97
97
|
def client
|
|
98
98
|
@client ||= Hue::Client.new
|
data/lib/hue/client.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require
|
|
2
|
-
require
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
require "net/http"
|
|
2
|
+
require "openssl"
|
|
3
|
+
require "json"
|
|
4
|
+
require "resolv"
|
|
5
5
|
|
|
6
6
|
module Hue
|
|
7
7
|
class Client
|
|
@@ -24,11 +24,11 @@ module Hue
|
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def bridge
|
|
27
|
-
@bridge_id
|
|
28
|
-
if @bridge_id
|
|
29
|
-
|
|
27
|
+
@bridge_id ||= find_bridge_id
|
|
28
|
+
bridge = if @bridge_id
|
|
29
|
+
bridges.find { |b| b.id == @bridge_id }
|
|
30
30
|
else
|
|
31
|
-
|
|
31
|
+
bridges.first
|
|
32
32
|
end
|
|
33
33
|
raise NoBridgeFound unless bridge
|
|
34
34
|
bridge
|
|
@@ -53,7 +53,7 @@ module Hue
|
|
|
53
53
|
|
|
54
54
|
def light(id)
|
|
55
55
|
id = id.to_s
|
|
56
|
-
lights.
|
|
56
|
+
lights.find { |l| l.id == id }
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
def groups
|
|
@@ -64,7 +64,7 @@ module Hue
|
|
|
64
64
|
return Group.new(self, bridge) if id.nil?
|
|
65
65
|
|
|
66
66
|
id = id.to_s
|
|
67
|
-
groups.
|
|
67
|
+
groups.find { |g| g.id == id }
|
|
68
68
|
end
|
|
69
69
|
|
|
70
70
|
def scenes
|
|
@@ -73,59 +73,61 @@ module Hue
|
|
|
73
73
|
|
|
74
74
|
def scene(id)
|
|
75
75
|
id = id.to_s
|
|
76
|
-
scenes.
|
|
76
|
+
scenes.find { |s| s.id == id }
|
|
77
77
|
end
|
|
78
78
|
|
|
79
79
|
private
|
|
80
80
|
|
|
81
81
|
def find_username
|
|
82
|
-
return ENV[
|
|
82
|
+
return ENV["HUE_USERNAME"] if ENV["HUE_USERNAME"]
|
|
83
83
|
|
|
84
|
-
json = JSON(File.read(File.expand_path(
|
|
85
|
-
json[
|
|
84
|
+
json = JSON(File.read(File.expand_path("~/.hue")))
|
|
85
|
+
json["username"]
|
|
86
86
|
rescue
|
|
87
|
-
|
|
87
|
+
nil
|
|
88
88
|
end
|
|
89
89
|
|
|
90
90
|
def validate_user
|
|
91
|
-
|
|
91
|
+
uri = URI.parse("https://#{bridge.ip}/api/#{@username}")
|
|
92
|
+
http = HttpClient.create(uri)
|
|
93
|
+
response = JSON(http.get(uri.path).body)
|
|
92
94
|
|
|
93
95
|
if response.is_a? Array
|
|
94
96
|
response = response.first
|
|
95
97
|
end
|
|
96
98
|
|
|
97
|
-
if error = response[
|
|
99
|
+
if (error = response["error"])
|
|
98
100
|
raise get_error(error)
|
|
99
101
|
end
|
|
100
102
|
|
|
101
|
-
response[
|
|
103
|
+
response["success"]
|
|
102
104
|
end
|
|
103
105
|
|
|
104
106
|
def register_user
|
|
105
107
|
body = JSON.dump({
|
|
106
|
-
devicetype:
|
|
108
|
+
devicetype: "Ruby"
|
|
107
109
|
})
|
|
108
110
|
|
|
109
|
-
uri = URI.parse("
|
|
110
|
-
http =
|
|
111
|
+
uri = URI.parse("https://#{bridge.ip}/api")
|
|
112
|
+
http = HttpClient.create(uri)
|
|
111
113
|
response = JSON(http.request_post(uri.path, body).body).first
|
|
112
114
|
|
|
113
|
-
if error = response[
|
|
115
|
+
if (error = response["error"])
|
|
114
116
|
raise get_error(error)
|
|
115
117
|
end
|
|
116
118
|
|
|
117
|
-
if @username = response[
|
|
118
|
-
File.write(File.expand_path(
|
|
119
|
+
if (@username = response["success"]["username"])
|
|
120
|
+
File.write(File.expand_path("~/.hue"), JSON.dump({username: @username}))
|
|
119
121
|
end
|
|
120
122
|
end
|
|
121
123
|
|
|
122
124
|
def find_bridge_id
|
|
123
|
-
return ENV[
|
|
125
|
+
return ENV["HUE_BRIDGE_ID"] if ENV["HUE_BRIDGE_ID"]
|
|
124
126
|
|
|
125
|
-
json = JSON(File.read(File.expand_path(
|
|
126
|
-
json[
|
|
127
|
+
json = JSON(File.read(File.expand_path("~/.hue")))
|
|
128
|
+
json["bridge_id"]
|
|
127
129
|
rescue
|
|
128
|
-
|
|
130
|
+
nil
|
|
129
131
|
end
|
|
130
132
|
|
|
131
133
|
def discovery_mdns(bs)
|
|
@@ -136,8 +138,8 @@ module Hue
|
|
|
136
138
|
bridge_target = resolver.getresource(bridge_ptr.name, Resolv::DNS::Resource::IN::SRV).target
|
|
137
139
|
|
|
138
140
|
bridge_hash = {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
+
"id" => resolver.getresource(bridge_ptr.name, Resolv::DNS::Resource::IN::TXT).strings[0].split("=")[1],
|
|
142
|
+
"internalipaddress" => resolver.getresource(bridge_target, Resolv::DNS::Resource::IN::A).address
|
|
141
143
|
}
|
|
142
144
|
|
|
143
145
|
bs << Bridge.new(self, bridge_hash)
|
|
@@ -145,20 +147,18 @@ module Hue
|
|
|
145
147
|
end
|
|
146
148
|
|
|
147
149
|
def discovery_meethue(bs)
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
easy.perform
|
|
153
|
-
JSON(easy.body).each do |hash|
|
|
150
|
+
uri = URI("https://discovery.meethue.com/")
|
|
151
|
+
response = Net::HTTP.get(uri)
|
|
152
|
+
|
|
153
|
+
JSON(response).each do |hash|
|
|
154
154
|
bs << Bridge.new(self, hash)
|
|
155
155
|
end
|
|
156
156
|
end
|
|
157
157
|
|
|
158
158
|
def get_error(error)
|
|
159
159
|
# Find error class and return instance
|
|
160
|
-
klass
|
|
161
|
-
klass.new(error[
|
|
160
|
+
klass ||= Hue::ERROR_MAP[error["type"]] || UnknownError
|
|
161
|
+
klass.new(error["description"])
|
|
162
162
|
end
|
|
163
163
|
end
|
|
164
164
|
end
|
data/lib/hue/editable_state.rb
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
require "color_conversion"
|
|
2
|
+
|
|
1
3
|
module Hue
|
|
2
4
|
module EditableState
|
|
5
|
+
HUE_RANGE = 0..65535
|
|
6
|
+
SATURATION_RANGE = 0..254
|
|
7
|
+
BRIGHTNESS_RANGE = 0..254
|
|
8
|
+
|
|
3
9
|
def on?
|
|
4
|
-
@
|
|
10
|
+
@on || false
|
|
5
11
|
end
|
|
6
12
|
|
|
7
13
|
def on!
|
|
@@ -12,16 +18,47 @@ module Hue
|
|
|
12
18
|
self.on = false
|
|
13
19
|
end
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
21
|
+
# Turn the light on if it's off and vice versa
|
|
22
|
+
def toggle!
|
|
23
|
+
if @on
|
|
24
|
+
off!
|
|
25
|
+
else
|
|
26
|
+
on!
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
%w[on hue saturation brightness color_temperature alert effect].each do |key|
|
|
31
|
+
define_method :"#{key}=" do |value|
|
|
17
32
|
set_state({key.to_sym => value})
|
|
18
|
-
instance_variable_set("@#{key}"
|
|
33
|
+
instance_variable_set(:"@#{key}", value)
|
|
19
34
|
end
|
|
20
35
|
end
|
|
21
36
|
|
|
22
37
|
def set_xy(x, y)
|
|
23
|
-
set_state({:
|
|
38
|
+
set_state({xy: [x, y]})
|
|
24
39
|
@x, @y = x, y
|
|
25
40
|
end
|
|
41
|
+
|
|
42
|
+
def hex
|
|
43
|
+
ColorConversion::Color.new(h: hue, s: saturation, b: brightness).hex
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def hex=(hex)
|
|
47
|
+
hex = "##{hex}" unless hex.start_with?("#")
|
|
48
|
+
hsb = ColorConversion::Color.new(hex).hsb
|
|
49
|
+
|
|
50
|
+
# Map values from standard HSB to what Hue wants and update state
|
|
51
|
+
state = {
|
|
52
|
+
hue: ((hsb[:h].to_f / 360.0) * HUE_RANGE.last.to_f).to_i,
|
|
53
|
+
saturation: ((hsb[:s].to_f / 100.0) * SATURATION_RANGE.last.to_f).to_i,
|
|
54
|
+
brightness: ((hsb[:b].to_f / 100.0) * BRIGHTNESS_RANGE.last.to_f).to_i
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
set_state(state)
|
|
58
|
+
|
|
59
|
+
@hue = state[:hue]
|
|
60
|
+
@saturation = state[:saturation]
|
|
61
|
+
@brightness = state[:brightness]
|
|
62
|
+
end
|
|
26
63
|
end
|
|
27
64
|
end
|