lights 0.8.18 → 1.0.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 +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
|