huebot 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/huebot/bot.rb +15 -3
- data/lib/huebot/cli/helpers.rb +1 -1
- data/lib/huebot/cli/runner.rb +14 -0
- data/lib/huebot/compiler/api_v1.rb +89 -11
- data/lib/huebot/compiler/compiler.rb +1 -1
- data/lib/huebot/program.rb +6 -4
- data/lib/huebot/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fd718fb625c5f417b31619579459bdfcaffac98276d9981882df7d9b1e192b9
|
4
|
+
data.tar.gz: 213fb99651e6826283d4c0be21c26e9442f146ea2df1734a2acb5c53f0e6eafa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: caa7f46fb1d7ac5954f7b1e8f8b48c81b69c3cea59c7ce0ad246eb6ecafda318bd161eec1aff2a41e7e8f6a84af4d2a18a555f56dab808e97b39ff3396b91d9c
|
7
|
+
data.tar.gz: 2221b64eb67ab257232358e52657446cb3b8c95d7f102220954ee71e9a85bc1447ec1566712b651bd1a0d5c4db8be2eff82097551302186cd092688ad0df5548
|
data/lib/huebot/bot.rb
CHANGED
@@ -41,7 +41,7 @@ module Huebot
|
|
41
41
|
# TODO error handling
|
42
42
|
_res = device.set_state i.state
|
43
43
|
@logger.log :set_state, {device: device.name, state: i.state, result: nil}
|
44
|
-
wait time if i.wait
|
44
|
+
wait Program::AST::Num.new(time) if i.wait
|
45
45
|
}
|
46
46
|
}.map(&:join)
|
47
47
|
wait i.pause.post if i.pause&.post
|
@@ -81,7 +81,7 @@ module Huebot
|
|
81
81
|
wait lp.pause.post if lp.pause&.post
|
82
82
|
}
|
83
83
|
when Program::AST::CountedLoop
|
84
|
-
lp.n.times {
|
84
|
+
number(lp.n).round.times {
|
85
85
|
wait lp.pause.pre if lp.pause&.pre
|
86
86
|
yield :counted
|
87
87
|
wait lp.pause.post if lp.pause&.post
|
@@ -124,11 +124,23 @@ module Huebot
|
|
124
124
|
}
|
125
125
|
end
|
126
126
|
|
127
|
-
def wait(
|
127
|
+
def wait(n)
|
128
|
+
seconds = number n
|
128
129
|
@logger.log :pause, {time: seconds}
|
129
130
|
@waiter.call seconds
|
130
131
|
end
|
131
132
|
|
133
|
+
def number(n)
|
134
|
+
case n
|
135
|
+
when Program::AST::Num
|
136
|
+
n.n
|
137
|
+
when Program::AST::RandomNum
|
138
|
+
rand(n.min..n.max)
|
139
|
+
else
|
140
|
+
raise Error, "Unknown numeric type. Expected Program::AST::Num, Program::AST::NRandomNum, found: #{n.class.name}"
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
132
144
|
module Waiter
|
133
145
|
def self.call(seconds)
|
134
146
|
sleep seconds
|
data/lib/huebot/cli/helpers.rb
CHANGED
data/lib/huebot/cli/runner.rb
CHANGED
@@ -8,6 +8,8 @@ module Huebot
|
|
8
8
|
rescue ::Huebot::Error => e
|
9
9
|
opts.stderr.puts "#{e.class.name}: #{e.message}"
|
10
10
|
return 1
|
11
|
+
rescue Interrupt
|
12
|
+
return 130
|
11
13
|
end
|
12
14
|
|
13
15
|
def self.run(sources, lights, groups, opts)
|
@@ -25,6 +27,8 @@ module Huebot
|
|
25
27
|
rescue ::Huebot::Error => e
|
26
28
|
opts.stderr.puts "#{e.class.name}: #{e.message}"
|
27
29
|
return 1
|
30
|
+
rescue Interrupt
|
31
|
+
return 130
|
28
32
|
end
|
29
33
|
|
30
34
|
def self.check(sources, lights, groups, opts)
|
@@ -47,6 +51,8 @@ module Huebot
|
|
47
51
|
rescue ::Huebot::Error => e
|
48
52
|
opts.stderr.puts "#{e.class.name}: #{e.message}"
|
49
53
|
return 1
|
54
|
+
rescue Interrupt
|
55
|
+
return 130
|
50
56
|
end
|
51
57
|
|
52
58
|
def self.get_state(lights, groups, opts)
|
@@ -56,6 +62,8 @@ module Huebot
|
|
56
62
|
opts.stdout.puts " #{device.get_state}"
|
57
63
|
end
|
58
64
|
0
|
65
|
+
rescue Interrupt
|
66
|
+
return 130
|
59
67
|
end
|
60
68
|
|
61
69
|
def self.set_ip(config, ip, opts)
|
@@ -64,6 +72,8 @@ module Huebot
|
|
64
72
|
rescue ::Huebot::Error => e
|
65
73
|
opts.stderr.puts "#{e.class.name}: #{e.message}"
|
66
74
|
return 1
|
75
|
+
rescue Interrupt
|
76
|
+
return 130
|
67
77
|
end
|
68
78
|
|
69
79
|
def self.clear_ip(config, opts)
|
@@ -72,6 +82,8 @@ module Huebot
|
|
72
82
|
rescue ::Huebot::Error => e
|
73
83
|
opts.stderr.puts "#{e.class.name}: #{e.message}"
|
74
84
|
return 1
|
85
|
+
rescue Interrupt
|
86
|
+
return 130
|
75
87
|
end
|
76
88
|
|
77
89
|
def self.unregister(config, opts)
|
@@ -80,6 +92,8 @@ module Huebot
|
|
80
92
|
rescue ::Huebot::Error => e
|
81
93
|
opts.stderr.puts "#{e.class.name}: #{e.message}"
|
82
94
|
return 1
|
95
|
+
rescue Interrupt
|
96
|
+
return 130
|
83
97
|
end
|
84
98
|
end
|
85
99
|
end
|
@@ -10,6 +10,8 @@ module Huebot
|
|
10
10
|
PARALLEL_KEYS = ["parallel"].freeze
|
11
11
|
INFINITE_KEYS = ["infinite"].freeze
|
12
12
|
COUNT_KEYS = ["count"].freeze
|
13
|
+
RANDOM_KEYS = ["random"].freeze
|
14
|
+
MIN_MAX = ["min", "max"].freeze
|
13
15
|
TIMER_KEYS = ["timer"].freeze
|
14
16
|
DEADLINE_KEYS = ["until"].freeze
|
15
17
|
HHMM = /\A[0-9]{2}:[0-9]{2}\Z/.freeze
|
@@ -187,26 +189,54 @@ module Huebot
|
|
187
189
|
lp =
|
188
190
|
case loop_val.keys
|
189
191
|
when INFINITE_KEYS
|
190
|
-
loop_val
|
192
|
+
loop_val.fetch("infinite") == true ? Program::AST::InfiniteLoop.new : Program::AST::CountedLoop.new(Program::AST::Num.new(1))
|
191
193
|
when COUNT_KEYS
|
192
|
-
num = loop_val
|
194
|
+
num = loop_val.fetch("count")
|
193
195
|
errors << "'loop.count' must be an integer. Found '#{num.class.name}'" unless num.is_a? Integer
|
194
|
-
Program::AST::CountedLoop.new(num)
|
196
|
+
Program::AST::CountedLoop.new(Program::AST::Num.new(num))
|
197
|
+
when RANDOM_KEYS
|
198
|
+
n = build_random loop_val, errors, warnings
|
199
|
+
Program::AST::CountedLoop.new(n)
|
195
200
|
when TIMER_KEYS
|
196
|
-
build_timer_loop loop_val
|
201
|
+
build_timer_loop loop_val.fetch("timer"), errors, warnings
|
197
202
|
when DEADLINE_KEYS
|
198
|
-
build_deadline_loop loop_val
|
203
|
+
build_deadline_loop loop_val.fetch("until"), errors, warnings
|
199
204
|
else
|
200
205
|
errors << "'loop' must contain exactly one of: 'infinite', 'count', 'timer', or 'until', and optionally 'pause'. Found: #{loop_val.keys.join ", "}"
|
201
|
-
Program::AST::CountedLoop.new(1)
|
206
|
+
Program::AST::CountedLoop.new(Program::AST::Num.new(1))
|
202
207
|
end
|
203
208
|
lp.pause = pause
|
204
209
|
lp
|
205
210
|
when nil
|
206
|
-
Program::AST::CountedLoop.new(1)
|
211
|
+
Program::AST::CountedLoop.new(Program::AST::Num.new(1))
|
207
212
|
else
|
208
213
|
errors << "'loop' must be an object. Found '#{loop_val.class.name}'"
|
209
|
-
Program::AST::CountedLoop.new(1)
|
214
|
+
Program::AST::CountedLoop.new(Program::AST::Num.new(1))
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
def build_random(t, errors, warnings)
|
219
|
+
random = t.delete("random") || {}
|
220
|
+
min = build_random_n(random, "min", errors, warnings)
|
221
|
+
max = build_random_n(random, "max", errors, warnings)
|
222
|
+
errors << "'random.max' must be greater than 'random.min'" unless max > min
|
223
|
+
errors << "Unknown keys in 'random': #{random.keys.join ", "}" if random.keys.any?
|
224
|
+
Program::AST::RandomNum.new(min, max)
|
225
|
+
end
|
226
|
+
|
227
|
+
def build_random_n(t, name, errors, warnings)
|
228
|
+
n = t.delete name
|
229
|
+
case n
|
230
|
+
when Integer, Float
|
231
|
+
if n >= 0
|
232
|
+
n
|
233
|
+
else
|
234
|
+
errors << "'random.#{name}' must be >= 0, found #{n}"
|
235
|
+
0
|
236
|
+
end
|
237
|
+
else
|
238
|
+
errors << "'random.#{name}' must be an integer or float > 0, found #{n.class.name}"
|
239
|
+
0
|
210
240
|
end
|
211
241
|
end
|
212
242
|
|
@@ -234,6 +264,7 @@ module Huebot
|
|
234
264
|
case @api_version
|
235
265
|
when 1.0 then build_pause_1_0(t, errors, warnings)
|
236
266
|
when 1.1 then build_pause_1_1(t, errors, warnings)
|
267
|
+
when 1.2 then build_pause_1_2(t, errors, warnings)
|
237
268
|
else raise Error, "Unknown api version '#{@api_version}'"
|
238
269
|
end
|
239
270
|
end
|
@@ -242,7 +273,7 @@ module Huebot
|
|
242
273
|
pause_val = t.delete "pause"
|
243
274
|
case pause_val
|
244
275
|
when Integer, Float
|
245
|
-
Program::AST::Pause.new(nil, pause_val)
|
276
|
+
Program::AST::Pause.new(nil, Program::AST::Num.new(pause_val))
|
246
277
|
when nil
|
247
278
|
nil
|
248
279
|
else
|
@@ -255,22 +286,69 @@ module Huebot
|
|
255
286
|
pause_val = t.delete "pause"
|
256
287
|
case pause_val
|
257
288
|
when Integer, Float
|
258
|
-
Program::AST::Pause.new(nil, pause_val)
|
289
|
+
Program::AST::Pause.new(nil, Program::AST::Num.new(pause_val))
|
259
290
|
when Hash
|
260
291
|
pre = pause_val.delete "before"
|
261
292
|
post = pause_val.delete "after"
|
262
293
|
errors << "'pause.before' must be an integer or float" unless pre.nil? or pre.is_a? Integer or pre.is_a? Float
|
263
294
|
errors << "'pause.after' must be an integer or float" unless post.nil? or post.is_a? Integer or post.is_a? Float
|
264
295
|
errors << "Unknown keys in 'pause': #{pause_val.keys.join ", "}" if pause_val.keys.any?
|
296
|
+
pre = Program::AST::Num.new(pre) if pre
|
297
|
+
post = Program::AST::Num.new(post) if post
|
265
298
|
Program::AST::Pause.new(pre, post)
|
266
299
|
when nil
|
267
300
|
nil
|
268
301
|
else
|
269
|
-
errors << "'pause' must be an integer or float"
|
302
|
+
errors << "'pause' must be an integer or float, or an object with 'before' and/or 'after'"
|
270
303
|
nil
|
271
304
|
end
|
272
305
|
end
|
273
306
|
|
307
|
+
def build_pause_1_2(t, errors, warnings)
|
308
|
+
pause_val = t.delete "pause"
|
309
|
+
case pause_val
|
310
|
+
when Integer, Float
|
311
|
+
Program::AST::Pause.new(nil, Program::AST::Num.new(pause_val))
|
312
|
+
when Hash
|
313
|
+
pre = build_pause_part(pause_val, "before", errors, warnings)
|
314
|
+
post = build_pause_part(pause_val, "after", errors, warnings)
|
315
|
+
errors << "'pause' requires one or both of 'before' or 'after'" if pre.nil? and post.nil?
|
316
|
+
errors << "Unknown keys in 'pause': #{pause_val.keys.join ", "}" if pause_val.keys.any?
|
317
|
+
Program::AST::Pause.new(pre, post)
|
318
|
+
when nil
|
319
|
+
nil
|
320
|
+
else
|
321
|
+
errors << "'pause' must be an integer or float, or an object with 'before' and/or 'after'"
|
322
|
+
nil
|
323
|
+
end
|
324
|
+
end
|
325
|
+
|
326
|
+
def build_pause_part(t, part, errors, warnings)
|
327
|
+
val = t.delete part
|
328
|
+
case val
|
329
|
+
when nil
|
330
|
+
nil
|
331
|
+
when Integer, Float
|
332
|
+
Program::AST::Num.new(val)
|
333
|
+
when Hash
|
334
|
+
if @api_version < 1.2
|
335
|
+
errors << "Unknown 'pause.#{part}' type (#{val.class.name})"
|
336
|
+
return Program::AST::Num.new(1)
|
337
|
+
end
|
338
|
+
|
339
|
+
case val.keys
|
340
|
+
when RANDOM_KEYS
|
341
|
+
build_random val, errors, warnings
|
342
|
+
else
|
343
|
+
errors << "Expected 'pause.#{part}' to contain 'random', found #{val.keys.join ", "}"
|
344
|
+
Program::AST::Num.new(1)
|
345
|
+
end
|
346
|
+
else
|
347
|
+
errors << "Unknown 'pause.#{part}' type (#{val.class.name})"
|
348
|
+
Program::AST::Num.new(1)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
274
352
|
def build_wait(t, errors, warnings)
|
275
353
|
wait = t.delete "wait"
|
276
354
|
case wait
|
@@ -13,7 +13,7 @@ module Huebot
|
|
13
13
|
def self.build(src)
|
14
14
|
compiler_class =
|
15
15
|
case src.api_version
|
16
|
-
when 1.0, 1.1 then ApiV1
|
16
|
+
when 1.0, 1.1, 1.2 then ApiV1
|
17
17
|
else raise Error, "Unknown API version '#{src.api_version}'"
|
18
18
|
end
|
19
19
|
compiler = compiler_class.new(src.api_version)
|
data/lib/huebot/program.rb
CHANGED
@@ -26,6 +26,8 @@ module Huebot
|
|
26
26
|
DeadlineLoop = Struct.new(:stop_time, :pause)
|
27
27
|
|
28
28
|
Pause = Struct.new(:pre, :post)
|
29
|
+
Num = Struct.new(:n)
|
30
|
+
RandomNum = Struct.new(:min, :max)
|
29
31
|
DeviceRef = Struct.new(:ref)
|
30
32
|
Light = Struct.new(:name)
|
31
33
|
Group = Struct.new(:name)
|
@@ -56,14 +58,14 @@ module Huebot
|
|
56
58
|
end
|
57
59
|
|
58
60
|
def errors(node = data)
|
59
|
-
node.children.reduce(node.errors) { |
|
60
|
-
|
61
|
+
node.children.reduce(node.errors) { |acc, child|
|
62
|
+
acc + errors(child)
|
61
63
|
}
|
62
64
|
end
|
63
65
|
|
64
66
|
def warnings(node = data)
|
65
|
-
node.children.reduce(node.warnings) { |
|
66
|
-
|
67
|
+
node.children.reduce(node.warnings) { |acc, child|
|
68
|
+
acc + warnings(child)
|
67
69
|
}
|
68
70
|
end
|
69
71
|
|
data/lib/huebot/version.rb
CHANGED