lights 0.8.18 → 1.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +6 -14
- data/README.md +3 -4
- data/bin/lights +32 -19
- data/lib/lights.rb +25 -8
- data/lib/lights/bridge.rb +0 -1
- data/lib/lights/bulb.rb +13 -6
- data/lib/lights/bulbstate.rb +17 -14
- data/lib/lights/command.rb +1 -2
- data/lib/lights/config.rb +45 -6
- data/lib/lights/datastore.rb +1 -2
- data/lib/lights/exception.rb +7 -1
- data/lib/lights/group.rb +5 -4
- data/lib/lights/hobject.rb +1 -2
- data/lib/lights/list.rb +1 -2
- data/lib/lights/rule.rb +18 -3
- data/lib/lights/scene.rb +7 -4
- data/lib/lights/schedule.rb +11 -4
- data/lib/lights/sensor.rb +12 -21
- data/lib/lights/user.rb +1 -2
- data/lib/lights/version.rb +1 -1
- data/lights.gemspec +3 -2
- data/spec/bulb_spec.rb +7 -0
- data/spec/bulbstate_spec.rb +10 -0
- data/spec/datastore_spec.rb +35 -5
- data/spec/group_spec.rb +139 -9
- data/spec/rule_spec.rb +0 -2
- metadata +20 -21
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
metadata.gz: !binary |-
|
9
|
-
ZDg4MGE0MmIwNjdhNzljZmFjNmI2YWQ3ZTAyNTRkZDExYzg4MTZkZmY4N2Fi
|
10
|
-
Y2ZlYWQ1Yjk4NmYzZDFiM2NlOGQzNDQ5MDgzYzE2NmM3OTE4MzAxMDQwZmZl
|
11
|
-
N2I1N2M5NjA1YWY2MWM2MzQ0ZDFlNjFmNzM0MWNmZDhlMTY2ZTc=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
Y2Q2OWVkMDI3ODAzMjI5NjUwYTI3MjU2YjY0MjY0NTE5YzEzNWE0MmZhODBj
|
14
|
-
NDcwODRhYTc2MDQ3OWI3YzM4MWQ3ZTkyY2Q3ZDE1Y2ViODhiYjU2ZGM4MmQx
|
15
|
-
OGE5NWU5N2Q2ZTFiNzE2MDNjNDAyMjgxYjljODUxMmQzMGNmNDA=
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a3bf9fc0031f505e57aeff2a521fa844f66da4d2d8f58cd72274bbe99ab16157
|
4
|
+
data.tar.gz: fd88ad10da1cdd5a82d7385e7e8eff031d13f2665ddc7db71e1f846ffb32dfa1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f651502f6f3b129085fb3973acdff5f96bc7fe6a789148dc93c1412733c53756547586f433a9aa913eb459e1c8ead64549074106aec944f2b92edb6339e4631f
|
7
|
+
data.tar.gz: 8b732115636f705f482f1d6cd14f0af1c63fb0b6b88f0bcbec90ee9de2d30c143a965eddd0b786e9011fbf07e1933abe8d8c03f38470f950d58c9fe890c1faca
|
data/README.md
CHANGED
@@ -16,7 +16,7 @@ Basic Usage
|
|
16
16
|
```ruby
|
17
17
|
require 'lights'
|
18
18
|
client = Lights.new( '192.168.x.x', 'username' )
|
19
|
-
client.
|
19
|
+
client.register
|
20
20
|
client.request_bulb_list
|
21
21
|
```
|
22
22
|
See [lights-examples](https://github.com/turnerba/lights-examples) for more usage examples.
|
@@ -26,11 +26,10 @@ CLI Quick Setup
|
|
26
26
|
|
27
27
|
```
|
28
28
|
lights discover -s
|
29
|
-
lights config -f --user <username>
|
30
29
|
lights register
|
31
30
|
lights list
|
32
|
-
lights on
|
33
|
-
lights off
|
31
|
+
lights on
|
32
|
+
lights off
|
34
33
|
```
|
35
34
|
|
36
35
|
See [Sample Usage (Implemented)](https://github.com/turnerba/lights/wiki/Sample-Usage-(Implemented)) for more usage examples.
|
data/bin/lights
CHANGED
@@ -18,18 +18,22 @@ class LightsCli
|
|
18
18
|
def configured?
|
19
19
|
@config["username"] && @config["bridge_ip"]
|
20
20
|
end
|
21
|
+
|
22
|
+
def ip_configured?
|
23
|
+
@config["bridge_ip"]
|
24
|
+
end
|
21
25
|
|
22
26
|
def config
|
23
27
|
options = {}
|
24
28
|
OptionParser.new do |opts|
|
25
|
-
opts.on("-u", "--user <username>", String, "Username"){|url| options[:user]=url}
|
26
29
|
opts.on("-i", "--ip <bridge ip>", String, "Bridge ip address"){|ip| options[:ip]=ip}
|
27
30
|
opts.on("-f", "--force", "Force write to config file"){|f| options[:force]=f}
|
28
31
|
opts.on("-l", "--list", "List saved configuration settings") {|l| options[:list]=l}
|
29
32
|
end.parse!
|
30
33
|
|
31
|
-
|
32
|
-
puts "
|
34
|
+
unless options[:ip] || options[:list]
|
35
|
+
puts "usage:"
|
36
|
+
puts " #{File.basename(__FILE__)} config (--ip <bridge IP> | --list)"
|
33
37
|
exit 1
|
34
38
|
end
|
35
39
|
|
@@ -52,7 +56,6 @@ class LightsCli
|
|
52
56
|
end
|
53
57
|
end
|
54
58
|
|
55
|
-
@config["username"] = options[:user] || @config["username"]
|
56
59
|
@config["bridge_ip"] = options[:ip] || @config["bridge_ip"]
|
57
60
|
|
58
61
|
write_config
|
@@ -70,7 +73,8 @@ class LightsCli
|
|
70
73
|
OptionParser.new do |opts|
|
71
74
|
opts.on("-l", "--lights 1,2,...N", Array, "Which lights are in the scene"){|l| options[:lights]=l}
|
72
75
|
opts.on("-n", "--name <name>", String, "Set scene name"){|n| options[:name]=n}
|
73
|
-
opts.on("-
|
76
|
+
opts.on("-r", "--recycle", "Can bridge recycle scene"){|r| options[:recycle]=r}
|
77
|
+
opts.on("-d", "--duration seconds", OptionParser::DecimalInteger, "Transition duration in seconds"){|d| options[:duration]=d}
|
74
78
|
end.parse!
|
75
79
|
|
76
80
|
if !options[:lights]
|
@@ -81,14 +85,12 @@ class LightsCli
|
|
81
85
|
puts "Must specify scene name."
|
82
86
|
exit 1
|
83
87
|
end
|
84
|
-
if !options[:id]
|
85
|
-
puts "Must specify scene id."
|
86
|
-
exit 1
|
87
|
-
end
|
88
88
|
|
89
|
-
s = Scene.new
|
89
|
+
s = Scene.new
|
90
90
|
s.name = options[:name]
|
91
91
|
s.lights = options[:lights]
|
92
|
+
s.recycle = options[:recycle] || false
|
93
|
+
s.transition_time = options[:duration]
|
92
94
|
hue.create_scene s
|
93
95
|
when "group"
|
94
96
|
OptionParser.new do |opts|
|
@@ -189,7 +191,14 @@ class LightsCli
|
|
189
191
|
|
190
192
|
hue.delete_user id
|
191
193
|
when "scene"
|
192
|
-
|
194
|
+
id = ARGV.shift
|
195
|
+
|
196
|
+
if !id
|
197
|
+
puts "Must specify scene id."
|
198
|
+
exit 1
|
199
|
+
end
|
200
|
+
|
201
|
+
hue.delete_scene id
|
193
202
|
when nil
|
194
203
|
STDERR.puts "Must specify a type to delete."
|
195
204
|
else
|
@@ -213,8 +222,8 @@ class LightsCli
|
|
213
222
|
when nil, "","lights"
|
214
223
|
response = options[:new] ? hue.request_new_bulb_list : hue.request_bulb_list
|
215
224
|
objects = BulbList.new(response)
|
216
|
-
titles = ["ID","NAME"]
|
217
|
-
methods = [:id,:name]
|
225
|
+
titles = ["ID","NAME","REACHABLE?"]
|
226
|
+
methods = [:id,:name,[:state,:reachable]]
|
218
227
|
when "sensors"
|
219
228
|
response = options[:new] ? hue.request_new_sensor_list : hue.request_sensor_list
|
220
229
|
objects = SensorList.new(response)
|
@@ -228,8 +237,8 @@ class LightsCli
|
|
228
237
|
when "scenes"
|
229
238
|
response = hue.request_scene_list
|
230
239
|
objects = SceneList.new(response)
|
231
|
-
titles = ["ID","NAME","LIGHTS"]
|
232
|
-
methods = [:id,:name,:lights]
|
240
|
+
titles = ["ID","NAME","LIGHTS","RECYCLE"]
|
241
|
+
methods = [:id,:name,:lights,:recycle]
|
233
242
|
when "users"
|
234
243
|
response = hue.request_config
|
235
244
|
objects = UserList.new(response["whitelist"])
|
@@ -263,7 +272,9 @@ class LightsCli
|
|
263
272
|
|
264
273
|
def register
|
265
274
|
lights = Lights.new @config["bridge_ip"], @config["username"]
|
266
|
-
response = lights.
|
275
|
+
response = lights.register
|
276
|
+
@config["username"] = lights.username
|
277
|
+
write_config
|
267
278
|
end
|
268
279
|
|
269
280
|
def discover
|
@@ -447,12 +458,14 @@ begin
|
|
447
458
|
cli.config
|
448
459
|
elsif command == "discover"
|
449
460
|
cli.discover
|
461
|
+
elsif !cli.ip_configured?
|
462
|
+
puts "Please run 'lights discover -s' or 'lights config --ip <IP>' before using."
|
463
|
+
elsif command == "register"
|
464
|
+
cli.register
|
450
465
|
elsif !cli.configured?
|
451
|
-
puts "Please run 'lights
|
466
|
+
puts "Please run 'lights register' before using."
|
452
467
|
elsif command == "list"
|
453
468
|
cli.list
|
454
|
-
elsif command == "register"
|
455
|
-
cli.register
|
456
469
|
elsif command == "on"
|
457
470
|
cli.on
|
458
471
|
elsif command == "off"
|
data/lib/lights.rb
CHANGED
@@ -12,8 +12,8 @@ require 'lights/loggerconfig'
|
|
12
12
|
|
13
13
|
class Lights
|
14
14
|
|
15
|
-
attr_reader :bulbs
|
16
|
-
def initialize(ip,username)
|
15
|
+
attr_reader :bulbs, :username
|
16
|
+
def initialize(ip,username=nil)
|
17
17
|
@ip = ip
|
18
18
|
@username = username
|
19
19
|
@http = Net::HTTP.new(ip,80)
|
@@ -25,9 +25,9 @@ class Lights
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def discover_hubs
|
28
|
-
http = Net::HTTP.new("
|
28
|
+
http = Net::HTTP.new("discovery.meethue.com",443)
|
29
29
|
http.use_ssl = true
|
30
|
-
request = Net::HTTP::Get.new( "/
|
30
|
+
request = Net::HTTP::Get.new( "/" )
|
31
31
|
response = http.request request
|
32
32
|
|
33
33
|
case response.code.to_i
|
@@ -35,21 +35,28 @@ class Lights
|
|
35
35
|
result = JSON.parse( response.body )
|
36
36
|
result.each { |b| @bridges << Bridge.new(b) }
|
37
37
|
else
|
38
|
+
@logger.fatal "Could not discover bridge. HTTP error #{response.code}"
|
39
|
+
@logger.fatal "Response: #{response.body}"
|
38
40
|
raise "Unknown error"
|
39
41
|
end
|
40
42
|
@bridges
|
41
43
|
end
|
42
44
|
|
43
|
-
def
|
44
|
-
data = { "devicetype"=>"lights"
|
45
|
-
"username"=>@username }
|
45
|
+
def register
|
46
|
+
data = { "devicetype"=>"lights" }
|
46
47
|
response = @http.post "/api", data.to_json
|
47
48
|
result = JSON.parse(response.body).first
|
48
49
|
if result.has_key? "error"
|
49
50
|
process_error result
|
51
|
+
elsif result["success"]
|
52
|
+
@username = result["success"]["username"]
|
50
53
|
end
|
54
|
+
result
|
51
55
|
end
|
52
56
|
|
57
|
+
# backwards compatibility
|
58
|
+
alias_method :register_username, :register
|
59
|
+
|
53
60
|
def request_config
|
54
61
|
get "config"
|
55
62
|
end
|
@@ -134,7 +141,11 @@ class Lights
|
|
134
141
|
end
|
135
142
|
|
136
143
|
def create_scene( scene )
|
137
|
-
|
144
|
+
post "scenes/#{scene.id}", scene
|
145
|
+
end
|
146
|
+
|
147
|
+
def delete_scene( id )
|
148
|
+
delete "scenes/#{id}"
|
138
149
|
end
|
139
150
|
|
140
151
|
def delete_group( id )
|
@@ -165,6 +176,8 @@ private
|
|
165
176
|
raise ParameterUnavailableException, result["error"]["description"]
|
166
177
|
when 101
|
167
178
|
raise BridgeConnectException
|
179
|
+
when 403
|
180
|
+
raise SceneLockedException, result["error"]["description"]
|
168
181
|
else
|
169
182
|
raise "Unknown Error: #{result["error"]["description"]}"
|
170
183
|
end
|
@@ -172,6 +185,7 @@ private
|
|
172
185
|
|
173
186
|
def get( path )
|
174
187
|
@logger.debug "==> GET: #{path}"
|
188
|
+
raise UsernameException unless @username
|
175
189
|
request = Net::HTTP::Get.new( "/api/#{@username}/#{path}" )
|
176
190
|
response = @http.request request
|
177
191
|
result = JSON.parse( response.body )
|
@@ -185,6 +199,7 @@ private
|
|
185
199
|
|
186
200
|
def put( path, data={} )
|
187
201
|
@logger.debug "==> PUT: #{path}"
|
202
|
+
raise UsernameException unless @username
|
188
203
|
@logger.debug data.to_json
|
189
204
|
response = @http.put( "/api/#{@username}/#{path}", data.to_json )
|
190
205
|
result = JSON.parse( response.body )
|
@@ -198,6 +213,7 @@ private
|
|
198
213
|
|
199
214
|
def post( path, data={} )
|
200
215
|
@logger.debug "==> POST: #{path}"
|
216
|
+
raise UsernameException unless @username
|
201
217
|
@logger.debug data.to_json
|
202
218
|
response = @http.post( "/api/#{@username}/#{path}", data.to_json )
|
203
219
|
result = JSON.parse( response.body )
|
@@ -211,6 +227,7 @@ private
|
|
211
227
|
|
212
228
|
def delete( path )
|
213
229
|
@logger.debug "==> DELETE: #{path}"
|
230
|
+
raise UsernameException unless @username
|
214
231
|
request = Net::HTTP::Delete.new( "/api/#{@username}/#{path}" )
|
215
232
|
response = @http.request request
|
216
233
|
result = JSON.parse( response.body )
|
data/lib/lights/bridge.rb
CHANGED
data/lib/lights/bulb.rb
CHANGED
@@ -2,22 +2,29 @@ require 'lights/bulbstate'
|
|
2
2
|
require 'lights/hobject'
|
3
3
|
|
4
4
|
class Bulb < HObject
|
5
|
-
attr_reader :id, :name, :type, :
|
5
|
+
attr_reader :id, :name, :type, :sw_version, :state,
|
6
|
+
:point_symbol, :model_id, :unique_id
|
7
|
+
attr_writer :name, :state
|
6
8
|
def initialize(id,data = {})
|
7
|
-
super(data)
|
8
9
|
@id = id
|
9
10
|
@name = data["name"]
|
10
11
|
@type = data["type"]
|
11
|
-
@
|
12
|
+
@sw_version = data["swversion"]
|
13
|
+
@point_symbol = data["pointsymbol"]
|
14
|
+
@model_id = data["modelid"]
|
15
|
+
@unique_id = data["uniqueid"]
|
12
16
|
@state = BulbState.new data["state"]
|
13
17
|
end
|
14
18
|
|
15
19
|
def data
|
16
|
-
data =
|
20
|
+
data = {}
|
17
21
|
data["name"] = @name if @name
|
18
22
|
data["type"] = @type if @type
|
19
|
-
data["swversion"] = @
|
20
|
-
data["state"] = @state.data
|
23
|
+
data["swversion"] = @sw_version if @sw_version
|
24
|
+
data["state"] = @state.data unless @state.data.empty?
|
25
|
+
data["pointsymbol"] = @point_symbol if @point_symbol
|
26
|
+
data["modelid"] = @model_id if @model_id
|
27
|
+
data["uniqueid"] = @unique_id if @unique_id
|
21
28
|
data
|
22
29
|
end
|
23
30
|
end
|
data/lib/lights/bulbstate.rb
CHANGED
@@ -45,18 +45,21 @@ class BulbState < HObject
|
|
45
45
|
:reachable, :transition_time
|
46
46
|
def initialize( data = {} )
|
47
47
|
data = {} if data == nil
|
48
|
-
super
|
49
|
-
@on = data["on"]
|
50
|
-
set_bri data["bri"]
|
51
|
-
set_hue data["hue"]
|
52
|
-
set_sat data["sat"]
|
53
|
-
set_xy data["xy"]
|
54
|
-
set_ct data["ct"]
|
55
|
-
set_alert data["alert"]
|
56
|
-
set_effect data["effect"]
|
57
|
-
set_color_mode data["colormode"]
|
58
48
|
@reachable = data["reachable"]
|
59
|
-
|
49
|
+
|
50
|
+
# bridge returns invaild values for state variables when reachable is false
|
51
|
+
unless @reachable == false
|
52
|
+
@on = data["on"]
|
53
|
+
set_bri data["bri"]
|
54
|
+
set_hue data["hue"]
|
55
|
+
set_sat data["sat"]
|
56
|
+
set_xy data["xy"]
|
57
|
+
set_ct data["ct"]
|
58
|
+
set_alert data["alert"]
|
59
|
+
set_effect data["effect"]
|
60
|
+
set_color_mode data["colormode"]
|
61
|
+
set_transition_time data["transitiontime"]
|
62
|
+
end
|
60
63
|
end
|
61
64
|
|
62
65
|
def color_mode=(value) set_color_mode(value) end
|
@@ -172,8 +175,8 @@ class BulbState < HObject
|
|
172
175
|
end
|
173
176
|
|
174
177
|
def data
|
175
|
-
data =
|
176
|
-
data["on"] = @on
|
178
|
+
data = {}
|
179
|
+
data["on"] = @on unless @on.nil?
|
177
180
|
data["bri"] = @bri if @bri
|
178
181
|
data["hue"] = @hue if @hue
|
179
182
|
data["sat"] = @sat if @sat
|
@@ -182,7 +185,7 @@ class BulbState < HObject
|
|
182
185
|
data["alert"] = @alert if @alert
|
183
186
|
data["effect"] = @effect if @effect
|
184
187
|
data["colormode"] = @color_mode if @color_mode
|
185
|
-
data["reachable"] = @reachable
|
188
|
+
data["reachable"] = @reachable unless @reachable.nil?
|
186
189
|
data["transitiontime"] = @transition_time if @transition_time
|
187
190
|
data
|
188
191
|
end
|
data/lib/lights/command.rb
CHANGED
@@ -3,14 +3,13 @@ require 'lights/hobject'
|
|
3
3
|
class Command < HObject
|
4
4
|
attr_reader :address, :method, :body
|
5
5
|
def initialize(data = {})
|
6
|
-
super
|
7
6
|
@address = data["address"]
|
8
7
|
@body = data["body"]
|
9
8
|
@method = data["method"]
|
10
9
|
end
|
11
10
|
|
12
11
|
def data
|
13
|
-
data =
|
12
|
+
data = {}
|
14
13
|
data["address"] = @address if @address
|
15
14
|
data["body"] = @body if @body
|
16
15
|
data["method"] = @method if @method
|
data/lib/lights/config.rb
CHANGED
@@ -2,19 +2,58 @@ require 'lights/userlist'
|
|
2
2
|
require 'lights/hobject'
|
3
3
|
|
4
4
|
class HueConfig < HObject
|
5
|
-
attr_reader :name, :
|
5
|
+
attr_reader :name, :zigbee_channel, :mac, :dhcp,
|
6
|
+
:ip_address, :netmask, :gateway,
|
7
|
+
:proxy_address, :proxy_port, :utc,
|
8
|
+
:local_time, :time_zone, :whitelist,
|
9
|
+
:swversion, :api_version, :sw_update,
|
10
|
+
:link_button, :portal_services,
|
11
|
+
:portal_connection, :portal_state
|
6
12
|
def initialize(data = {})
|
7
|
-
super
|
8
13
|
@name = data["name"]
|
9
|
-
@
|
14
|
+
@zigbee_channel = data["zigbeechannel"]
|
15
|
+
@mac = data["mac"]
|
16
|
+
@dhcp = data["dhcp"]
|
17
|
+
@ip_address = data["ipaddress"]
|
18
|
+
@netmask = data["netmask"]
|
19
|
+
@gateway = data["gateway"]
|
20
|
+
@proxy_address = data["proxyaddress"]
|
21
|
+
@proxy_port = data["proxyport"]
|
22
|
+
@utc = data["UTC"]
|
23
|
+
@local_time = data["localtime"]
|
24
|
+
@time_zone = data["timezone"]
|
10
25
|
@whitelist = UserList.new(data["whitelist"])
|
26
|
+
@sw_version = data["swversion"]
|
27
|
+
@api_version = data["apiversion"]
|
28
|
+
@sw_update = data["swupdate"]
|
29
|
+
@link_button = data["linkbutton"]
|
30
|
+
@portal_services = data["portalservices"]
|
31
|
+
@portal_connection = data["portalconnection"]
|
32
|
+
@portal_state = data["portalstate"]
|
11
33
|
end
|
12
34
|
|
13
35
|
def data
|
14
|
-
data =
|
36
|
+
data = {}
|
15
37
|
data["name"] = @name if @name
|
16
|
-
data["
|
17
|
-
data["
|
38
|
+
data["zigbeechannel"] = @zigbee_channel if @zigbee_channel
|
39
|
+
data["mac"] = @mac if @mac
|
40
|
+
data["dhcp"] = @dhcp unless @dhcp.nil?
|
41
|
+
data["ipaddress"] = @ip_address if @ip_address
|
42
|
+
data["netmask"] = @netmask if @netmask
|
43
|
+
data["gateway"] = @gateway if @gateway
|
44
|
+
data["proxyaddress"] = @proxy_address if @proxy_address
|
45
|
+
data["proxyport"] = @proxy_port if @proxy_port
|
46
|
+
data["UTC"] = @utc if @utc
|
47
|
+
data["localtime"] = @local_time if @local_time
|
48
|
+
data["timezone"] = @time_zone if @time_zone
|
49
|
+
data["whitelist"] = @whitelist.data unless @whitelist.data.empty?
|
50
|
+
data["swversion"] = @sw_version if @sw_version
|
51
|
+
data["apiversion"] = @api_version if @api_version
|
52
|
+
data["swupdate"] = @sw_update unless @sw_update.nil?
|
53
|
+
data["linkbutton"] = @link_button unless @link_button.nil?
|
54
|
+
data["portalservices"] = @portal_services unless @portal_services.nil?
|
55
|
+
data["portalconnection"] = @portal_connection if @portal_connection
|
56
|
+
data["portalstate"] = @portal_state unless @portal_state.nil?
|
18
57
|
data
|
19
58
|
end
|
20
59
|
end
|
data/lib/lights/datastore.rb
CHANGED
@@ -11,7 +11,6 @@ class Datastore < HObject
|
|
11
11
|
attr_reader :lights, :groups, :config, :rules,
|
12
12
|
:scenes, :schedules, :sensors
|
13
13
|
def initialize(data = {})
|
14
|
-
super
|
15
14
|
@lights = BulbList.new(data["lights"])
|
16
15
|
@groups = GroupList.new(data["groups"])
|
17
16
|
@config = HueConfig.new(data["config"])
|
@@ -32,7 +31,7 @@ class Datastore < HObject
|
|
32
31
|
end
|
33
32
|
|
34
33
|
def data
|
35
|
-
data =
|
34
|
+
data = {}
|
36
35
|
data["lights"] = @lights.data if !@lights.data.empty?
|
37
36
|
data["groups"] = @groups.data if !@groups.data.empty?
|
38
37
|
data["config"] = @config.data if !@config.data.empty?
|
data/lib/lights/exception.rb
CHANGED
@@ -12,7 +12,7 @@ end
|
|
12
12
|
|
13
13
|
class BulbStateValueOutOfRangeException < Exception
|
14
14
|
def initalize(msg = "Value out of range.")
|
15
|
-
super
|
15
|
+
super
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
@@ -33,3 +33,9 @@ class ParameterUnavailableException < Exception
|
|
33
33
|
super
|
34
34
|
end
|
35
35
|
end
|
36
|
+
|
37
|
+
class SceneLockedException < Exception
|
38
|
+
def initialize(msg = "Scene could not be removed, because it's locked.")
|
39
|
+
super
|
40
|
+
end
|
41
|
+
end
|
data/lib/lights/group.rb
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
require 'lights/hobject'
|
2
2
|
|
3
3
|
class Group < HObject
|
4
|
-
attr_reader :id, :data, :name, :lights, :action
|
4
|
+
attr_reader :id, :data, :name, :lights, :action, :type
|
5
5
|
attr_writer :name, :lights, :action
|
6
6
|
def initialize( id = nil, data = {} )
|
7
|
-
super(data)
|
8
7
|
@id = id
|
9
8
|
@action = BulbState.new(data["action"])
|
10
9
|
@name = data["name"]
|
11
10
|
@lights = data["lights"]
|
11
|
+
@type = data["type"]
|
12
12
|
end
|
13
13
|
|
14
14
|
def data
|
15
|
-
data =
|
15
|
+
data = {}
|
16
16
|
data["name"] = @name if @name
|
17
17
|
data["lights"] = @lights if @lights
|
18
|
-
data["
|
18
|
+
data["type"] = @type if @type
|
19
|
+
data["action"] = @action.data unless @action.data.empty?
|
19
20
|
data
|
20
21
|
end
|
21
22
|
end
|
data/lib/lights/hobject.rb
CHANGED
data/lib/lights/list.rb
CHANGED
data/lib/lights/rule.rb
CHANGED
@@ -1,16 +1,31 @@
|
|
1
1
|
require 'lights/hobject'
|
2
2
|
|
3
3
|
class Rule < HObject
|
4
|
-
attr_reader :id, :
|
4
|
+
attr_reader :id, :name, :owner, :created,
|
5
|
+
:last_triggered, :times_triggered,
|
6
|
+
:status, :conditions, :actions
|
5
7
|
def initialize( id = nil, data = {} )
|
6
|
-
super(data)
|
7
8
|
@id = id
|
8
9
|
@name = data["name"]
|
10
|
+
@owner = data["owner"]
|
11
|
+
@created = data["created"]
|
12
|
+
@last_triggered = data["lasttriggered"]
|
13
|
+
@times_triggered = data["timestriggered"]
|
14
|
+
@status = data["status"]
|
15
|
+
@conditions = data["conditions"]
|
16
|
+
@actions = data["actions"]
|
9
17
|
end
|
10
18
|
|
11
19
|
def data
|
12
|
-
data =
|
20
|
+
data = {}
|
13
21
|
data["name"] = @name if @name
|
22
|
+
data["owner"] = @owner if @owner
|
23
|
+
data["created"] = @created if @created
|
24
|
+
data["lasttriggered"] = @last_triggered if @last_triggered
|
25
|
+
data["timestriggered"] = @times_triggered if @times_triggered
|
26
|
+
data["status"] = @status if @status
|
27
|
+
data["conditions"] = @conditions if @conditions
|
28
|
+
data["actions"] = @actions if @actions
|
14
29
|
data
|
15
30
|
end
|
16
31
|
end
|
data/lib/lights/scene.rb
CHANGED
@@ -1,20 +1,23 @@
|
|
1
1
|
require 'lights/hobject'
|
2
2
|
|
3
3
|
class Scene < HObject
|
4
|
-
attr_accessor :id, :name, :active, :lights
|
5
|
-
def initialize(id,data = {})
|
6
|
-
super(data)
|
4
|
+
attr_accessor :id, :name, :active, :lights, :recycle, :transition_time
|
5
|
+
def initialize(id = nil,data = {})
|
7
6
|
@id = id
|
8
7
|
@name = data["name"]
|
9
8
|
@active = data["active"]
|
10
9
|
@lights = data["lights"]
|
10
|
+
@recycle = data["recycle"]
|
11
|
+
@transition_time = data["transitiontime"]
|
11
12
|
end
|
12
13
|
|
13
14
|
def data
|
14
15
|
data = {}
|
15
16
|
data["name"] = @name if @name
|
16
|
-
data["active"] = @active
|
17
|
+
data["active"] = @active unless @active.nil?
|
17
18
|
data["lights"] = @lights if @lights
|
19
|
+
data["recycle"] = @recycle unless @recycle.nil?
|
20
|
+
data["transitiontime"] = @transition_time if @transition_time
|
18
21
|
data
|
19
22
|
end
|
20
23
|
end
|
data/lib/lights/schedule.rb
CHANGED
@@ -2,13 +2,17 @@ require 'lights/command'
|
|
2
2
|
require 'lights/hobject'
|
3
3
|
|
4
4
|
class Schedule < HObject
|
5
|
-
attr_reader :id, :name, :time, :status
|
5
|
+
attr_reader :id, :name, :time, :status,
|
6
|
+
:description, :local_time,
|
7
|
+
:created, :command
|
6
8
|
def initialize(id,data = {})
|
7
|
-
super(data)
|
8
9
|
@id = id
|
9
10
|
@name = data["name"]
|
10
11
|
@time = data["time"]
|
11
12
|
@status = data["status"]
|
13
|
+
@description = data["description"]
|
14
|
+
@local_time = data["localtime"]
|
15
|
+
@created = data["created"]
|
12
16
|
@command = Command.new(data["command"])
|
13
17
|
end
|
14
18
|
|
@@ -17,11 +21,14 @@ class Schedule < HObject
|
|
17
21
|
end
|
18
22
|
|
19
23
|
def data
|
20
|
-
data =
|
24
|
+
data = {}
|
21
25
|
data["name"] = @name if @name
|
22
26
|
data["time"] = @time if @time
|
23
27
|
data["status"] = @status if @status
|
24
|
-
data["
|
28
|
+
data["description"] = @description if @description
|
29
|
+
data["localtime"] = @local_time if @local_time
|
30
|
+
data["created"] = @created if @created
|
31
|
+
data["command"] = @command.data unless @command.data.empty?
|
25
32
|
data
|
26
33
|
end
|
27
34
|
end
|
data/lib/lights/sensor.rb
CHANGED
@@ -1,35 +1,25 @@
|
|
1
1
|
class SensorState < HObject
|
2
2
|
attr_reader :last_updated
|
3
3
|
def initialize(data)
|
4
|
-
super
|
5
4
|
@last_updated = data["lastupdated"]
|
5
|
+
@daylight = data["daylight"]
|
6
|
+
@button_event = data["buttonevent"]
|
6
7
|
end
|
7
8
|
|
8
9
|
def data
|
9
|
-
data =
|
10
|
+
data = {}
|
10
11
|
data["lastupdated"] = @last_updated if @last_updated
|
11
|
-
data
|
12
|
-
|
13
|
-
end
|
14
|
-
|
15
|
-
class TapState < SensorState
|
16
|
-
attr_reader :button_event
|
17
|
-
def initialize(data)
|
18
|
-
super
|
19
|
-
@button_event = data["button_event"]
|
20
|
-
end
|
21
|
-
|
22
|
-
def data
|
23
|
-
data = @data
|
24
|
-
data["button_event"] = @button_event if @button_event
|
12
|
+
data["daylight"] = @daylight unless @daylight.nil?
|
13
|
+
data["buttonevent"] = @button_event if @button_event
|
25
14
|
data
|
26
15
|
end
|
27
16
|
end
|
28
17
|
|
29
18
|
class Sensor < HObject
|
30
|
-
attr_reader :id, :data, :name, :type, :model_id,
|
19
|
+
attr_reader :id, :data, :name, :type, :model_id,
|
20
|
+
:manufacturer_name, :unique_id,
|
21
|
+
:sw_version, :state
|
31
22
|
def initialize( id, data = {} )
|
32
|
-
super(data)
|
33
23
|
@id = id
|
34
24
|
@name = data["name"]
|
35
25
|
@type = data["type"]
|
@@ -37,19 +27,20 @@ class Sensor < HObject
|
|
37
27
|
@manufacturer_name = data["manufacturername"]
|
38
28
|
@unique_id = data["uniqueid"]
|
39
29
|
@sw_version = data["swversion"]
|
30
|
+
@config = data["config"]
|
40
31
|
@state = SensorState.new(data["state"])
|
41
|
-
#@config = SensorConfig.new(data["config"])
|
42
32
|
end
|
43
33
|
|
44
34
|
def data
|
45
|
-
data =
|
35
|
+
data = {}
|
46
36
|
data["name"] = @name if @name
|
47
37
|
data["type"] = @type if @type
|
48
38
|
data["modelid"] = @model_id if @model_id
|
49
39
|
data["manufacturername"] = @manufacturer_name if @manufacturer_name
|
50
40
|
data["uniqueid"] = @unique_id if @unique_id
|
51
41
|
data["swversion"] = @sw_version if @sw_version
|
52
|
-
data["
|
42
|
+
data["config"] = @config if @config
|
43
|
+
data["state"] = @state.data unless @state.data.empty?
|
53
44
|
data
|
54
45
|
end
|
55
46
|
end
|
data/lib/lights/user.rb
CHANGED
@@ -3,7 +3,6 @@ require 'lights/hobject'
|
|
3
3
|
class User < HObject
|
4
4
|
attr_reader :id, :name, :create_date, :last_use_date
|
5
5
|
def initialize( id, data = {} )
|
6
|
-
super(data)
|
7
6
|
@id = id
|
8
7
|
@name = data["name"]
|
9
8
|
@create_date = data["create date"]
|
@@ -11,7 +10,7 @@ class User < HObject
|
|
11
10
|
end
|
12
11
|
|
13
12
|
def data
|
14
|
-
data =
|
13
|
+
data = {}
|
15
14
|
data["name"] = @name if @name
|
16
15
|
data["create date"] = @create_date if @create_date
|
17
16
|
data["last use date"] = @last_use_date if @last_use_date
|
data/lib/lights/version.rb
CHANGED
data/lights.gemspec
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'lights/version'
|
5
|
+
require 'date'
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = 'lights'
|
@@ -12,14 +13,14 @@ Gem::Specification.new do |s|
|
|
12
13
|
s.summary = "lights"
|
13
14
|
s.homepage = 'http://rubygems.org/gems/lights'
|
14
15
|
s.license = 'MIT'
|
15
|
-
s.date =
|
16
|
+
s.date = Date.today.to_s
|
16
17
|
|
17
18
|
s.files = `git ls-files`.split($/)
|
18
19
|
s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
20
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
20
21
|
s.require_paths = ["lib"]
|
21
22
|
|
22
|
-
s.add_runtime_dependency "simpletable", "~> 0.3.
|
23
|
+
s.add_runtime_dependency "simpletable", "~> 0.3.2"
|
23
24
|
|
24
25
|
s.add_development_dependency "bundler", "~> 1.3"
|
25
26
|
s.add_development_dependency "rake"
|
data/spec/bulb_spec.rb
CHANGED
@@ -7,6 +7,13 @@ describe Bulb do
|
|
7
7
|
bulb.name.should eql "test name"
|
8
8
|
end
|
9
9
|
|
10
|
+
it "properly set name parameter" do
|
11
|
+
data = { "name" => "test name" }
|
12
|
+
bulb = Bulb.new(1,data)
|
13
|
+
bulb.name = "new test name"
|
14
|
+
bulb.name.should eql "new test name"
|
15
|
+
end
|
16
|
+
|
10
17
|
it "properly creates state object" do
|
11
18
|
data = {
|
12
19
|
"name" => "test name",
|
data/spec/bulbstate_spec.rb
CHANGED
@@ -248,6 +248,16 @@ describe BulbState do
|
|
248
248
|
expect { b.ct = BulbState::MIN_CT - 1 }.to raise_error
|
249
249
|
end
|
250
250
|
|
251
|
+
it "should ignore out of range color temperature when 'reachable'= false" do
|
252
|
+
state = {
|
253
|
+
"reachable" => false,
|
254
|
+
"ct" => 0
|
255
|
+
}
|
256
|
+
b = BulbState.new state
|
257
|
+
b.data["ct"].should eq nil
|
258
|
+
b.data["reachable"].should eq false
|
259
|
+
end
|
260
|
+
|
251
261
|
# EFFECT
|
252
262
|
it "should properly set effect value in constructor" do
|
253
263
|
data = { "effect" => BulbState::Effect::COLORLOOP }
|
data/spec/datastore_spec.rb
CHANGED
@@ -2,15 +2,45 @@ require 'lights'
|
|
2
2
|
|
3
3
|
describe Datastore do
|
4
4
|
it "properly reconstructs sub objects" do
|
5
|
+
data = JSON.parse(DATASTORE_JSON)
|
6
|
+
ds = Datastore.new data
|
7
|
+
ds.data.should eql data
|
8
|
+
end
|
9
|
+
|
10
|
+
it "properly reconstructs light objects" do
|
5
11
|
data = JSON.parse(DATASTORE_JSON)
|
6
12
|
ds = Datastore.new data
|
7
13
|
ds.lights.data.should eql data["lights"]
|
14
|
+
end
|
15
|
+
it "properly reconstructs group objects" do
|
16
|
+
data = JSON.parse(DATASTORE_JSON)
|
17
|
+
ds = Datastore.new data
|
8
18
|
ds.groups.data.should eql data["groups"]
|
19
|
+
end
|
20
|
+
it "properly reconstructs rule objects" do
|
21
|
+
data = JSON.parse(DATASTORE_JSON)
|
22
|
+
ds = Datastore.new data
|
9
23
|
ds.rules.data.should eql data["rules"]
|
24
|
+
end
|
25
|
+
it "properly reconstructs scene objects" do
|
26
|
+
data = JSON.parse(DATASTORE_JSON)
|
27
|
+
ds = Datastore.new data
|
10
28
|
ds.scenes.data.should eql data["scenes"]
|
29
|
+
end
|
30
|
+
it "properly reconstructs schedule objects" do
|
31
|
+
data = JSON.parse(DATASTORE_JSON)
|
32
|
+
ds = Datastore.new data
|
11
33
|
ds.schedules.data.should eql data["schedules"]
|
34
|
+
end
|
35
|
+
it "properly reconstructs sensor objects" do
|
36
|
+
data = JSON.parse(DATASTORE_JSON)
|
37
|
+
ds = Datastore.new data
|
12
38
|
ds.sensors.data.should eql data["sensors"]
|
13
|
-
|
39
|
+
end
|
40
|
+
it "properly reconstructs config object" do
|
41
|
+
data = JSON.parse(DATASTORE_JSON)
|
42
|
+
ds = Datastore.new data
|
43
|
+
ds.config.data.should eql data["config"]
|
14
44
|
end
|
15
45
|
end
|
16
46
|
|
@@ -19,7 +49,7 @@ DATASTORE_JSON = %Q{
|
|
19
49
|
"lights": {
|
20
50
|
"1": {
|
21
51
|
"state": {
|
22
|
-
"on":
|
52
|
+
"on": false,
|
23
53
|
"bri": 254,
|
24
54
|
"hue": 34495,
|
25
55
|
"sat": 232,
|
@@ -227,7 +257,7 @@ DATASTORE_JSON = %Q{
|
|
227
257
|
"name": "Philips hue",
|
228
258
|
"zigbeechannel": 25,
|
229
259
|
"mac": "00:11:22:33:44:55",
|
230
|
-
"dhcp":
|
260
|
+
"dhcp": false,
|
231
261
|
"ipaddress": "192.168.1.27",
|
232
262
|
"netmask": "255.255.255.0",
|
233
263
|
"gateway": "192.168.1.1",
|
@@ -269,7 +299,7 @@ DATASTORE_JSON = %Q{
|
|
269
299
|
"notify": false
|
270
300
|
},
|
271
301
|
"linkbutton": false,
|
272
|
-
"portalservices":
|
302
|
+
"portalservices": false,
|
273
303
|
"portalconnection": "connected",
|
274
304
|
"portalstate": {
|
275
305
|
"signedon": true,
|
@@ -320,7 +350,7 @@ DATASTORE_JSON = %Q{
|
|
320
350
|
"4",
|
321
351
|
"5"
|
322
352
|
],
|
323
|
-
"active":
|
353
|
+
"active": false
|
324
354
|
},
|
325
355
|
"da01b1eaf-on-0": {
|
326
356
|
"name": "Purple on 0",
|
data/spec/group_spec.rb
CHANGED
@@ -2,22 +2,152 @@ require 'lights'
|
|
2
2
|
|
3
3
|
describe Group do
|
4
4
|
it "properly parses input parameters" do
|
5
|
-
data =
|
6
|
-
"key1" => "value 1",
|
7
|
-
"key2" => "value 2",
|
8
|
-
}
|
5
|
+
data = JSON.parse(GROUPS_JSON)["1"]
|
9
6
|
group = Group.new(1,data)
|
10
7
|
group.id.should eql 1
|
11
|
-
group.
|
8
|
+
group.name.should eql "Ceiling light"
|
9
|
+
group.type.should eql "LightGroup"
|
10
|
+
group.lights.should eql ["1","2","3","4"]
|
12
11
|
end
|
13
12
|
|
14
13
|
it "properly reconstucts object hash" do
|
15
|
-
data =
|
16
|
-
"key1" => "value 1",
|
17
|
-
"key2" => "value 2",
|
18
|
-
}
|
14
|
+
data = JSON.parse(GROUPS_JSON)["1"]
|
19
15
|
group = Group.new(1,data)
|
20
16
|
group.id.should eql 1
|
21
17
|
group.data.should eql data
|
22
18
|
end
|
23
19
|
end
|
20
|
+
|
21
|
+
GROUPS_JSON = %Q{
|
22
|
+
{
|
23
|
+
"1": {
|
24
|
+
"name": "Ceiling light",
|
25
|
+
"lights": [
|
26
|
+
"1",
|
27
|
+
"2",
|
28
|
+
"3",
|
29
|
+
"4"
|
30
|
+
],
|
31
|
+
"type": "LightGroup",
|
32
|
+
"action": {
|
33
|
+
"on": true,
|
34
|
+
"bri": 254,
|
35
|
+
"hue": 56100,
|
36
|
+
"sat": 232,
|
37
|
+
"effect": "none",
|
38
|
+
"xy": [
|
39
|
+
0.4119,
|
40
|
+
0.1949
|
41
|
+
],
|
42
|
+
"ct": 293,
|
43
|
+
"colormode": "xy"
|
44
|
+
}
|
45
|
+
},
|
46
|
+
"2": {
|
47
|
+
"name": "Lamp",
|
48
|
+
"lights": [
|
49
|
+
"5"
|
50
|
+
],
|
51
|
+
"type": "LightGroup",
|
52
|
+
"action": {
|
53
|
+
"on": true,
|
54
|
+
"bri": 254,
|
55
|
+
"hue": 56100,
|
56
|
+
"sat": 232,
|
57
|
+
"effect": "none",
|
58
|
+
"xy": [
|
59
|
+
0.4119,
|
60
|
+
0.1949
|
61
|
+
],
|
62
|
+
"ct": 293,
|
63
|
+
"colormode": "xy"
|
64
|
+
}
|
65
|
+
},
|
66
|
+
"3": {
|
67
|
+
"name": "HueCraft_Ambiance1",
|
68
|
+
"lights": [
|
69
|
+
"1",
|
70
|
+
"2"
|
71
|
+
],
|
72
|
+
"type": "LightGroup",
|
73
|
+
"action": {
|
74
|
+
"on": true,
|
75
|
+
"bri": 254,
|
76
|
+
"hue": 56100,
|
77
|
+
"sat": 232,
|
78
|
+
"effect": "none",
|
79
|
+
"xy": [
|
80
|
+
0.4119,
|
81
|
+
0.1949
|
82
|
+
],
|
83
|
+
"ct": 293,
|
84
|
+
"colormode": "xy"
|
85
|
+
}
|
86
|
+
},
|
87
|
+
"4": {
|
88
|
+
"name": "HueCraft_Ambiance2",
|
89
|
+
"lights": [
|
90
|
+
"3",
|
91
|
+
"4"
|
92
|
+
],
|
93
|
+
"type": "LightGroup",
|
94
|
+
"action": {
|
95
|
+
"on": true,
|
96
|
+
"bri": 254,
|
97
|
+
"hue": 56100,
|
98
|
+
"sat": 232,
|
99
|
+
"effect": "none",
|
100
|
+
"xy": [
|
101
|
+
0.4119,
|
102
|
+
0.1949
|
103
|
+
],
|
104
|
+
"ct": 293,
|
105
|
+
"colormode": "xy"
|
106
|
+
}
|
107
|
+
},
|
108
|
+
"5": {
|
109
|
+
"name": "HueCraft_Effect1",
|
110
|
+
"lights": [
|
111
|
+
"5"
|
112
|
+
],
|
113
|
+
"type": "LightGroup",
|
114
|
+
"action": {
|
115
|
+
"on": true,
|
116
|
+
"bri": 254,
|
117
|
+
"hue": 56100,
|
118
|
+
"sat": 232,
|
119
|
+
"effect": "none",
|
120
|
+
"xy": [
|
121
|
+
0.4119,
|
122
|
+
0.1949
|
123
|
+
],
|
124
|
+
"ct": 293,
|
125
|
+
"colormode": "xy"
|
126
|
+
}
|
127
|
+
},
|
128
|
+
"6": {
|
129
|
+
"name": "HueCraft_HueCraft",
|
130
|
+
"lights": [
|
131
|
+
"1",
|
132
|
+
"2",
|
133
|
+
"3",
|
134
|
+
"4",
|
135
|
+
"5"
|
136
|
+
],
|
137
|
+
"type": "LightGroup",
|
138
|
+
"action": {
|
139
|
+
"on": true,
|
140
|
+
"bri": 254,
|
141
|
+
"hue": 56100,
|
142
|
+
"sat": 232,
|
143
|
+
"effect": "none",
|
144
|
+
"xy": [
|
145
|
+
0.4119,
|
146
|
+
0.1949
|
147
|
+
],
|
148
|
+
"ct": 293,
|
149
|
+
"colormode": "xy"
|
150
|
+
}
|
151
|
+
}
|
152
|
+
}
|
153
|
+
}
|
data/spec/rule_spec.rb
CHANGED
metadata
CHANGED
@@ -1,97 +1,97 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lights
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brady Turner
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: simpletable
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.3.
|
19
|
+
version: 0.3.2
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.3.
|
26
|
+
version: 0.3.2
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.3'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.3'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: rspec
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - ~>
|
59
|
+
- - "~>"
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '2.6'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - ~>
|
66
|
+
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '2.6'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: cucumber
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: aruba
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
89
|
version: '0'
|
90
90
|
type: :development
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
97
|
description: Client library and CLI for controlling Philips Hue lights.
|
@@ -101,7 +101,7 @@ executables:
|
|
101
101
|
extensions: []
|
102
102
|
extra_rdoc_files: []
|
103
103
|
files:
|
104
|
-
- .gitignore
|
104
|
+
- ".gitignore"
|
105
105
|
- Gemfile
|
106
106
|
- LICENSE.txt
|
107
107
|
- README.md
|
@@ -154,17 +154,16 @@ require_paths:
|
|
154
154
|
- lib
|
155
155
|
required_ruby_version: !ruby/object:Gem::Requirement
|
156
156
|
requirements:
|
157
|
-
- -
|
157
|
+
- - ">="
|
158
158
|
- !ruby/object:Gem::Version
|
159
159
|
version: '0'
|
160
160
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
161
161
|
requirements:
|
162
|
-
- -
|
162
|
+
- - ">="
|
163
163
|
- !ruby/object:Gem::Version
|
164
164
|
version: '0'
|
165
165
|
requirements: []
|
166
|
-
|
167
|
-
rubygems_version: 2.0.6
|
166
|
+
rubygems_version: 3.0.6
|
168
167
|
signing_key:
|
169
168
|
specification_version: 4
|
170
169
|
summary: lights
|