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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 79ad74c909d44b5bc3ddd5a5f65a2359cf385de96cd9e504cf30ce390ab2252f
4
- data.tar.gz: 71ab0f9b2267ea514859f4ebc9525e4cb5c8389895ccf85df2653a495c7bc104
3
+ metadata.gz: dfb49da8914ecdd5cc21ca0223801fa0d432890a3df4c352ab7c3914c1bd63fe
4
+ data.tar.gz: 9f402e6d1c9dbd17f5cb7d3741bcc7c487461a5438adf3cba81a71df9feb50f9
5
5
  SHA512:
6
- metadata.gz: 8f514b4bc19ddc8b00d8794fe7802779c332f371072db40c30f6a247316764b43306919e571256c5200451965aa9629312e30c82d96838a78d5f4658df22bf95
7
- data.tar.gz: 6c4b78db5f22aa70860c34eb9a046909805a93924dc2fb3c7bcae45ced4d552b04e3c05645a1ac54135b220fae189641352820b90f00b78ae00506701ce3dc4d
6
+ metadata.gz: 0753ef46f3cdbc1e5a8fb6539747e662a2e537089aa83e32ecf47c89334b1acb71ced47f77230e1fcae00314d8dd70e8e4d37380c27f25ebb0ccafe837121daa
7
+ data.tar.gz: e78f3fc06bcdbd1685de98d5473b2564d904a722053527505002f5a5bbfa43e51e99832d2a9a29eb5a12d3e9bab94d91429f78628625e74acbae6876b909f43a
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -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: @title,
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 (not yet implemented)
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).each do |x|
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.new h
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
- s, _ = RXFHelper.read(obj)
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
- import_xml(text_to_xml(s))
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
- @h = JSON.parse(s, symbolize_names: true).to_snake_case
395
- puts ('@h: ' + @h.pretty_inspect).debug if @debug
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.pretty_inspect).debug if @debug
400
- m = Macro.new(debug: @debug)
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
- puts 'after doc' if @debug
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: @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:)/); a.shift
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
- def to_h()
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
- a = @h[:days_of_week]
1018
- a.unshift a.pop
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
- dow = a.map.with_index {|x, i| x ? i : nil }.compact.join(',')
1358
+ a = Date::ABBR_DAYNAMES
1021
1359
 
1022
- s = "%s %s * * %s" % [@h[:minute], @h[:hour], dow]
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
- if $debug then
1025
- puts 's: ' + s.inspect
1026
- puts 'detail: ' + detail.inspect
1027
- puts '@h: ' + @h.inspect
1028
- end
1363
+ "at %s on %s" % [time, days.join(', ')]
1364
+ end
1365
+
1366
+ private
1367
+
1368
+ def time()
1029
1369
 
1030
- ChronicCron.new(s, detail[:time]).to_time == detail[:time]
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 < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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 GPSEnabledTrigger < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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 < Trigger
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
- class FlipDeviceTrigger < Trigger
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 < Trigger
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