ruby-macrodroid 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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