ruby-macrodroid 0.9.10 → 0.9.15

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.
@@ -35,6 +35,7 @@ module ObjectX
35
35
  puts 'r: ' + r.inspect if debug
36
36
 
37
37
  nested = description.element('item/description')
38
+ puts 'nested: ' + nested.inspect if debug
38
39
 
39
40
  if r[1].any? and not nested then
40
41
 
@@ -46,7 +47,7 @@ module ObjectX
46
47
  #o = r[0].new([description, self]) if r
47
48
  index = macro.actions.length
48
49
  macro.add Action.new
49
- o = object_create(r[0],[description, macro]) if r
50
+ o = object_create(r[0],[description, macro, r[1]]) if r
50
51
  macro.actions[index] = o
51
52
  puts 'after o' if debug
52
53
  o
@@ -132,7 +133,8 @@ class MacroObject
132
133
  end
133
134
 
134
135
  def to_h()
135
-
136
+
137
+ @h.delete :macro
136
138
  hashify(@h)
137
139
 
138
140
  end
@@ -204,6 +206,7 @@ class MacroObject
204
206
  new_key = key.to_s.gsub(/\w_\w/){|x| x[0] + x[-1].upcase}
205
207
  new_key = new_key.prepend 'm_' unless @list.include? new_key
206
208
  new_key = 'm_SIGUID' if new_key == 'm_siguid'
209
+ new_key = 'm_SSIDList' if new_key == 'm_ssidList'
207
210
  new_val = value.is_a?(Hash) ? hashify(value) : value
208
211
  r.merge(new_key => new_val)
209
212
  end
