lights 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/README.md +1 -1
- data/bin/lights +102 -16
- data/lib/lights.rb +17 -7
- data/lib/lights/bulbstate.rb +2 -2
- data/lib/lights/scene.rb +20 -0
- data/lib/lights/user.rb +12 -0
- data/lib/lights/version.rb +1 -1
- data/spec/features/{rue.feature → lights.feature} +14 -5
- data/spec/scene_spec.rb +23 -0
- metadata +7 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YTdhNGFiOWU0YWY5ZGZiYmY1N2YxNGNhN2M4Mjg5MGFiOTg4MDUxZg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzAwNjIxMmMyOTk2YTAxN2Q5NDZmNDU1NmY2MTAzMGY5NDdhOTFjYg==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
M2NjZjcwMTlhYjFkNDM0ZTIyMzk3YTgzODdiMjAzMmFhYzA3ZTEzMWIxNWFi
|
10
|
+
NjVlMTdlMTg4YmY4YzEwM2YyODYwZjM2NmUwMGFiYTdiNzZhNjk0ZTQwY2Vi
|
11
|
+
N2M3ZDljZDJiZmE3MGQzOWM2N2UyMjdkMTJiZmM2NTNhZjkxOTY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZThlOTU3NmI0ZTk2NGQwMDE4ODY0YTBkM2FhYzJhNDY1YjBiOWUwYjg3NzU1
|
14
|
+
N2U3NzgxM2I4NjI2ZjFlODYwYjliNzgzY2M3MzcyOGJmYTExN2M1YWU5MmVh
|
15
|
+
MzM2MDkwYjY5NzM4NTgxZjQzZDZhYWU4ODNmMjhmOGI4YTRjNWM=
|
data/README.md
CHANGED
data/bin/lights
CHANGED
@@ -68,24 +68,98 @@ class LightsCli
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def list
|
71
|
-
|
71
|
+
hue = Lights.new @config["bridge_ip"], @config["username"]
|
72
72
|
if !ARGV[0] || ARGV[0] == "lights"
|
73
|
-
bulbs_response =
|
73
|
+
bulbs_response = hue.request_bulb_list
|
74
|
+
bulbs = []
|
74
75
|
bulbs_response.each do |id,value|
|
75
|
-
|
76
|
-
|
76
|
+
bulbs << hue.request_bulb_info( id )
|
77
|
+
end
|
78
|
+
c1w = bulbs.collect{|s|s.id.to_s}.group_by(&:size).max.first + 2
|
79
|
+
c2w = bulbs.collect{|s|s.name.to_s}.group_by(&:size).max.first + 2
|
80
|
+
c1w = 4 if c1w < 4
|
81
|
+
c2w = 6 if c2w < 6
|
82
|
+
|
83
|
+
puts "ID".ljust(c1w) + "NAME".ljust(c2w)
|
84
|
+
puts "=" * (c1w+c2w)
|
85
|
+
bulbs.each do |b|
|
86
|
+
puts b.id.ljust(c1w) + b.name.ljust(c2w)
|
77
87
|
end
|
78
88
|
elsif ARGV[0] == "sensors"
|
79
|
-
sensors_response =
|
89
|
+
sensors_response = hue.request_sensor_list
|
90
|
+
sensors = []
|
80
91
|
sensors_response.each do |id,value|
|
81
|
-
|
82
|
-
|
92
|
+
sensors << hue.request_sensor_info( id )
|
93
|
+
end
|
94
|
+
c1w = sensors.collect{|s|s.id.to_s}.group_by(&:size).max.first + 2
|
95
|
+
c2w = sensors.collect{|s|s.name.to_s}.group_by(&:size).max.first + 2
|
96
|
+
c1w = 4 if c1w < 4
|
97
|
+
c2w = 6 if c2w < 6
|
98
|
+
|
99
|
+
puts "ID".ljust(c1w) + "NAME".ljust(c2w)
|
100
|
+
puts "=" * (c1w+c2w)
|
101
|
+
sensors.each do |s|
|
102
|
+
puts s.id.ljust(c1w) + s.name.ljust(c2w)
|
83
103
|
end
|
84
104
|
elsif ARGV[0] == "groups"
|
85
|
-
groups_response =
|
105
|
+
groups_response = hue.request_group_list
|
106
|
+
groups = []
|
86
107
|
groups_response.each do |id,value|
|
87
|
-
|
88
|
-
|
108
|
+
groups << hue.request_group_info( id )
|
109
|
+
end
|
110
|
+
|
111
|
+
c1w = groups.collect{|g|g.id.to_s}.group_by(&:size).max.first + 2
|
112
|
+
c2w = groups.collect{|g|g.name.to_s}.group_by(&:size).max.first + 2
|
113
|
+
c3w = groups.collect{|g|g.lights.to_s}.group_by(&:size).max.first + 2
|
114
|
+
c1w = 4 if c1w < 4
|
115
|
+
c2w = 6 if c2w < 6
|
116
|
+
c3w = 8 if c3w < 8
|
117
|
+
|
118
|
+
puts "ID".ljust(c1w) + "NAME".ljust(c2w) + "LIGHTS".ljust(c3w)
|
119
|
+
puts "=" * (c1w+c2w+c3w)
|
120
|
+
groups.each do |g|
|
121
|
+
puts g.id.ljust(c1w) + g.name.ljust(c2w) + g.lights.join(',').ljust(c3w)
|
122
|
+
end
|
123
|
+
elsif ARGV[0] == "scenes"
|
124
|
+
scenes_response = hue.request_scene_list
|
125
|
+
scenes = []
|
126
|
+
scenes_response.each do |id,value|
|
127
|
+
scenes << Scene.new(id,value)
|
128
|
+
end
|
129
|
+
|
130
|
+
c1w = scenes.collect{|s|s.id.to_s}.group_by(&:size).max.first + 2
|
131
|
+
c2w = scenes.collect{|s|s.name.to_s}.group_by(&:size).max.first + 2
|
132
|
+
c3w = scenes.collect{|s|s.lights.to_s}.group_by(&:size).max.first + 2
|
133
|
+
c1w = 4 if c1w < 4
|
134
|
+
c2w = 6 if c2w < 6
|
135
|
+
c3w = 8 if c3w < 8
|
136
|
+
|
137
|
+
puts "ID".ljust(c1w) + "NAME".ljust(c2w) + "LIGHTS".ljust(c3w)
|
138
|
+
puts "=" * (c1w+c2w+c3w)
|
139
|
+
scenes.each do |s|
|
140
|
+
puts s.id.ljust(c1w) + s.name.ljust(c2w) + s.lights.join(',').ljust(c3w)
|
141
|
+
end
|
142
|
+
elsif ARGV[0] == "users"
|
143
|
+
config_response = hue.request_config
|
144
|
+
|
145
|
+
users = []
|
146
|
+
config_response["whitelist"].each do |id,value|
|
147
|
+
users << User.new(id,value)
|
148
|
+
end
|
149
|
+
|
150
|
+
c1w = users.collect{|u|u.id.to_s}.group_by(&:size).max.first + 2
|
151
|
+
c2w = users.collect{|u|u.name.to_s}.group_by(&:size).max.first + 2
|
152
|
+
c3w = users.collect{|u|u.create_date.to_s}.group_by(&:size).max.first + 2
|
153
|
+
c4w = users.collect{|u|u.last_use_date.to_s}.group_by(&:size).max.first + 2
|
154
|
+
c1w = 4 if c1w < 4
|
155
|
+
c2w = 6 if c2w < 6
|
156
|
+
c3w = 15 if c3w < 15
|
157
|
+
c4w = 15 if c4w < 15
|
158
|
+
|
159
|
+
puts "ID".ljust(c1w) + "NAME".ljust(c2w) + "CREATE DATE".ljust(c3w) + "LAST USE DATE".ljust(c4w)
|
160
|
+
puts "=" * (c1w+c2w+c3w+c4w)
|
161
|
+
users.each do |u|
|
162
|
+
puts u.id.ljust(c1w) + u.name.ljust(c2w) + u.create_date.ljust(c3w) + u.last_use_date.ljust(c4w)
|
89
163
|
end
|
90
164
|
end
|
91
165
|
end
|
@@ -168,6 +242,9 @@ class LightsCli
|
|
168
242
|
opts.on("-l", "--lights 1,2,...N", Array, "Which lights to control") do |l|
|
169
243
|
options[:lights] = l
|
170
244
|
end
|
245
|
+
opts.on("-g", "--groups 1,2,...N", Array, "Which groups to control") do |g|
|
246
|
+
options[:groups] = g
|
247
|
+
end
|
171
248
|
opts.on("-d", "--duration seconds", OptionParser::DecimalInteger, "Transition duration in seconds") do |d|
|
172
249
|
options[:duration] = d
|
173
250
|
end
|
@@ -182,8 +259,8 @@ class LightsCli
|
|
182
259
|
puts "Must specify a state to set."
|
183
260
|
bad_args = true
|
184
261
|
end
|
185
|
-
if !options[:lights]
|
186
|
-
puts "Must specify which lights to control."
|
262
|
+
if !options[:lights] && !options[:groups]
|
263
|
+
puts "Must specify which lights/groups to control."
|
187
264
|
bad_args = true
|
188
265
|
end
|
189
266
|
if (options[:hue] || options[:saturation]) \
|
@@ -223,12 +300,16 @@ class LightsCli
|
|
223
300
|
if options[:xy]
|
224
301
|
s.xy = options[:xy]
|
225
302
|
end
|
226
|
-
|
227
|
-
|
303
|
+
|
304
|
+
if options[:lights]
|
305
|
+
set_bulb_state(s,options[:lights])
|
306
|
+
elsif options[:groups]
|
307
|
+
set_group_state(s,options[:groups])
|
308
|
+
end
|
228
309
|
end
|
229
310
|
|
230
311
|
private
|
231
|
-
def
|
312
|
+
def set_bulb_state(state,bulbs)
|
232
313
|
lights = Lights.new @config["bridge_ip"], @config["username"]
|
233
314
|
if bulbs.first == "all"
|
234
315
|
lights.set_group_state 0,state
|
@@ -236,6 +317,11 @@ private
|
|
236
317
|
bulbs.each { |l| lights.set_bulb_state(l,state) }
|
237
318
|
end
|
238
319
|
end
|
320
|
+
|
321
|
+
def set_group_state(state,groups)
|
322
|
+
hue = Lights.new @config["bridge_ip"], @config["username"]
|
323
|
+
groups.each { |g| hue.set_group_state(g,state) }
|
324
|
+
end
|
239
325
|
|
240
326
|
def write_config
|
241
327
|
File.open(LIGHTS_CONFIG_PATH,"w+") { |file| file.write(@config.to_json) }
|
@@ -256,7 +342,7 @@ private
|
|
256
342
|
|
257
343
|
s = BulbState.new
|
258
344
|
s.on = is_on
|
259
|
-
|
345
|
+
set_bulb_state s, options[:lights]
|
260
346
|
end
|
261
347
|
end
|
262
348
|
|
data/lib/lights.rb
CHANGED
@@ -4,12 +4,14 @@ require 'net/http'
|
|
4
4
|
require 'uri'
|
5
5
|
require 'json'
|
6
6
|
|
7
|
-
require 'lights/bulb
|
8
|
-
require 'lights/group
|
9
|
-
require 'lights/bridge
|
10
|
-
require 'lights/exception
|
11
|
-
require 'lights/sensor
|
12
|
-
require 'lights/
|
7
|
+
require 'lights/bulb'
|
8
|
+
require 'lights/group'
|
9
|
+
require 'lights/bridge'
|
10
|
+
require 'lights/exception'
|
11
|
+
require 'lights/sensor'
|
12
|
+
require 'lights/scene'
|
13
|
+
require 'lights/user'
|
14
|
+
require 'lights/loggerconfig'
|
13
15
|
|
14
16
|
def jp( s )
|
15
17
|
puts JSON.pretty_generate( s )
|
@@ -78,7 +80,7 @@ class Lights
|
|
78
80
|
end
|
79
81
|
|
80
82
|
def request_sensor_info( id )
|
81
|
-
response = get
|
83
|
+
response = get "sensors/#{id}"
|
82
84
|
Sensor.new(id,response)
|
83
85
|
end
|
84
86
|
|
@@ -94,6 +96,14 @@ class Lights
|
|
94
96
|
get "schedules"
|
95
97
|
end
|
96
98
|
|
99
|
+
def request_scene_list
|
100
|
+
get "scenes"
|
101
|
+
end
|
102
|
+
|
103
|
+
def request_config
|
104
|
+
get "config"
|
105
|
+
end
|
106
|
+
|
97
107
|
def set_bulb_state( id, state )
|
98
108
|
put "lights/#{id}/state", state
|
99
109
|
end
|
data/lib/lights/bulbstate.rb
CHANGED
@@ -148,8 +148,8 @@ class BulbState
|
|
148
148
|
raise BulbStateValueTypeException, "Value has incorrect type. Requires array, got #{value.class}"
|
149
149
|
elsif value.nil?
|
150
150
|
return
|
151
|
-
elsif value.length == 2 && value[0].
|
152
|
-
&& value[1].
|
151
|
+
elsif value.length == 2 && value[0].is_a?(Numeric) \
|
152
|
+
&& value[1].is_a?(Numeric) && value[0].to_f >= MIN_XY \
|
153
153
|
&& value[0].to_f <= MAX_XY && value[1].to_f >= MIN_XY \
|
154
154
|
&& value[1].to_f <= MAX_XY
|
155
155
|
@xy = []
|
data/lib/lights/scene.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
class Scene
|
2
|
+
|
3
|
+
attr_reader :id, :name, :active, :lights
|
4
|
+
|
5
|
+
def initialize(id,data = {})
|
6
|
+
@id = id
|
7
|
+
@name = data["name"]
|
8
|
+
@active = data["active"]
|
9
|
+
@lights = data["lights"]
|
10
|
+
end
|
11
|
+
|
12
|
+
def data
|
13
|
+
data = {}
|
14
|
+
data["name"] = @name if @name
|
15
|
+
data["active"] = @active if @active
|
16
|
+
data["lights"] = @lights if @lights
|
17
|
+
data
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
data/lib/lights/user.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
class User
|
2
|
+
|
3
|
+
attr_reader :id, :name, :create_date, :last_use_date
|
4
|
+
def initialize( id, data = {} )
|
5
|
+
puts data.inspect
|
6
|
+
@id = id
|
7
|
+
@data = data
|
8
|
+
@name = data["name"]
|
9
|
+
@create_date = data["create date"]
|
10
|
+
@last_use_date = data["last use date"]
|
11
|
+
end
|
12
|
+
end
|
data/lib/lights/version.rb
CHANGED
@@ -3,21 +3,30 @@ Feature: Lights
|
|
3
3
|
Scenario: No command
|
4
4
|
When I run `lights`
|
5
5
|
Then the output should contain "Must specify a command."
|
6
|
+
|
6
7
|
Scenario: List Default
|
7
8
|
When I run `lights list`
|
8
|
-
Then the output should contain "
|
9
|
+
Then the output should contain "ID"
|
9
10
|
|
10
|
-
Scenario: List Hue
|
11
|
+
Scenario: List Hue lights
|
11
12
|
When I run `lights list lights`
|
12
|
-
Then the output should contain "
|
13
|
+
Then the output should contain "ID"
|
13
14
|
|
14
15
|
Scenario: List Hue groups
|
15
16
|
When I run `lights list groups`
|
16
|
-
Then the output should contain "
|
17
|
+
Then the output should contain "ID"
|
17
18
|
|
18
19
|
Scenario: List Hue sensors
|
19
20
|
When I run `lights list sensors`
|
20
|
-
Then the output should contain "
|
21
|
+
Then the output should contain "ID"
|
22
|
+
|
23
|
+
Scenario: List Hue scenes
|
24
|
+
When I run `lights list scenes`
|
25
|
+
Then the output should contain "ID"
|
26
|
+
|
27
|
+
Scenario: List registered users
|
28
|
+
When I run `lights list users`
|
29
|
+
Then the output should contain "ID"
|
21
30
|
|
22
31
|
# This test is failing because OptionParser is casting the string as an integer (0)
|
23
32
|
# Scenario: Incorrect parameters to set
|
data/spec/scene_spec.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'lights'
|
2
|
+
|
3
|
+
describe Scene do
|
4
|
+
it "properly parse input parameters" do
|
5
|
+
data = { "name" => "test name",
|
6
|
+
"lights" => ["1","2","3"],
|
7
|
+
"active" => true }
|
8
|
+
scene = Scene.new(1,data)
|
9
|
+
scene.name.should eql "test name"
|
10
|
+
scene.id.should eql 1
|
11
|
+
scene.lights.should eql ["1","2","3"]
|
12
|
+
scene.active.should eql true
|
13
|
+
end
|
14
|
+
|
15
|
+
it "properly reconstucts object hash" do
|
16
|
+
data = { "name" => "test name",
|
17
|
+
"lights" => ["1","2","3"],
|
18
|
+
"active" => true }
|
19
|
+
scene = Scene.new(1,data)
|
20
|
+
scene.data.should eql data
|
21
|
+
scene.id.should eql 1
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lights
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brady Turner
|
@@ -100,15 +100,18 @@ files:
|
|
100
100
|
- lib/lights/exception.rb
|
101
101
|
- lib/lights/group.rb
|
102
102
|
- lib/lights/loggerconfig.rb
|
103
|
+
- lib/lights/scene.rb
|
103
104
|
- lib/lights/sensor.rb
|
105
|
+
- lib/lights/user.rb
|
104
106
|
- lib/lights/version.rb
|
105
107
|
- lights.gemspec
|
106
108
|
- spec/bridge_spec.rb
|
107
109
|
- spec/bulb_spec.rb
|
108
110
|
- spec/bulbstate_spec.rb
|
109
|
-
- spec/features/
|
111
|
+
- spec/features/lights.feature
|
110
112
|
- spec/features/support/setup.rb
|
111
113
|
- spec/group_spec.rb
|
114
|
+
- spec/scene_spec.rb
|
112
115
|
homepage: http://rubygems.org/gems/lights
|
113
116
|
licenses:
|
114
117
|
- MIT
|
@@ -137,6 +140,7 @@ test_files:
|
|
137
140
|
- spec/bridge_spec.rb
|
138
141
|
- spec/bulb_spec.rb
|
139
142
|
- spec/bulbstate_spec.rb
|
140
|
-
- spec/features/
|
143
|
+
- spec/features/lights.feature
|
141
144
|
- spec/features/support/setup.rb
|
142
145
|
- spec/group_spec.rb
|
146
|
+
- spec/scene_spec.rb
|