ruby-macrodroid 0.4.0 → 0.6.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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/ruby-macrodroid.rb +1478 -76
- metadata +46 -6
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: dfb49da8914ecdd5cc21ca0223801fa0d432890a3df4c352ab7c3914c1bd63fe
|
4
|
+
data.tar.gz: 9f402e6d1c9dbd17f5cb7d3741bcc7c487461a5438adf3cba81a71df9feb50f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0753ef46f3cdbc1e5a8fb6539747e662a2e537089aa83e32ecf47c89334b1acb71ced47f77230e1fcae00314d8dd70e8e4d37380c27f25ebb0ccafe837121daa
|
7
|
+
data.tar.gz: e78f3fc06bcdbd1685de98d5473b2564d904a722053527505002f5a5bbfa43e51e99832d2a9a29eb5a12d3e9bab94d91429f78628625e74acbae6876b909f43a
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/ruby-macrodroid.rb
CHANGED
@@ -3,10 +3,19 @@
|
|
3
3
|
# file: ruby-macrodroid.rb
|
4
4
|
|
5
5
|
require 'uuid'
|
6
|
+
require 'yaml'
|
7
|
+
require 'glw'
|
8
|
+
require 'geozone'
|
6
9
|
require 'rxfhelper'
|
7
10
|
require 'chronic_cron'
|
8
11
|
|
9
12
|
|
13
|
+
MODEL =<<EOF
|
14
|
+
device
|
15
|
+
connectivity
|
16
|
+
airplane_mode is disabled
|
17
|
+
EOF
|
18
|
+
|
10
19
|
class TriggersNlp
|
11
20
|
include AppRoutes
|
12
21
|
|
@@ -20,11 +29,45 @@ class TriggersNlp
|
|
20
29
|
|
21
30
|
def triggers(params)
|
22
31
|
|
23
|
-
get /^at (\d+:\d+(?:[ap]m)?) on (.*)/i do |time, days|
|
32
|
+
get /^(?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)/i do |time, days|
|
24
33
|
[TimerTrigger, {time: time, days: days}]
|
25
34
|
end
|
26
35
|
|
36
|
+
# time.is? 'at 18:30pm on Mon or Tue'
|
37
|
+
get /^time.is\? ['"](?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)['"]/i do |time, days|
|
38
|
+
[TimerTrigger, {time: time, days: days.gsub(' or ',', ')}]
|
39
|
+
end
|
40
|
+
|
41
|
+
get /^shake[ _]device\??$/i do
|
42
|
+
[ShakeDeviceTrigger, {}]
|
43
|
+
end
|
44
|
+
|
45
|
+
get /^Flip Device (.*)$/i do |motion|
|
46
|
+
facedown = motion =~ /Face Up (?:->|to) Face Down/i
|
47
|
+
[FlipDeviceTrigger, {face_down: facedown }]
|
48
|
+
end
|
49
|
+
|
50
|
+
get /^flip_device_down\?$/i do
|
51
|
+
[FlipDeviceTrigger, {face_down: true }]
|
52
|
+
end
|
27
53
|
|
54
|
+
get /^flip_device_up\?$/i do
|
55
|
+
[FlipDeviceTrigger, {face_down: false }]
|
56
|
+
end
|
57
|
+
|
58
|
+
get /^Failed Login Attempt$/i do
|
59
|
+
[FailedLoginTrigger, {}]
|
60
|
+
end
|
61
|
+
|
62
|
+
get /^failed_login?$/i do
|
63
|
+
[FailedLoginTrigger, {}]
|
64
|
+
end
|
65
|
+
|
66
|
+
get /^Geofence (Entry|Exit) \(([^\)]+)/i do |direction, name|
|
67
|
+
enter_area = direction.downcase.to_sym == :entry
|
68
|
+
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
69
|
+
end
|
70
|
+
|
28
71
|
end
|
29
72
|
|
30
73
|
alias find_trigger run_route
|
@@ -44,10 +87,73 @@ class ActionsNlp
|
|
44
87
|
|
45
88
|
def actions(params)
|
46
89
|
|
90
|
+
# e.g. message popup: hello world!
|
47
91
|
get /^message popup: (.*)/i do |msg|
|
48
92
|
[ToastAction, {msg: msg}]
|
49
93
|
end
|
50
94
|
|
95
|
+
# e.g. Popup Message 'hello world!'
|
96
|
+
get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
|
97
|
+
[ToastAction, {msg: msg}]
|
98
|
+
end
|
99
|
+
|
100
|
+
# e.g. say current time
|
101
|
+
get /^say current[ _]time/i do
|
102
|
+
[SayTimeAction, {}]
|
103
|
+
end
|
104
|
+
|
105
|
+
get /^Torch :?(.*)/i do |onoffstate|
|
106
|
+
state = onoffstate.downcase == 'on' ? 0 : 1
|
107
|
+
[CameraFlashLightAction, {state: state}]
|
108
|
+
end
|
109
|
+
|
110
|
+
get /^Take Picture/i do
|
111
|
+
[TakePictureAction, {}]
|
112
|
+
end
|
113
|
+
|
114
|
+
get /^take_picture/i do
|
115
|
+
[TakePictureAction, {}]
|
116
|
+
end
|
117
|
+
|
118
|
+
# e.g. Display Notification: Hi there: This is the body of the message
|
119
|
+
get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
|
120
|
+
[NotificationAction, {subject: subject, text: text}]
|
121
|
+
end
|
122
|
+
|
123
|
+
|
124
|
+
# e.g. Enable Wifi
|
125
|
+
get /^(Enable|Disable) Wifi$/i do |raw_state|
|
126
|
+
|
127
|
+
state = raw_state.downcase.to_sym == :enable ? 0 : 1
|
128
|
+
[SetWifiAction, {state: state}]
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
# e.g. Play: Altair
|
133
|
+
get /^Play: (.*)$/i do |name|
|
134
|
+
|
135
|
+
[PlaySoundAction, {file_path: name}]
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
# e.g. Launch Settings
|
140
|
+
get /^Launch (.*)$/i do |application|
|
141
|
+
|
142
|
+
h = {
|
143
|
+
application_name: application,
|
144
|
+
package_to_launch: 'com.android.' + application.downcase
|
145
|
+
}
|
146
|
+
[LaunchActivityAction, h]
|
147
|
+
|
148
|
+
end
|
149
|
+
|
150
|
+
# e.g. HTTP GET http://someurl.com/something
|
151
|
+
get /^HTTP GET ([^$]+)$/i do |url|
|
152
|
+
|
153
|
+
[OpenWebPageAction, url_to_open: url]
|
154
|
+
|
155
|
+
end
|
156
|
+
|
51
157
|
|
52
158
|
end
|
53
159
|
|
@@ -55,6 +161,29 @@ class ActionsNlp
|
|
55
161
|
|
56
162
|
end
|
57
163
|
|
164
|
+
class ConstraintsNlp
|
165
|
+
include AppRoutes
|
166
|
+
|
167
|
+
def initialize()
|
168
|
+
|
169
|
+
super()
|
170
|
+
params = {}
|
171
|
+
constraints(params)
|
172
|
+
|
173
|
+
end
|
174
|
+
|
175
|
+
def constraints(params)
|
176
|
+
|
177
|
+
get /^airplane mode (.*)/i do |state|
|
178
|
+
[AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/) == 0}]
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
182
|
+
|
183
|
+
alias find_constraint run_route
|
184
|
+
|
185
|
+
end
|
186
|
+
|
58
187
|
module Params
|
59
188
|
|
60
189
|
refine Hash do
|
@@ -112,19 +241,16 @@ class Macro
|
|
112
241
|
using ColouredText
|
113
242
|
using Params
|
114
243
|
|
115
|
-
attr_reader :local_variables, :triggers, :actions, :guid
|
116
|
-
attr_accessor :title
|
244
|
+
attr_reader :local_variables, :triggers, :actions, :constraints, :guid
|
245
|
+
attr_accessor :title, :description
|
117
246
|
|
118
|
-
def initialize(name=nil, debug: false)
|
247
|
+
def initialize(name=nil, geofence: geofence, debug: false)
|
119
248
|
|
120
|
-
@title, @debug = name, debug
|
249
|
+
@title, @geofence, @debug = name, geofence, debug
|
121
250
|
|
122
|
-
puts 'inside Macro#initialize' if @debug
|
123
|
-
|
124
|
-
lv=[], triggers=[], actions=[]
|
125
|
-
@local_variables, @triggers, @actions = lv, triggers, actions
|
251
|
+
puts 'inside Macro#initialize' if @debug
|
126
252
|
|
127
|
-
@triggers, @actions, @constraints = [], [], []
|
253
|
+
@local_variables, @triggers, @actions, @constraints = [], [], [], []
|
128
254
|
@h = {}
|
129
255
|
|
130
256
|
end
|
@@ -156,9 +282,9 @@ class Macro
|
|
156
282
|
local_variables: @local_variables,
|
157
283
|
m_trigger_list: @triggers.map(&:to_h),
|
158
284
|
m_action_list: @actions.map(&:to_h),
|
159
|
-
m_constraint_list:
|
285
|
+
m_constraint_list: @constraints.map(&:to_h),
|
160
286
|
m_description: '',
|
161
|
-
m_name:
|
287
|
+
m_name: title(),
|
162
288
|
m_excludeLog: false,
|
163
289
|
m_GUID: guid(),
|
164
290
|
m_isOrCondition: false,
|
@@ -174,6 +300,14 @@ class Macro
|
|
174
300
|
|
175
301
|
def import_h(h)
|
176
302
|
|
303
|
+
if @debug then
|
304
|
+
puts 'inside import_h'
|
305
|
+
puts 'h:' + h.inspect
|
306
|
+
end
|
307
|
+
|
308
|
+
@title = h[:name]
|
309
|
+
@description = h[:description]
|
310
|
+
|
177
311
|
# fetch the local variables
|
178
312
|
@local_variables = h['local_variables']
|
179
313
|
|
@@ -188,13 +322,15 @@ class Macro
|
|
188
322
|
object(action.to_snake_case)
|
189
323
|
end
|
190
324
|
|
191
|
-
# fetch the constraints
|
325
|
+
# fetch the constraints
|
326
|
+
@constraints = h[:constraint_list].map do |constraint|
|
327
|
+
object(constraint.to_snake_case)
|
328
|
+
end
|
192
329
|
|
193
330
|
@h = h
|
194
331
|
|
195
|
-
%i(local_variables m_trigger_list m_action_list)
|
196
|
-
@h[x] = []
|
197
|
-
end
|
332
|
+
%i(local_variables m_trigger_list m_action_list m_constraint_list)\
|
333
|
+
.each {|x| @h[x] = [] }
|
198
334
|
|
199
335
|
@h
|
200
336
|
|
@@ -208,6 +344,7 @@ class Macro
|
|
208
344
|
end
|
209
345
|
|
210
346
|
@title = node.attributes[:name]
|
347
|
+
@description = node.attributes[:description]
|
211
348
|
|
212
349
|
if node.element('triggers') then
|
213
350
|
|
@@ -235,6 +372,14 @@ class Macro
|
|
235
372
|
end
|
236
373
|
|
237
374
|
end
|
375
|
+
|
376
|
+
# get all the constraints
|
377
|
+
@constraints = node.xpath('constraints/*').map do |e|
|
378
|
+
|
379
|
+
puts 'e.name: ' + e.name.inspect if @debug
|
380
|
+
{airplanemode: AirplaneModeConstraint}[e.name.to_sym].new(e.attributes.to_h)
|
381
|
+
|
382
|
+
end
|
238
383
|
|
239
384
|
else
|
240
385
|
|
@@ -266,6 +411,19 @@ class Macro
|
|
266
411
|
end
|
267
412
|
|
268
413
|
end
|
414
|
+
|
415
|
+
cp = ConstraintsNlp.new
|
416
|
+
|
417
|
+
@constraints = node.xpath('constraint').map do |e|
|
418
|
+
|
419
|
+
r = cp.find_constraint e.text
|
420
|
+
puts 'found constraint ' + r.inspect if @debug
|
421
|
+
|
422
|
+
if r then
|
423
|
+
r[0].new(r[1])
|
424
|
+
end
|
425
|
+
|
426
|
+
end
|
269
427
|
|
270
428
|
end
|
271
429
|
|
@@ -273,16 +431,16 @@ class Macro
|
|
273
431
|
|
274
432
|
end
|
275
433
|
|
276
|
-
def match?(triggerx, detail={time: $env[:time]} )
|
434
|
+
def match?(triggerx, detail={time: $env[:time]}, model=nil )
|
277
435
|
|
278
|
-
if @triggers.any? {|x| x.type == triggerx and x.match?(detail) } then
|
436
|
+
if @triggers.any? {|x| x.type == triggerx and x.match?(detail, model) } then
|
279
437
|
|
280
438
|
if @debug then
|
281
439
|
puts 'checking constraints ...'
|
282
440
|
puts '@constraints: ' + @constraints.inspect
|
283
441
|
end
|
284
442
|
|
285
|
-
if @constraints.all? {|x| x.match?($env.merge(detail)) } then
|
443
|
+
if @constraints.all? {|x| x.match?($env.merge(detail), model) } then
|
286
444
|
|
287
445
|
true
|
288
446
|
|
@@ -296,9 +454,65 @@ class Macro
|
|
296
454
|
|
297
455
|
end
|
298
456
|
|
457
|
+
# invokes the actions
|
458
|
+
#
|
299
459
|
def run()
|
300
460
|
@actions.map(&:invoke)
|
301
|
-
end
|
461
|
+
end
|
462
|
+
|
463
|
+
# prepares the environment in order for triggers to test fire successfully
|
464
|
+
# Used for testing
|
465
|
+
#
|
466
|
+
def set_env()
|
467
|
+
@triggers.each(&:set_env)
|
468
|
+
end
|
469
|
+
|
470
|
+
def to_pc()
|
471
|
+
|
472
|
+
heading = '# ' + @title
|
473
|
+
heading += '\n# ' + @description if @description
|
474
|
+
condition = @triggers.first.to_pc
|
475
|
+
actions = @actions.map(&:to_pc).join("\n")
|
476
|
+
|
477
|
+
<<EOF
|
478
|
+
#{heading}
|
479
|
+
|
480
|
+
if #{condition} then
|
481
|
+
#{actions}
|
482
|
+
end
|
483
|
+
EOF
|
484
|
+
end
|
485
|
+
|
486
|
+
def to_s()
|
487
|
+
|
488
|
+
a = [
|
489
|
+
'm: ' + @title,
|
490
|
+
@triggers.map {|x| "t: %s" % x}.join("\n"),
|
491
|
+
@actions.map {|x| "a: %s" % x}.join("\n"),
|
492
|
+
@constraints.map {|x| "a: %s" % x}.join("\n")
|
493
|
+
]
|
494
|
+
|
495
|
+
if @description and @description.length >= 1 then
|
496
|
+
a.insert(1, 'd: ' + @description)
|
497
|
+
end
|
498
|
+
|
499
|
+
a.join("\n")
|
500
|
+
|
501
|
+
end
|
502
|
+
|
503
|
+
def to_summary()
|
504
|
+
|
505
|
+
a = [
|
506
|
+
'm: ' + @title,
|
507
|
+
't: ' + @triggers.map(&:to_s).join(", "),
|
508
|
+
'a: ' + @actions.map(&:to_s).join(", "),
|
509
|
+
]
|
510
|
+
|
511
|
+
a << 'c: ' + @constraints.map(&:to_s).join(", ") if @constraints.any?
|
512
|
+
|
513
|
+
a.join("\n") + "\n"
|
514
|
+
|
515
|
+
end
|
302
516
|
|
303
517
|
private
|
304
518
|
|
@@ -310,17 +524,28 @@ class Macro
|
|
310
524
|
|
311
525
|
puts ('inside object h:' + h.inspect).debug if @debug
|
312
526
|
klass = Object.const_get h[:class_type]
|
313
|
-
klass.
|
527
|
+
puts klass.inspect.highlight if $debug
|
528
|
+
|
529
|
+
if klass == GeofenceTrigger then
|
530
|
+
puts 'GeofenceTrigger found'.highlight if $debug
|
531
|
+
klass.new(@geofence, h)
|
532
|
+
else
|
533
|
+
klass.new h
|
534
|
+
end
|
535
|
+
|
314
536
|
end
|
315
537
|
|
316
538
|
end
|
317
539
|
|
318
540
|
|
541
|
+
class MacroDroidError < Exception
|
542
|
+
end
|
543
|
+
|
319
544
|
class MacroDroid
|
320
545
|
using ColouredText
|
321
546
|
using Params
|
322
547
|
|
323
|
-
attr_reader :macros
|
548
|
+
attr_reader :macros, :geofence
|
324
549
|
|
325
550
|
def initialize(obj=nil, debug: false)
|
326
551
|
|
@@ -328,16 +553,36 @@ class MacroDroid
|
|
328
553
|
|
329
554
|
if obj then
|
330
555
|
|
331
|
-
|
556
|
+
raw_s, _ = RXFHelper.read(obj)
|
557
|
+
|
558
|
+
s = raw_s.strip
|
332
559
|
|
333
560
|
if s[0] == '{' then
|
561
|
+
|
334
562
|
import_json(s)
|
563
|
+
|
335
564
|
elsif s[0] == '<'
|
565
|
+
|
336
566
|
import_xml(s)
|
337
567
|
@h = build_h
|
568
|
+
|
338
569
|
else
|
339
|
-
|
570
|
+
|
571
|
+
puts 's: ' + s.inspect if @debug
|
572
|
+
|
573
|
+
xml = if s =~ /m:\s/ then
|
574
|
+
puts 'before text_to_xml' if @debug
|
575
|
+
text_to_xml(s)
|
576
|
+
elsif s =~ /^# /
|
577
|
+
pc_to_xml(s)
|
578
|
+
else
|
579
|
+
raise MacroDroidError, 'invalid input'
|
580
|
+
end
|
581
|
+
import_xml(xml)
|
340
582
|
@h = build_h
|
583
|
+
|
584
|
+
|
585
|
+
|
341
586
|
end
|
342
587
|
|
343
588
|
else
|
@@ -389,15 +634,53 @@ class MacroDroid
|
|
389
634
|
|
390
635
|
alias to_json export_json
|
391
636
|
|
392
|
-
def import_json(s)
|
393
637
|
|
394
|
-
|
395
|
-
|
638
|
+
def to_h()
|
639
|
+
|
640
|
+
@h.merge(macro_list: @macros.map(&:to_h)).to_camel_case
|
641
|
+
|
642
|
+
end
|
643
|
+
|
644
|
+
# returns pseudocode
|
645
|
+
#
|
646
|
+
def to_pc()
|
647
|
+
@macros.map(&:to_pc).join("\n\n")
|
648
|
+
end
|
649
|
+
|
650
|
+
def to_s()
|
651
|
+
@macros.map(&:to_s).join("\n")
|
652
|
+
end
|
653
|
+
|
654
|
+
def to_summary()
|
655
|
+
@macros.map(&:to_summary).join("\n")
|
656
|
+
end
|
657
|
+
|
658
|
+
private
|
659
|
+
|
660
|
+
def import_json(s)
|
396
661
|
|
662
|
+
h = JSON.parse(s, symbolize_names: true)
|
663
|
+
puts 'json_to_yaml: ' + h.to_yaml if @debug
|
664
|
+
|
665
|
+
@h = h.to_snake_case
|
666
|
+
puts ('@h: ' + @h.inspect).debug if @debug
|
667
|
+
|
668
|
+
|
669
|
+
# fetch the geofence data
|
670
|
+
if @h[:geofence_data] then
|
671
|
+
|
672
|
+
@geofence = @h[:geofence_data][:geofence_map].map do |id, properties|
|
673
|
+
[id, GeofenceMap.new(properties)]
|
674
|
+
end.to_h
|
675
|
+
|
676
|
+
end
|
677
|
+
|
397
678
|
@macros = @h[:macro_list].map do |macro|
|
398
679
|
|
399
|
-
puts ('macro: ' + macro.
|
400
|
-
|
680
|
+
puts ('macro: ' + macro.inspect).debug if @debug
|
681
|
+
puts '@geofence: ' + @geofence.inspect if @debug
|
682
|
+
|
683
|
+
m = Macro.new(geofence: @geofence, debug: @debug )
|
401
684
|
m.import_h(macro)
|
402
685
|
m
|
403
686
|
|
@@ -409,23 +692,52 @@ class MacroDroid
|
|
409
692
|
|
410
693
|
def import_xml(raws)
|
411
694
|
|
695
|
+
puts 'raws: ' + raws.inspect if @debug
|
412
696
|
s = RXFHelper.read(raws).first
|
413
697
|
puts 's: ' + s.inspect if @debug
|
414
698
|
doc = Rexle.new(s)
|
415
|
-
|
699
|
+
|
700
|
+
if @debug then
|
701
|
+
puts 'doc: ' + doc.root.xml
|
702
|
+
end
|
703
|
+
|
704
|
+
debug = @debug
|
416
705
|
|
417
706
|
@macros = doc.root.xpath('macro').map do |node|
|
418
707
|
|
419
|
-
macro = Macro.new @title, debug:
|
708
|
+
macro = Macro.new @title, debug: debug
|
420
709
|
macro.import_xml(node)
|
421
710
|
macro
|
422
711
|
|
423
712
|
end
|
424
713
|
end
|
425
714
|
|
715
|
+
def pc_to_xml(s)
|
716
|
+
|
717
|
+
macros = s.strip.split(/(?=#)/).map do |raw_macro|
|
718
|
+
|
719
|
+
a = raw_macro.lines
|
720
|
+
name = a.shift[/(?<=# ).*/]
|
721
|
+
description = a.shift[/(?<=# ).*/] if a[0][/^# /]
|
722
|
+
body = a.join.strip
|
723
|
+
|
724
|
+
a2 = body.lines
|
725
|
+
# get the trigger
|
726
|
+
trigger = [:trigger, {}, a2[0][/^if (.*) then/,1]]
|
727
|
+
action = [:action, {}, a2[1].strip]
|
728
|
+
[:macro, {name: name, description: description}, trigger, action, []]
|
729
|
+
|
730
|
+
end
|
731
|
+
|
732
|
+
doc = Rexle.new([:macros, {}, '', *macros])
|
733
|
+
doc.root.xml pretty: true
|
734
|
+
|
735
|
+
end
|
736
|
+
|
426
737
|
def text_to_xml(s)
|
427
738
|
|
428
|
-
a = s.split(/.*(?=^m:)/)
|
739
|
+
a = s.split(/.*(?=^m:)/)
|
740
|
+
puts 'a : ' + a.inspect if @debug
|
429
741
|
a.map!(&:chomp)
|
430
742
|
|
431
743
|
macros = a.map do |x|
|
@@ -439,8 +751,9 @@ class MacroDroid
|
|
439
751
|
lines.each {|line| h[line[0].to_sym] << line[/^\w: +(.*)/,1] }
|
440
752
|
triggers = h[:t].map {|text| [:trigger, {}, text]}
|
441
753
|
actions = h[:a].map {|text| [:action, {}, text]}
|
754
|
+
constraints = h[:c].map {|text| [:constraint, {}, text]}
|
442
755
|
|
443
|
-
[:macro, {name: name},'', *triggers, *actions]
|
756
|
+
[:macro, {name: name},'', *triggers, *actions, *constraints]
|
444
757
|
|
445
758
|
end
|
446
759
|
|
@@ -448,15 +761,18 @@ class MacroDroid
|
|
448
761
|
doc.root.xml pretty: true
|
449
762
|
|
450
763
|
end
|
764
|
+
|
451
765
|
|
452
|
-
|
453
|
-
|
454
|
-
@h.merge(macro_list: @macros.map(&:to_h)).to_camel_case
|
766
|
+
end
|
455
767
|
|
768
|
+
class GeofenceMap
|
769
|
+
|
770
|
+
attr_accessor :name, :longitude, :latitude, :radius, :id
|
771
|
+
|
772
|
+
def initialize(h)
|
773
|
+
@id, @latitude, @longitude, @name, @radius = h.values
|
456
774
|
end
|
457
|
-
|
458
|
-
|
459
|
-
|
775
|
+
|
460
776
|
end
|
461
777
|
|
462
778
|
class MacroObject
|
@@ -467,6 +783,8 @@ class MacroObject
|
|
467
783
|
|
468
784
|
def initialize(h={})
|
469
785
|
|
786
|
+
$env ||= {}
|
787
|
+
|
470
788
|
@h = {constraint_list: [], is_or_condition: false,
|
471
789
|
is_disabled: false}.merge(h)
|
472
790
|
@list = []
|
@@ -495,6 +813,10 @@ class MacroObject
|
|
495
813
|
h2.merge('m_classType' => self.class.to_s)
|
496
814
|
|
497
815
|
end
|
816
|
+
|
817
|
+
def to_s()
|
818
|
+
"#<%s %s>" % [self.class, @h.inspect]
|
819
|
+
end
|
498
820
|
|
499
821
|
protected
|
500
822
|
|
@@ -518,10 +840,11 @@ class Trigger < MacroObject
|
|
518
840
|
@list << 'fakeIcon'
|
519
841
|
end
|
520
842
|
|
521
|
-
def match?(detail={})
|
843
|
+
def match?(detail={}, model=nil)
|
844
|
+
|
845
|
+
# only match where the key exists in the trigger object
|
846
|
+
detail.select {|k,v| @h.include? k }.all? {|key,value| @h[key] == value}
|
522
847
|
|
523
|
-
detail.all? {|key,value| @h[key] == value}
|
524
|
-
|
525
848
|
end
|
526
849
|
|
527
850
|
end
|
@@ -1008,27 +1331,50 @@ class TimerTrigger < Trigger
|
|
1008
1331
|
use_alarm: false
|
1009
1332
|
}
|
1010
1333
|
|
1011
|
-
super(options.merge filter(options,h))
|
1334
|
+
super(options.merge filter(options, h))
|
1012
1335
|
|
1013
1336
|
end
|
1014
1337
|
|
1015
|
-
def match?(detail={time: $env[:time]})
|
1338
|
+
def match?(detail={time: $env[:time]}, model=nil)
|
1339
|
+
|
1340
|
+
time() == detail[:time]
|
1016
1341
|
|
1017
|
-
|
1018
|
-
|
1342
|
+
end
|
1343
|
+
|
1344
|
+
# sets the environmental conditions for this trigger to fire
|
1345
|
+
#
|
1346
|
+
def set_env()
|
1347
|
+
$env[:time] = time()
|
1348
|
+
end
|
1349
|
+
|
1350
|
+
def to_pc()
|
1351
|
+
"time.is? '%s'" % self.to_s.gsub(',', ' or')
|
1352
|
+
end
|
1353
|
+
|
1354
|
+
def to_s()
|
1355
|
+
|
1356
|
+
dow = @h[:days_of_week]
|
1019
1357
|
|
1020
|
-
|
1358
|
+
a = Date::ABBR_DAYNAMES
|
1021
1359
|
|
1022
|
-
|
1360
|
+
time = Time.parse("%s:%s" % [@h[:hour], @h[:minute]]).strftime("%-H:%M%P")
|
1361
|
+
days = (a[1..-1] << a.first).zip(dow).select {|_,b| b}.map(&:first)
|
1023
1362
|
|
1024
|
-
|
1025
|
-
|
1026
|
-
|
1027
|
-
|
1028
|
-
|
1363
|
+
"at %s on %s" % [time, days.join(', ')]
|
1364
|
+
end
|
1365
|
+
|
1366
|
+
private
|
1367
|
+
|
1368
|
+
def time()
|
1029
1369
|
|
1030
|
-
|
1370
|
+
a = @h[:days_of_week].clone
|
1371
|
+
a.unshift a.pop
|
1031
1372
|
|
1373
|
+
dow = a.map.with_index {|x, i| x ? i : nil }.compact.join(',')
|
1374
|
+
s = "%s %s * * %s" % [@h[:minute], @h[:hour], dow]
|
1375
|
+
recent_time = ($env && $env[:time]) ? $env[:time] : Time.now
|
1376
|
+
ChronicCron.new(s, recent_time).to_time
|
1377
|
+
|
1032
1378
|
end
|
1033
1379
|
|
1034
1380
|
end
|
@@ -1101,6 +1447,15 @@ class RegularIntervalTrigger < Trigger
|
|
1101
1447
|
|
1102
1448
|
end
|
1103
1449
|
|
1450
|
+
class DeviceEventsTrigger < Trigger
|
1451
|
+
|
1452
|
+
def initialize(h={})
|
1453
|
+
super(h)
|
1454
|
+
@group = 'device_events'
|
1455
|
+
end
|
1456
|
+
|
1457
|
+
end
|
1458
|
+
|
1104
1459
|
# Category: Device Events
|
1105
1460
|
#
|
1106
1461
|
# Airplane Mode Changed
|
@@ -1112,7 +1467,7 @@ end
|
|
1112
1467
|
# shorthand example:
|
1113
1468
|
# airplanemode: enabled
|
1114
1469
|
#
|
1115
|
-
class AirplaneModeTrigger <
|
1470
|
+
class AirplaneModeTrigger < DeviceEventsTrigger
|
1116
1471
|
|
1117
1472
|
def initialize(h={})
|
1118
1473
|
|
@@ -1128,7 +1483,7 @@ end
|
|
1128
1483
|
|
1129
1484
|
# Category: Device Events
|
1130
1485
|
#
|
1131
|
-
class AutoSyncChangeTrigger <
|
1486
|
+
class AutoSyncChangeTrigger < DeviceEventsTrigger
|
1132
1487
|
|
1133
1488
|
def initialize(h={})
|
1134
1489
|
|
@@ -1144,7 +1499,7 @@ end
|
|
1144
1499
|
|
1145
1500
|
# Category: Device Events
|
1146
1501
|
#
|
1147
|
-
class DayDreamTrigger <
|
1502
|
+
class DayDreamTrigger < DeviceEventsTrigger
|
1148
1503
|
|
1149
1504
|
def initialize(h={})
|
1150
1505
|
|
@@ -1160,7 +1515,7 @@ end
|
|
1160
1515
|
|
1161
1516
|
# Category: Device Events
|
1162
1517
|
#
|
1163
|
-
class DockTrigger <
|
1518
|
+
class DockTrigger < DeviceEventsTrigger
|
1164
1519
|
|
1165
1520
|
def initialize(h={})
|
1166
1521
|
|
@@ -1176,7 +1531,30 @@ end
|
|
1176
1531
|
|
1177
1532
|
# Category: Device Events
|
1178
1533
|
#
|
1179
|
-
class
|
1534
|
+
class FailedLoginTrigger < DeviceEventsTrigger
|
1535
|
+
|
1536
|
+
def initialize(h={})
|
1537
|
+
|
1538
|
+
options = {
|
1539
|
+
num_failures: 1
|
1540
|
+
}
|
1541
|
+
|
1542
|
+
super(options.merge h)
|
1543
|
+
|
1544
|
+
end
|
1545
|
+
|
1546
|
+
def to_pc()
|
1547
|
+
'failed_login?'
|
1548
|
+
end
|
1549
|
+
|
1550
|
+
def to_s()
|
1551
|
+
'Failed Login Attempt'
|
1552
|
+
end
|
1553
|
+
end
|
1554
|
+
|
1555
|
+
# Category: Device Events
|
1556
|
+
#
|
1557
|
+
class GPSEnabledTrigger < DeviceEventsTrigger
|
1180
1558
|
|
1181
1559
|
def initialize(h={})
|
1182
1560
|
|
@@ -1192,7 +1570,7 @@ end
|
|
1192
1570
|
|
1193
1571
|
# Category: Device Events
|
1194
1572
|
#
|
1195
|
-
class MusicPlayingTrigger <
|
1573
|
+
class MusicPlayingTrigger < DeviceEventsTrigger
|
1196
1574
|
|
1197
1575
|
def initialize(h={})
|
1198
1576
|
|
@@ -1209,7 +1587,7 @@ end
|
|
1209
1587
|
|
1210
1588
|
# Category: Device Events
|
1211
1589
|
#
|
1212
|
-
class DeviceUnlockedTrigger <
|
1590
|
+
class DeviceUnlockedTrigger < DeviceEventsTrigger
|
1213
1591
|
|
1214
1592
|
def initialize(h={})
|
1215
1593
|
|
@@ -1224,7 +1602,7 @@ end
|
|
1224
1602
|
|
1225
1603
|
# Category: Device Events
|
1226
1604
|
#
|
1227
|
-
class AutoRotateChangeTrigger <
|
1605
|
+
class AutoRotateChangeTrigger < DeviceEventsTrigger
|
1228
1606
|
|
1229
1607
|
def initialize(h={})
|
1230
1608
|
|
@@ -1240,7 +1618,7 @@ end
|
|
1240
1618
|
|
1241
1619
|
# Category: Device Events
|
1242
1620
|
#
|
1243
|
-
class ClipboardChangeTrigger <
|
1621
|
+
class ClipboardChangeTrigger < DeviceEventsTrigger
|
1244
1622
|
|
1245
1623
|
def initialize(h={})
|
1246
1624
|
|
@@ -1257,7 +1635,7 @@ end
|
|
1257
1635
|
|
1258
1636
|
# Category: Device Events
|
1259
1637
|
#
|
1260
|
-
class BootTrigger <
|
1638
|
+
class BootTrigger < DeviceEventsTrigger
|
1261
1639
|
|
1262
1640
|
def initialize(h={})
|
1263
1641
|
|
@@ -1272,7 +1650,7 @@ end
|
|
1272
1650
|
|
1273
1651
|
# Category: Device Events
|
1274
1652
|
#
|
1275
|
-
class IntentReceivedTrigger <
|
1653
|
+
class IntentReceivedTrigger < DeviceEventsTrigger
|
1276
1654
|
|
1277
1655
|
def initialize(h={})
|
1278
1656
|
|
@@ -1292,7 +1670,7 @@ end
|
|
1292
1670
|
|
1293
1671
|
# Category: Device Events
|
1294
1672
|
#
|
1295
|
-
class NotificationTrigger <
|
1673
|
+
class NotificationTrigger < DeviceEventsTrigger
|
1296
1674
|
|
1297
1675
|
def initialize(h={})
|
1298
1676
|
|
@@ -1318,7 +1696,7 @@ end
|
|
1318
1696
|
|
1319
1697
|
# Category: Device Events
|
1320
1698
|
#
|
1321
|
-
class ScreenOnOffTrigger <
|
1699
|
+
class ScreenOnOffTrigger < DeviceEventsTrigger
|
1322
1700
|
|
1323
1701
|
def initialize(h={})
|
1324
1702
|
|
@@ -1334,7 +1712,7 @@ end
|
|
1334
1712
|
|
1335
1713
|
# Category: Device Events
|
1336
1714
|
#
|
1337
|
-
class SilentModeTrigger <
|
1715
|
+
class SilentModeTrigger < DeviceEventsTrigger
|
1338
1716
|
|
1339
1717
|
def initialize(h={})
|
1340
1718
|
|
@@ -1377,8 +1755,15 @@ end
|
|
1377
1755
|
#
|
1378
1756
|
class GeofenceTrigger < Trigger
|
1379
1757
|
|
1380
|
-
def initialize(h={})
|
1758
|
+
def initialize(geofence, h={})
|
1381
1759
|
|
1760
|
+
if h[:name] then
|
1761
|
+
|
1762
|
+
found = geofence.find {|x| x.name == h[:name]}
|
1763
|
+
h[:geofence_id] = found.id
|
1764
|
+
|
1765
|
+
end
|
1766
|
+
|
1382
1767
|
options = {
|
1383
1768
|
update_rate_text: '5 Minutes',
|
1384
1769
|
geofence_id: '',
|
@@ -1387,9 +1772,18 @@ class GeofenceTrigger < Trigger
|
|
1387
1772
|
enter_area: true
|
1388
1773
|
}
|
1389
1774
|
|
1390
|
-
super(options.merge h)
|
1775
|
+
super(options.merge filter(options, h))
|
1776
|
+
@geofence = geofence
|
1391
1777
|
|
1392
1778
|
end
|
1779
|
+
|
1780
|
+
def to_s()
|
1781
|
+
|
1782
|
+
puts ' @geofence: ' + @geofence.inspect if $debug
|
1783
|
+
direction = @h[:enter_area] ? 'Entry' : 'Exit'
|
1784
|
+
"Geofence %s (%s)" % [direction, @geofence[@h[:geofence_id].to_sym].name]
|
1785
|
+
|
1786
|
+
end
|
1393
1787
|
|
1394
1788
|
end
|
1395
1789
|
|
@@ -1410,9 +1804,19 @@ class SunriseSunsetTrigger < Trigger
|
|
1410
1804
|
|
1411
1805
|
end
|
1412
1806
|
|
1807
|
+
|
1808
|
+
class SensorsTrigger < Trigger
|
1809
|
+
|
1810
|
+
def initialize(h={})
|
1811
|
+
super(h)
|
1812
|
+
@group = 'sensors'
|
1813
|
+
end
|
1814
|
+
|
1815
|
+
end
|
1816
|
+
|
1413
1817
|
# Category: Sensors
|
1414
1818
|
#
|
1415
|
-
class ActivityRecognitionTrigger <
|
1819
|
+
class ActivityRecognitionTrigger < SensorsTrigger
|
1416
1820
|
|
1417
1821
|
def initialize(h={})
|
1418
1822
|
|
@@ -1429,7 +1833,7 @@ end
|
|
1429
1833
|
|
1430
1834
|
# Category: Sensors
|
1431
1835
|
#
|
1432
|
-
class ProximityTrigger <
|
1836
|
+
class ProximityTrigger < SensorsTrigger
|
1433
1837
|
|
1434
1838
|
def initialize(h={})
|
1435
1839
|
|
@@ -1446,7 +1850,7 @@ end
|
|
1446
1850
|
|
1447
1851
|
# Category: Sensors
|
1448
1852
|
#
|
1449
|
-
class ShakeDeviceTrigger <
|
1853
|
+
class ShakeDeviceTrigger < SensorsTrigger
|
1450
1854
|
|
1451
1855
|
def initialize(h={})
|
1452
1856
|
|
@@ -1456,12 +1860,25 @@ class ShakeDeviceTrigger < Trigger
|
|
1456
1860
|
super(options.merge h)
|
1457
1861
|
|
1458
1862
|
end
|
1863
|
+
|
1864
|
+
def to_pc()
|
1865
|
+
'shake_device?'
|
1866
|
+
end
|
1867
|
+
|
1868
|
+
def to_s()
|
1869
|
+
'Shake Device'
|
1870
|
+
end
|
1459
1871
|
|
1460
1872
|
end
|
1461
1873
|
|
1462
1874
|
# Category: Sensors
|
1463
1875
|
#
|
1464
|
-
|
1876
|
+
# options:
|
1877
|
+
# Face Up -> Face Down
|
1878
|
+
# Face Down -> Face Up
|
1879
|
+
# Any -> Face Down
|
1880
|
+
#
|
1881
|
+
class FlipDeviceTrigger < SensorsTrigger
|
1465
1882
|
|
1466
1883
|
def initialize(h={})
|
1467
1884
|
|
@@ -1473,13 +1890,23 @@ class FlipDeviceTrigger < Trigger
|
|
1473
1890
|
|
1474
1891
|
super(options.merge h)
|
1475
1892
|
|
1893
|
+
end
|
1894
|
+
|
1895
|
+
def to_pc()
|
1896
|
+
@h[:face_down] ? 'flip_device_down?' : 'flip_device_up?'
|
1476
1897
|
end
|
1898
|
+
|
1899
|
+
def to_s()
|
1900
|
+
|
1901
|
+
action = @h[:face_down] ? 'Face Up -> Face Down' : 'Face Down -> Face Up'
|
1902
|
+
'Flip Device ' + action
|
1903
|
+
end
|
1477
1904
|
|
1478
1905
|
end
|
1479
1906
|
|
1480
1907
|
# Category: Sensors
|
1481
1908
|
#
|
1482
|
-
class OrientationTrigger <
|
1909
|
+
class OrientationTrigger < SensorsTrigger
|
1483
1910
|
|
1484
1911
|
def initialize(h={})
|
1485
1912
|
|
@@ -1661,6 +2088,10 @@ class LaunchActivityAction < ApplicationAction
|
|
1661
2088
|
super(options.merge h)
|
1662
2089
|
|
1663
2090
|
end
|
2091
|
+
|
2092
|
+
def to_s()
|
2093
|
+
'Launch ' + @h[:application_name]
|
2094
|
+
end
|
1664
2095
|
|
1665
2096
|
end
|
1666
2097
|
|
@@ -1698,6 +2129,10 @@ class OpenWebPageAction < ApplicationAction
|
|
1698
2129
|
super(options.merge h)
|
1699
2130
|
|
1700
2131
|
end
|
2132
|
+
|
2133
|
+
def to_s()
|
2134
|
+
'HTTP GET'
|
2135
|
+
end
|
1701
2136
|
|
1702
2137
|
end
|
1703
2138
|
|
@@ -1745,6 +2180,15 @@ class TakePictureAction < CameraAction
|
|
1745
2180
|
super(options.merge h)
|
1746
2181
|
|
1747
2182
|
end
|
2183
|
+
|
2184
|
+
def to_pc()
|
2185
|
+
camera = @h[:use_front_camera] ? :front : :back
|
2186
|
+
'take_photo :' + camera.to_s
|
2187
|
+
end
|
2188
|
+
|
2189
|
+
def to_s()
|
2190
|
+
'Take Picture'
|
2191
|
+
end
|
1748
2192
|
|
1749
2193
|
end
|
1750
2194
|
|
@@ -1773,6 +2217,11 @@ class SetWifiAction < ConnectivityAction
|
|
1773
2217
|
super(options.merge h)
|
1774
2218
|
|
1775
2219
|
end
|
2220
|
+
|
2221
|
+
def to_s()
|
2222
|
+
action = @h[:state] == 0 ? 'Enable' : 'Disable'
|
2223
|
+
action + ' Wifi'
|
2224
|
+
end
|
1776
2225
|
|
1777
2226
|
end
|
1778
2227
|
|
@@ -1903,6 +2352,20 @@ class SayTimeAction < DateTimeAction
|
|
1903
2352
|
super(options.merge h)
|
1904
2353
|
|
1905
2354
|
end
|
2355
|
+
|
2356
|
+
def invoke()
|
2357
|
+
time = ($env and $env[:time]) ? $env[:time] : Time.now
|
2358
|
+
tformat = @h['12_hour'] ? "%-I:%M%P" : "%H:%M"
|
2359
|
+
super(time.strftime(tformat))
|
2360
|
+
end
|
2361
|
+
|
2362
|
+
def to_pc()
|
2363
|
+
'say current_time()'
|
2364
|
+
end
|
2365
|
+
|
2366
|
+
def to_s()
|
2367
|
+
'Say Current Time'
|
2368
|
+
end
|
1906
2369
|
|
1907
2370
|
end
|
1908
2371
|
|
@@ -2074,6 +2537,14 @@ class CameraFlashLightAction < DeviceSettingsAction
|
|
2074
2537
|
|
2075
2538
|
end
|
2076
2539
|
|
2540
|
+
def to_pc()
|
2541
|
+
'torch :on'
|
2542
|
+
end
|
2543
|
+
|
2544
|
+
def to_s()
|
2545
|
+
'Torch On'
|
2546
|
+
end
|
2547
|
+
|
2077
2548
|
end
|
2078
2549
|
|
2079
2550
|
# Category: Device Settings
|
@@ -2411,6 +2882,10 @@ class PlaySoundAction < MediaAction
|
|
2411
2882
|
super(options.merge h)
|
2412
2883
|
|
2413
2884
|
end
|
2885
|
+
|
2886
|
+
def to_s()
|
2887
|
+
'Play: ' + @h[:file_path]
|
2888
|
+
end
|
2414
2889
|
|
2415
2890
|
end
|
2416
2891
|
|
@@ -2615,6 +3090,9 @@ end
|
|
2615
3090
|
class NotificationAction < NotificationsAction
|
2616
3091
|
|
2617
3092
|
def initialize(h={})
|
3093
|
+
|
3094
|
+
h[:notification_subject] = h[:subject] if h[:subject]
|
3095
|
+
h[:notification_text] = h[:text] if h[:text]
|
2618
3096
|
|
2619
3097
|
options = {
|
2620
3098
|
ringtone_name: 'Default',
|
@@ -2630,9 +3108,13 @@ class NotificationAction < NotificationsAction
|
|
2630
3108
|
run_macro_when_pressed: false
|
2631
3109
|
}
|
2632
3110
|
|
2633
|
-
super(options.merge h)
|
3111
|
+
super(options.merge filter(options, h))
|
2634
3112
|
|
2635
3113
|
end
|
3114
|
+
|
3115
|
+
def to_s()
|
3116
|
+
'Display Notification: ' + "%s: %s" % [@h[:notification_subject], @h[:notification_text]]
|
3117
|
+
end
|
2636
3118
|
|
2637
3119
|
end
|
2638
3120
|
|
@@ -2665,6 +3147,14 @@ class ToastAction < NotificationsAction
|
|
2665
3147
|
def invoke()
|
2666
3148
|
super(@h[:message_text])
|
2667
3149
|
end
|
3150
|
+
|
3151
|
+
def to_pc()
|
3152
|
+
"popup_message '%s'" % @h[:message_text]
|
3153
|
+
end
|
3154
|
+
|
3155
|
+
def to_s()
|
3156
|
+
"Popup Message '%s'" % @h[:message_text]
|
3157
|
+
end
|
2668
3158
|
|
2669
3159
|
end
|
2670
3160
|
|
@@ -2993,5 +3483,917 @@ class Constraint < MacroObject
|
|
2993
3483
|
def initialize(h={})
|
2994
3484
|
super(h)
|
2995
3485
|
end
|
3486
|
+
|
3487
|
+
def match?(detail={}, model=nil)
|
3488
|
+
|
3489
|
+
detail.select {|k,v| @h.include? k }.all? {|key,value| @h[key] == value}
|
3490
|
+
|
3491
|
+
end
|
3492
|
+
|
3493
|
+
#def to_s()
|
3494
|
+
# ''
|
3495
|
+
#end
|
3496
|
+
|
3497
|
+
protected
|
3498
|
+
|
3499
|
+
def toggle_match?(key, val)
|
3500
|
+
|
3501
|
+
if @h[key] == true and val == key.to_s then
|
3502
|
+
true
|
3503
|
+
elsif @h[key] == false and val != key.to_s
|
3504
|
+
true
|
3505
|
+
else
|
3506
|
+
false
|
3507
|
+
end
|
3508
|
+
|
3509
|
+
end
|
3510
|
+
|
3511
|
+
end
|
3512
|
+
|
3513
|
+
class TimeOfDayConstraint < Constraint
|
3514
|
+
|
3515
|
+
def initialize(h={})
|
3516
|
+
|
3517
|
+
options = {
|
3518
|
+
end_hour: 8,
|
3519
|
+
end_minute: 0,
|
3520
|
+
start_hour: 22,
|
3521
|
+
start_minute: 0
|
3522
|
+
}
|
3523
|
+
|
3524
|
+
super(options.merge h)
|
3525
|
+
|
3526
|
+
end
|
3527
|
+
|
3528
|
+
end
|
3529
|
+
|
3530
|
+
# Category: Battery/Power
|
3531
|
+
#
|
3532
|
+
class BatteryLevelConstraint < Constraint
|
3533
|
+
|
3534
|
+
def initialize(h={})
|
3535
|
+
|
3536
|
+
options = {
|
3537
|
+
battery_level: 23,
|
3538
|
+
equals: false,
|
3539
|
+
greater_than: false
|
3540
|
+
}
|
3541
|
+
|
3542
|
+
super(options.merge h)
|
3543
|
+
|
3544
|
+
end
|
3545
|
+
|
3546
|
+
end
|
3547
|
+
|
3548
|
+
# Category: Battery/Power
|
3549
|
+
#
|
3550
|
+
class BatterySaverStateConstraint < Constraint
|
3551
|
+
|
3552
|
+
def initialize(h={})
|
3553
|
+
|
3554
|
+
options = {
|
3555
|
+
option: 0
|
3556
|
+
}
|
3557
|
+
|
3558
|
+
super(options.merge h)
|
3559
|
+
|
3560
|
+
end
|
3561
|
+
|
3562
|
+
end
|
3563
|
+
|
3564
|
+
# Category: Battery/Power
|
3565
|
+
#
|
3566
|
+
class BatteryTemperatureConstraint < Constraint
|
3567
|
+
|
3568
|
+
def initialize(h={})
|
3569
|
+
|
3570
|
+
options = {
|
3571
|
+
equals: false,
|
3572
|
+
greater_than: false,
|
3573
|
+
temperature: 30
|
3574
|
+
}
|
3575
|
+
|
3576
|
+
super(options.merge h)
|
3577
|
+
|
3578
|
+
end
|
3579
|
+
|
3580
|
+
end
|
3581
|
+
|
3582
|
+
# Category: Battery/Power
|
3583
|
+
#
|
3584
|
+
class ExternalPowerConstraint < Constraint
|
3585
|
+
|
3586
|
+
def initialize(h={})
|
3587
|
+
|
3588
|
+
options = {
|
3589
|
+
external_power: true,
|
3590
|
+
power_connected_options: [false, true, false]
|
3591
|
+
}
|
3592
|
+
|
3593
|
+
super(options.merge h)
|
3594
|
+
|
3595
|
+
end
|
3596
|
+
|
3597
|
+
end
|
3598
|
+
|
3599
|
+
# Category: Connectivity
|
3600
|
+
#
|
3601
|
+
class BluetoothConstraint < Constraint
|
3602
|
+
|
3603
|
+
def initialize(h={})
|
3604
|
+
|
3605
|
+
options = {
|
3606
|
+
any_device: false,
|
3607
|
+
bt_state: 0,
|
3608
|
+
device_name: 'Any Device'
|
3609
|
+
}
|
3610
|
+
|
3611
|
+
super(options.merge h)
|
3612
|
+
|
3613
|
+
end
|
3614
|
+
|
3615
|
+
end
|
3616
|
+
|
3617
|
+
# Category: Connectivity
|
3618
|
+
#
|
3619
|
+
class GPSEnabledConstraint < Constraint
|
3620
|
+
|
3621
|
+
def initialize(h={})
|
3622
|
+
|
3623
|
+
options = {
|
3624
|
+
enabled: true
|
3625
|
+
}
|
3626
|
+
|
3627
|
+
super(options.merge h)
|
3628
|
+
|
3629
|
+
end
|
3630
|
+
|
3631
|
+
end
|
3632
|
+
|
3633
|
+
# Category: Connectivity
|
3634
|
+
#
|
3635
|
+
class LocationModeConstraint < Constraint
|
3636
|
+
|
3637
|
+
def initialize(h={})
|
3638
|
+
|
3639
|
+
options = {
|
3640
|
+
options: [false, false, false, true]
|
3641
|
+
}
|
3642
|
+
|
3643
|
+
super(options.merge h)
|
3644
|
+
|
3645
|
+
end
|
3646
|
+
|
3647
|
+
end
|
3648
|
+
|
3649
|
+
# Category: Connectivity
|
3650
|
+
#
|
3651
|
+
class SignalOnOffConstraint < Constraint
|
3652
|
+
|
3653
|
+
def initialize(h={})
|
3654
|
+
|
3655
|
+
options = {
|
3656
|
+
option: 0
|
3657
|
+
}
|
3658
|
+
|
3659
|
+
super(options.merge h)
|
3660
|
+
|
3661
|
+
end
|
3662
|
+
|
3663
|
+
end
|
3664
|
+
|
3665
|
+
# Category: Connectivity
|
3666
|
+
#
|
3667
|
+
class WifiConstraint < Constraint
|
3668
|
+
|
3669
|
+
def initialize(h={})
|
3670
|
+
|
3671
|
+
options = {
|
3672
|
+
ssid_list: [],
|
3673
|
+
wifi_state: 0
|
3674
|
+
}
|
3675
|
+
|
3676
|
+
super(options.merge h)
|
3677
|
+
|
3678
|
+
end
|
3679
|
+
|
3680
|
+
end
|
3681
|
+
|
3682
|
+
# Category: Connectivity
|
3683
|
+
#
|
3684
|
+
class CellTowerConstraint < Constraint
|
3685
|
+
|
3686
|
+
def initialize(h={})
|
3687
|
+
|
3688
|
+
options = {
|
3689
|
+
cell_group_name: 'test group',
|
3690
|
+
cell_ids: ["524,14,41070731"],
|
3691
|
+
in_range: true
|
3692
|
+
}
|
3693
|
+
|
3694
|
+
super(options.merge h)
|
3695
|
+
|
3696
|
+
end
|
3697
|
+
|
3698
|
+
end
|
3699
|
+
|
3700
|
+
# Category: Connectivity
|
3701
|
+
#
|
3702
|
+
class IsRoamingConstraint < Constraint
|
3703
|
+
|
3704
|
+
def initialize(h={})
|
3705
|
+
|
3706
|
+
options = {
|
3707
|
+
is_roaming: true
|
3708
|
+
}
|
3709
|
+
|
3710
|
+
super(options.merge h)
|
3711
|
+
|
3712
|
+
end
|
3713
|
+
|
3714
|
+
end
|
3715
|
+
|
3716
|
+
# Category: Connectivity
|
3717
|
+
#
|
3718
|
+
class DataOnOffConstraint < Constraint
|
3719
|
+
|
3720
|
+
def initialize(h={})
|
3721
|
+
|
3722
|
+
options = {
|
3723
|
+
data_on: true
|
3724
|
+
}
|
3725
|
+
|
3726
|
+
super(options.merge h)
|
3727
|
+
|
3728
|
+
end
|
3729
|
+
|
3730
|
+
end
|
3731
|
+
|
3732
|
+
# Category: Connectivity
|
3733
|
+
#
|
3734
|
+
class WifiHotSpotConstraint < Constraint
|
3735
|
+
|
3736
|
+
def initialize(h={})
|
3737
|
+
|
3738
|
+
options = {
|
3739
|
+
check_connections: false,
|
3740
|
+
comparison_value: 0,
|
3741
|
+
connected_count: 0,
|
3742
|
+
enabled: true
|
3743
|
+
}
|
3744
|
+
|
3745
|
+
super(options.merge h)
|
3746
|
+
|
3747
|
+
end
|
3748
|
+
|
3749
|
+
end
|
3750
|
+
|
3751
|
+
# Category: Date/Time
|
3752
|
+
#
|
3753
|
+
class CalendarConstraint < Constraint
|
3754
|
+
|
3755
|
+
def initialize(h={})
|
3756
|
+
|
3757
|
+
options = {
|
3758
|
+
enable_regex: false,
|
3759
|
+
availability: 0,
|
3760
|
+
calendar_id: '1',
|
3761
|
+
calendar_name: 'PC Sync',
|
3762
|
+
detail_text: '',
|
3763
|
+
entry_set: true,
|
3764
|
+
ignore_all_day: false,
|
3765
|
+
title_text: ''
|
3766
|
+
}
|
3767
|
+
|
3768
|
+
super(options.merge h)
|
3769
|
+
|
3770
|
+
end
|
3771
|
+
|
3772
|
+
end
|
3773
|
+
|
3774
|
+
# Category: Date/Time
|
3775
|
+
#
|
3776
|
+
class DayOfWeekConstraint < Constraint
|
3777
|
+
|
3778
|
+
def initialize(h={})
|
3779
|
+
|
3780
|
+
options = {
|
3781
|
+
days_of_week: [false, false, true, false, false, false, false]
|
3782
|
+
}
|
3783
|
+
|
3784
|
+
super(options.merge h)
|
3785
|
+
|
3786
|
+
end
|
3787
|
+
|
3788
|
+
end
|
3789
|
+
|
3790
|
+
# Category: Date/Time
|
3791
|
+
#
|
3792
|
+
class TimeOfDayConstraint < Constraint
|
3793
|
+
|
3794
|
+
def initialize(h={})
|
3795
|
+
|
3796
|
+
options = {
|
3797
|
+
end_hour: 1,
|
3798
|
+
end_minute: 1,
|
3799
|
+
start_hour: 21,
|
3800
|
+
start_minute: 58
|
3801
|
+
}
|
3802
|
+
|
3803
|
+
super(options.merge h)
|
3804
|
+
|
3805
|
+
end
|
3806
|
+
|
3807
|
+
end
|
3808
|
+
|
3809
|
+
# Category: Date/Time
|
3810
|
+
#
|
3811
|
+
class DayOfMonthConstraint < Constraint
|
3812
|
+
|
3813
|
+
def initialize(h={})
|
3814
|
+
|
3815
|
+
options = {
|
3816
|
+
day_names: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31"],
|
3817
|
+
days_of_month: [false, false, false, false, false, false, false, true, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]
|
3818
|
+
}
|
3819
|
+
|
3820
|
+
super(options.merge h)
|
3821
|
+
|
3822
|
+
end
|
3823
|
+
|
3824
|
+
end
|
3825
|
+
|
3826
|
+
# Category: Date/Time
|
3827
|
+
#
|
3828
|
+
class MonthOfYearConstraint < Constraint
|
3829
|
+
|
3830
|
+
def initialize(h={})
|
3831
|
+
|
3832
|
+
options = {
|
3833
|
+
months: [false, false, false, false, false, false, false, true, false, false, false, false]
|
3834
|
+
}
|
3835
|
+
|
3836
|
+
super(options.merge h)
|
3837
|
+
|
3838
|
+
end
|
3839
|
+
|
3840
|
+
end
|
3841
|
+
|
3842
|
+
# Category: Date/Time
|
3843
|
+
#
|
3844
|
+
class SunsetSunriseConstraint < Constraint
|
3845
|
+
|
3846
|
+
def initialize(h={})
|
3847
|
+
|
3848
|
+
options = {
|
3849
|
+
option: 0
|
3850
|
+
}
|
3851
|
+
|
3852
|
+
super(options.merge h)
|
3853
|
+
|
3854
|
+
end
|
3855
|
+
|
3856
|
+
end
|
3857
|
+
|
3858
|
+
# Category: Device State
|
3859
|
+
#
|
3860
|
+
class AirplaneModeConstraint < Constraint
|
3861
|
+
|
3862
|
+
def initialize(h={})
|
3863
|
+
|
3864
|
+
options = {
|
3865
|
+
enabled: true
|
3866
|
+
}
|
3867
|
+
|
3868
|
+
super(options.merge h)
|
3869
|
+
|
3870
|
+
end
|
3871
|
+
|
3872
|
+
def match?(detail={}, model=nil)
|
3873
|
+
|
3874
|
+
puts 'inside airplaneModeConstraint#match?' if $debug
|
3875
|
+
|
3876
|
+
if detail.has_key? :enabled then
|
3877
|
+
|
3878
|
+
puts 'detail has the key' if $debug
|
3879
|
+
super(detail)
|
3880
|
+
|
3881
|
+
elsif model
|
3882
|
+
|
3883
|
+
if $debug then
|
3884
|
+
puts 'checking the model'
|
3885
|
+
switch = model.connectivity.airplane_mode.switch
|
3886
|
+
puts 'switch: ' + switch.inspect
|
3887
|
+
end
|
3888
|
+
|
3889
|
+
toggle_match?(:enabled, switch)
|
3890
|
+
|
3891
|
+
end
|
3892
|
+
|
3893
|
+
end
|
3894
|
+
|
3895
|
+
def to_pc()
|
3896
|
+
status = @h[:enabled] ? 'enabled?' : 'disabled?'
|
3897
|
+
'airplane_mode.' + status
|
3898
|
+
end
|
3899
|
+
|
3900
|
+
def to_s()
|
3901
|
+
|
3902
|
+
status = @h[:enabled] ? 'Enabled' : 'Disabled'
|
3903
|
+
'Airplane Mode ' + status
|
3904
|
+
|
3905
|
+
end
|
3906
|
+
|
3907
|
+
end
|
3908
|
+
|
3909
|
+
# Category: Device State
|
3910
|
+
#
|
3911
|
+
class AutoRotateConstraint < Constraint
|
3912
|
+
|
3913
|
+
def initialize(h={})
|
3914
|
+
|
3915
|
+
options = {
|
3916
|
+
enabled: true
|
3917
|
+
}
|
3918
|
+
|
3919
|
+
super(options.merge h)
|
3920
|
+
|
3921
|
+
end
|
3922
|
+
|
3923
|
+
end
|
3924
|
+
|
3925
|
+
# Category: Device State
|
3926
|
+
#
|
3927
|
+
class DeviceLockedConstraint < Constraint
|
3928
|
+
|
3929
|
+
def initialize(h={})
|
3930
|
+
|
3931
|
+
options = {
|
3932
|
+
locked: true
|
3933
|
+
}
|
3934
|
+
|
3935
|
+
super(options.merge h)
|
3936
|
+
|
3937
|
+
end
|
3938
|
+
|
3939
|
+
end
|
3940
|
+
|
3941
|
+
# Category: Device State
|
3942
|
+
#
|
3943
|
+
class RoamingOnOffConstraint < Constraint
|
3944
|
+
|
3945
|
+
def initialize(h={})
|
3946
|
+
|
3947
|
+
options = {
|
3948
|
+
roaming_on: true
|
3949
|
+
}
|
3950
|
+
|
3951
|
+
super(options.merge h)
|
3952
|
+
|
3953
|
+
end
|
3954
|
+
|
3955
|
+
end
|
3956
|
+
|
3957
|
+
# Category: Device State
|
3958
|
+
#
|
3959
|
+
class TimeSinceBootConstraint < Constraint
|
3960
|
+
|
3961
|
+
def initialize(h={})
|
3962
|
+
|
3963
|
+
options = {
|
3964
|
+
less_than: true,
|
3965
|
+
time_period_seconds: 10921
|
3966
|
+
}
|
3967
|
+
|
3968
|
+
super(options.merge h)
|
3969
|
+
|
3970
|
+
end
|
3971
|
+
|
3972
|
+
end
|
3973
|
+
|
3974
|
+
# Category: Device State
|
3975
|
+
#
|
3976
|
+
class AutoSyncConstraint < Constraint
|
3977
|
+
|
3978
|
+
def initialize(h={})
|
3979
|
+
|
3980
|
+
options = {
|
3981
|
+
enabled: false
|
3982
|
+
}
|
3983
|
+
|
3984
|
+
super(options.merge h)
|
3985
|
+
|
3986
|
+
end
|
3987
|
+
|
3988
|
+
end
|
3989
|
+
|
3990
|
+
# Category: Device State
|
3991
|
+
#
|
3992
|
+
class NFCStateConstraint < Constraint
|
3993
|
+
|
3994
|
+
def initialize(h={})
|
3995
|
+
|
3996
|
+
options = {
|
3997
|
+
enabled: true
|
3998
|
+
}
|
3999
|
+
|
4000
|
+
super(options.merge h)
|
4001
|
+
|
4002
|
+
end
|
4003
|
+
|
4004
|
+
end
|
4005
|
+
|
4006
|
+
# Category: Device State
|
4007
|
+
#
|
4008
|
+
class IsRootedConstraint < Constraint
|
4009
|
+
|
4010
|
+
def initialize(h={})
|
4011
|
+
|
4012
|
+
options = {
|
4013
|
+
rooted: true
|
4014
|
+
}
|
4015
|
+
|
4016
|
+
super(options.merge h)
|
4017
|
+
|
4018
|
+
end
|
4019
|
+
|
4020
|
+
end
|
4021
|
+
|
4022
|
+
# Category: Device State
|
4023
|
+
#
|
4024
|
+
class VpnConstraint < Constraint
|
4025
|
+
|
4026
|
+
def initialize(h={})
|
4027
|
+
|
4028
|
+
options = {
|
4029
|
+
option: 0
|
4030
|
+
}
|
4031
|
+
|
4032
|
+
super(options.merge h)
|
4033
|
+
|
4034
|
+
end
|
4035
|
+
|
4036
|
+
end
|
4037
|
+
|
4038
|
+
# Category: MacroDroid Specific
|
4039
|
+
#
|
4040
|
+
class MacroEnabledConstraint < Constraint
|
4041
|
+
|
4042
|
+
def initialize(h={})
|
4043
|
+
|
4044
|
+
options = {
|
4045
|
+
enabled: true,
|
4046
|
+
macro_ids: [-8016812002629322290],
|
4047
|
+
macro_names: ["Intruder photo "]
|
4048
|
+
}
|
4049
|
+
|
4050
|
+
super(options.merge h)
|
4051
|
+
|
4052
|
+
end
|
4053
|
+
|
4054
|
+
end
|
4055
|
+
|
4056
|
+
# Category: MacroDroid Specific
|
4057
|
+
#
|
4058
|
+
class ModeConstraint < Constraint
|
4059
|
+
|
4060
|
+
def initialize(h={})
|
4061
|
+
|
4062
|
+
options = {
|
4063
|
+
mode: 'Away',
|
4064
|
+
mode_selected: true
|
4065
|
+
}
|
4066
|
+
|
4067
|
+
super(options.merge h)
|
4068
|
+
|
4069
|
+
end
|
4070
|
+
|
4071
|
+
end
|
4072
|
+
|
4073
|
+
# Category: MacroDroid Specific
|
4074
|
+
#
|
4075
|
+
class TriggerThatInvokedConstraint < Constraint
|
4076
|
+
|
4077
|
+
def initialize(h={})
|
4078
|
+
|
4079
|
+
options = {
|
4080
|
+
not: false,
|
4081
|
+
si_guid_that_invoked: -4951291100076165433,
|
4082
|
+
trigger_name: 'Shake Device'
|
4083
|
+
}
|
4084
|
+
|
4085
|
+
super(options.merge h)
|
4086
|
+
|
4087
|
+
end
|
4088
|
+
|
4089
|
+
end
|
4090
|
+
|
4091
|
+
# Category: MacroDroid Specific
|
4092
|
+
#
|
4093
|
+
class LastRunTimeConstraint < Constraint
|
4094
|
+
|
4095
|
+
def initialize(h={})
|
4096
|
+
|
4097
|
+
options = {
|
4098
|
+
check_this_macro: false,
|
4099
|
+
invoked: true,
|
4100
|
+
macro_ids: [-6922688338672048267],
|
4101
|
+
macro_names: ["Opendoor"],
|
4102
|
+
time_period_seconds: 7260
|
4103
|
+
}
|
4104
|
+
|
4105
|
+
super(options.merge h)
|
4106
|
+
|
4107
|
+
end
|
4108
|
+
|
4109
|
+
end
|
4110
|
+
|
4111
|
+
# Category: Media
|
4112
|
+
#
|
4113
|
+
class HeadphonesConnectionConstraint < Constraint
|
4114
|
+
|
4115
|
+
def initialize(h={})
|
4116
|
+
|
4117
|
+
options = {
|
4118
|
+
connected: true
|
4119
|
+
}
|
4120
|
+
|
4121
|
+
super(options.merge h)
|
4122
|
+
|
4123
|
+
end
|
4124
|
+
|
4125
|
+
end
|
4126
|
+
|
4127
|
+
# Category: Media
|
4128
|
+
#
|
4129
|
+
class MusicActiveConstraint < Constraint
|
4130
|
+
|
4131
|
+
def initialize(h={})
|
4132
|
+
|
4133
|
+
options = {
|
4134
|
+
music_active: true
|
4135
|
+
}
|
4136
|
+
|
4137
|
+
super(options.merge h)
|
4138
|
+
|
4139
|
+
end
|
4140
|
+
|
4141
|
+
end
|
4142
|
+
|
4143
|
+
# Category: Notification
|
4144
|
+
#
|
4145
|
+
class NotificationPresentConstraint < Constraint
|
4146
|
+
|
4147
|
+
def initialize(h={})
|
4148
|
+
|
4149
|
+
options = {
|
4150
|
+
enable_regex: false,
|
4151
|
+
application_name_list: ["All applications"],
|
4152
|
+
exact_match: false,
|
4153
|
+
excludes: false,
|
4154
|
+
excludes_apps: -1,
|
4155
|
+
option: 0,
|
4156
|
+
package_name_list: ["allApplications"],
|
4157
|
+
text_content: ''
|
4158
|
+
}
|
4159
|
+
|
4160
|
+
super(options.merge h)
|
4161
|
+
|
4162
|
+
end
|
4163
|
+
|
4164
|
+
end
|
4165
|
+
|
4166
|
+
# Category: Notification
|
4167
|
+
#
|
4168
|
+
class PriorityModeConstraint < Constraint
|
4169
|
+
|
4170
|
+
def initialize(h={})
|
4171
|
+
|
4172
|
+
options = {
|
4173
|
+
in_mode: true,
|
4174
|
+
selected_index: 0
|
4175
|
+
}
|
4176
|
+
|
4177
|
+
super(options.merge h)
|
4178
|
+
|
4179
|
+
end
|
4180
|
+
|
4181
|
+
end
|
4182
|
+
|
4183
|
+
# Category: Notification
|
4184
|
+
#
|
4185
|
+
class NotificationVolumeConstraint < Constraint
|
4186
|
+
|
4187
|
+
def initialize(h={})
|
4188
|
+
|
4189
|
+
options = {
|
4190
|
+
option: 1
|
4191
|
+
}
|
4192
|
+
|
4193
|
+
super(options.merge h)
|
4194
|
+
|
4195
|
+
end
|
4196
|
+
|
4197
|
+
end
|
4198
|
+
|
4199
|
+
# Category: Phone
|
4200
|
+
#
|
4201
|
+
class InCallConstraint < Constraint
|
4202
|
+
|
4203
|
+
def initialize(h={})
|
4204
|
+
|
4205
|
+
options = {
|
4206
|
+
in_call: true
|
4207
|
+
}
|
4208
|
+
|
4209
|
+
super(options.merge h)
|
4210
|
+
|
4211
|
+
end
|
4212
|
+
|
4213
|
+
end
|
4214
|
+
|
4215
|
+
# Category: Phone
|
4216
|
+
#
|
4217
|
+
class PhoneRingingConstraint < Constraint
|
4218
|
+
|
4219
|
+
def initialize(h={})
|
4220
|
+
|
4221
|
+
options = {
|
4222
|
+
ringing: true
|
4223
|
+
}
|
4224
|
+
|
4225
|
+
super(options.merge h)
|
4226
|
+
|
4227
|
+
end
|
4228
|
+
|
4229
|
+
end
|
4230
|
+
|
4231
|
+
# Category: Screen and Speaker
|
4232
|
+
#
|
4233
|
+
class BrightnessConstraint < Constraint
|
4234
|
+
|
4235
|
+
def initialize(h={})
|
4236
|
+
|
4237
|
+
options = {
|
4238
|
+
brightness: 35,
|
4239
|
+
equals: false,
|
4240
|
+
force_pie_mode: false,
|
4241
|
+
greater_than: false,
|
4242
|
+
is_auto_brightness: false
|
4243
|
+
}
|
4244
|
+
|
4245
|
+
super(options.merge h)
|
4246
|
+
|
4247
|
+
end
|
4248
|
+
|
4249
|
+
end
|
4250
|
+
|
4251
|
+
# Category: Screen and Speaker
|
4252
|
+
#
|
4253
|
+
class VolumeConstraint < Constraint
|
4254
|
+
|
4255
|
+
def initialize(h={})
|
4256
|
+
|
4257
|
+
options = {
|
4258
|
+
option: 0
|
4259
|
+
}
|
4260
|
+
|
4261
|
+
super(options.merge h)
|
4262
|
+
|
4263
|
+
end
|
4264
|
+
|
4265
|
+
end
|
4266
|
+
|
4267
|
+
# Category: Screen and Speaker
|
4268
|
+
#
|
4269
|
+
class SpeakerPhoneConstraint < Constraint
|
4270
|
+
|
4271
|
+
def initialize(h={})
|
4272
|
+
|
4273
|
+
options = {
|
4274
|
+
enabled: true
|
4275
|
+
}
|
4276
|
+
|
4277
|
+
super(options.merge h)
|
4278
|
+
|
4279
|
+
end
|
4280
|
+
|
4281
|
+
end
|
4282
|
+
|
4283
|
+
# Category: Screen and Speaker
|
4284
|
+
#
|
4285
|
+
class DarkThemeConstraint < Constraint
|
4286
|
+
|
4287
|
+
def initialize(h={})
|
4288
|
+
|
4289
|
+
options = {
|
4290
|
+
option: 0
|
4291
|
+
}
|
4292
|
+
|
4293
|
+
super(options.merge h)
|
4294
|
+
|
4295
|
+
end
|
4296
|
+
|
4297
|
+
end
|
4298
|
+
|
4299
|
+
# Category: Screen and Speaker
|
4300
|
+
#
|
4301
|
+
class ScreenOnOffConstraint < Constraint
|
4302
|
+
|
4303
|
+
def initialize(h={})
|
4304
|
+
|
4305
|
+
options = {
|
4306
|
+
a: true,
|
4307
|
+
screen_on: true
|
4308
|
+
}
|
4309
|
+
|
4310
|
+
super(options.merge h)
|
4311
|
+
|
4312
|
+
end
|
4313
|
+
|
4314
|
+
end
|
4315
|
+
|
4316
|
+
# Category: Screen and Speaker
|
4317
|
+
#
|
4318
|
+
class VolumeLevelConstraint < Constraint
|
4319
|
+
|
4320
|
+
def initialize(h={})
|
4321
|
+
|
4322
|
+
options = {
|
4323
|
+
comparison: 0,
|
4324
|
+
stream_index_array: [false, true, false, false, false, false, false],
|
4325
|
+
volume: 42
|
4326
|
+
}
|
4327
|
+
|
4328
|
+
super(options.merge h)
|
4329
|
+
|
4330
|
+
end
|
4331
|
+
|
4332
|
+
end
|
4333
|
+
|
4334
|
+
# Category: Sensors
|
4335
|
+
#
|
4336
|
+
class FaceUpDownConstraint < Constraint
|
4337
|
+
|
4338
|
+
def initialize(h={})
|
4339
|
+
|
4340
|
+
options = {
|
4341
|
+
option: -1,
|
4342
|
+
selected_options: [true, false, true, false, false, false]
|
4343
|
+
}
|
4344
|
+
|
4345
|
+
super(options.merge h)
|
4346
|
+
|
4347
|
+
end
|
4348
|
+
|
4349
|
+
end
|
4350
|
+
|
4351
|
+
# Category: Sensors
|
4352
|
+
#
|
4353
|
+
class LightLevelConstraint < Constraint
|
4354
|
+
|
4355
|
+
def initialize(h={})
|
4356
|
+
|
4357
|
+
options = {
|
4358
|
+
light_level: -1,
|
4359
|
+
light_level_float: 5000.0,
|
4360
|
+
option: 1
|
4361
|
+
}
|
4362
|
+
|
4363
|
+
super(options.merge h)
|
4364
|
+
|
4365
|
+
end
|
4366
|
+
|
4367
|
+
end
|
4368
|
+
|
4369
|
+
# Category: Sensors
|
4370
|
+
#
|
4371
|
+
class DeviceOrientationConstraint < Constraint
|
4372
|
+
|
4373
|
+
def initialize(h={})
|
4374
|
+
|
4375
|
+
options = {
|
4376
|
+
portrait: true
|
4377
|
+
}
|
4378
|
+
|
4379
|
+
super(options.merge h)
|
4380
|
+
|
4381
|
+
end
|
4382
|
+
|
4383
|
+
end
|
4384
|
+
|
4385
|
+
# Category: Sensors
|
4386
|
+
#
|
4387
|
+
class ProximitySensorConstraint < Constraint
|
4388
|
+
|
4389
|
+
def initialize(h={})
|
4390
|
+
|
4391
|
+
options = {
|
4392
|
+
near: true
|
4393
|
+
}
|
4394
|
+
|
4395
|
+
super(options.merge h)
|
4396
|
+
|
4397
|
+
end
|
2996
4398
|
|
2997
4399
|
end
|