@@ -0,0 +1,75 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # file: constraintsnlp.rb
4
+
5
+
6
+ class ConstraintsNlp
7
+ include AppRoutes
8
+
9
+ def initialize()
10
+
11
+ super()
12
+ params = {}
13
+ constraints(params)
14
+
15
+ end
16
+
17
+ def constraints(params)
18
+
19
+ # Device State
20
+
21
+ get /^Device (locked|unlocked)/i do |state|
22
+ [DeviceLockedConstraint, {locked: state.downcase == 'locked'}]
23
+ end
24
+
25
+ get /^airplane mode (.*)/i do |state|
26
+ [AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
27
+ end
28
+
29
+ #
30
+
31
+ # -- MacroDroid specific -----------------------------------------------------------------------
32
+
33
+ get /^(\w+) (=) (.*)/i do |loperand, operator, roperand|
34
+
35
+ h = {
36
+ loperand: loperand,
37
+ operator: operator,
38
+ roperand: roperand
39
+ }
40
+
41
+ [MacroDroidVariableConstraint, h]
42
+
43
+ end
44
+
45
+ # -- Sensors -----------------------------------
46
+ #
47
+ get /^Light Sensor (Less|Greater) than (50.0)lx/i do |operator, val|
48
+
49
+ level, option = operator.downcase == 'less' ? [-1,0] : [1,1]
50
+
51
+ h = {
52
+ light_level: level,
53
+ light_level_float: val,
54
+ option: option
55
+ }
56
+
57
+ [LightLevelConstraint, h]
58
+ end
59
+
60
+ get /^Proximity Sensor: (Near|Far)/i do |distance|
61
+ [ProximitySensorConstraint, {near: distance.downcase == 'near'}]
62
+ end
63
+
64
+
65
+ # -- Screen and Speaker ---------------------------
66
+ #
67
+ get /^Screen (On|Off)/i do |state|
68
+ [ScreenOnOffConstraint, {screen_on: state.downcase == 'on'}]
69
+ end
70
+
71
+ end
72
+
73
+ alias find_constraint run_route
74
+
75
+ end
@@ -2,17 +2,12 @@
2
2
 
3
3
 
4
4
  # This file contains the following classes:
5
- #
6
- # ## Nlp classes
7
- #
8
- # TriggersNlp ActionsNlp ConstraintsNlp
9
- #
5
+ #
10
6
  # ## Macro class
11
7
  #
12
8
  # Macro
13
9
 
14
10
 
15
-
16
11
  VAR_TYPES = {
17
12
  String: [2, :string_value],
18
13
  TrueClass: [0, :boolean_value],
@@ -22,465 +17,6 @@ VAR_TYPES = {
22
17
  }
23
18
 
24
19
 
25
-
26
- class TriggersNlp
27
- include AppRoutes
28
- using ColouredText
29
-
30
- def initialize(macro=nil)
31
-
32
- super()
33
- params = {macro: macro}
34
- triggers(params)
35
-
36
- end
37
-
38
- def triggers(params)
39
-
40
- # -- Battery/Power ---------------------------------------------
41
-
42
- get /^Power Connected: (Wired \([^\)]+\))/i do |s|
43
-
44
- h = {
45
- power_connected_options: [true, true, true],
46
- has_set_usb_option: true,
47
- power_connected: true
48
- }
49
-
50
- a = ['Wired (Fast Charge)', 'Wireless', 'Wired (Slow Charge)']
51
-
52
- puts ('s: ' + s.inspect).debug
53
-
54
- options = s.downcase.split(/ \+ /)
55
- puts ('options: ' + options.inspect).debug
56
-
57
- h[:power_connected_options] = a.map {|x| options.include? x.downcase }
58
-
59
- [ExternalPowerTrigger, h]
60
- end
61
-
62
- get /^Power Connected: Any/i do |s|
63
-
64
- h = {
65
- power_connected_options: [true, true, true],
66
- has_set_usb_option: true,
67
- power_connected: true
68
- }
69
-
70
- [ExternalPowerTrigger, h]
71
- end
72
-
73
- # -- Device Events ----------------------------------------------------
74
-
75
- get /^Screen[ _](On|Off)/i do |state|
76
- [ScreenOnOffTrigger, {screen_on: state.downcase == 'on'}]
77
- end
78
-
79
- # e.g. at 7:30pm daily
80
- get /^(?:at )?(\d+:\d+(?:[ap]m)?) daily/i do |time, days|
81
- [TimerTrigger, {time: time,
82
- days: %w(Mon Tue Wed Thu Fri Sat Sun).join(', ')}]
83
- end
84
-
85
- get /^(?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)/i do |time, days|
86
- [TimerTrigger, {time: time, days: days}]
87
- end
88
-
89
- # time.is? 'at 18:30pm on Mon or Tue'
90
- get /^time.is\? ['"](?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)['"]/i do |time, days|
91
- [TimerTrigger, {time: time, days: days.gsub(' or ',', ')}]
92
- end
93
-
94
- get /^shake[ _]device\??$/i do
95
- [ShakeDeviceTrigger, {}]
96
- end
97
-
98
- get /^Flip Device (.*)$/i do |motion|
99
- facedown = motion =~ /Face Up (?:->|to) Face Down/i
100
- [FlipDeviceTrigger, {face_down: facedown }]
101
- end
102
-
103
- get /^flip_device_down\?$/i do
104
- [FlipDeviceTrigger, {face_down: true }]
105
- end
106
-
107
- get /^flip_device_up\?$/i do
108
- [FlipDeviceTrigger, {face_down: false }]
109
- end
110
-
111
- get /^Failed Login Attempt$/i do
112
- [FailedLoginTrigger, {}]
113
- end
114
-
115
- get /^failed_login?$/i do
116
- [FailedLoginTrigger, {}]
117
- end
118
-
119
- get /^Geofence (Entry|Exit) \(([^\)]+)/i do |direction, name|
120
- enter_area = direction.downcase.to_sym == :entry
121
- [GeofenceTrigger, {name: name, enter_area: enter_area}]
122
- end
123
-
124
- get /^location (entered|exited) \(([^\)]+)/i do |direction, name|
125
- enter_area = direction.downcase.to_sym == :entered
126
- [GeofenceTrigger, {name: name, enter_area: enter_area}]
127
- end
128
-
129
- # eg. Proximity Sensor (Near)
130
- #
131
- get /^Proximity Sensor \(([^\)]+)\)/i do |distance|
132
-
133
- [ProximityTrigger, {distance: distance}]
134
- end
135
-
136
- # eg. Proximity near
137
- #
138
- get /^Proximity (near|far|slow wave|fast wave)/i do |distance|
139
-
140
- [ProximityTrigger, {distance: distance}]
141
- end
142
-
143
- get /^WebHook \(Url\)/i do
144
- [WebHookTrigger, params]
145
- end
146
-
147
- get /^WebHook/i do
148
- [WebHookTrigger, params]
149
- end
150
-
151
- get /^wh/i do
152
- [WebHookTrigger, params]
153
- end
154
-
155
- # MacroDroid specific ---------------------------------------------------------------
156
-
157
- get /^EmptyTrigger$/i do
158
- [EmptyTrigger, params]
159
- end
160
-
161
- end
162
-
163
- alias find_trigger run_route
164
-
165
- def to_s(colour: false)
166
- 'TriggersNlp ' + @h.inspect
167
- end
168
-
169
- alias to_summary to_s
170
- end
171
-
172
- class ActionsNlp
173
- include AppRoutes
174
-
175
- def initialize(macro=nil)
176
-
177
- super()
178
-
179
- params = {macro: macro}
180
- actions(params)
181
-
182
- end
183
-
184
- def actions(params)
185
-
186
- # -- Conditions/Loops ---------------------------------------------
187
- #
188
-
189
- get /else if (.*)/i do
190
- [ElseIfConditionAction, {}]
191
- end
192
-
193
- #e.g a: if Airplane mode enabled
194
- #
195
- get /if (.*)/i do
196
- [IfConditionAction, {}]
197
- end
198
-
199
- get /else/i do
200
- [ElseAction, {}]
201
- end
202
-
203
- get /End If/i do
204
- [EndIfAction, {}]
205
- end
206
-
207
-
208
- # -- Connectivity ------------------------------------------------------
209
-
210
- get /^(Enable|Disable) HotSpot/i do |state|
211
- enable, state = if state.downcase == 'enable' then
212
- [true, 0]
213
- else
214
- [false, 1]
215
- end
216
- [SetHotspotAction, {turn_wifi_on: enable, state: state }]
217
- end
218
-
219
- # e.g. message popup: hello world!
220
- get /^(?:message popup|popup message): (.*)/i do |msg|
221
- [ToastAction, {msg: msg}]
222
- end
223
-
224
- # e.g. Popup Message 'hello world!'
225
- get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
226
- [ToastAction, {msg: msg}]
227
- end
228
-
229
- # e.g. Popup Message\n hello world!
230
- get /^Popup Message\n\s+(.*)/im do |msg|
231
- [ToastAction, {msg: msg}]
232
- end
233
-
234
- # e.g. Popup Message
235
- get /^Popup Message$/i do
236
- [ToastAction, {}]
237
- end
238
-
239
- # e.g. say current time
240
- get /^say current[ _]time/i do
241
- [SayTimeAction, {}]
242
- end
243
-
244
- get /^Torch :?(.*)/i do |onoffstate|
245
- state = %w(on off toggle).index onoffstate.downcase
246
- [CameraFlashLightAction, {state: state}]
247
- end
248
-
249
- get /^Take Picture/i do
250
- [TakePictureAction, {}]
251
- end
252
-
253
- get /^take_picture/i do
254
- [TakePictureAction, {}]
255
- end
256
-
257
- # -- DEVICE ACTIONS ------------------------------------------------------
258
-
259
- get /^Speak text \(([^\)]+)\)/i do |text|
260
- [SpeakTextAction, {text: text}]
261
- end
262
-
263
- get /^Speak text ['"]([^'"]+)/i do |text|
264
- [SpeakTextAction, {text: text}]
265
- end
266
-
267
- get /^Speak text$/i do |text|
268
- [SpeakTextAction, {}]
269
- end
270
-
271
- get /^Vibrate \(([^\)]+)/i do |pattern|
272
- [VibrateAction, {pattern: pattern}]
273
- end
274
-
275
- get /^Vibrate$/i do |pattern|
276
- [VibrateAction, {pattern: 'short buzz'}]
277
- end
278
-
279
- # e.g. Display Notification: Hi there: This is the body of the message
280
- get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
281
- [NotificationAction, {subject: subject, text: text}]
282
- end
283
-
284
-
285
- # e.g. Enable Wifi
286
- get /^(Enable|Disable) Wifi$/i do |raw_state|
287
-
288
- state = raw_state.downcase.to_sym == :enable ? 0 : 1
289
- [SetWifiAction, {state: state}]
290
-
291
- end
292
-
293
- # e.g. Play: Altair
294
- get /^Play: (.*)$/i do |name|
295
-
296
- [PlaySoundAction, {file_path: name}]
297
-
298
- end
299
-
300
- # e.g. Launch Settings
301
- get /^Launch (.*)$/i do |application|
302
-
303
- h = {
304
- application_name: application,
305
- package_to_launch: 'com.android.' + application.downcase
306
- }
307
- [LaunchActivityAction, h]
308
-
309
- end
310
-
311
- # e.g. HTTP GET http://someurl.com/something
312
- get /^HTTP GET ([^$]+)$/i do |url|
313
-
314
- [OpenWebPageAction, url_to_open: url]
315
-
316
- end
317
-
318
- get /^HTTP GET$/i do
319
-
320
- [OpenWebPageAction, {}]
321
-
322
- end
323
-
324
- # e.g. webhook entered_kitchen
325
- #
326
- get /(?:webhook|HTTP GET) ([^$]+)$/i do |s|
327
- key = s =~ /^http/ ? :url_to_open : :identifier
328
- [OpenWebPageAction, {key => s}]
329
- end
330
-
331
- #
332
- get /^WebHook \(Url\)/i do
333
- [OpenWebPageAction, {}]
334
- end
335
-
336
- # e.g. webhook entered_kitchen
337
- #
338
- get /^webhook$/i do
339
- [OpenWebPageAction, {}, params[:macro]]
340
- end
341
-
342
- # -- Location ---------------------------------------------------------
343
-
344
- get /^Force Location Update$/i do
345
- [ForceLocationUpdateAction, params]
346
- end
347
-
348
- get /^Share Location$/i do
349
- [ShareLocationAction, {}]
350
- end
351
-
352
- #a: Keep Device Awake Screen On Until Disabled
353
- #
354
- get /Keep Device Awake Screen On Until Disabled/i do
355
- [KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
356
- end
357
-
358
-
359
- #a: Keep Device Awake Screen On 1h 1m 1s
360
- #
361
- get /Keep Device Awake Screen On ([^$]+)/i do |duration|
362
-
363
- a = duration.split.map(&:to_i)
364
- secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
365
-
366
- h = {
367
- permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
368
- }
369
- [KeepAwakeAction, h]
370
- end
371
-
372
- get /(?:Keep Device|stay) Awake$/i do
373
- [KeepAwakeAction, {}]
374
- end
375
-
376
- #a: Disable Keep Awake
377
- #
378
- get /Disable Keep Awake|stay awake off/i do
379
- [KeepAwakeAction, {enabled: false, screen_option: 0}]
380
- end
381
-
382
-
383
- # -- MacroDroid Specific ------------------------------------------------
384
- #
385
-
386
- get /^((?:En|Dis)able) Macro$/i do |rawstate|
387
- state = %w(enable disable toggle).index(rawstate.downcase)
388
- [DisableMacroAction, {state: state}]
389
- end
390
-
391
- get /^Set Variable$/i do
392
- [SetVariableAction, {}]
393
- end
394
-
395
- get /^wait (\d+) seconds$/i do |seconds|
396
- [PauseAction, {delay_in_seconds: seconds.to_i}]
397
- end
398
-
399
- # -- Screen ------------------------------------------------
400
- #
401
- get /^Screen (On|Off)$/i do |state|
402
- [ScreenOnAction, {screen_off: state.downcase == 'off'}]
403
- end
404
-
405
- end
406
-
407
- alias find_action run_route
408
-
409
-
410
- end
411
-
412
- class ConstraintsNlp
413
- include AppRoutes
414
-
415
- def initialize()
416
-
417
- super()
418
- params = {}
419
- constraints(params)
420
-
421
- end
422
-
423
- def constraints(params)
424
-
425
- # Device State
426
-
427
- get /^Device (locked|unlocked)/i do |state|
428
- [DeviceLockedConstraint, {locked: state.downcase == 'locked'}]
429
- end
430
-
431
- get /^airplane mode (.*)/i do |state|
432
- [AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
433
- end
434
-
435
- #
436
-
437
- # -- MacroDroid specific -----------------------------------------------------------------------
438
-
439
- get /^(\w+) (=) (.*)/i do |loperand, operator, roperand|
440
-
441
- h = {
442
- loperand: loperand,
443
- operator: operator,
444
- roperand: roperand
445
- }
446
-
447
- [MacroDroidVariableConstraint, h]
448
-
449
- end
450
-
451
- # -- Sensors -----------------------------------
452
- #
453
- get /^Light Sensor (Less|Greater) than (50.0)lx/i do |operator, val|
454
-
455
- level, option = operator.downcase == 'less' ? [-1,0] : [1,1]
456
-
457
- h = {
458
- light_level: level,
459
- light_level_float: val,
460
- option: option
461
- }
462
-
463
- [LightLevelConstraint, h]
464
- end
465
-
466
- get /^Proximity Sensor: (Near|Far)/i do |distance|
467
- [ProximitySensorConstraint, {near: distance.downcase == 'near'}]
468
- end
469
-
470
-
471
- # -- Screen and Speaker ---------------------------
472
- #
473
- get /^Screen (On|Off)/i do |state|
474
- [ScreenOnOffConstraint, {screen_on: state.downcase == 'on'}]
475
- end
476
-
477
- end
478
-
479
- alias find_constraint run_route
480
-
481
- end
482
-
483
-
484
20
  class MacroError < Exception
485
21
  end
486
22
 
@@ -504,6 +40,7 @@ class Macro
504
40
  @local_variables, @triggers, @actions, @constraints = {}, [], [], []
505
41
  @h = {}
506
42
  @guid = generate_guid()
43
+ @enabled = true
507
44
 
508
45
  end
509
46
 
@@ -529,6 +66,18 @@ class Macro
529
66
  end
530
67
 
531
68
  end
69
+
70
+ def disable()
71
+ @enabled = false
72
+ end
73
+
74
+ def enable()
75
+ @enabled = true
76
+ end
77
+
78
+ def enabled?()
79
+ @enabled
80
+ end
532
81
 
533
82
  def to_h()
534
83
 
@@ -547,7 +96,7 @@ class Macro
547
96
  m_excludeLog: false,
548
97
  m_GUID: @guid,
549
98
  m_isOrCondition: false,
550
- m_enabled: true,
99
+ m_enabled: @enabled,
551
100
  m_descriptionOpen: false,
552
101
  m_headingColor: 0
553
102
  }
@@ -719,7 +268,7 @@ class Macro
719
268
  r = tp.find_trigger trigger
720
269
  puts 'r: ' + r.inspect if @debug
721
270
  #o = r[0].new([description, self]) if r
722
- o = object_create(r[0], [description, self]) if r
271
+ o = object_create(r[0], [description, self, r[1]]) if r
723
272
  puts 'after o' if @debug
724
273
  o
725
274
 
@@ -765,7 +314,6 @@ class Macro
765
314
 
766
315
  end
767
316
 
768
-
769
317
 
770
318
  ap = ActionsNlp.new self
771
319
 
@@ -808,7 +356,7 @@ class Macro
808
356
 
809
357
  end
810
358
 
811
- def match?(triggerx, detail={time: $env[:time]}, model=nil )
359
+ def match?(triggerx, detail={}, model=nil )
812
360
 
813
361
  if @triggers.any? {|x| x.type == triggerx and x.match?(detail, model) } then
814
362
 
@@ -939,8 +487,6 @@ EOF
939
487
  s = x.to_s(colour: colour)
940
488
  #puts 's: ' + s.inspect
941
489
 
942
-
943
-
944
490
  r = if indent <= 0 then
945
491
 
946
492
  lines = s.lines
@@ -993,9 +539,6 @@ EOF
993
539
 
994
540
  end.join("\n")
995
541
 
996
-
997
-
998
-
999
542
  a << actions
1000
543
 
1001
544
 
@@ -1006,10 +549,6 @@ EOF
1006
549
  end.join("\n")
1007
550
  end
1008
551
 
1009
-
1010
-
1011
-
1012
-
1013
552
  a.join("\n") + "\n"
1014
553
 
1015
554
  end
@@ -1076,9 +615,6 @@ EOF
1076
615
 
1077
616
  end
1078
617
 
1079
- end
1080
-
1081
-
1082
-
618
+ end
1083
619
 
1084
620
  end