lights 0.8.9 → 0.8.10
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 +1 -6
- data/lib/lights.rb +1 -7
- data/lib/lights/bulb.rb +7 -2
- data/lib/lights/bulblist.rb +22 -0
- data/lib/lights/bulbstate.rb +18 -17
- data/lib/lights/command.rb +1 -1
- data/lib/lights/config.rb +26 -0
- data/lib/lights/datastore.rb +50 -0
- data/lib/lights/group.rb +1 -3
- data/lib/lights/grouplist.rb +22 -0
- data/lib/lights/rule.rb +1 -3
- data/lib/lights/rulelist.rb +22 -0
- data/lib/lights/scene.rb +4 -0
- data/lib/lights/scenelist.rb +22 -0
- data/lib/lights/schedule.rb +1 -1
- data/lib/lights/schedulelist.rb +22 -0
- data/lib/lights/sensor.rb +36 -0
- data/lib/lights/sensorlist.rb +23 -0
- data/lib/lights/user.rb +12 -0
- data/lib/lights/userlist.rb +22 -0
- data/lib/lights/version.rb +1 -1
- data/lights.gemspec +1 -1
- data/spec/datastore_spec.rb +515 -0
- metadata +14 -3
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MWJlYThiNGQ5NzkxYjA3NjRmOTcxYzNmMGFkMzcyY2I0Mzk5MjY5Mg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZDFiM2M3ZDE3OWU5YWMwZDgyOTY5YTk4MjRiMzA5NmVjY2Q5NDEyNw==
|
7
7
|
!binary "U0hBNTEy":
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
MTEwOTkwNTdhYjUyMTNmZDJiOTkwYWIzZWZlNzc0MWJlYjNmYjgzMWE1Y2Yy
|
10
|
+
ZGFmYmRlNTBiNmRjYWExNGUwYWE1M2I1YTdmNjVjYmI5NzcyYWExZjFjMTgx
|
11
|
+
M2EwMmMwNjQ1MmY3NmFhMmMzMmY2NzZhZGIwYjE4ODFjNDVmZGE=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZmU0YTE1ZGUxOTgyNTAyMzlhNzQ4OTUzZDg4NDMyMmRlNDEzOTY3M2ViODNm
|
14
|
+
NzhiMTM5MDNkYTI0MDQyYTc1ZGU0N2RkZjVlNTYwZjRiNDg0ZjA4NjE4MGM1
|
15
|
+
OTg5MGNhM2E1MzM5OGRjMjczN2U1YzcyZGU1MjUyZTA3ZTcwNDk=
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
lights
|
2
2
|
========
|
3
|
-
A Ruby library & CLI for
|
3
|
+
A Ruby library & CLI for interacting with Philips Hue.
|
4
4
|
|
5
5
|
* Philips Hue API Documentation: http://www.developers.meethue.com/philips-hue-api
|
6
6
|
* lights on RubyGems: https://rubygems.org/gems/lights
|
data/bin/lights
CHANGED
@@ -173,12 +173,7 @@ class LightsCli
|
|
173
173
|
methods = [:id,:name,:time,:scene,:status]
|
174
174
|
when "datastore"
|
175
175
|
response = hue.request_datastore
|
176
|
-
|
177
|
-
response["groups"].each {|id,value| objects << Group.new(id,value)}
|
178
|
-
response["config"]["whitelist"].each {|id,value| objects << User.new(id,value)}
|
179
|
-
response["rules"].each {|id,value| objects << Rule.new(id,value)}
|
180
|
-
response["scenes"].each {|id,value| objects << Scene.new(id,value)}
|
181
|
-
response["schedules"].each {|id,value| objects << Schedule.new(id,value)}
|
176
|
+
objects = Datastore.new(response).all
|
182
177
|
titles = ["TYPE","ID","NAME"]
|
183
178
|
methods = [:class,:id,:name]
|
184
179
|
else
|
data/lib/lights.rb
CHANGED
@@ -4,15 +4,9 @@ require 'net/http'
|
|
4
4
|
require 'uri'
|
5
5
|
require 'json'
|
6
6
|
|
7
|
-
require 'lights/bulb'
|
8
|
-
require 'lights/group'
|
9
7
|
require 'lights/bridge'
|
10
8
|
require 'lights/exception'
|
11
|
-
require 'lights/
|
12
|
-
require 'lights/scene'
|
13
|
-
require 'lights/user'
|
14
|
-
require 'lights/rule'
|
15
|
-
require 'lights/schedule'
|
9
|
+
require 'lights/datastore'
|
16
10
|
require 'lights/loggerconfig'
|
17
11
|
|
18
12
|
def jp( s )
|
data/lib/lights/bulb.rb
CHANGED
@@ -9,17 +9,22 @@ class Bulb
|
|
9
9
|
@id = id
|
10
10
|
@name = data["name"]
|
11
11
|
@type = data["type"]
|
12
|
-
@swversion = data["
|
12
|
+
@swversion = data["swversion"]
|
13
13
|
@state = BulbState.new data["state"]
|
14
|
+
@data = data
|
14
15
|
end
|
15
16
|
|
16
17
|
def data
|
17
|
-
data =
|
18
|
+
data = @data
|
18
19
|
data["name"] = @name if @name
|
19
20
|
data["type"] = @type if @type
|
20
21
|
data["swversion"] = @swversion if @swversion
|
21
22
|
data["state"] = @state.data if !@state.data.empty?
|
22
23
|
data
|
23
24
|
end
|
25
|
+
|
26
|
+
def to_json(options={})
|
27
|
+
data.to_json
|
28
|
+
end
|
24
29
|
end
|
25
30
|
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'lights/bulb'
|
2
|
+
|
3
|
+
class BulbList
|
4
|
+
|
5
|
+
attr_reader :bulbs
|
6
|
+
def initialize(data = {})
|
7
|
+
@bulbs = []
|
8
|
+
data.each{|id,value| @bulbs << Bulb.new(id,value)} if data
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def data
|
13
|
+
data = @data
|
14
|
+
@bulbs.each {|b| data[b.id] = b.data} if @bulbs
|
15
|
+
data
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_json(options={})
|
19
|
+
data.to_json
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/lights/bulbstate.rb
CHANGED
@@ -46,6 +46,7 @@ class BulbState
|
|
46
46
|
set_color_mode data["colormode"]
|
47
47
|
@reachable = data["reachable"]
|
48
48
|
set_transition_time data["transitiontime"]
|
49
|
+
@data = data
|
49
50
|
end
|
50
51
|
|
51
52
|
def color_mode=(value) set_color_mode(value) end
|
@@ -55,7 +56,7 @@ class BulbState
|
|
55
56
|
|| value == ColorMode::CT
|
56
57
|
@color_mode = value
|
57
58
|
else
|
58
|
-
raise BulbStateValueTypeException, "
|
59
|
+
raise BulbStateValueTypeException, "Color mode value has incorrect type. Requires 'hs', 'xy', or 'ct'. Was #{value.inspect}"
|
59
60
|
end
|
60
61
|
end
|
61
62
|
|
@@ -66,7 +67,7 @@ class BulbState
|
|
66
67
|
|| value == Alert::LSELECT
|
67
68
|
@alert = value
|
68
69
|
else
|
69
|
-
raise BulbStateValueTypeException, "
|
70
|
+
raise BulbStateValueTypeException, "Alert value has incorrect type. Requires 'none', 'select', or 'lselect'. Was #{value.inspect}"
|
70
71
|
end
|
71
72
|
end
|
72
73
|
|
@@ -75,7 +76,7 @@ class BulbState
|
|
75
76
|
if value.nil? || value == Effect::NONE || value == Effect::COLORLOOP
|
76
77
|
@effect = value
|
77
78
|
else
|
78
|
-
raise BulbStateValueTypeException, "
|
79
|
+
raise BulbStateValueTypeException, "Effect value has incorrect type. Requires 'none' or 'colorloop'. Was #{value.inspect}"
|
79
80
|
end
|
80
81
|
end
|
81
82
|
|
@@ -85,7 +86,7 @@ class BulbState
|
|
85
86
|
if !!value == value
|
86
87
|
@on = value
|
87
88
|
else
|
88
|
-
raise BulbStateValueTypeException, "
|
89
|
+
raise BulbStateValueTypeException, "On value has incorrect type. Requires boolean, got #{value.class}. Was #{value.inspect}"
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
@@ -94,58 +95,58 @@ class BulbState
|
|
94
95
|
if value.nil? || value.between?(MIN_BRI,MAX_BRI)
|
95
96
|
@bri = value
|
96
97
|
else
|
97
|
-
raise BulbStateValueOutOfRangeException, "
|
98
|
+
raise BulbStateValueOutOfRangeException, "Brightness value out of range. Must be [#{MIN_BRI},#{MAX_BRI}]. Was #{value.inspect}"
|
98
99
|
end
|
99
100
|
end
|
100
101
|
|
101
102
|
def ct=(value); set_ct(value) end
|
102
103
|
def set_ct(value)
|
103
104
|
if !value.nil? && (!value.is_a? Integer)
|
104
|
-
raise BulbStateValueTypeException, "
|
105
|
+
raise BulbStateValueTypeException, "Color temperature value has incorrect type. Requires integer, got #{value.class}"
|
105
106
|
elsif value.nil? || value.between?(MIN_CT,MAX_CT)
|
106
107
|
@ct = value
|
107
108
|
else
|
108
|
-
raise BulbStateValueOutOfRangeException, "
|
109
|
+
raise BulbStateValueOutOfRangeException, "Color temperature value out of range. Must be [#{MIN_CT},#{MAX_CT}]. Was #{value.inspect}"
|
109
110
|
end
|
110
111
|
end
|
111
112
|
|
112
113
|
def sat=(value); set_sat(value) end
|
113
114
|
def set_sat(value)
|
114
115
|
if !value.nil? && (!value.is_a? Integer)
|
115
|
-
raise BulbStateValueTypeException, "
|
116
|
+
raise BulbStateValueTypeException, "Saturation value has incorrect type. Requires integer, got #{value.class}"
|
116
117
|
elsif value.nil? || value.between?(MIN_SAT,MAX_SAT)
|
117
118
|
@sat = value
|
118
119
|
else
|
119
|
-
raise BulbStateValueOutOfRangeException, "
|
120
|
+
raise BulbStateValueOutOfRangeException, "Saturation alue out of range. Must be [#{MIN_SAT},#{MAX_SAT}]. Was #{value.inspect}"
|
120
121
|
end
|
121
122
|
end
|
122
123
|
|
123
124
|
def hue=(value); set_hue(value) end
|
124
125
|
def set_hue(value)
|
125
126
|
if !value.nil? && (!value.is_a? Integer)
|
126
|
-
raise BulbStateValueTypeException, "
|
127
|
+
raise BulbStateValueTypeException, "Hue value has incorrect type. Requires integer, got #{value.class}"
|
127
128
|
elsif value.nil? || value.between?(MIN_HUE,MAX_HUE)
|
128
129
|
@hue = value
|
129
130
|
else
|
130
|
-
raise BulbStateValueOutOfRangeException, "
|
131
|
+
raise BulbStateValueOutOfRangeException, "Hue value out of range. Must be [#{MIN_HUE},#{MAX_HUE}]. Was #{value.inspect}"
|
131
132
|
end
|
132
133
|
end
|
133
134
|
|
134
135
|
def transition_time=(value); set_transition_time(value) end
|
135
136
|
def set_transition_time(value)
|
136
137
|
if !value.nil? && (!value.is_a? Numeric)
|
137
|
-
raise BulbStateValueTypeException, "
|
138
|
+
raise BulbStateValueTypeException, "Transition time value has incorrect type. Requires decimal, got #{value.class}"
|
138
139
|
elsif value.nil? || value >= MIN_TRANSITION_TIME
|
139
140
|
@transition_time = value
|
140
141
|
else
|
141
|
-
raise BulbStateValueOutOfRangeException, "
|
142
|
+
raise BulbStateValueOutOfRangeException, "Transition time value out of range. Must be > #{MIN_TRANSITION_TIME}. Was #{value.inspect}"
|
142
143
|
end
|
143
144
|
end
|
144
145
|
|
145
146
|
def xy=(value); set_xy(value) end
|
146
147
|
def set_xy(value)
|
147
148
|
if !value.nil? && (!value.is_a? Array)
|
148
|
-
raise BulbStateValueTypeException, "
|
149
|
+
raise BulbStateValueTypeException, "XY value has incorrect type. Requires array, got #{value.class}"
|
149
150
|
elsif value.nil?
|
150
151
|
return
|
151
152
|
elsif value.length == 2 && value[0].is_a?(Numeric) \
|
@@ -156,12 +157,12 @@ class BulbState
|
|
156
157
|
@xy[0] = value[0].to_f
|
157
158
|
@xy[1] = value[1].to_f
|
158
159
|
else
|
159
|
-
raise BulbStateValueOutOfRangeException, "
|
160
|
+
raise BulbStateValueOutOfRangeException, "XY value out of range. Must be [#{MIN_XY},#{MAX_XY}]. Was #{value.inspect}"
|
160
161
|
end
|
161
162
|
end
|
162
163
|
|
163
164
|
def data
|
164
|
-
data =
|
165
|
+
data = @data
|
165
166
|
data["on"] = @on if (@on!=nil)
|
166
167
|
data["bri"] = @bri if @bri
|
167
168
|
data["hue"] = @hue if @hue
|
@@ -176,7 +177,7 @@ class BulbState
|
|
176
177
|
data
|
177
178
|
end
|
178
179
|
|
179
|
-
def to_json
|
180
|
+
def to_json(options={})
|
180
181
|
data.to_json
|
181
182
|
end
|
182
183
|
end
|
data/lib/lights/command.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'lights/userlist'
|
2
|
+
|
3
|
+
class HueConfig
|
4
|
+
|
5
|
+
attr_reader :name, :swversion, :whitelist
|
6
|
+
|
7
|
+
def initialize(data = {})
|
8
|
+
@name = data["name"]
|
9
|
+
@swversion = data["swversion"]
|
10
|
+
@whitelist = UserList.new(data["whitelist"])
|
11
|
+
@data = data
|
12
|
+
end
|
13
|
+
|
14
|
+
def data
|
15
|
+
data = @data
|
16
|
+
data["name"] = @name if @name
|
17
|
+
data["swversion"] = @swversion if @swversion
|
18
|
+
data["whitelist"] = @whitelist.data if !@whitelist.data.empty?
|
19
|
+
data
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_json(options={})
|
23
|
+
data.to_json
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'lights/config'
|
2
|
+
require 'lights/bulblist'
|
3
|
+
require 'lights/grouplist'
|
4
|
+
require 'lights/scenelist'
|
5
|
+
require 'lights/rulelist'
|
6
|
+
require 'lights/schedulelist'
|
7
|
+
require 'lights/sensorlist'
|
8
|
+
|
9
|
+
class Datastore
|
10
|
+
|
11
|
+
attr_reader :lights, :groups, :config, :rules,
|
12
|
+
:scenes, :schedules, :sensors
|
13
|
+
def initialize(data = {})
|
14
|
+
@data = {}
|
15
|
+
@lights = BulbList.new(data["lights"])
|
16
|
+
@groups = GroupList.new(data["groups"])
|
17
|
+
@config = HueConfig.new(data["config"])
|
18
|
+
@schedules = ScheduleList.new(data["schedules"])
|
19
|
+
@scenes = SceneList.new(data["scenes"])
|
20
|
+
@rules = RuleList.new(data["rules"])
|
21
|
+
@sensors = SensorList.new(data["sensors"])
|
22
|
+
end
|
23
|
+
|
24
|
+
def all
|
25
|
+
@lights.bulbs + \
|
26
|
+
@groups.groups + \
|
27
|
+
[@config] + \
|
28
|
+
@schedules.schedules + \
|
29
|
+
@scenes.scenes + \
|
30
|
+
@rules.rules + \
|
31
|
+
@sensors.sensors
|
32
|
+
end
|
33
|
+
|
34
|
+
def data
|
35
|
+
data = @data
|
36
|
+
data["lights"] = @lights.data if !@lights.data.empty?
|
37
|
+
data["groups"] = @groups.data if !@groups.data.empty?
|
38
|
+
data["config"] = @config.data if !@config.data.empty?
|
39
|
+
data["schedules"] = @schedules.data if !@schedules.data.empty?
|
40
|
+
data["scenes"] = @scenes.data if !@scenes.data.empty?
|
41
|
+
data["rules"] = @rules.data if !@rules.data.empty?
|
42
|
+
data["sensors"] = @sensors.data if !@sensors.data.empty?
|
43
|
+
data
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_json(options={})
|
47
|
+
data.to_json
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
data/lib/lights/group.rb
CHANGED
@@ -16,15 +16,13 @@ class Group
|
|
16
16
|
|
17
17
|
def data
|
18
18
|
data = @data
|
19
|
-
data["id"] = @id if @id
|
20
19
|
data["name"] = @name if @name
|
21
20
|
data["lights"] = @lights if @lights
|
22
21
|
data["action"] = @action.data if @action.data != {}
|
23
22
|
data
|
24
23
|
end
|
25
24
|
|
26
|
-
def to_json
|
25
|
+
def to_json(options={})
|
27
26
|
data.to_json
|
28
27
|
end
|
29
|
-
|
30
28
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'lights/group'
|
2
|
+
|
3
|
+
class GroupList
|
4
|
+
|
5
|
+
attr_reader :groups
|
6
|
+
def initialize(data = {})
|
7
|
+
@groups = []
|
8
|
+
data.each{|id,value| @groups << Group.new(id,value)} if data
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def data
|
13
|
+
data = @data
|
14
|
+
@groups.each {|g| data[g.id] = g.data} if @groups
|
15
|
+
data
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_json(options={})
|
19
|
+
data.to_json
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/lights/rule.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'lights/rule'
|
2
|
+
|
3
|
+
class RuleList
|
4
|
+
|
5
|
+
attr_reader :rules
|
6
|
+
def initialize(data = {})
|
7
|
+
@rules = []
|
8
|
+
data.each{|id,value| @rules << Rule.new(id,value)} if data
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def data
|
13
|
+
data = @data
|
14
|
+
@rules.each {|b| data[b.id] = b.data} if @rules
|
15
|
+
data
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_json(options={})
|
19
|
+
data.to_json
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/lights/scene.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'lights/scene'
|
2
|
+
|
3
|
+
class SceneList
|
4
|
+
|
5
|
+
attr_reader :scenes
|
6
|
+
def initialize(data = {})
|
7
|
+
@scenes = []
|
8
|
+
data.each{|id,value| @scenes << Scene.new(id,value)} if data
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def data
|
13
|
+
data = @data
|
14
|
+
@scenes.each {|b| data[b.id] = b.data} if @scenes
|
15
|
+
data
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_json(options={})
|
19
|
+
data.to_json
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/lights/schedule.rb
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'lights/schedule'
|
2
|
+
|
3
|
+
class ScheduleList
|
4
|
+
|
5
|
+
attr_reader :schedules
|
6
|
+
def initialize(data = {})
|
7
|
+
@schedules = []
|
8
|
+
data.each{|id,value| @schedules << Schedule.new(id,value)} if data
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def data
|
13
|
+
data = @data
|
14
|
+
@schedules.each {|s| data[s.id] = s.data} if @schedules
|
15
|
+
data
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_json(options={})
|
19
|
+
data.to_json
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/lights/sensor.rb
CHANGED
@@ -4,6 +4,16 @@ class SensorState
|
|
4
4
|
@data = data
|
5
5
|
@last_updated = data["lastupdated"]
|
6
6
|
end
|
7
|
+
|
8
|
+
def data
|
9
|
+
data = @data
|
10
|
+
data["lastupdated"] = @last_updated if @last_updated
|
11
|
+
data
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_json(options={})
|
15
|
+
data.to_json
|
16
|
+
end
|
7
17
|
end
|
8
18
|
|
9
19
|
class TapState < SensorState
|
@@ -12,6 +22,16 @@ class TapState < SensorState
|
|
12
22
|
@button_event = data["button_event"]
|
13
23
|
super
|
14
24
|
end
|
25
|
+
|
26
|
+
def data
|
27
|
+
data = @data
|
28
|
+
data["button_event"] = @button_event if @button_event
|
29
|
+
data
|
30
|
+
end
|
31
|
+
|
32
|
+
def to_json(options={})
|
33
|
+
data.to_json
|
34
|
+
end
|
15
35
|
end
|
16
36
|
|
17
37
|
class Sensor
|
@@ -28,4 +48,20 @@ class Sensor
|
|
28
48
|
@state = SensorState.new(data["state"])
|
29
49
|
#@config = SensorConfig.new(data["config"])
|
30
50
|
end
|
51
|
+
|
52
|
+
def data
|
53
|
+
data = @data
|
54
|
+
data["name"] = @name if @name
|
55
|
+
data["type"] = @type if @type
|
56
|
+
data["modelid"] = @model_id if @model_id
|
57
|
+
data["manufacturername"] = @manufacturer_name if @manufacturer_name
|
58
|
+
data["uniqueid"] = @unique_id if @unique_id
|
59
|
+
data["swversion"] = @sw_version if @sw_version
|
60
|
+
data["state"] = @state.data if @state.data if !@state.data.empty?
|
61
|
+
data
|
62
|
+
end
|
63
|
+
|
64
|
+
def to_json(options={})
|
65
|
+
data.to_json
|
66
|
+
end
|
31
67
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'lights/sensor'
|
2
|
+
|
3
|
+
class SensorList
|
4
|
+
|
5
|
+
attr_reader :sensors
|
6
|
+
|
7
|
+
def initialize(data = {})
|
8
|
+
@sensors = []
|
9
|
+
data.each{|id,value| @sensors << Sensor.new(id,value)} if data
|
10
|
+
@data = data
|
11
|
+
end
|
12
|
+
|
13
|
+
def data
|
14
|
+
data = @data
|
15
|
+
@sensors.each {|s| data[s.id] = s.data} if @sensors
|
16
|
+
data
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_json(options={})
|
20
|
+
data.to_json
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
data/lib/lights/user.rb
CHANGED
@@ -8,4 +8,16 @@ class User
|
|
8
8
|
@create_date = data["create date"]
|
9
9
|
@last_use_date = data["last use date"]
|
10
10
|
end
|
11
|
+
|
12
|
+
def data
|
13
|
+
data = @data
|
14
|
+
data["name"] = @name if @name
|
15
|
+
data["create date"] = @create_date if @create_date
|
16
|
+
data["last use date"] = @last_use_date if @last_use_date
|
17
|
+
data
|
18
|
+
end
|
19
|
+
|
20
|
+
def to_json(options={})
|
21
|
+
data.to_json
|
22
|
+
end
|
11
23
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'lights/user'
|
2
|
+
|
3
|
+
class UserList
|
4
|
+
|
5
|
+
attr_reader :users
|
6
|
+
def initialize(data = {})
|
7
|
+
@users = []
|
8
|
+
data.each{|id,value| @users << User.new(id,value)} if data
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def data
|
13
|
+
data = @data
|
14
|
+
@users.each {|u| data[u.id] = u.data} if @users
|
15
|
+
data
|
16
|
+
end
|
17
|
+
|
18
|
+
def to_json(options={})
|
19
|
+
data.to_json
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
data/lib/lights/version.rb
CHANGED
data/lights.gemspec
CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
|
|
19
19
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
20
20
|
s.require_paths = ["lib"]
|
21
21
|
|
22
|
-
s.add_runtime_dependency "simpletable", "~> 0.3.
|
22
|
+
s.add_runtime_dependency "simpletable", "~> 0.3.1"
|
23
23
|
|
24
24
|
s.add_development_dependency "bundler", "~> 1.3"
|
25
25
|
s.add_development_dependency "rake"
|
@@ -0,0 +1,515 @@
|
|
1
|
+
require 'lights'
|
2
|
+
|
3
|
+
describe Datastore do
|
4
|
+
it "properly reconstructs sub objects" do
|
5
|
+
data = JSON.parse(DATASTORE_JSON)
|
6
|
+
ds = Datastore.new data
|
7
|
+
ds.lights.data.should eql data["lights"]
|
8
|
+
ds.groups.data.should eql data["groups"]
|
9
|
+
ds.rules.data.should eql data["rules"]
|
10
|
+
ds.scenes.data.should eql data["scenes"]
|
11
|
+
ds.schedules.data.should eql data["schedules"]
|
12
|
+
ds.sensors.data.should eql data["sensors"]
|
13
|
+
ds.data.should eql data
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
DATASTORE_JSON = %Q{
|
18
|
+
{
|
19
|
+
"lights": {
|
20
|
+
"1": {
|
21
|
+
"state": {
|
22
|
+
"on": true,
|
23
|
+
"bri": 254,
|
24
|
+
"hue": 34495,
|
25
|
+
"sat": 232,
|
26
|
+
"effect": "none",
|
27
|
+
"xy": [
|
28
|
+
0.3151,
|
29
|
+
0.3251
|
30
|
+
],
|
31
|
+
"ct": 155,
|
32
|
+
"alert": "none",
|
33
|
+
"colormode": "xy",
|
34
|
+
"reachable": true
|
35
|
+
},
|
36
|
+
"type": "Extended color light",
|
37
|
+
"name": "Hue Lamp 1",
|
38
|
+
"modelid": "LCT001",
|
39
|
+
"uniqueid": "00:17:88:01:00:aa:bb:cb-0b",
|
40
|
+
"swversion": "66013452",
|
41
|
+
"pointsymbol": {
|
42
|
+
"1": "0a00f1f01f1f1001f1ff100000000001f2000000",
|
43
|
+
"2": "none",
|
44
|
+
"3": "none",
|
45
|
+
"4": "none",
|
46
|
+
"5": "none",
|
47
|
+
"6": "none",
|
48
|
+
"7": "none",
|
49
|
+
"8": "none"
|
50
|
+
}
|
51
|
+
},
|
52
|
+
"2": {
|
53
|
+
"state": {
|
54
|
+
"on": true,
|
55
|
+
"bri": 254,
|
56
|
+
"hue": 34495,
|
57
|
+
"sat": 232,
|
58
|
+
"effect": "none",
|
59
|
+
"xy": [
|
60
|
+
0.3151,
|
61
|
+
0.3251
|
62
|
+
],
|
63
|
+
"ct": 155,
|
64
|
+
"alert": "none",
|
65
|
+
"colormode": "xy",
|
66
|
+
"reachable": true
|
67
|
+
},
|
68
|
+
"type": "Extended color light",
|
69
|
+
"name": "Hue Lamp 2",
|
70
|
+
"modelid": "LCT001",
|
71
|
+
"uniqueid": "00:17:88:01:00:aa:bb:ca-0b",
|
72
|
+
"swversion": "66013452",
|
73
|
+
"pointsymbol": {
|
74
|
+
"1": "0a00f1f01f1f1001f1ff100000000001f2000000",
|
75
|
+
"2": "none",
|
76
|
+
"3": "none",
|
77
|
+
"4": "none",
|
78
|
+
"5": "none",
|
79
|
+
"6": "none",
|
80
|
+
"7": "none",
|
81
|
+
"8": "none"
|
82
|
+
}
|
83
|
+
},
|
84
|
+
"3": {
|
85
|
+
"state": {
|
86
|
+
"on": true,
|
87
|
+
"bri": 254,
|
88
|
+
"hue": 34495,
|
89
|
+
"sat": 232,
|
90
|
+
"effect": "none",
|
91
|
+
"xy": [
|
92
|
+
0.3151,
|
93
|
+
0.3251
|
94
|
+
],
|
95
|
+
"ct": 155,
|
96
|
+
"alert": "none",
|
97
|
+
"colormode": "xy",
|
98
|
+
"reachable": true
|
99
|
+
},
|
100
|
+
"type": "Extended color light",
|
101
|
+
"name": "Hue Lamp 3",
|
102
|
+
"modelid": "LCT001",
|
103
|
+
"uniqueid": "00:17:88:01:00:aa:bb:c9-0b",
|
104
|
+
"swversion": "66013452",
|
105
|
+
"pointsymbol": {
|
106
|
+
"1": "0a00f1f01f1f1001f1ff100000000001f2000000",
|
107
|
+
"2": "none",
|
108
|
+
"3": "none",
|
109
|
+
"4": "none",
|
110
|
+
"5": "none",
|
111
|
+
"6": "none",
|
112
|
+
"7": "none",
|
113
|
+
"8": "none"
|
114
|
+
}
|
115
|
+
},
|
116
|
+
"4": {
|
117
|
+
"state": {
|
118
|
+
"on": true,
|
119
|
+
"bri": 254,
|
120
|
+
"hue": 34495,
|
121
|
+
"sat": 232,
|
122
|
+
"effect": "none",
|
123
|
+
"xy": [
|
124
|
+
0.3151,
|
125
|
+
0.3251
|
126
|
+
],
|
127
|
+
"ct": 155,
|
128
|
+
"alert": "none",
|
129
|
+
"colormode": "xy",
|
130
|
+
"reachable": true
|
131
|
+
},
|
132
|
+
"type": "Extended color light",
|
133
|
+
"name": "Hue Lamp 4",
|
134
|
+
"modelid": "LCT001",
|
135
|
+
"uniqueid": "00:17:88:01:00:aa:bb:c8-0b",
|
136
|
+
"swversion": "66013452",
|
137
|
+
"pointsymbol": {
|
138
|
+
"1": "none",
|
139
|
+
"2": "none",
|
140
|
+
"3": "none",
|
141
|
+
"4": "none",
|
142
|
+
"5": "none",
|
143
|
+
"6": "none",
|
144
|
+
"7": "none",
|
145
|
+
"8": "none"
|
146
|
+
}
|
147
|
+
},
|
148
|
+
"5": {
|
149
|
+
"state": {
|
150
|
+
"on": true,
|
151
|
+
"bri": 254,
|
152
|
+
"hue": 34495,
|
153
|
+
"sat": 232,
|
154
|
+
"effect": "none",
|
155
|
+
"xy": [
|
156
|
+
0.3151,
|
157
|
+
0.3251
|
158
|
+
],
|
159
|
+
"ct": 155,
|
160
|
+
"alert": "select",
|
161
|
+
"colormode": "xy",
|
162
|
+
"reachable": true
|
163
|
+
},
|
164
|
+
"type": "Extended color light",
|
165
|
+
"name": "BT Lamp",
|
166
|
+
"modelid": "LCT001",
|
167
|
+
"uniqueid": "00:17:88:01:00:aa:bb:c7-0b",
|
168
|
+
"swversion": "66013452",
|
169
|
+
"pointsymbol": {
|
170
|
+
"1": "none",
|
171
|
+
"2": "none",
|
172
|
+
"3": "none",
|
173
|
+
"4": "none",
|
174
|
+
"5": "none",
|
175
|
+
"6": "none",
|
176
|
+
"7": "none",
|
177
|
+
"8": "none"
|
178
|
+
}
|
179
|
+
}
|
180
|
+
},
|
181
|
+
"groups": {
|
182
|
+
"1": {
|
183
|
+
"name": "Ceiling light",
|
184
|
+
"lights": [
|
185
|
+
"1",
|
186
|
+
"2",
|
187
|
+
"3",
|
188
|
+
"4"
|
189
|
+
],
|
190
|
+
"type": "LightGroup",
|
191
|
+
"action": {
|
192
|
+
"on": true,
|
193
|
+
"bri": 254,
|
194
|
+
"hue": 34495,
|
195
|
+
"sat": 232,
|
196
|
+
"effect": "none",
|
197
|
+
"xy": [
|
198
|
+
0.3151,
|
199
|
+
0.3251
|
200
|
+
],
|
201
|
+
"ct": 155,
|
202
|
+
"colormode": "xy"
|
203
|
+
}
|
204
|
+
},
|
205
|
+
"2": {
|
206
|
+
"name": "Lamp",
|
207
|
+
"lights": [
|
208
|
+
"5"
|
209
|
+
],
|
210
|
+
"type": "LightGroup",
|
211
|
+
"action": {
|
212
|
+
"on": true,
|
213
|
+
"bri": 254,
|
214
|
+
"hue": 34495,
|
215
|
+
"sat": 232,
|
216
|
+
"effect": "none",
|
217
|
+
"xy": [
|
218
|
+
0.3151,
|
219
|
+
0.3251
|
220
|
+
],
|
221
|
+
"ct": 155,
|
222
|
+
"colormode": "xy"
|
223
|
+
}
|
224
|
+
}
|
225
|
+
},
|
226
|
+
"config": {
|
227
|
+
"name": "Philips hue",
|
228
|
+
"zigbeechannel": 25,
|
229
|
+
"mac": "00:11:22:33:44:55",
|
230
|
+
"dhcp": true,
|
231
|
+
"ipaddress": "192.168.1.27",
|
232
|
+
"netmask": "255.255.255.0",
|
233
|
+
"gateway": "192.168.1.1",
|
234
|
+
"proxyaddress": "none",
|
235
|
+
"proxyport": 0,
|
236
|
+
"UTC": "2015-01-01T00:11:24",
|
237
|
+
"localtime": "2014-12-31T19:11:24",
|
238
|
+
"timezone": "America/New_York",
|
239
|
+
"whitelist": {
|
240
|
+
"testuser1": {
|
241
|
+
"last use date": "2015-01-01T00:11:24",
|
242
|
+
"create date": "2014-12-30T20:05:07",
|
243
|
+
"name": "lights"
|
244
|
+
},
|
245
|
+
"test user 2": {
|
246
|
+
"last use date": "2014-05-26T14:20:54",
|
247
|
+
"create date": "2013-08-03T17:05:51",
|
248
|
+
"name": "unofficial hue app for osx"
|
249
|
+
},
|
250
|
+
"test user 3": {
|
251
|
+
"last use date": "2014-12-31T02:19:57",
|
252
|
+
"create date": "2013-08-03T18:48:19",
|
253
|
+
"name": "test user"
|
254
|
+
}
|
255
|
+
},
|
256
|
+
"swversion": "01018228",
|
257
|
+
"apiversion": "1.5.0",
|
258
|
+
"swupdate": {
|
259
|
+
"updatestate": 0,
|
260
|
+
"checkforupdate": false,
|
261
|
+
"devicetypes": {
|
262
|
+
"bridge": false,
|
263
|
+
"lights": [
|
264
|
+
|
265
|
+
]
|
266
|
+
},
|
267
|
+
"url": "",
|
268
|
+
"text": "",
|
269
|
+
"notify": false
|
270
|
+
},
|
271
|
+
"linkbutton": false,
|
272
|
+
"portalservices": true,
|
273
|
+
"portalconnection": "connected",
|
274
|
+
"portalstate": {
|
275
|
+
"signedon": true,
|
276
|
+
"incoming": true,
|
277
|
+
"outgoing": true,
|
278
|
+
"communication": "disconnected"
|
279
|
+
}
|
280
|
+
},
|
281
|
+
"schedules": {
|
282
|
+
"6033895564917352": {
|
283
|
+
"name": "Alarm",
|
284
|
+
"description": "Energize",
|
285
|
+
"command": {
|
286
|
+
"address": "/api/8Wc85V5IrG0XTHfB/groups/0/action",
|
287
|
+
"body": {
|
288
|
+
"scene": "d942060b6-on-5"
|
289
|
+
},
|
290
|
+
"method": "PUT"
|
291
|
+
},
|
292
|
+
"localtime": "W124/T06:40:00",
|
293
|
+
"time": "W124/T11:40:00",
|
294
|
+
"created": "2014-09-18T02:54:16",
|
295
|
+
"status": "disabled"
|
296
|
+
},
|
297
|
+
"0326522980291031": {
|
298
|
+
"name": "Alarm",
|
299
|
+
"description": "",
|
300
|
+
"command": {
|
301
|
+
"address": "/api/8Wc85V5IrG0XTHfB/groups/0/action",
|
302
|
+
"body": {
|
303
|
+
"scene": "19a493ad2-off-0"
|
304
|
+
},
|
305
|
+
"method": "PUT"
|
306
|
+
},
|
307
|
+
"localtime": "W124/T07:45:00",
|
308
|
+
"time": "W124/T12:45:00",
|
309
|
+
"created": "2014-09-09T01:13:57",
|
310
|
+
"status": "enabled"
|
311
|
+
}
|
312
|
+
},
|
313
|
+
"scenes": {
|
314
|
+
"fd0ceaedb-on-0": {
|
315
|
+
"name": "Purple and Green",
|
316
|
+
"lights": [
|
317
|
+
"1",
|
318
|
+
"2",
|
319
|
+
"3",
|
320
|
+
"4",
|
321
|
+
"5"
|
322
|
+
],
|
323
|
+
"active": true
|
324
|
+
},
|
325
|
+
"da01b1eaf-on-0": {
|
326
|
+
"name": "Purple on 0",
|
327
|
+
"lights": [
|
328
|
+
"1",
|
329
|
+
"2",
|
330
|
+
"3",
|
331
|
+
"4",
|
332
|
+
"5"
|
333
|
+
],
|
334
|
+
"active": true
|
335
|
+
},
|
336
|
+
"182a404bb-on-0": {
|
337
|
+
"name": "Deck flower on 0",
|
338
|
+
"lights": [
|
339
|
+
"1",
|
340
|
+
"2",
|
341
|
+
"3",
|
342
|
+
"4",
|
343
|
+
"5"
|
344
|
+
],
|
345
|
+
"active": true
|
346
|
+
},
|
347
|
+
"8fc639a85f-on-0": {
|
348
|
+
"name": "Reading on 0",
|
349
|
+
"lights": [
|
350
|
+
"5"
|
351
|
+
],
|
352
|
+
"active": true
|
353
|
+
},
|
354
|
+
"fedd8e5db-on-0": {
|
355
|
+
"name": "Dark red on 0",
|
356
|
+
"lights": [
|
357
|
+
"1",
|
358
|
+
"2",
|
359
|
+
"3",
|
360
|
+
"4",
|
361
|
+
"5"
|
362
|
+
],
|
363
|
+
"active": true
|
364
|
+
}
|
365
|
+
},
|
366
|
+
"rules": {
|
367
|
+
"1": {
|
368
|
+
"name": "Tap 2.3 Reading",
|
369
|
+
"owner": "8Wc85V5IrG0XTHfB",
|
370
|
+
"created": "2014-09-17T23:34:25",
|
371
|
+
"lasttriggered": "2014-12-31T03:29:37",
|
372
|
+
"timestriggered": 10,
|
373
|
+
"status": "enabled",
|
374
|
+
"conditions": [
|
375
|
+
{
|
376
|
+
"address": "/sensors/2/state/buttonevent",
|
377
|
+
"operator": "eq",
|
378
|
+
"value": "17"
|
379
|
+
},
|
380
|
+
{
|
381
|
+
"address": "/sensors/2/state/lastupdated",
|
382
|
+
"operator": "dx"
|
383
|
+
}
|
384
|
+
],
|
385
|
+
"actions": [
|
386
|
+
{
|
387
|
+
"address": "/groups/0/action",
|
388
|
+
"method": "PUT",
|
389
|
+
"body": {
|
390
|
+
"scene": "dc8a6e2b5-on-0"
|
391
|
+
}
|
392
|
+
}
|
393
|
+
]
|
394
|
+
},
|
395
|
+
"2": {
|
396
|
+
"name": "Tap 2.1 All lights off",
|
397
|
+
"owner": "8Wc85V5IrG0XTHfB",
|
398
|
+
"created": "2014-07-16T20:43:43",
|
399
|
+
"lasttriggered": "2014-12-31T06:29:46",
|
400
|
+
"timestriggered": 12,
|
401
|
+
"status": "enabled",
|
402
|
+
"conditions": [
|
403
|
+
{
|
404
|
+
"address": "/sensors/2/state/buttonevent",
|
405
|
+
"operator": "eq",
|
406
|
+
"value": "34"
|
407
|
+
},
|
408
|
+
{
|
409
|
+
"address": "/sensors/2/state/lastupdated",
|
410
|
+
"operator": "dx"
|
411
|
+
}
|
412
|
+
],
|
413
|
+
"actions": [
|
414
|
+
{
|
415
|
+
"address": "/groups/0/action",
|
416
|
+
"method": "PUT",
|
417
|
+
"body": {
|
418
|
+
"scene": "19a493ad2-off-0"
|
419
|
+
}
|
420
|
+
}
|
421
|
+
]
|
422
|
+
},
|
423
|
+
"3": {
|
424
|
+
"name": "Tap 2.4 Purple",
|
425
|
+
"owner": "8Wc85V5IrG0XTHfB",
|
426
|
+
"created": "2014-07-19T16:32:31",
|
427
|
+
"lasttriggered": "none",
|
428
|
+
"timestriggered": 0,
|
429
|
+
"status": "enabled",
|
430
|
+
"conditions": [
|
431
|
+
{
|
432
|
+
"address": "/sensors/2/state/buttonevent",
|
433
|
+
"operator": "eq",
|
434
|
+
"value": "18"
|
435
|
+
},
|
436
|
+
{
|
437
|
+
"address": "/sensors/2/state/lastupdated",
|
438
|
+
"operator": "dx"
|
439
|
+
}
|
440
|
+
],
|
441
|
+
"actions": [
|
442
|
+
{
|
443
|
+
"address": "/groups/0/action",
|
444
|
+
"method": "PUT",
|
445
|
+
"body": {
|
446
|
+
"scene": "da01b1eaf-on-0"
|
447
|
+
}
|
448
|
+
}
|
449
|
+
]
|
450
|
+
},
|
451
|
+
"4": {
|
452
|
+
"name": "Tap 2.2 Energize",
|
453
|
+
"owner": "8Wc85V5IrG0XTHfB",
|
454
|
+
"created": "2014-07-16T20:43:43",
|
455
|
+
"lasttriggered": "2014-12-31T21:42:04",
|
456
|
+
"timestriggered": 9,
|
457
|
+
"status": "enabled",
|
458
|
+
"conditions": [
|
459
|
+
{
|
460
|
+
"address": "/sensors/2/state/buttonevent",
|
461
|
+
"operator": "eq",
|
462
|
+
"value": "16"
|
463
|
+
},
|
464
|
+
{
|
465
|
+
"address": "/sensors/2/state/lastupdated",
|
466
|
+
"operator": "dx"
|
467
|
+
}
|
468
|
+
],
|
469
|
+
"actions": [
|
470
|
+
{
|
471
|
+
"address": "/groups/0/action",
|
472
|
+
"method": "PUT",
|
473
|
+
"body": {
|
474
|
+
"scene": "d942060b6-on-0"
|
475
|
+
}
|
476
|
+
}
|
477
|
+
]
|
478
|
+
}
|
479
|
+
},
|
480
|
+
"sensors": {
|
481
|
+
"1": {
|
482
|
+
"state": {
|
483
|
+
"daylight": false,
|
484
|
+
"lastupdated": "none"
|
485
|
+
},
|
486
|
+
"config": {
|
487
|
+
"on": true,
|
488
|
+
"long": "none",
|
489
|
+
"lat": "none",
|
490
|
+
"sunriseoffset": 30,
|
491
|
+
"sunsetoffset": -30
|
492
|
+
},
|
493
|
+
"name": "Daylight",
|
494
|
+
"type": "Daylight",
|
495
|
+
"modelid": "PHDL00",
|
496
|
+
"manufacturername": "Philips",
|
497
|
+
"swversion": "1.0"
|
498
|
+
},
|
499
|
+
"2": {
|
500
|
+
"state": {
|
501
|
+
"buttonevent": 16,
|
502
|
+
"lastupdated": "2014-12-31T21:42:04"
|
503
|
+
},
|
504
|
+
"config": {
|
505
|
+
"on": true
|
506
|
+
},
|
507
|
+
"name": "Hue Tap 1",
|
508
|
+
"type": "ZGPSwitch",
|
509
|
+
"modelid": "ZGPSWITCH",
|
510
|
+
"manufacturername": "Philips",
|
511
|
+
"uniqueid": "00:00:00:00:00:aa:bb:cc-f2"
|
512
|
+
}
|
513
|
+
}
|
514
|
+
}
|
515
|
+
}
|
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.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brady Turner
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ~>
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.3.
|
19
|
+
version: 0.3.1
|
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.1
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -110,21 +110,31 @@ files:
|
|
110
110
|
- lib/lights.rb
|
111
111
|
- lib/lights/bridge.rb
|
112
112
|
- lib/lights/bulb.rb
|
113
|
+
- lib/lights/bulblist.rb
|
113
114
|
- lib/lights/bulbstate.rb
|
114
115
|
- lib/lights/command.rb
|
116
|
+
- lib/lights/config.rb
|
117
|
+
- lib/lights/datastore.rb
|
115
118
|
- lib/lights/exception.rb
|
116
119
|
- lib/lights/group.rb
|
120
|
+
- lib/lights/grouplist.rb
|
117
121
|
- lib/lights/loggerconfig.rb
|
118
122
|
- lib/lights/rule.rb
|
123
|
+
- lib/lights/rulelist.rb
|
119
124
|
- lib/lights/scene.rb
|
125
|
+
- lib/lights/scenelist.rb
|
120
126
|
- lib/lights/schedule.rb
|
127
|
+
- lib/lights/schedulelist.rb
|
121
128
|
- lib/lights/sensor.rb
|
129
|
+
- lib/lights/sensorlist.rb
|
122
130
|
- lib/lights/user.rb
|
131
|
+
- lib/lights/userlist.rb
|
123
132
|
- lib/lights/version.rb
|
124
133
|
- lights.gemspec
|
125
134
|
- spec/bridge_spec.rb
|
126
135
|
- spec/bulb_spec.rb
|
127
136
|
- spec/bulbstate_spec.rb
|
137
|
+
- spec/datastore_spec.rb
|
128
138
|
- spec/features/lights.feature
|
129
139
|
- spec/features/support/setup.rb
|
130
140
|
- spec/group_spec.rb
|
@@ -158,6 +168,7 @@ test_files:
|
|
158
168
|
- spec/bridge_spec.rb
|
159
169
|
- spec/bulb_spec.rb
|
160
170
|
- spec/bulbstate_spec.rb
|
171
|
+
- spec/datastore_spec.rb
|
161
172
|
- spec/features/lights.feature
|
162
173
|
- spec/features/support/setup.rb
|
163
174
|
- spec/group_spec.rb
|