ruby-macrodroid 0.8.11 → 0.9.3
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 +16 -330
- data/lib/ruby-macrodroid/actions.rb +199 -35
- data/lib/ruby-macrodroid/base.rb +21 -15
- data/lib/ruby-macrodroid/constraints.rb +1338 -0
- data/lib/ruby-macrodroid/macro.rb +528 -47
- data/lib/ruby-macrodroid/triggers.rb +46 -14
- metadata +11 -10
- metadata.gz.sig +0 -0
@@ -3,6 +3,10 @@
|
|
3
3
|
|
4
4
|
# This file contains the following classes:
|
5
5
|
#
|
6
|
+
# ## Nlp classes
|
7
|
+
#
|
8
|
+
# TriggersNlp ActionsNlp ConstraintsNlp
|
9
|
+
#
|
6
10
|
# ## Macro class
|
7
11
|
#
|
8
12
|
# Macro
|
@@ -12,11 +16,372 @@
|
|
12
16
|
VAR_TYPES = {
|
13
17
|
String: [2, :string_value],
|
14
18
|
TrueClass: [0, :boolean_value],
|
15
|
-
|
19
|
+
FalseClass: [0, :boolean_value],
|
16
20
|
Integer: [1, :int_value],
|
17
21
|
Float: [3, :decimal_value]
|
18
22
|
}
|
19
23
|
|
24
|
+
class TriggersNlp
|
25
|
+
include AppRoutes
|
26
|
+
|
27
|
+
def initialize(macro=nil)
|
28
|
+
|
29
|
+
super()
|
30
|
+
params = {macro: macro}
|
31
|
+
triggers(params)
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
def triggers(params)
|
36
|
+
|
37
|
+
# e.g. at 7:30pm daily
|
38
|
+
get /^(?:at )?(\d+:\d+(?:[ap]m)?) daily/i do |time, days|
|
39
|
+
[TimerTrigger, {time: time,
|
40
|
+
days: %w(Mon Tue Wed Thu Fri Sat Sun).join(', ')}]
|
41
|
+
end
|
42
|
+
|
43
|
+
get /^(?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)/i do |time, days|
|
44
|
+
[TimerTrigger, {time: time, days: days}]
|
45
|
+
end
|
46
|
+
|
47
|
+
# time.is? 'at 18:30pm on Mon or Tue'
|
48
|
+
get /^time.is\? ['"](?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)['"]/i do |time, days|
|
49
|
+
[TimerTrigger, {time: time, days: days.gsub(' or ',', ')}]
|
50
|
+
end
|
51
|
+
|
52
|
+
get /^shake[ _]device\??$/i do
|
53
|
+
[ShakeDeviceTrigger, {}]
|
54
|
+
end
|
55
|
+
|
56
|
+
get /^Flip Device (.*)$/i do |motion|
|
57
|
+
facedown = motion =~ /Face Up (?:->|to) Face Down/i
|
58
|
+
[FlipDeviceTrigger, {face_down: facedown }]
|
59
|
+
end
|
60
|
+
|
61
|
+
get /^flip_device_down\?$/i do
|
62
|
+
[FlipDeviceTrigger, {face_down: true }]
|
63
|
+
end
|
64
|
+
|
65
|
+
get /^flip_device_up\?$/i do
|
66
|
+
[FlipDeviceTrigger, {face_down: false }]
|
67
|
+
end
|
68
|
+
|
69
|
+
get /^Failed Login Attempt$/i do
|
70
|
+
[FailedLoginTrigger, {}]
|
71
|
+
end
|
72
|
+
|
73
|
+
get /^failed_login?$/i do
|
74
|
+
[FailedLoginTrigger, {}]
|
75
|
+
end
|
76
|
+
|
77
|
+
get /^Geofence (Entry|Exit) \(([^\)]+)/i do |direction, name|
|
78
|
+
enter_area = direction.downcase.to_sym == :entry
|
79
|
+
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
80
|
+
end
|
81
|
+
|
82
|
+
get /^location (entered|exited) \(([^\)]+)/i do |direction, name|
|
83
|
+
enter_area = direction.downcase.to_sym == :entered
|
84
|
+
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
85
|
+
end
|
86
|
+
|
87
|
+
# eg. Proximity Sensor (Near)
|
88
|
+
#
|
89
|
+
get /^Proximity Sensor \(([^\)]+)\)/i do |distance|
|
90
|
+
|
91
|
+
[ProximityTrigger, {distance: distance}]
|
92
|
+
end
|
93
|
+
|
94
|
+
# eg. Proximity near
|
95
|
+
#
|
96
|
+
get /^Proximity (near|far|slow wave|fast wave)/i do |distance|
|
97
|
+
|
98
|
+
[ProximityTrigger, {distance: distance}]
|
99
|
+
end
|
100
|
+
|
101
|
+
get /^WebHook \(Url\)/i do
|
102
|
+
[WebHookTrigger, params]
|
103
|
+
end
|
104
|
+
|
105
|
+
get /^WebHook/i do
|
106
|
+
[WebHookTrigger, params]
|
107
|
+
end
|
108
|
+
|
109
|
+
get /^wh/i do
|
110
|
+
[WebHookTrigger, params]
|
111
|
+
end
|
112
|
+
|
113
|
+
# MacroDroid specific ---------------------------------------------------------------
|
114
|
+
|
115
|
+
get /^EmptyTrigger$/i do
|
116
|
+
[EmptyTrigger, params]
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
120
|
+
|
121
|
+
alias find_trigger run_route
|
122
|
+
|
123
|
+
def to_s(colour: false)
|
124
|
+
'TriggersNlp ' + @h.inspect
|
125
|
+
end
|
126
|
+
|
127
|
+
alias to_summary to_s
|
128
|
+
end
|
129
|
+
|
130
|
+
class ActionsNlp
|
131
|
+
include AppRoutes
|
132
|
+
|
133
|
+
def initialize(macro=nil)
|
134
|
+
|
135
|
+
super()
|
136
|
+
params = {macro: macro}
|
137
|
+
actions(params)
|
138
|
+
|
139
|
+
end
|
140
|
+
|
141
|
+
def actions(params)
|
142
|
+
|
143
|
+
# e.g. message popup: hello world!
|
144
|
+
get /^message popup: (.*)/i do |msg|
|
145
|
+
[ToastAction, {msg: msg}]
|
146
|
+
end
|
147
|
+
|
148
|
+
# e.g. Popup Message 'hello world!'
|
149
|
+
get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
|
150
|
+
[ToastAction, {msg: msg}]
|
151
|
+
end
|
152
|
+
|
153
|
+
# e.g. Popup Message\n hello world!
|
154
|
+
get /^Popup Message\n\s+(.*)/im do |msg|
|
155
|
+
[ToastAction, {msg: msg}]
|
156
|
+
end
|
157
|
+
|
158
|
+
# e.g. Popup Message
|
159
|
+
get /^Popup Message$/i do
|
160
|
+
[ToastAction, {}]
|
161
|
+
end
|
162
|
+
|
163
|
+
# e.g. say current time
|
164
|
+
get /^say current[ _]time/i do
|
165
|
+
[SayTimeAction, {}]
|
166
|
+
end
|
167
|
+
|
168
|
+
get /^Torch :?(.*)/i do |onoffstate|
|
169
|
+
state = %w(on off toggle).index onoffstate.downcase
|
170
|
+
[CameraFlashLightAction, {state: state}]
|
171
|
+
end
|
172
|
+
|
173
|
+
get /^Take Picture/i do
|
174
|
+
[TakePictureAction, {}]
|
175
|
+
end
|
176
|
+
|
177
|
+
get /^take_picture/i do
|
178
|
+
[TakePictureAction, {}]
|
179
|
+
end
|
180
|
+
|
181
|
+
# -- DEVICE ACTIONS ------------------------------------------------------
|
182
|
+
|
183
|
+
get /^Speak text \(([^\)]+)\)/i do |text|
|
184
|
+
[SpeakTextAction, {text: text}]
|
185
|
+
end
|
186
|
+
|
187
|
+
get /^Speak text ['"]([^'"]+)/i do |text|
|
188
|
+
[SpeakTextAction, {text: text}]
|
189
|
+
end
|
190
|
+
|
191
|
+
get /^Speak text$/i do |text|
|
192
|
+
[SpeakTextAction, {}]
|
193
|
+
end
|
194
|
+
|
195
|
+
get /^Vibrate \(([^\)]+)/i do |pattern|
|
196
|
+
[VibrateAction, {pattern: pattern}]
|
197
|
+
end
|
198
|
+
|
199
|
+
# e.g. Display Notification: Hi there: This is the body of the message
|
200
|
+
get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
|
201
|
+
[NotificationAction, {subject: subject, text: text}]
|
202
|
+
end
|
203
|
+
|
204
|
+
|
205
|
+
# e.g. Enable Wifi
|
206
|
+
get /^(Enable|Disable) Wifi$/i do |raw_state|
|
207
|
+
|
208
|
+
state = raw_state.downcase.to_sym == :enable ? 0 : 1
|
209
|
+
[SetWifiAction, {state: state}]
|
210
|
+
|
211
|
+
end
|
212
|
+
|
213
|
+
# e.g. Play: Altair
|
214
|
+
get /^Play: (.*)$/i do |name|
|
215
|
+
|
216
|
+
[PlaySoundAction, {file_path: name}]
|
217
|
+
|
218
|
+
end
|
219
|
+
|
220
|
+
# e.g. Launch Settings
|
221
|
+
get /^Launch (.*)$/i do |application|
|
222
|
+
|
223
|
+
h = {
|
224
|
+
application_name: application,
|
225
|
+
package_to_launch: 'com.android.' + application.downcase
|
226
|
+
}
|
227
|
+
[LaunchActivityAction, h]
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
# e.g. HTTP GET http://someurl.com/something
|
232
|
+
get /^HTTP GET ([^$]+)$/i do |url|
|
233
|
+
|
234
|
+
[OpenWebPageAction, url_to_open: url]
|
235
|
+
|
236
|
+
end
|
237
|
+
|
238
|
+
get /^HTTP GET$/i do
|
239
|
+
|
240
|
+
[OpenWebPageAction, {}]
|
241
|
+
|
242
|
+
end
|
243
|
+
|
244
|
+
# e.g. webhook entered_kitchen
|
245
|
+
#
|
246
|
+
get /(?:webhook|HTTP GET) ([^$]+)$/i do |s|
|
247
|
+
key = s =~ /^http/ ? :url_to_open : :identifier
|
248
|
+
[OpenWebPageAction, {key => s}]
|
249
|
+
end
|
250
|
+
|
251
|
+
#
|
252
|
+
get /^WebHook \(Url\)/i do
|
253
|
+
[OpenWebPageAction, params]
|
254
|
+
end
|
255
|
+
|
256
|
+
# e.g. webhook entered_kitchen
|
257
|
+
#
|
258
|
+
get /^webhook$/i do
|
259
|
+
[OpenWebPageAction, params]
|
260
|
+
end
|
261
|
+
|
262
|
+
# -- Location ---------------------------------------------------------
|
263
|
+
|
264
|
+
get /^Force Location Update$/i do
|
265
|
+
[ForceLocationUpdateAction, params]
|
266
|
+
end
|
267
|
+
|
268
|
+
get /^Share Location$/i do
|
269
|
+
[ShareLocationAction, params]
|
270
|
+
end
|
271
|
+
|
272
|
+
#a: Keep Device Awake Screen On Until Disabled
|
273
|
+
#
|
274
|
+
get /Keep Device Awake Screen On Until Disabled/i do
|
275
|
+
[KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
|
276
|
+
end
|
277
|
+
|
278
|
+
|
279
|
+
#a: Keep Device Awake Screen On 1h 1m 1s
|
280
|
+
#
|
281
|
+
get /Keep Device Awake Screen On ([^$]+)/i do |duration|
|
282
|
+
|
283
|
+
a = duration.split.map(&:to_i)
|
284
|
+
secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
|
285
|
+
|
286
|
+
h = {
|
287
|
+
permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
|
288
|
+
}
|
289
|
+
[KeepAwakeAction, h]
|
290
|
+
end
|
291
|
+
|
292
|
+
get /Keep Device Awake$/i do
|
293
|
+
[KeepAwakeAction, params]
|
294
|
+
end
|
295
|
+
|
296
|
+
#a: Disable Keep Awake
|
297
|
+
#
|
298
|
+
get /Disable Keep Awake/i do
|
299
|
+
[KeepAwakeAction, {enabled: false, screen_option: 0}]
|
300
|
+
end
|
301
|
+
|
302
|
+
#e.g a: if Airplane mode enabled
|
303
|
+
#
|
304
|
+
get /if (.*)/i do
|
305
|
+
[IfConditionAction, {}]
|
306
|
+
end
|
307
|
+
|
308
|
+
get /End If/i do
|
309
|
+
[EndIfAction, {}]
|
310
|
+
end
|
311
|
+
|
312
|
+
# -- MacroDroid Specific ------------------------------------------------
|
313
|
+
#
|
314
|
+
get /^Set Variable$/i do
|
315
|
+
[SetVariableAction, {}]
|
316
|
+
end
|
317
|
+
|
318
|
+
end
|
319
|
+
|
320
|
+
alias find_action run_route
|
321
|
+
|
322
|
+
|
323
|
+
end
|
324
|
+
|
325
|
+
class ConstraintsNlp
|
326
|
+
include AppRoutes
|
327
|
+
|
328
|
+
def initialize()
|
329
|
+
|
330
|
+
super()
|
331
|
+
params = {}
|
332
|
+
constraints(params)
|
333
|
+
|
334
|
+
end
|
335
|
+
|
336
|
+
def constraints(params)
|
337
|
+
|
338
|
+
# Device State
|
339
|
+
|
340
|
+
get /^Device (locked|unlocked)/i do |state|
|
341
|
+
[DeviceLockedConstraint, {locked: state.downcase == 'locked'}]
|
342
|
+
end
|
343
|
+
|
344
|
+
get /^airplane mode (.*)/i do |state|
|
345
|
+
[AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
|
346
|
+
end
|
347
|
+
|
348
|
+
#
|
349
|
+
|
350
|
+
# -- Sensors -----------------------------------
|
351
|
+
#
|
352
|
+
get /^Light Sensor (Less|Greater) than (50.0)lx/i do |operator, val|
|
353
|
+
|
354
|
+
level, option = operator.downcase == 'less' ? [-1,0] : [1,1]
|
355
|
+
|
356
|
+
h = {
|
357
|
+
light_level: level,
|
358
|
+
light_level_float: val,
|
359
|
+
option: option
|
360
|
+
}
|
361
|
+
|
362
|
+
[LightLevelConstraint, h]
|
363
|
+
end
|
364
|
+
|
365
|
+
get /^Proximity Sensor: (Near|Far)/i do |distance|
|
366
|
+
[ProximitySensorConstraint, {near: distance.downcase == 'near'}]
|
367
|
+
end
|
368
|
+
|
369
|
+
|
370
|
+
# -- Screen and Speaker ---------------------------
|
371
|
+
#
|
372
|
+
get /^Screen (On|Off)/i do |state|
|
373
|
+
[ScreenOnOffConstraint, {screen_on: state.downcase == 'on'}]
|
374
|
+
end
|
375
|
+
|
376
|
+
end
|
377
|
+
|
378
|
+
alias find_constraint run_route
|
379
|
+
|
380
|
+
end
|
381
|
+
|
382
|
+
|
383
|
+
class MacroError < Exception
|
384
|
+
end
|
20
385
|
|
21
386
|
class Macro
|
22
387
|
using ColouredText
|
@@ -24,15 +389,17 @@ class Macro
|
|
24
389
|
|
25
390
|
attr_reader :local_variables, :triggers, :actions, :constraints,
|
26
391
|
:guid, :deviceid
|
27
|
-
attr_accessor :title, :description
|
392
|
+
attr_accessor :title, :description, :remote_url
|
28
393
|
|
29
|
-
def initialize(name=nil, geofences: nil, deviceid: nil,
|
394
|
+
def initialize(name=nil, geofences: nil, deviceid: nil, remote_url: nil,
|
395
|
+
debug: false)
|
30
396
|
|
31
397
|
@title, @geofences, @deviceid, @debug = name, geofences, deviceid, debug
|
398
|
+
@remote_url = remote_url
|
32
399
|
|
33
400
|
puts 'inside Macro#initialize' if @debug
|
34
401
|
|
35
|
-
@local_variables, @triggers, @actions, @constraints =
|
402
|
+
@local_variables, @triggers, @actions, @constraints = {}, [], [], []
|
36
403
|
@h = {}
|
37
404
|
|
38
405
|
end
|
@@ -59,9 +426,13 @@ class Macro
|
|
59
426
|
end
|
60
427
|
|
61
428
|
def to_h()
|
429
|
+
|
430
|
+
a = @local_variables.map do |k,v|
|
431
|
+
varify(k,v).to_camelcase.map{|key,value| ['m_' + key, value]}.to_h
|
432
|
+
end
|
62
433
|
|
63
434
|
h = {
|
64
|
-
local_variables:
|
435
|
+
local_variables: a,
|
65
436
|
m_trigger_list: @triggers.map(&:to_h),
|
66
437
|
m_action_list: @actions.map(&:to_h),
|
67
438
|
m_category: @category,
|
@@ -71,7 +442,7 @@ class Macro
|
|
71
442
|
m_excludeLog: false,
|
72
443
|
m_GUID: guid(),
|
73
444
|
m_isOrCondition: false,
|
74
|
-
m_enabled:
|
445
|
+
m_enabled: true,
|
75
446
|
m_descriptionOpen: false,
|
76
447
|
m_headingColor: 0
|
77
448
|
}
|
@@ -96,7 +467,7 @@ class Macro
|
|
96
467
|
if h[:local_variables].any? and h[:local_variables].first.any? then
|
97
468
|
|
98
469
|
@local_variables = h[:local_variables].map do |var|
|
99
|
-
|
470
|
+
|
100
471
|
val = case var[:type]
|
101
472
|
when 0 # boolean
|
102
473
|
var[:boolean_value]
|
@@ -115,7 +486,7 @@ class Macro
|
|
115
486
|
|
116
487
|
# fetch the triggers
|
117
488
|
@triggers = h[:trigger_list].map do |trigger|
|
118
|
-
puts 'trigger: ' + trigger.inspect
|
489
|
+
puts 'trigger: ' + trigger.inspect if @debug
|
119
490
|
#exit
|
120
491
|
object(trigger.to_snake_case)
|
121
492
|
|
@@ -194,31 +565,103 @@ class Macro
|
|
194
565
|
|
195
566
|
@title = node.text('macro') || node.attributes[:name]
|
196
567
|
|
197
|
-
|
198
|
-
|
568
|
+
d = node.element('description')
|
569
|
+
|
570
|
+
if d then
|
571
|
+
|
572
|
+
desc = []
|
573
|
+
desc << d.text.strip
|
574
|
+
|
575
|
+
if d.element('item/description') then
|
576
|
+
desc << d.text('item/description').strip
|
577
|
+
end
|
578
|
+
|
579
|
+
@description = desc.join("\n")
|
580
|
+
|
199
581
|
end
|
200
582
|
|
583
|
+
node.xpath('variable').each {|e| set_var(*e.text.to_s.split(/: */,2)) }
|
584
|
+
|
201
585
|
#@description = node.attributes[:description]
|
202
586
|
|
203
587
|
tp = TriggersNlp.new(self)
|
204
588
|
|
205
|
-
@triggers = node.xpath('trigger').
|
589
|
+
@triggers = node.xpath('trigger').flat_map do |e|
|
206
590
|
|
207
591
|
r = tp.find_trigger e.text
|
208
592
|
|
209
593
|
puts 'found trigger ' + r.inspect if @debug
|
210
594
|
|
211
|
-
|
212
|
-
|
213
|
-
|
595
|
+
item = e.element('item')
|
596
|
+
if item then
|
597
|
+
|
598
|
+
if item.element('description') then
|
599
|
+
|
600
|
+
item.xpath('description').map do |description|
|
601
|
+
|
602
|
+
inner_lines = description.text.to_s.strip.lines
|
603
|
+
puts 'inner_lines: ' + inner_lines.inspect if @debug
|
604
|
+
|
605
|
+
trigger = if e.text.to_s.strip.empty? then
|
606
|
+
inner_lines.shift.strip
|
607
|
+
else
|
608
|
+
e.text.strip
|
609
|
+
end
|
610
|
+
|
611
|
+
puts 'trigger: ' + trigger.inspect if @debug
|
612
|
+
|
613
|
+
r = tp.find_trigger trigger
|
614
|
+
puts 'r: ' + r.inspect if @debug
|
615
|
+
#o = r[0].new([description, self]) if r
|
616
|
+
o = object_create(r[0], [description, self]) if r
|
617
|
+
puts 'after o' if @debug
|
618
|
+
o
|
619
|
+
|
620
|
+
end
|
621
|
+
|
622
|
+
else
|
623
|
+
|
624
|
+
trigger = e.text.strip
|
625
|
+
r = tp.find_trigger trigger
|
626
|
+
|
627
|
+
a = e.xpath('item/*')
|
628
|
+
|
629
|
+
h = if a.any? then
|
630
|
+
a.map {|node| [node.name.to_sym, node.text.to_s]}.to_h
|
631
|
+
else
|
632
|
+
{}
|
633
|
+
end
|
634
|
+
|
635
|
+
r = tp.find_trigger trigger
|
636
|
+
#r[0].new(h) if r
|
637
|
+
if r then
|
638
|
+
object_create(r[0], h)
|
639
|
+
else
|
640
|
+
raise MacroError, 'App-routes: Trigger "' + trigger + '" not found'
|
641
|
+
end
|
642
|
+
|
643
|
+
end
|
644
|
+
|
645
|
+
else
|
646
|
+
|
647
|
+
trigger = e.text.strip
|
648
|
+
r = tp.find_trigger trigger
|
649
|
+
#r[0].new(r[1]) if r
|
650
|
+
|
651
|
+
if r then
|
652
|
+
object_create(r[0],r[1])
|
214
653
|
else
|
215
|
-
|
654
|
+
raise MacroError, 'App-routes: Trigger "' + trigger + '" not found'
|
216
655
|
end
|
656
|
+
|
217
657
|
end
|
218
658
|
|
659
|
+
|
219
660
|
end
|
661
|
+
|
662
|
+
|
220
663
|
|
221
|
-
ap = ActionsNlp.new
|
664
|
+
ap = ActionsNlp.new self
|
222
665
|
|
223
666
|
@actions = node.xpath('action').flat_map do |e|
|
224
667
|
|
@@ -245,8 +688,10 @@ class Macro
|
|
245
688
|
|
246
689
|
r = ap.find_action action
|
247
690
|
puts 'r: ' + r.inspect if @debug
|
248
|
-
|
249
|
-
|
691
|
+
puts 'description: ' + description.xml.inspect if @debug
|
692
|
+
#o = r[0].new([description, self]) if r
|
693
|
+
o = object_create(r[0],[description, self]) if r
|
694
|
+
puts 'after o' if @debug
|
250
695
|
o
|
251
696
|
|
252
697
|
end
|
@@ -254,6 +699,7 @@ class Macro
|
|
254
699
|
else
|
255
700
|
|
256
701
|
action = e.text.strip
|
702
|
+
puts 'action: ' + action.inspect if @debug
|
257
703
|
r = ap.find_action action
|
258
704
|
|
259
705
|
a = e.xpath('item/*')
|
@@ -263,9 +709,11 @@ class Macro
|
|
263
709
|
else
|
264
710
|
{}
|
265
711
|
end
|
712
|
+
puts 'h: ' + h.inspect if @debug
|
266
713
|
|
267
|
-
r = ap.find_action action
|
268
|
-
r[0].new(h) if r
|
714
|
+
#r = ap.find_action action
|
715
|
+
#r[0].new(h.merge(macro: self)) if r
|
716
|
+
object_create(r[0], h.merge(macro: self)) if r
|
269
717
|
|
270
718
|
end
|
271
719
|
|
@@ -273,7 +721,8 @@ class Macro
|
|
273
721
|
|
274
722
|
action = e.text.strip
|
275
723
|
r = ap.find_action action
|
276
|
-
r[0].new(r[1]) if r
|
724
|
+
#r[0].new(r[1]) if r
|
725
|
+
object_create(r[0],r[1]) if r
|
277
726
|
|
278
727
|
end
|
279
728
|
|
@@ -286,9 +735,7 @@ class Macro
|
|
286
735
|
r = cp.find_constraint e.text
|
287
736
|
puts 'found constraint ' + r.inspect if @debug
|
288
737
|
|
289
|
-
if r
|
290
|
-
r[0].new(r[1])
|
291
|
-
end
|
738
|
+
object_create(r[0], r[1]) if r
|
292
739
|
|
293
740
|
end
|
294
741
|
|
@@ -333,6 +780,27 @@ class Macro
|
|
333
780
|
def set_env()
|
334
781
|
@triggers.each(&:set_env)
|
335
782
|
end
|
783
|
+
|
784
|
+
def set_var(label, v='')
|
785
|
+
|
786
|
+
value = if v.to_f.to_s == v
|
787
|
+
v.to_f
|
788
|
+
elsif v.downcase == 'true'
|
789
|
+
true
|
790
|
+
elsif v.downcase == 'false'
|
791
|
+
false
|
792
|
+
elsif v.to_i.to_s == v
|
793
|
+
v.to_i
|
794
|
+
else
|
795
|
+
v
|
796
|
+
end
|
797
|
+
|
798
|
+
if not @local_variables.has_key? label.to_sym then
|
799
|
+
@local_variables.merge!({label.to_sym => value})
|
800
|
+
end
|
801
|
+
|
802
|
+
varify(label, value)
|
803
|
+
end
|
336
804
|
|
337
805
|
def to_pc()
|
338
806
|
|
@@ -378,13 +846,21 @@ EOF
|
|
378
846
|
puts 'before triggers' if @debug
|
379
847
|
|
380
848
|
a << @triggers.map do |x|
|
849
|
+
|
850
|
+
puts 'x: ' + x.inspect if @debug
|
851
|
+
raise 'Macro#to_s trigger cannot be nil' if x.nil?
|
852
|
+
|
381
853
|
s =-x.to_s(colour: colour)
|
854
|
+
puts 's: ' + s.inspect if @debug
|
382
855
|
|
383
856
|
s2 = if s.lines.length > 1 then
|
384
857
|
"\n" + s.lines.map {|x| x.prepend (' ' * (indent+1)) }.join
|
385
858
|
else
|
386
859
|
' ' + s
|
387
860
|
end
|
861
|
+
|
862
|
+
puts 's2: ' + s2.inspect if @debug
|
863
|
+
|
388
864
|
#s.lines > 1 ? "\n" + x : x
|
389
865
|
(colour ? "t".bg_red.gray.bold : 't') + ":" + s2
|
390
866
|
end.join("\n")
|
@@ -519,42 +995,47 @@ EOF
|
|
519
995
|
|
520
996
|
puts ('inside object h:' + h.inspect).debug if @debug
|
521
997
|
klass = Object.const_get h[:class_type]
|
522
|
-
puts klass.inspect.highlight if
|
998
|
+
puts klass.inspect.highlight if @debug
|
523
999
|
|
524
1000
|
if klass == GeofenceTrigger then
|
525
|
-
puts 'GeofenceTrigger found'.highlight if
|
1001
|
+
puts 'GeofenceTrigger found'.highlight if @debug
|
526
1002
|
GeofenceTrigger.new(h, geofences: @geofences)
|
527
1003
|
else
|
528
|
-
puts 'before klass'
|
1004
|
+
puts 'before klass' if @debug
|
529
1005
|
h2 = h.merge( macro: self)
|
530
|
-
puts 'h2: ' + h2.inspect
|
1006
|
+
puts 'h2: ' + h2.inspect if @debug
|
531
1007
|
r = klass.new h2
|
532
|
-
puts 'r:' + r.inspect
|
1008
|
+
puts 'r:' + r.inspect if @debug
|
533
1009
|
r
|
534
1010
|
|
535
1011
|
end
|
536
1012
|
|
537
1013
|
end
|
538
1014
|
|
539
|
-
def
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
type = VAR_TYPES[value.class.to_s.to_sym]
|
546
|
-
|
547
|
-
h = {
|
548
|
-
boolean_value: false,
|
549
|
-
decimal_value: 0.0,
|
550
|
-
int_value: 0,
|
551
|
-
name: key,
|
552
|
-
string_value: '',
|
553
|
-
type: type[0]
|
554
|
-
}
|
555
|
-
h[type[1]] = value
|
556
|
-
h
|
1015
|
+
def object_create(klass, *args)
|
1016
|
+
|
1017
|
+
begin
|
1018
|
+
klass.new(*args)
|
1019
|
+
rescue
|
1020
|
+
raise MacroError, klass.to_s + ': ' + ($!).to_s
|
557
1021
|
end
|
1022
|
+
end
|
1023
|
+
|
1024
|
+
def varify(label, value='')
|
1025
|
+
|
1026
|
+
|
1027
|
+
type = VAR_TYPES[value.class.to_s.to_sym]
|
1028
|
+
|
1029
|
+
h = {
|
1030
|
+
boolean_value: false,
|
1031
|
+
decimal_value: 0.0,
|
1032
|
+
int_value: 0,
|
1033
|
+
name: label,
|
1034
|
+
string_value: '',
|
1035
|
+
type: type[0]
|
1036
|
+
}
|
1037
|
+
h[type[1]] = value
|
1038
|
+
h
|
558
1039
|
|
559
1040
|
end
|
560
1041
|
|