ruby-macrodroid 0.7.10 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,148 @@
1
+ # file: ruby-macrodroid/base.rb
2
+
3
+ # This file contains the following classes:
4
+ #
5
+ # ## Object class
6
+ #
7
+ # MacroObject
8
+ #
9
+
10
+
11
+ module Params
12
+
13
+ refine Hash do
14
+
15
+ # turns keys from camelCase into snake_case
16
+
17
+ def to_snake_case(h=self)
18
+
19
+ h.inject({}) do |r, x|
20
+
21
+ key, value = x
22
+ #puts 'value: ' + value.inspect
23
+
24
+ val = if value.is_a?(Hash) then
25
+ to_snake_case(value)
26
+ elsif value.is_a?(Array) and value.first.is_a? Hash
27
+ value.map {|row| to_snake_case(row)}
28
+ else
29
+ value
30
+ end
31
+
32
+ r.merge key.to_s.sub(/^m_/,'').gsub(/[A-Z][a-z]/){|x| '_' +
33
+ x.downcase}.gsub(/[a-z][A-Z]/){|x| x[0] + '_' + x[1].downcase}\
34
+ .downcase.to_sym => val
35
+
36
+ end
37
+ end
38
+
39
+ # turns keys from snake_case to CamelCase
40
+ def to_camel_case(h=self)
41
+
42
+ h.inject({}) do |r,x|
43
+
44
+ key, value = x
45
+
46
+ val = if value.is_a?(Hash) then
47
+ to_camel_case(value)
48
+ elsif value.is_a?(Array) and value.first.is_a? Hash
49
+ value.map {|row| to_camel_case(row)}
50
+ else
51
+ value
52
+ end
53
+
54
+ r.merge({key.to_s.gsub(/(?<!^m)_[a-z]/){|x| x[-1].upcase} => val})
55
+ end
56
+
57
+ end
58
+
59
+
60
+ end
61
+
62
+ end
63
+
64
+ class MacroObject
65
+ using ColouredText
66
+
67
+ attr_reader :type, :siguid
68
+ attr_accessor :options
69
+
70
+ def initialize(h={})
71
+
72
+ $env ||= {}
73
+
74
+ @attributes = %i(constraint_list is_or_condition is_disabled siguid)
75
+ @h = {constraint_list: [], is_or_condition: false,
76
+ is_disabled: false, siguid: nil}.merge(h)
77
+ @list = []
78
+
79
+ # fetch the class name and convert from camelCase to snake_eyes
80
+ @type = self.class.to_s.sub(/Trigger|Action$/,'')\
81
+ .gsub(/\B[A-Z][a-z]/){|x| '_' + x.downcase}\
82
+ .gsub(/[a-z][A-Z]/){|x| x[0] + '_' + x[1].downcase}\
83
+ .downcase.to_sym
84
+ @constraints = []
85
+ end
86
+
87
+ def to_h()
88
+
89
+ h = @h
90
+
91
+ h2 = h.inject({}) do |r,x|
92
+ puts 'x: ' + x.inspect if @debug
93
+ key, value = x
94
+ puts 'key: ' + key.inspect if @debug
95
+ new_key = key.to_s.gsub(/\w_\w/){|x| x[0] + x[-1].upcase}
96
+ new_key = new_key.prepend 'm_' unless @list.include? new_key
97
+ new_key = 'm_SIGUID' if new_key == 'm_siguid'
98
+ r.merge(new_key => value)
99
+ end
100
+
101
+ h2.merge('m_classType' => self.class.to_s)
102
+
103
+ end
104
+
105
+ def siguid()
106
+ @h[:siguid]
107
+ end
108
+
109
+ def to_s(colour: false)
110
+
111
+ h = @h.clone
112
+ h.delete :macro
113
+ @s ||= "#<%s %s>" % [self.class, h.inspect]
114
+ operator = @h[:is_or_condition] ? 'OR' : 'AND'
115
+ constraints = @constraints.map \
116
+ {|x| x.to_summary(colour: colour)}.join(" %s " % operator)
117
+
118
+ @s + constraints
119
+
120
+ end
121
+
122
+ alias to_summary to_s
123
+
124
+ protected
125
+
126
+ def filter(options, h)
127
+
128
+ (h.keys - (options.keys + @attributes.to_a)).each {|key| h.delete key }
129
+ return h
130
+
131
+ end
132
+
133
+ def uuid()
134
+ UUID.new.generate
135
+ end
136
+
137
+ def object(h={})
138
+
139
+ puts ('inside object h:' + h.inspect).debug if @debug
140
+ klass = Object.const_get h[:class_type]
141
+ puts klass.inspect.highlight if $debug
142
+
143
+ klass.new h
144
+
145
+ end
146
+
147
+ end
148
+
@@ -0,0 +1,1558 @@
1
+ # file: ruby-macrodroid/constraints.rb
2
+
3
+ # This file contains the following classes:
4
+ #
5
+ #
6
+ # ## Trigger classes
7
+ #
8
+ # Trigger WebHookTrigger WifiConnectionTrigger
9
+ # ApplicationInstalledRemovedTrigger ApplicationLaunchedTrigger
10
+ # BatteryLevelTrigger BatteryTemperatureTrigger PowerButtonToggleTrigger
11
+ # ExternalPowerTrigger CallActiveTrigger IncomingCallTrigger
12
+ # OutgoingCallTrigger CallEndedTrigger CallMissedTrigger IncomingSMSTrigger
13
+ # WebHookTrigger WifiConnectionTrigger BluetoothTrigger HeadphonesTrigger
14
+ # SignalOnOffTrigger UsbDeviceConnectionTrigger WifiSSIDTrigger
15
+ # CalendarTrigger TimerTrigger StopwatchTrigger DayTrigger
16
+ # RegularIntervalTrigger DeviceEventsTrigger AirplaneModeTrigger
17
+ # AutoSyncChangeTrigger DayDreamTrigger DockTrigger FailedLoginTrigger
18
+ # GPSEnabledTrigger MusicPlayingTrigger DeviceUnlockedTrigger
19
+ # AutoRotateChangeTrigger ClipboardChangeTrigger BootTrigger
20
+ # IntentReceivedTrigger NotificationTrigger ScreenOnOffTrigger
21
+ # SilentModeTrigger WeatherTrigger GeofenceTrigger SunriseSunsetTrigger
22
+ # SensorsTrigger ActivityRecognitionTrigger ProximityTrigger
23
+ # ShakeDeviceTrigger FlipDeviceTrigger OrientationTrigger
24
+ # FloatingButtonTrigger ShortcutTrigger VolumeButtonTrigger
25
+ # MediaButtonPressedTrigger SwipeTrigger
26
+ #
27
+
28
+
29
+ class Trigger < MacroObject
30
+ using Params
31
+
32
+ attr_reader :constraints
33
+
34
+ def initialize(h={})
35
+ super({fakeIcon: 0}.merge(h))
36
+ @list << 'fakeIcon'
37
+
38
+ # fetch the constraints
39
+ @constraints = @h[:constraint_list].map do |constraint|
40
+ object(constraint.to_snake_case)
41
+ end
42
+
43
+ end
44
+
45
+ def match?(detail={}, model=nil)
46
+
47
+ # only match where the key exists in the trigger object
48
+ detail.select {|k,v| @h.include? k }.all? {|key,value| @h[key] == value}
49
+
50
+ end
51
+
52
+ end
53
+
54
+
55
+
56
+
57
+ # Category: Applications
58
+ #
59
+ # Also known as Wifi State Change
60
+ #
61
+ # wifi_state options:
62
+ # 0 - Wifi Enabled
63
+ # 1 - Wifi Disabled
64
+ # 2 - Connected to network
65
+ # ssid_list options:
66
+ # ["Any Network"]
67
+ # ["some Wifi SSID"] - 1 or more SSID can be supplied
68
+ # 3 - Disconnected from network
69
+ # ssid_list options:
70
+ # ["Any Network"]
71
+ # ["some Wifi SSID"] - 1 or more SSID can be supplied
72
+
73
+ class WifiConnectionTrigger < Trigger
74
+
75
+ def initialize(h={})
76
+
77
+ options = {
78
+ ssid_list: [""],
79
+ wifi_state: 2
80
+ }
81
+
82
+ super(options.merge h)
83
+
84
+ end
85
+
86
+ def to_s(colour: false)
87
+ 'WifiConnectionTrigger ' + @h.inspect
88
+ end
89
+
90
+ alias to_summary to_s
91
+ end
92
+
93
+ # Category: Applications
94
+ #
95
+ class ApplicationInstalledRemovedTrigger < Trigger
96
+
97
+ def initialize(h={})
98
+
99
+ options = {
100
+ application_name_list: [],
101
+ package_name_list: [],
102
+ installed: true,
103
+ application_option: 0,
104
+ updated: false
105
+ }
106
+
107
+ super(options.merge h)
108
+
109
+ end
110
+
111
+ def to_s(colour: false)
112
+ 'ApplicationInstalledRemovedTrigger ' + @h.inspect
113
+ end
114
+
115
+ alias to_summary to_s
116
+ end
117
+
118
+ # Category: Applications
119
+ #
120
+ class ApplicationLaunchedTrigger < Trigger
121
+
122
+ def initialize(h={})
123
+
124
+ options = {
125
+ application_name_list: ["Chrome"],
126
+ package_name_list: ["com.android.chrome"],
127
+ launched: true
128
+ }
129
+
130
+ super(options.merge h)
131
+
132
+ end
133
+
134
+ def to_s(colour: false)
135
+ 'ApplicationLaunchedTrigger ' + @h.inspect
136
+ end
137
+
138
+ alias to_summary to_s
139
+ end
140
+
141
+ # Category: Battery/Power
142
+ #
143
+ class BatteryLevelTrigger < Trigger
144
+
145
+ def initialize(h={})
146
+
147
+ options = {
148
+ battery_level: 50,
149
+ decreases_to: true,
150
+ option: 0
151
+ }
152
+
153
+ super(options.merge h)
154
+
155
+ end
156
+
157
+ def to_s(colour: false)
158
+ operator = @h[:decreases_to] ? '<=' : '>='
159
+ "Battery %s %s%%" % [operator, @h[:battery_level]]
160
+ end
161
+
162
+ end
163
+
164
+ # Category: Battery/Power
165
+ #
166
+ class BatteryTemperatureTrigger < Trigger
167
+
168
+ def initialize(h={})
169
+
170
+ options = {
171
+ decreases_to: true,
172
+ option: 0,
173
+ temperature: 30
174
+ }
175
+
176
+ super(options.merge h)
177
+
178
+ end
179
+
180
+ def to_s(colour: false)
181
+ 'BatteryTemperatureTrigger ' + @h.inspect
182
+ end
183
+
184
+ alias to_summary to_s
185
+ end
186
+
187
+ # Category: Battery/Power
188
+ #
189
+ class PowerButtonToggleTrigger < Trigger
190
+
191
+ def initialize(h={})
192
+
193
+ options = {
194
+ num_toggles: 3
195
+ }
196
+
197
+ super(options.merge h)
198
+
199
+ end
200
+
201
+ def to_s(colour: false)
202
+ 'PowerButtonToggleTrigger ' + @h.inspect
203
+ end
204
+
205
+ alias to_summary to_s
206
+ end
207
+
208
+
209
+ # Category: Battery/Power
210
+ #
211
+ class ExternalPowerTrigger < Trigger
212
+
213
+ def initialize(h={})
214
+
215
+ options = {
216
+ power_connected_options: [true, true, true],
217
+ has_set_usb_option: true,
218
+ power_connected: true,
219
+ has_set_new_power_connected_options: true
220
+ }
221
+
222
+ super(options.merge h)
223
+
224
+ end
225
+
226
+ def to_s(colour: false)
227
+
228
+ return 'Power Disconnected' unless @h[:power_connected]
229
+
230
+ status = 'Power Connectd'
231
+ options = if @h[:power_connected_options].all? then
232
+ 'Any'
233
+ else
234
+
235
+ a = ['Wired (Fast Charge)', 'Wireless', 'Wired (Slow Charge)']
236
+ @h[:power_connected_options].map.with_index {|x,i| x ? i : nil}\
237
+ .compact.map {|i| a[i] }.join(' + ')
238
+
239
+ end
240
+
241
+ "%s: %s" % [status, options]
242
+
243
+ end
244
+
245
+ alias to_summary to_s
246
+
247
+ end
248
+
249
+ # Category: Call/SMS
250
+ #
251
+ class CallActiveTrigger < Trigger
252
+
253
+ def initialize(h={})
254
+
255
+ options = {
256
+ contact_list: [{:m_id=>"-2", :m_lookupKey=>"-2", :m_name=>"[Any Number]"}],
257
+ secondary_class_type: 'CallActiveTrigger',
258
+ signal_on: true
259
+ }
260
+
261
+ super(options.merge h)
262
+
263
+ end
264
+
265
+ def to_s(colour: false)
266
+ 'CallActiveTrigger ' + @h.inspect
267
+ end
268
+
269
+ alias to_summary to_s
270
+ end
271
+
272
+ # Category: Call/SMS
273
+ #
274
+ class IncomingCallTrigger < Trigger
275
+
276
+ def initialize(h={})
277
+
278
+ options = {
279
+ incoming_call_from_list: [{:m_id=>"-2", :m_lookupKey=>"-2", :m_name=>"[Any Number]"}],
280
+ group_id_list: [],
281
+ group_name_list: [],
282
+ option: 0,
283
+ phone_number_exclude: false
284
+ }
285
+
286
+ super(options.merge h)
287
+
288
+ end
289
+
290
+ def to_s(colour: false)
291
+ caller = @h[:incoming_call_from_list].map {|x| "%s" % x[:name]}.join(', ')
292
+ "Call Incoming [%s]" % caller
293
+ end
294
+
295
+ alias to_summary to_s
296
+ end
297
+
298
+ # Category: Call/SMS
299
+ #
300
+ class OutgoingCallTrigger < Trigger
301
+
302
+ def initialize(h={})
303
+
304
+ options = {
305
+ outgoing_call_to_list: [{:m_id=>"-2", :m_lookupKey=>"-2", :m_name=>"[Any Number]"}],
306
+ group_id_list: [],
307
+ group_name_list: [],
308
+ option: 0,
309
+ phone_number_exclude: false
310
+ }
311
+
312
+ super(options.merge h)
313
+
314
+ end
315
+
316
+ def to_s(colour: false)
317
+ 'OutgoingCallTrigger ' + @h.inspect
318
+ end
319
+
320
+ alias to_summary to_s
321
+ end
322
+
323
+ # Category: Call/SMS
324
+ #
325
+ class CallEndedTrigger < Trigger
326
+
327
+ def initialize(h={})
328
+
329
+ options = {
330
+ contact_list: [{:m_id=>"-2", :m_lookupKey=>"-2", :m_name=>"[Any Number]"}],
331
+ group_id_list: [],
332
+ group_name_list: [],
333
+ option: 0,
334
+ phone_number_exclude: false
335
+ }
336
+
337
+ super(options.merge h)
338
+
339
+ end
340
+
341
+ def to_s(colour: false)
342
+ 'CallEndedTrigger ' + @h.inspect
343
+ end
344
+
345
+ alias to_summary to_s
346
+ end
347
+
348
+ # Category: Call/SMS
349
+ #
350
+ class CallMissedTrigger < Trigger
351
+
352
+ def initialize(h={})
353
+
354
+ options = {
355
+ contact_list: [{:m_id=>"-2", :m_lookupKey=>"-2", :m_name=>"[Any Number]"}]
356
+ }
357
+
358
+ super(options.merge h)
359
+
360
+ end
361
+
362
+ def to_s(colour: false)
363
+ 'CallMissedTrigger ' + @h.inspect
364
+ end
365
+
366
+ alias to_summary to_s
367
+ end
368
+
369
+ # Category: Call/SMS
370
+ #
371
+ class IncomingSMSTrigger < Trigger
372
+
373
+ def initialize(h={})
374
+
375
+ options = {
376
+ sms_from_list: [{:m_id=>"-2", :m_lookupKey=>"-2", :m_name=>"[Any Number]"}],
377
+ group_id_list: [],
378
+ group_name_list: [],
379
+ sms_content: '',
380
+ option: 0,
381
+ excludes: false,
382
+ exact_match: false,
383
+ enable_regex: false,
384
+ sms_number_exclude: false
385
+ }
386
+
387
+ super(options.merge h)
388
+
389
+ end
390
+
391
+ def to_s(colour: false)
392
+ 'IncomingSMSTrigger ' + @h.inspect
393
+ end
394
+
395
+ alias to_summary to_s
396
+ end
397
+
398
+ # Category: Connectivity
399
+ #
400
+ class WebHookTrigger < Trigger
401
+
402
+ def initialize(h={})
403
+
404
+ options = {
405
+ identifier: ''
406
+ }
407
+
408
+ super(options.merge h)
409
+
410
+ end
411
+
412
+ def to_s(colour: false)
413
+
414
+ url = "https://trigger.macrodroid.com/%s/%s" % \
415
+ [@h[:macro].deviceid, @h[:identifier]]
416
+ @s = 'WebHook (Url)' + "\n " + url
417
+ super()
418
+
419
+ end
420
+
421
+ alias to_summary to_s
422
+ end
423
+
424
+ # Category: Connectivity
425
+ #
426
+ class WifiConnectionTrigger < Trigger
427
+
428
+ def initialize(h={})
429
+
430
+ options = {
431
+ ssid_list: [],
432
+ wifi_state: 0
433
+ }
434
+
435
+ super(options.merge h)
436
+
437
+ end
438
+
439
+ def to_s(colour: false)
440
+ access_point = @h[:ssid_list].first
441
+ 'Connected to network ' + access_point
442
+ end
443
+
444
+ alias to_summary to_s
445
+ end
446
+
447
+ # Category: Connectivity
448
+ #
449
+ class BluetoothTrigger < Trigger
450
+
451
+ def initialize(h={})
452
+
453
+ options = {
454
+ device_name: 'Any Device',
455
+ bt_state: 0,
456
+ any_device: false
457
+ }
458
+
459
+ super(options.merge h)
460
+
461
+ end
462
+
463
+ def to_s(colour: false)
464
+ 'BluetoothTrigger ' + @h.inspect
465
+ end
466
+
467
+ alias to_summary to_s
468
+ end
469
+
470
+ # Category: Connectivity
471
+ #
472
+ class HeadphonesTrigger < Trigger
473
+
474
+ def initialize(h={})
475
+
476
+ options = {
477
+ headphones_connected: true,
478
+ mic_option: 0
479
+ }
480
+
481
+ super(options.merge h)
482
+
483
+ end
484
+
485
+ def to_s(colour: false)
486
+ 'HeadphonesTrigger ' + @h.inspect
487
+ end
488
+
489
+ alias to_summary to_s
490
+ end
491
+
492
+ # Category: Connectivity
493
+ #
494
+ class SignalOnOffTrigger < Trigger
495
+
496
+ def initialize(h={})
497
+
498
+ options = {
499
+ signal_on: true
500
+ }
501
+
502
+ super(options.merge h)
503
+
504
+ end
505
+
506
+ def to_s(colour: false)
507
+ 'SignalOnOffTrigger ' + @h.inspect
508
+ end
509
+
510
+ alias to_summary to_s
511
+ end
512
+
513
+ # Category: Connectivity
514
+ #
515
+ class UsbDeviceConnectionTrigger < Trigger
516
+
517
+ def initialize(h={})
518
+
519
+ options = {
520
+ option: 0
521
+ }
522
+
523
+ super(options.merge h)
524
+
525
+ end
526
+
527
+ def to_s(colour: false)
528
+ 'UsbDeviceConnectionTrigger ' + @h.inspect
529
+ end
530
+
531
+ alias to_summary to_s
532
+ end
533
+
534
+ # Category: Connectivity
535
+ #
536
+ # Also known as Wifi SSID Transition
537
+ #
538
+ # options:
539
+ # in_range: true | false
540
+ # wifi_cell_info: {display_name: "some Wifi SSID",
541
+ # ssid: "some Wifi SSID"} - 1 or more allowed
542
+ #
543
+ class WifiSSIDTrigger < Trigger
544
+
545
+ def initialize(h={})
546
+
547
+ options = {
548
+ wifi_cell_info_list: [{:display_name=>"", :ssid=>""}],
549
+ ssid_list: [],
550
+ in_range: true
551
+ }
552
+
553
+ super(options.merge h)
554
+
555
+ end
556
+
557
+ def to_h()
558
+
559
+ h = super()
560
+ val = h[:m_inRange]
561
+
562
+ h[:m_InRange] = val
563
+ h.delete :m_inRange
564
+
565
+ return h
566
+
567
+ end
568
+
569
+ def to_s(colour: false)
570
+ 'WifiSSIDTrigger ' + @h.inspect
571
+ end
572
+
573
+ alias to_summary to_s
574
+ end
575
+
576
+ # Category: Date/Time
577
+ #
578
+ class CalendarTrigger < Trigger
579
+
580
+ def initialize(h={})
581
+
582
+ options = {
583
+ title_text: '',
584
+ detail_text: '',
585
+ calendar_name: 'Contacts',
586
+ calendar_id: '3',
587
+ availability: 0,
588
+ check_in_advance: false,
589
+ advance_time_seconds: 0,
590
+ event_start: true,
591
+ ignore_all_day: false,
592
+ negative_advance_check: false,
593
+ enable_regex: false
594
+ }
595
+
596
+ super(options.merge h)
597
+
598
+ end
599
+
600
+ def to_s(colour: false)
601
+ 'CalendarTrigger ' + @h.inspect
602
+ end
603
+
604
+ alias to_summary to_s
605
+ end
606
+
607
+ # Category: Date/Time
608
+ #
609
+ class TimerTrigger < Trigger
610
+ using ColouredText
611
+
612
+
613
+ def initialize(h={})
614
+
615
+ puts 'TimerTrigger h: ' + h.inspect if $debug
616
+
617
+ if h[:days] then
618
+
619
+ days = [false] * 7
620
+
621
+ h[:days].split(/, */).each do |x|
622
+
623
+ r = Date::DAYNAMES.grep /#{x}/i
624
+ i = Date::DAYNAMES.index(r.first)
625
+ days[i-1] = true
626
+
627
+ end
628
+
629
+ h[:days_of_week] = days
630
+
631
+ end
632
+
633
+ if h[:time] then
634
+
635
+ t = Time.parse(h[:time])
636
+ h[:hour], h[:minute] = t.hour, t.min
637
+
638
+ end
639
+
640
+ #puts ('h: ' + h.inspect).debug
641
+
642
+ @options = {
643
+ alarm_id: uuid(),
644
+ days_of_week: [false, false, false, false, false, false, false],
645
+ minute: 10,
646
+ hour: 7,
647
+ use_alarm: false
648
+ }
649
+
650
+ #super(options.merge filter(options, h))
651
+ super(@options.merge h)
652
+
653
+ end
654
+
655
+ def match?(detail={time: $env[:time]}, model=nil)
656
+
657
+ time() == detail[:time]
658
+
659
+ end
660
+
661
+ # sets the environmental conditions for this trigger to fire
662
+ #
663
+ def set_env()
664
+ $env[:time] = time()
665
+ end
666
+
667
+ def to_pc()
668
+ "time.is? '%s'" % self.to_s.gsub(',', ' or')
669
+ end
670
+
671
+ def to_s(colour: false)
672
+
673
+ dow = @h[:days_of_week]
674
+
675
+ wd = Date::ABBR_DAYNAMES
676
+ a = (wd[1..-1] << wd.first)
677
+
678
+ a2 = dow.map.with_index.to_a
679
+ start = a2.find {|x,i| x}.last
680
+ r = a2[start..-1].take_while {|x,i| x == true}
681
+ r2 = a2[start..-1].select {|x,i| x}
682
+
683
+ days = if r == r2 then
684
+
685
+ x1, x2 = a2[start].last, a2[r.length-1].last
686
+
687
+ if (x2 - x1) >= 2 then
688
+ "%s-%s" % [a[x1],a[x2]]
689
+ else
690
+ a.zip(dow).select {|_,b| b}.map(&:first).join(', ')
691
+ end
692
+ else
693
+ a.zip(dow).select {|_,b| b}.map(&:first).join(', ')
694
+ end
695
+
696
+ time = Time.parse("%s:%s" % [@h[:hour], @h[:minute]]).strftime("%H:%M")
697
+
698
+ "%s %s" % [time, days]
699
+ end
700
+
701
+ alias to_summary to_s
702
+
703
+ private
704
+
705
+ def time()
706
+
707
+ a = @h[:days_of_week].clone
708
+ a.unshift a.pop
709
+
710
+ dow = a.map.with_index {|x, i| x ? i : nil }.compact.join(',')
711
+ s = "%s %s * * %s" % [@h[:minute], @h[:hour], dow]
712
+ recent_time = ($env && $env[:time]) ? $env[:time] : Time.now
713
+ ChronicCron.new(s, recent_time).to_time
714
+
715
+ end
716
+
717
+ end
718
+
719
+ # Category: Date/Time
720
+ #
721
+ class StopwatchTrigger < Trigger
722
+
723
+ def initialize(h={})
724
+
725
+ options = {
726
+ stopwatch_name: 'timer1',
727
+ seconds: 240
728
+ }
729
+
730
+ super(options.merge h)
731
+
732
+ end
733
+
734
+ def to_s(colour: false)
735
+ 'StopwatchTrigger ' + @h.inspect
736
+ end
737
+
738
+ alias to_summary to_s
739
+ end
740
+
741
+ # Category: Date/Time
742
+ #
743
+ # Also known as Day of Week/Month
744
+ #
745
+ # month_of_year equal to 0 means it occurs every month
746
+ # day_of_week starts with a Monday (value is 0)
747
+ #
748
+ class DayTrigger < Trigger
749
+
750
+ def initialize(h={})
751
+
752
+ options = {
753
+ alarm_id: uuid(),
754
+ hour: 9,
755
+ minute: 0,
756
+ month_of_year: 0,
757
+ option: 0,
758
+ day_of_week: 2,
759
+ day_of_month: 0,
760
+ use_alarm: false
761
+ }
762
+
763
+ super(options.merge h)
764
+
765
+ end
766
+
767
+ def to_s(colour: false)
768
+ 'DayTrigger ' + @h.inspect
769
+ end
770
+
771
+ alias to_summary to_s
772
+ end
773
+
774
+ # Category: Date/Time
775
+ #
776
+ # Regular Interval
777
+ #
778
+ class RegularIntervalTrigger < Trigger
779
+
780
+ def initialize(h={})
781
+
782
+ options = {
783
+ ignore_reference_start_time: false,
784
+ minutes: 0,
785
+ seconds: 7200,
786
+ start_hour: 9,
787
+ start_minute: 10,
788
+ use_alarm: false
789
+ }
790
+
791
+ super(options.merge h)
792
+
793
+ end
794
+
795
+ def to_s(colour: false)
796
+
797
+ interval = Subunit.new(units={minutes:60, hours:60}, \
798
+ seconds: @h[:seconds]).strfunit("%c")
799
+ 'Regular Interval ' + "\n Interval: " + interval
800
+
801
+ end
802
+
803
+ alias to_summary to_s
804
+ end
805
+
806
+ class DeviceEventsTrigger < Trigger
807
+
808
+ def initialize(h={})
809
+ super(h)
810
+ @group = 'device_events'
811
+ end
812
+
813
+ end
814
+
815
+ # Category: Device Events
816
+ #
817
+ # Airplane Mode Changed
818
+ #
819
+ # options:
820
+ # Airplane Mode Enabled
821
+ # Airplane Mode Disabled
822
+ #
823
+ # shorthand example:
824
+ # airplanemode: enabled
825
+ #
826
+ class AirplaneModeTrigger < DeviceEventsTrigger
827
+
828
+ def initialize(h={})
829
+
830
+ options = {
831
+ airplane_mode_enabled: true
832
+ }
833
+
834
+ super(options.merge h)
835
+
836
+ end
837
+
838
+ def to_s(colour: false)
839
+ 'AirplaneModeTrigger ' + @h.inspect
840
+ end
841
+
842
+ alias to_summary to_s
843
+ end
844
+
845
+ # Category: Device Events
846
+ #
847
+ class AutoSyncChangeTrigger < DeviceEventsTrigger
848
+
849
+ def initialize(h={})
850
+
851
+ options = {
852
+ option: 0
853
+ }
854
+
855
+ super(options.merge h)
856
+
857
+ end
858
+
859
+ def to_s(colour: false)
860
+ 'AutoSyncChangeTrigger ' + @h.inspect
861
+ end
862
+
863
+ alias to_summary to_s
864
+ end
865
+
866
+ # Category: Device Events
867
+ #
868
+ class DayDreamTrigger < DeviceEventsTrigger
869
+
870
+ def initialize(h={})
871
+
872
+ options = {
873
+ day_dream_enabled: true
874
+ }
875
+
876
+ super(options.merge h)
877
+
878
+ end
879
+
880
+ def to_s(colour: false)
881
+ 'DayDreamTrigger ' + @h.inspect
882
+ end
883
+
884
+ alias to_summary to_s
885
+ end
886
+
887
+ # Category: Device Events
888
+ #
889
+ class DockTrigger < DeviceEventsTrigger
890
+
891
+ def initialize(h={})
892
+
893
+ options = {
894
+ dock_type: 0
895
+ }
896
+
897
+ super(options.merge h)
898
+
899
+ end
900
+
901
+ def to_s(colour: false)
902
+ 'DockTrigger ' + @h.inspect
903
+ end
904
+
905
+ alias to_summary to_s
906
+ end
907
+
908
+ # Category: Device Events
909
+ #
910
+ class FailedLoginTrigger < DeviceEventsTrigger
911
+
912
+ def initialize(h={})
913
+
914
+ options = {
915
+ num_failures: 1
916
+ }
917
+
918
+ super(options.merge h)
919
+
920
+ end
921
+
922
+ def to_pc()
923
+ 'failed_login?'
924
+ end
925
+
926
+ def to_s(colour: false)
927
+ 'Failed Login Attempt'
928
+ end
929
+ end
930
+
931
+ # Category: Device Events
932
+ #
933
+ class GPSEnabledTrigger < DeviceEventsTrigger
934
+
935
+ def initialize(h={})
936
+
937
+ options = {
938
+ gps_mode_enabled: true
939
+ }
940
+
941
+ super(options.merge h)
942
+
943
+ end
944
+
945
+ def to_s(colour: false)
946
+ 'GPSEnabledTrigger ' + @h.inspect
947
+ end
948
+
949
+ alias to_summary to_s
950
+ end
951
+
952
+ # Category: Device Events
953
+ #
954
+ class MusicPlayingTrigger < DeviceEventsTrigger
955
+
956
+ def initialize(h={})
957
+
958
+ options = {
959
+ option: 0
960
+ }
961
+
962
+ super(options.merge h)
963
+
964
+ end
965
+
966
+ def to_s(colour: false)
967
+ 'MusicPlayingTrigger ' + @h.inspect
968
+ end
969
+
970
+ alias to_summary to_s
971
+ end
972
+
973
+
974
+ # Category: Device Events
975
+ #
976
+ class DeviceUnlockedTrigger < DeviceEventsTrigger
977
+
978
+ def initialize(h={})
979
+
980
+ options = {
981
+ }
982
+
983
+ super(options.merge h)
984
+
985
+ end
986
+
987
+ def to_s(colour: false)
988
+ 'Screen Unlocked'
989
+ end
990
+
991
+ alias to_summary to_s
992
+
993
+ end
994
+
995
+ # Category: Device Events
996
+ #
997
+ class AutoRotateChangeTrigger < DeviceEventsTrigger
998
+
999
+ def initialize(h={})
1000
+
1001
+ options = {
1002
+ option: 0
1003
+ }
1004
+
1005
+ super(options.merge h)
1006
+
1007
+ end
1008
+
1009
+ def to_s(colour: false)
1010
+ 'AutoRotateChangeTrigger ' + @h.inspect
1011
+ end
1012
+
1013
+ alias to_summary to_s
1014
+ end
1015
+
1016
+ # Category: Device Events
1017
+ #
1018
+ class ClipboardChangeTrigger < DeviceEventsTrigger
1019
+
1020
+ def initialize(h={})
1021
+
1022
+ options = {
1023
+ text: '',
1024
+ enable_regex: false
1025
+ }
1026
+
1027
+ super(options.merge h)
1028
+
1029
+ end
1030
+
1031
+ def to_s(colour: false)
1032
+ 'ClipboardChangeTrigger ' + @h.inspect
1033
+ end
1034
+
1035
+ alias to_summary to_s
1036
+ end
1037
+
1038
+ # Category: Device Events
1039
+ #
1040
+ class BootTrigger < DeviceEventsTrigger
1041
+
1042
+ def initialize(h={})
1043
+
1044
+ options = {
1045
+ }
1046
+
1047
+ super(options.merge h)
1048
+
1049
+ end
1050
+
1051
+ def to_s(colour: false)
1052
+ 'BootTrigger ' + @h.inspect
1053
+ end
1054
+
1055
+ alias to_summary to_s
1056
+ end
1057
+
1058
+ # Category: Device Events
1059
+ #
1060
+ class IntentReceivedTrigger < DeviceEventsTrigger
1061
+
1062
+ def initialize(h={})
1063
+
1064
+ options = {
1065
+ action: '',
1066
+ extra_params: [],
1067
+ extra_value_patterns: [],
1068
+ extra_variables: [],
1069
+ enable_regex: false
1070
+ }
1071
+
1072
+ super(options.merge h)
1073
+
1074
+ end
1075
+
1076
+ def to_s(colour: false)
1077
+ 'IntentReceivedTrigger ' + @h.inspect
1078
+ end
1079
+
1080
+ alias to_summary to_s
1081
+ end
1082
+
1083
+ # Category: Device Events
1084
+ #
1085
+ class NotificationTrigger < DeviceEventsTrigger
1086
+
1087
+ def initialize(h={})
1088
+
1089
+ options = {
1090
+ text_content: '',
1091
+ package_name_list: ["Any Application"],
1092
+ application_name_list: ["Any Application"],
1093
+ exclude_apps: false,
1094
+ ignore_ongoing: true,
1095
+ option: 0,
1096
+ exact_match: false,
1097
+ excludes: false,
1098
+ sound_option: 0,
1099
+ supress_multiples: true,
1100
+ enable_regex: false
1101
+ }
1102
+
1103
+ super(options.merge h)
1104
+
1105
+ end
1106
+
1107
+ def to_s(colour: false)
1108
+ s = (@h[:package_name_list] + @h[:application_name_list]).uniq.join(', ')
1109
+ 'Notification Received ' + "\n Any Content (%s)" % s
1110
+ end
1111
+
1112
+ alias to_summary to_s
1113
+ end
1114
+
1115
+ # Category: Device Events
1116
+ #
1117
+ class ScreenOnOffTrigger < DeviceEventsTrigger
1118
+
1119
+ def initialize(h={})
1120
+
1121
+ options = {
1122
+ screen_on: true
1123
+ }
1124
+
1125
+ super(options.merge h)
1126
+
1127
+ end
1128
+
1129
+ def to_s(colour: false)
1130
+ 'Screen ' + (@h[:screen_on] ? 'On' : 'Off')
1131
+ end
1132
+
1133
+ alias to_summary to_s
1134
+
1135
+ end
1136
+
1137
+ # Category: Device Events
1138
+ #
1139
+ class SilentModeTrigger < DeviceEventsTrigger
1140
+
1141
+ def initialize(h={})
1142
+
1143
+ options = {
1144
+ silent_enabled: true
1145
+ }
1146
+
1147
+ super(options.merge h)
1148
+
1149
+ end
1150
+
1151
+ def to_s(colour: false)
1152
+ 'SilentModeTrigger ' + @h.inspect
1153
+ end
1154
+
1155
+ alias to_summary to_s
1156
+ end
1157
+
1158
+ # Category: Location
1159
+ #
1160
+ class WeatherTrigger < Trigger
1161
+
1162
+ def initialize(h={})
1163
+
1164
+ options = {
1165
+ humidity_above: true,
1166
+ humidity_value: 50,
1167
+ option: 4,
1168
+ temp_below: true,
1169
+ temp_celcius: true,
1170
+ temperature: 0,
1171
+ weather_condition: 0,
1172
+ wind_speed_above: true,
1173
+ wind_speed_value: 0,
1174
+ wind_speed_value_mph: 0
1175
+ }
1176
+
1177
+ super(options.merge h)
1178
+
1179
+ end
1180
+
1181
+ def to_s(colour: false)
1182
+ 'WeatherTrigger ' + @h.inspect
1183
+ end
1184
+
1185
+ alias to_summary to_s
1186
+ end
1187
+
1188
+ # Category: Location
1189
+ #
1190
+ class GeofenceTrigger < Trigger
1191
+
1192
+ def initialize( h={}, geofences: {})
1193
+
1194
+ if h[:name] then
1195
+ puts ('geofences2: ' + geofences.inspect) if $debug
1196
+ found = geofences.find {|x| x.name.downcase == h[:name].downcase}
1197
+ h[:geofence_id] = found.id if found
1198
+
1199
+ end
1200
+
1201
+ options = {
1202
+ update_rate_text: '5 Minutes',
1203
+ geofence_id: '',
1204
+ geofence_update_rate_minutes: 5,
1205
+ trigger_from_unknown: false,
1206
+ enter_area: true
1207
+ }
1208
+
1209
+ super(options.merge filter(options, h))
1210
+ @geofences = geofences
1211
+
1212
+ end
1213
+
1214
+ def to_s(colour: false)
1215
+
1216
+ if $debug then
1217
+ puts ' @geofences: ' + @geofences.inspect
1218
+ puts '@h: ' + @h.inspect
1219
+ puts '@h[:geofence_id]: ' + @h[:geofence_id].inspect
1220
+ end
1221
+
1222
+ direction = @h[:enter_area] ? 'Entry' : 'Exit'
1223
+
1224
+ found = @geofences.find {|x| x.id == @h[:geofence_id]}
1225
+ puts 'found: ' + found.inspect if @debug
1226
+ label = found ? found.name : 'error: name not found'
1227
+
1228
+ "Geofence %s (%s)" % [direction, label]
1229
+
1230
+ end
1231
+
1232
+ end
1233
+
1234
+ # Category: Location
1235
+ #
1236
+ class SunriseSunsetTrigger < Trigger
1237
+
1238
+ def initialize(h={})
1239
+
1240
+ options = {
1241
+ option: 0,
1242
+ time_adjust_seconds: 0
1243
+ }
1244
+
1245
+ super(options.merge h)
1246
+
1247
+ end
1248
+
1249
+ def to_s(colour: false)
1250
+ 'SunriseSunsetTrigger ' + @h.inspect
1251
+ end
1252
+
1253
+ alias to_summary to_s
1254
+ end
1255
+
1256
+
1257
+ class SensorsTrigger < Trigger
1258
+
1259
+ def initialize(h={})
1260
+ super(h)
1261
+ @group = 'sensors'
1262
+ end
1263
+
1264
+ end
1265
+
1266
+ # Category: Sensors
1267
+ #
1268
+ class ActivityRecognitionTrigger < SensorsTrigger
1269
+
1270
+ def initialize(h={})
1271
+
1272
+ options = {
1273
+ confidence_level: 50,
1274
+ selected_index: 1
1275
+ }
1276
+
1277
+ super(options.merge h)
1278
+
1279
+ @activity = ['In Vehicle', 'On Bicycle', 'Running', 'Walking', 'Still']
1280
+
1281
+ end
1282
+
1283
+ def to_s(colour: false)
1284
+ activity = @activity[@h[:selected_index]]
1285
+ 'Activity - ' + activity
1286
+ end
1287
+
1288
+ def to_summary(colour: false)
1289
+
1290
+ activity = @activity[@h[:selected_index]]
1291
+ s = if activity.length > 10 then
1292
+ activity[0..7] + '..'
1293
+ else
1294
+ activity
1295
+ end
1296
+
1297
+ 'Activity - ' + s
1298
+
1299
+ end
1300
+
1301
+ end
1302
+
1303
+ # Category: Sensors
1304
+ #
1305
+ class ProximityTrigger < SensorsTrigger
1306
+
1307
+ def initialize(h={})
1308
+
1309
+ if h[:distance] then
1310
+
1311
+ case h[:distance].to_sym
1312
+ when :near
1313
+ options[:near] = true
1314
+ end
1315
+ end
1316
+
1317
+ options = {
1318
+ near: true,
1319
+ selected_option: 0
1320
+ }
1321
+
1322
+ super(options.merge h)
1323
+
1324
+ end
1325
+
1326
+ def to_s(colour: false)
1327
+
1328
+ distance = if @h[:near] then
1329
+ 'Near'
1330
+ else
1331
+ 'Far'
1332
+ end
1333
+
1334
+ "Proximity Sensor (%s)" % distance
1335
+ end
1336
+
1337
+ alias to_summary to_s
1338
+
1339
+ end
1340
+
1341
+ # Category: Sensors
1342
+ #
1343
+ class ShakeDeviceTrigger < SensorsTrigger
1344
+
1345
+ def initialize(h={})
1346
+
1347
+ options = {
1348
+ }
1349
+
1350
+ super(options.merge h)
1351
+
1352
+ end
1353
+
1354
+ def to_pc()
1355
+ 'shake_device?'
1356
+ end
1357
+
1358
+ def to_s(colour: false)
1359
+ 'Shake Device'
1360
+ end
1361
+
1362
+ end
1363
+
1364
+ # Category: Sensors
1365
+ #
1366
+ # options:
1367
+ # Face Up -> Face Down
1368
+ # Face Down -> Face Up
1369
+ # Any -> Face Down
1370
+ #
1371
+ class FlipDeviceTrigger < SensorsTrigger
1372
+
1373
+ def initialize(h={})
1374
+
1375
+ options = {
1376
+ any_start: false,
1377
+ face_down: true,
1378
+ work_with_screen_off: false
1379
+ }
1380
+
1381
+ super(options.merge h)
1382
+
1383
+ end
1384
+
1385
+ def to_pc()
1386
+ @h[:face_down] ? 'flip_device_down?' : 'flip_device_up?'
1387
+ end
1388
+
1389
+ def to_s(colour: false)
1390
+
1391
+ action = @h[:face_down] ? 'Face Up -> Face Down' : 'Face Down -> Face Up'
1392
+ 'Flip Device ' + action
1393
+ end
1394
+
1395
+ end
1396
+
1397
+ # Category: Sensors
1398
+ #
1399
+ class OrientationTrigger < SensorsTrigger
1400
+
1401
+ def initialize(h={})
1402
+
1403
+ options = {
1404
+ check_orientation_alive: true,
1405
+ option: 0
1406
+ }
1407
+
1408
+ super(options.merge h)
1409
+
1410
+ end
1411
+
1412
+ def to_s(colour: false)
1413
+ 'OrientationTrigger ' + @h.inspect
1414
+ end
1415
+
1416
+ alias to_summary to_s
1417
+ end
1418
+
1419
+ # Category: User Input
1420
+ #
1421
+ class FloatingButtonTrigger < Trigger
1422
+
1423
+ def initialize(h={})
1424
+
1425
+ options = {
1426
+ image_resource_id: 0,
1427
+ icon_bg_color: -9079435,
1428
+ alpha: 100,
1429
+ padding: 20,
1430
+ force_location: false,
1431
+ show_on_lock_screen: false,
1432
+ size: 0,
1433
+ transparent_background: false,
1434
+ x_location: 0,
1435
+ y_location: 0
1436
+ }
1437
+
1438
+ super(options.merge h)
1439
+
1440
+ end
1441
+
1442
+ def to_s(colour: false)
1443
+ 'Floating Button'
1444
+ end
1445
+
1446
+ alias to_summary to_s
1447
+ end
1448
+
1449
+ # Category: User Input
1450
+ #
1451
+ class ShortcutTrigger < Trigger
1452
+
1453
+ def initialize(h={})
1454
+
1455
+ options = {
1456
+ }
1457
+
1458
+ super(options.merge h)
1459
+
1460
+ end
1461
+
1462
+ def to_s(colour: false)
1463
+ 'ShortcutTrigger ' + @h.inspect
1464
+ end
1465
+
1466
+ alias to_summary to_s
1467
+ end
1468
+
1469
+ # Category: User Input
1470
+ #
1471
+ class VolumeButtonTrigger < Trigger
1472
+
1473
+ def initialize(h={})
1474
+
1475
+ options = {
1476
+ dont_change_volume: true,
1477
+ monitor_option: 1,
1478
+ not_configured: false,
1479
+ option: 0
1480
+ }
1481
+
1482
+ super(options.merge h)
1483
+
1484
+ end
1485
+
1486
+ def to_s(colour: false)
1487
+
1488
+ a = [
1489
+ 'Volume Up',
1490
+ 'Volume Down',
1491
+ 'Volume Up - Long Press',
1492
+ 'Volume Down - Long Press'
1493
+ ]
1494
+
1495
+ lines = [a[@h[:option]]]
1496
+ lines << ' ' + (@h[:dont_change_volume] ? 'Retain Previous Volume' : 'Update Volume')
1497
+ @s = lines.join("\n")
1498
+ end
1499
+
1500
+ def to_summary(colour: false)
1501
+ a = [
1502
+ 'Volume Up',
1503
+ 'Volume Down',
1504
+ 'Volume Up - Long Press',
1505
+ 'Volume Down - Long Press'
1506
+ ]
1507
+
1508
+ lines = [a[@h[:option]]]
1509
+ lines << (@h[:dont_change_volume] ? 'Retain Previous Volume' : 'Update Volume')
1510
+ @s = lines.join(": ")
1511
+ end
1512
+
1513
+ end
1514
+
1515
+ # Category: User Input
1516
+ #
1517
+ class MediaButtonPressedTrigger < Trigger
1518
+
1519
+ def initialize(h={})
1520
+
1521
+ options = {
1522
+ option: 'Single Press',
1523
+ cancel_press: false
1524
+ }
1525
+
1526
+ super(options.merge h)
1527
+
1528
+ end
1529
+
1530
+ def to_s(colour: false)
1531
+ 'MediaButtonPressedTrigger ' + @h.inspect
1532
+ end
1533
+
1534
+ alias to_summary to_s
1535
+ end
1536
+
1537
+ # Category: User Input
1538
+ #
1539
+ class SwipeTrigger < Trigger
1540
+
1541
+ def initialize(h={})
1542
+
1543
+ options = {
1544
+ swipe_start_area: 0,
1545
+ swipe_motion: 0,
1546
+ cleared: true
1547
+ }
1548
+
1549
+ super(options.merge h)
1550
+
1551
+ end
1552
+
1553
+ def to_s(colour: false)
1554
+ 'SwipeTrigger ' + @h.inspect
1555
+ end
1556
+
1557
+ alias to_summary to_s
1558
+ end