ruby-macrodroid 0.7.7 → 0.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/ruby-macrodroid.rb +145 -4189
- data/lib/ruby-macrodroid/actions.rb +2056 -0
- data/lib/ruby-macrodroid/base.rb +148 -0
- data/lib/ruby-macrodroid/triggers.rb +1558 -0
- metadata +19 -16
- metadata.gz.sig +0 -0
@@ -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
|