ruby-macrodroid 0.9.9 → 0.9.14
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 +50 -33
- data/lib/ruby-macrodroid/actions.rb +160 -59
- data/lib/ruby-macrodroid/actionsnlp.rb +252 -0
- data/lib/ruby-macrodroid/base.rb +11 -6
- data/lib/ruby-macrodroid/constraintsnlp.rb +75 -0
- data/lib/ruby-macrodroid/macro.rb +26 -473
- data/lib/ruby-macrodroid/triggers.rb +160 -18
- data/lib/ruby-macrodroid/triggersnlp.rb +219 -0
- metadata +5 -2
- metadata.gz.sig +0 -0
@@ -0,0 +1,252 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# file: actionsnlp.rb
|
4
|
+
|
5
|
+
|
6
|
+
class ActionsNlp
|
7
|
+
include AppRoutes
|
8
|
+
|
9
|
+
def initialize(macro=nil)
|
10
|
+
|
11
|
+
super()
|
12
|
+
|
13
|
+
params = {macro: macro}
|
14
|
+
actions(params)
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def actions(params)
|
19
|
+
|
20
|
+
# -- Conditions/Loops ---------------------------------------------
|
21
|
+
#
|
22
|
+
|
23
|
+
get /else if (.*)/i do
|
24
|
+
[ElseIfConditionAction, {}]
|
25
|
+
end
|
26
|
+
|
27
|
+
#e.g a: if Airplane mode enabled
|
28
|
+
#
|
29
|
+
get /if (.*)/i do
|
30
|
+
[IfConditionAction, {}]
|
31
|
+
end
|
32
|
+
|
33
|
+
get /else/i do
|
34
|
+
[ElseAction, {}]
|
35
|
+
end
|
36
|
+
|
37
|
+
get /End If/i do
|
38
|
+
[EndIfAction, {}]
|
39
|
+
end
|
40
|
+
|
41
|
+
|
42
|
+
# -- Connectivity ------------------------------------------------------
|
43
|
+
|
44
|
+
get /^(Enable|Disable) HotSpot/i do |state|
|
45
|
+
enable, state = if state.downcase == 'enable' then
|
46
|
+
[true, 0]
|
47
|
+
else
|
48
|
+
[false, 1]
|
49
|
+
end
|
50
|
+
[SetHotspotAction, {turn_wifi_on: enable, state: state }]
|
51
|
+
end
|
52
|
+
|
53
|
+
# e.g. message popup: hello world!
|
54
|
+
get /^(?:message popup|popup message): (.*)/i do |msg|
|
55
|
+
[ToastAction, {msg: msg}]
|
56
|
+
end
|
57
|
+
|
58
|
+
# e.g. Popup Message 'hello world!'
|
59
|
+
get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
|
60
|
+
[ToastAction, {msg: msg}]
|
61
|
+
end
|
62
|
+
|
63
|
+
# e.g. Popup Message\n hello world!
|
64
|
+
get /^Popup Message\n\s+(.*)/im do |msg|
|
65
|
+
[ToastAction, {msg: msg}]
|
66
|
+
end
|
67
|
+
|
68
|
+
# e.g. Popup Message
|
69
|
+
get /^Popup Message$/i do
|
70
|
+
[ToastAction, {}]
|
71
|
+
end
|
72
|
+
|
73
|
+
# e.g. say current time
|
74
|
+
get /^say current[ _]time/i do
|
75
|
+
[SayTimeAction, {}]
|
76
|
+
end
|
77
|
+
|
78
|
+
get /^Torch :?(.*)/i do |onoffstate|
|
79
|
+
state = %w(on off toggle).index onoffstate.downcase
|
80
|
+
[CameraFlashLightAction, {state: state}]
|
81
|
+
end
|
82
|
+
|
83
|
+
get /^Take Picture/i do
|
84
|
+
[TakePictureAction, {}]
|
85
|
+
end
|
86
|
+
|
87
|
+
get /^take_picture/i do
|
88
|
+
[TakePictureAction, {}]
|
89
|
+
end
|
90
|
+
|
91
|
+
# -- DEVICE ACTIONS ------------------------------------------------------
|
92
|
+
|
93
|
+
get /^Speak text \(([^\)]+)\)/i do |text|
|
94
|
+
[SpeakTextAction, {text: text}]
|
95
|
+
end
|
96
|
+
|
97
|
+
get /^Speak text ['"]([^'"]+)/i do |text|
|
98
|
+
[SpeakTextAction, {text: text}]
|
99
|
+
end
|
100
|
+
|
101
|
+
get /^Speak text$/i do |text|
|
102
|
+
[SpeakTextAction, {}]
|
103
|
+
end
|
104
|
+
|
105
|
+
get /^Vibrate \(([^\)]+)/i do |pattern|
|
106
|
+
[VibrateAction, {pattern: pattern}]
|
107
|
+
end
|
108
|
+
|
109
|
+
get /^Vibrate$/i do |pattern|
|
110
|
+
[VibrateAction, {pattern: 'short buzz'}]
|
111
|
+
end
|
112
|
+
|
113
|
+
# e.g. Display Notification: Hi there: This is the body of the message
|
114
|
+
get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
|
115
|
+
[NotificationAction, {subject: subject, text: text}]
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
# e.g. Enable Wifi
|
120
|
+
get /^(Enable|Disable) Wifi$/i do |raw_state|
|
121
|
+
|
122
|
+
state = raw_state.downcase.to_sym == :enable ? 0 : 1
|
123
|
+
[SetWifiAction, {state: state}]
|
124
|
+
|
125
|
+
end
|
126
|
+
|
127
|
+
# e.g. Play: Altair
|
128
|
+
get /^Play: (.*)$/i do |name|
|
129
|
+
|
130
|
+
[PlaySoundAction, {file_path: name}]
|
131
|
+
|
132
|
+
end
|
133
|
+
|
134
|
+
# e.g. Launch Settings
|
135
|
+
get /^Launch (.*)$/i do |application|
|
136
|
+
|
137
|
+
h = {
|
138
|
+
application_name: application,
|
139
|
+
package_to_launch: 'com.android.' + application.downcase
|
140
|
+
}
|
141
|
+
[LaunchActivityAction, h]
|
142
|
+
|
143
|
+
end
|
144
|
+
|
145
|
+
# e.g. HTTP GET http://someurl.com/something
|
146
|
+
get /^HTTP GET ([^$]+)$/i do |url|
|
147
|
+
|
148
|
+
[OpenWebPageAction, url_to_open: url]
|
149
|
+
|
150
|
+
end
|
151
|
+
|
152
|
+
get /^HTTP GET$/i do
|
153
|
+
|
154
|
+
[OpenWebPageAction, {}]
|
155
|
+
|
156
|
+
end
|
157
|
+
|
158
|
+
# e.g. webhook entered_kitchen
|
159
|
+
#
|
160
|
+
get /(?:webhook|HTTP GET) ([^$]+)$/i do |s|
|
161
|
+
key = s =~ /^http/ ? :url_to_open : :identifier
|
162
|
+
[OpenWebPageAction, {key => s}]
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
get /^WebHook \(Url\)/i do
|
167
|
+
[OpenWebPageAction, {}]
|
168
|
+
end
|
169
|
+
|
170
|
+
# e.g. webhook entered_kitchen
|
171
|
+
#
|
172
|
+
get /^webhook$/i do
|
173
|
+
[OpenWebPageAction, {}, params[:macro]]
|
174
|
+
end
|
175
|
+
|
176
|
+
# -- Location ---------------------------------------------------------
|
177
|
+
|
178
|
+
get /^Force Location Update$/i do
|
179
|
+
[ForceLocationUpdateAction, params]
|
180
|
+
end
|
181
|
+
|
182
|
+
get /^Share Location$/i do
|
183
|
+
[ShareLocationAction, {}]
|
184
|
+
end
|
185
|
+
|
186
|
+
#a: Keep Device Awake Screen On Until Disabled
|
187
|
+
#
|
188
|
+
get /Keep Device Awake Screen On Until Disabled/i do
|
189
|
+
[KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
#a: Keep Device Awake Screen On 1h 1m 1s
|
194
|
+
#
|
195
|
+
get /Keep Device Awake Screen On ([^$]+)/i do |duration|
|
196
|
+
|
197
|
+
a = duration.split.map(&:to_i)
|
198
|
+
secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
|
199
|
+
|
200
|
+
h = {
|
201
|
+
permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
|
202
|
+
}
|
203
|
+
[KeepAwakeAction, h]
|
204
|
+
end
|
205
|
+
|
206
|
+
get /(?:Keep Device|stay) Awake$/i do
|
207
|
+
[KeepAwakeAction, {}]
|
208
|
+
end
|
209
|
+
|
210
|
+
#a: Disable Keep Awake
|
211
|
+
#
|
212
|
+
get /Disable Keep Awake|stay awake off/i do
|
213
|
+
[KeepAwakeAction, {enabled: false, screen_option: 0}]
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
# -- MacroDroid Specific ------------------------------------------------
|
218
|
+
#
|
219
|
+
|
220
|
+
get /^((?:En|Dis)able) Macro$/i do |rawstate|
|
221
|
+
state = %w(enable disable toggle).index(rawstate.downcase)
|
222
|
+
[DisableMacroAction, {state: state}]
|
223
|
+
end
|
224
|
+
|
225
|
+
get /^Macro Run$/i do
|
226
|
+
[ForceMacroRunAction, {}]
|
227
|
+
end
|
228
|
+
|
229
|
+
get /^Run Macro$/i do
|
230
|
+
[ForceMacroRunAction, {}]
|
231
|
+
end
|
232
|
+
|
233
|
+
get /^Set Variable$/i do
|
234
|
+
[SetVariableAction, {}]
|
235
|
+
end
|
236
|
+
|
237
|
+
get /^wait (\d+) seconds$/i do |seconds|
|
238
|
+
[PauseAction, {delay_in_seconds: seconds.to_i}]
|
239
|
+
end
|
240
|
+
|
241
|
+
# -- Screen ------------------------------------------------
|
242
|
+
#
|
243
|
+
get /^Screen (On|Off)$/i do |state|
|
244
|
+
[ScreenOnAction, {screen_off: state.downcase == 'off'}]
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
248
|
+
|
249
|
+
alias find_action run_route
|
250
|
+
|
251
|
+
|
252
|
+
end
|
data/lib/ruby-macrodroid/base.rb
CHANGED
@@ -34,7 +34,10 @@ module ObjectX
|
|
34
34
|
r = ap.find_action action
|
35
35
|
puts 'r: ' + r.inspect if debug
|
36
36
|
|
37
|
-
|
37
|
+
nested = description.element('item/description')
|
38
|
+
puts 'nested: ' + nested.inspect if debug
|
39
|
+
|
40
|
+
if r[1].any? and not nested then
|
38
41
|
|
39
42
|
macro.add r[0].new(r[1])
|
40
43
|
|
@@ -44,7 +47,7 @@ module ObjectX
|
|
44
47
|
#o = r[0].new([description, self]) if r
|
45
48
|
index = macro.actions.length
|
46
49
|
macro.add Action.new
|
47
|
-
o = object_create(r[0],[description, macro]) if r
|
50
|
+
o = object_create(r[0],[description, macro, r[1]]) if r
|
48
51
|
macro.actions[index] = o
|
49
52
|
puts 'after o' if debug
|
50
53
|
o
|
@@ -130,7 +133,8 @@ class MacroObject
|
|
130
133
|
end
|
131
134
|
|
132
135
|
def to_h()
|
133
|
-
|
136
|
+
|
137
|
+
@h.delete :macro
|
134
138
|
hashify(@h)
|
135
139
|
|
136
140
|
end
|
@@ -194,14 +198,15 @@ class MacroObject
|
|
194
198
|
private
|
195
199
|
|
196
200
|
def hashify(h)
|
197
|
-
puts 'h: ' + h.inspect
|
201
|
+
#puts 'h: ' + h.inspect
|
198
202
|
h2 = h.inject({}) do |r,x|
|
199
|
-
puts 'x: ' + x.inspect #if $debug
|
203
|
+
#puts 'x: ' + x.inspect #if $debug
|
200
204
|
key, value = x
|
201
|
-
puts 'key: ' + key.inspect #if $debug
|
205
|
+
#puts 'key: ' + key.inspect #if $debug
|
202
206
|
new_key = key.to_s.gsub(/\w_\w/){|x| x[0] + x[-1].upcase}
|
203
207
|
new_key = new_key.prepend 'm_' unless @list.include? new_key
|
204
208
|
new_key = 'm_SIGUID' if new_key == 'm_siguid'
|
209
|
+
new_key = 'm_SSIDList' if new_key == 'm_ssidList'
|
205
210
|
new_val = value.is_a?(Hash) ? hashify(value) : value
|
206
211
|
r.merge(new_key => new_val)
|
207
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,450 +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
|
-
# -- Connectivity ------------------------------------------------------
|
187
|
-
|
188
|
-
get /^(Enable|Disable) HotSpot/i do |state|
|
189
|
-
enable, state = if state.downcase == 'enable' then
|
190
|
-
[true, 0]
|
191
|
-
else
|
192
|
-
[false, 1]
|
193
|
-
end
|
194
|
-
[SetHotspotAction, {turn_wifi_on: enable, state: state }]
|
195
|
-
end
|
196
|
-
|
197
|
-
# e.g. message popup: hello world!
|
198
|
-
get /^message popup: (.*)/i do |msg|
|
199
|
-
[ToastAction, {msg: msg}]
|
200
|
-
end
|
201
|
-
|
202
|
-
# e.g. Popup Message 'hello world!'
|
203
|
-
get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
|
204
|
-
[ToastAction, {msg: msg}]
|
205
|
-
end
|
206
|
-
|
207
|
-
# e.g. Popup Message\n hello world!
|
208
|
-
get /^Popup Message\n\s+(.*)/im do |msg|
|
209
|
-
[ToastAction, {msg: msg}]
|
210
|
-
end
|
211
|
-
|
212
|
-
# e.g. Popup Message
|
213
|
-
get /^Popup Message$/i do
|
214
|
-
[ToastAction, {}]
|
215
|
-
end
|
216
|
-
|
217
|
-
# e.g. say current time
|
218
|
-
get /^say current[ _]time/i do
|
219
|
-
[SayTimeAction, {}]
|
220
|
-
end
|
221
|
-
|
222
|
-
get /^Torch :?(.*)/i do |onoffstate|
|
223
|
-
state = %w(on off toggle).index onoffstate.downcase
|
224
|
-
[CameraFlashLightAction, {state: state}]
|
225
|
-
end
|
226
|
-
|
227
|
-
get /^Take Picture/i do
|
228
|
-
[TakePictureAction, {}]
|
229
|
-
end
|
230
|
-
|
231
|
-
get /^take_picture/i do
|
232
|
-
[TakePictureAction, {}]
|
233
|
-
end
|
234
|
-
|
235
|
-
# -- DEVICE ACTIONS ------------------------------------------------------
|
236
|
-
|
237
|
-
get /^Speak text \(([^\)]+)\)/i do |text|
|
238
|
-
[SpeakTextAction, {text: text}]
|
239
|
-
end
|
240
|
-
|
241
|
-
get /^Speak text ['"]([^'"]+)/i do |text|
|
242
|
-
[SpeakTextAction, {text: text}]
|
243
|
-
end
|
244
|
-
|
245
|
-
get /^Speak text$/i do |text|
|
246
|
-
[SpeakTextAction, {}]
|
247
|
-
end
|
248
|
-
|
249
|
-
get /^Vibrate \(([^\)]+)/i do |pattern|
|
250
|
-
[VibrateAction, {pattern: pattern}]
|
251
|
-
end
|
252
|
-
|
253
|
-
get /^Vibrate$/i do |pattern|
|
254
|
-
[VibrateAction, {pattern: 'short buzz'}]
|
255
|
-
end
|
256
|
-
|
257
|
-
# e.g. Display Notification: Hi there: This is the body of the message
|
258
|
-
get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
|
259
|
-
[NotificationAction, {subject: subject, text: text}]
|
260
|
-
end
|
261
|
-
|
262
|
-
|
263
|
-
# e.g. Enable Wifi
|
264
|
-
get /^(Enable|Disable) Wifi$/i do |raw_state|
|
265
|
-
|
266
|
-
state = raw_state.downcase.to_sym == :enable ? 0 : 1
|
267
|
-
[SetWifiAction, {state: state}]
|
268
|
-
|
269
|
-
end
|
270
|
-
|
271
|
-
# e.g. Play: Altair
|
272
|
-
get /^Play: (.*)$/i do |name|
|
273
|
-
|
274
|
-
[PlaySoundAction, {file_path: name}]
|
275
|
-
|
276
|
-
end
|
277
|
-
|
278
|
-
# e.g. Launch Settings
|
279
|
-
get /^Launch (.*)$/i do |application|
|
280
|
-
|
281
|
-
h = {
|
282
|
-
application_name: application,
|
283
|
-
package_to_launch: 'com.android.' + application.downcase
|
284
|
-
}
|
285
|
-
[LaunchActivityAction, h]
|
286
|
-
|
287
|
-
end
|
288
|
-
|
289
|
-
# e.g. HTTP GET http://someurl.com/something
|
290
|
-
get /^HTTP GET ([^$]+)$/i do |url|
|
291
|
-
|
292
|
-
[OpenWebPageAction, url_to_open: url]
|
293
|
-
|
294
|
-
end
|
295
|
-
|
296
|
-
get /^HTTP GET$/i do
|
297
|
-
|
298
|
-
[OpenWebPageAction, {}]
|
299
|
-
|
300
|
-
end
|
301
|
-
|
302
|
-
# e.g. webhook entered_kitchen
|
303
|
-
#
|
304
|
-
get /(?:webhook|HTTP GET) ([^$]+)$/i do |s|
|
305
|
-
key = s =~ /^http/ ? :url_to_open : :identifier
|
306
|
-
[OpenWebPageAction, {key => s}]
|
307
|
-
end
|
308
|
-
|
309
|
-
#
|
310
|
-
get /^WebHook \(Url\)/i do
|
311
|
-
[OpenWebPageAction, {}]
|
312
|
-
end
|
313
|
-
|
314
|
-
# e.g. webhook entered_kitchen
|
315
|
-
#
|
316
|
-
get /^webhook$/i do
|
317
|
-
[OpenWebPageAction, {}, params[:macro]]
|
318
|
-
end
|
319
|
-
|
320
|
-
# -- Location ---------------------------------------------------------
|
321
|
-
|
322
|
-
get /^Force Location Update$/i do
|
323
|
-
[ForceLocationUpdateAction, params]
|
324
|
-
end
|
325
|
-
|
326
|
-
get /^Share Location$/i do
|
327
|
-
[ShareLocationAction, {}]
|
328
|
-
end
|
329
|
-
|
330
|
-
#a: Keep Device Awake Screen On Until Disabled
|
331
|
-
#
|
332
|
-
get /Keep Device Awake Screen On Until Disabled/i do
|
333
|
-
[KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
|
334
|
-
end
|
335
|
-
|
336
|
-
|
337
|
-
#a: Keep Device Awake Screen On 1h 1m 1s
|
338
|
-
#
|
339
|
-
get /Keep Device Awake Screen On ([^$]+)/i do |duration|
|
340
|
-
|
341
|
-
a = duration.split.map(&:to_i)
|
342
|
-
secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
|
343
|
-
|
344
|
-
h = {
|
345
|
-
permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
|
346
|
-
}
|
347
|
-
[KeepAwakeAction, h]
|
348
|
-
end
|
349
|
-
|
350
|
-
get /(?:Keep Device|stay) Awake$/i do
|
351
|
-
[KeepAwakeAction, {}]
|
352
|
-
end
|
353
|
-
|
354
|
-
#a: Disable Keep Awake
|
355
|
-
#
|
356
|
-
get /Disable Keep Awake|stay awake off/i do
|
357
|
-
[KeepAwakeAction, {enabled: false, screen_option: 0}]
|
358
|
-
end
|
359
|
-
|
360
|
-
#e.g a: if Airplane mode enabled
|
361
|
-
#
|
362
|
-
get /if (.*)/i do
|
363
|
-
[IfConditionAction, {}]
|
364
|
-
end
|
365
|
-
|
366
|
-
get /else/i do
|
367
|
-
[ElseAction, {}]
|
368
|
-
end
|
369
|
-
|
370
|
-
get /End If/i do
|
371
|
-
[EndIfAction, {}]
|
372
|
-
end
|
373
|
-
|
374
|
-
# -- MacroDroid Specific ------------------------------------------------
|
375
|
-
#
|
376
|
-
get /^Set Variable$/i do
|
377
|
-
[SetVariableAction, {}]
|
378
|
-
end
|
379
|
-
|
380
|
-
get /^wait (\d+) seconds$/i do |seconds|
|
381
|
-
[PauseAction, {delay_in_seconds: seconds.to_i}]
|
382
|
-
end
|
383
|
-
|
384
|
-
# -- Screen ------------------------------------------------
|
385
|
-
#
|
386
|
-
get /^Screen (On|Off)$/i do |state|
|
387
|
-
[ScreenOnAction, {screen_off: state.downcase == 'off'}]
|
388
|
-
end
|
389
|
-
|
390
|
-
end
|
391
|
-
|
392
|
-
alias find_action run_route
|
393
|
-
|
394
|
-
|
395
|
-
end
|
396
|
-
|
397
|
-
class ConstraintsNlp
|
398
|
-
include AppRoutes
|
399
|
-
|
400
|
-
def initialize()
|
401
|
-
|
402
|
-
super()
|
403
|
-
params = {}
|
404
|
-
constraints(params)
|
405
|
-
|
406
|
-
end
|
407
|
-
|
408
|
-
def constraints(params)
|
409
|
-
|
410
|
-
# Device State
|
411
|
-
|
412
|
-
get /^Device (locked|unlocked)/i do |state|
|
413
|
-
[DeviceLockedConstraint, {locked: state.downcase == 'locked'}]
|
414
|
-
end
|
415
|
-
|
416
|
-
get /^airplane mode (.*)/i do |state|
|
417
|
-
[AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
|
418
|
-
end
|
419
|
-
|
420
|
-
#
|
421
|
-
|
422
|
-
# -- MacroDroid specific -----------------------------------------------------------------------
|
423
|
-
|
424
|
-
get /^(\w+) (=) (\[?\w+\]?)/i do |loperand, operator, roperand|
|
425
|
-
|
426
|
-
h = {
|
427
|
-
loperand: loperand,
|
428
|
-
operator: operator,
|
429
|
-
roperand: roperand
|
430
|
-
}
|
431
|
-
|
432
|
-
[MacroDroidVariableConstraint, h]
|
433
|
-
|
434
|
-
end
|
435
|
-
|
436
|
-
# -- Sensors -----------------------------------
|
437
|
-
#
|
438
|
-
get /^Light Sensor (Less|Greater) than (50.0)lx/i do |operator, val|
|
439
|
-
|
440
|
-
level, option = operator.downcase == 'less' ? [-1,0] : [1,1]
|
441
|
-
|
442
|
-
h = {
|
443
|
-
light_level: level,
|
444
|
-
light_level_float: val,
|
445
|
-
option: option
|
446
|
-
}
|
447
|
-
|
448
|
-
[LightLevelConstraint, h]
|
449
|
-
end
|
450
|
-
|
451
|
-
get /^Proximity Sensor: (Near|Far)/i do |distance|
|
452
|
-
[ProximitySensorConstraint, {near: distance.downcase == 'near'}]
|
453
|
-
end
|
454
|
-
|
455
|
-
|
456
|
-
# -- Screen and Speaker ---------------------------
|
457
|
-
#
|
458
|
-
get /^Screen (On|Off)/i do |state|
|
459
|
-
[ScreenOnOffConstraint, {screen_on: state.downcase == 'on'}]
|
460
|
-
end
|
461
|
-
|
462
|
-
end
|
463
|
-
|
464
|
-
alias find_constraint run_route
|
465
|
-
|
466
|
-
end
|
467
|
-
|
468
|
-
|
469
20
|
class MacroError < Exception
|
470
21
|
end
|
471
22
|
|
@@ -475,19 +26,21 @@ class Macro
|
|
475
26
|
include ObjectX
|
476
27
|
|
477
28
|
attr_reader :local_variables, :triggers, :actions, :constraints,
|
478
|
-
:guid, :deviceid
|
29
|
+
:guid, :deviceid, :parent
|
479
30
|
attr_accessor :title, :description, :remote_url, :picture_path
|
480
31
|
|
481
32
|
def initialize(name=nil, geofences: nil, deviceid: nil, remote_url: nil, \
|
482
|
-
picture_path: nil, debug: false)
|
33
|
+
picture_path: nil, parent: nil, debug: false)
|
483
34
|
|
484
35
|
@title, @geofences, @deviceid, @debug = name, geofences, deviceid, debug
|
485
|
-
@remote_url, @picture_path = remote_url, picture_path
|
36
|
+
@remote_url, @picture_path, @parent = remote_url, picture_path, parent
|
486
37
|
|
487
38
|
puts 'inside Macro#initialize' if @debug
|
488
39
|
|
489
40
|
@local_variables, @triggers, @actions, @constraints = {}, [], [], []
|
490
41
|
@h = {}
|
42
|
+
@guid = generate_guid()
|
43
|
+
@enabled = true
|
491
44
|
|
492
45
|
end
|
493
46
|
|
@@ -513,6 +66,18 @@ class Macro
|
|
513
66
|
end
|
514
67
|
|
515
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
|
516
81
|
|
517
82
|
def to_h()
|
518
83
|
|
@@ -529,9 +94,9 @@ class Macro
|
|
529
94
|
m_description: '',
|
530
95
|
m_name: title(),
|
531
96
|
m_excludeLog: false,
|
532
|
-
m_GUID: guid
|
97
|
+
m_GUID: @guid,
|
533
98
|
m_isOrCondition: false,
|
534
|
-
m_enabled:
|
99
|
+
m_enabled: @enabled,
|
535
100
|
m_descriptionOpen: false,
|
536
101
|
m_headingColor: 0
|
537
102
|
}
|
@@ -548,6 +113,7 @@ class Macro
|
|
548
113
|
puts 'h:' + h.inspect
|
549
114
|
end
|
550
115
|
|
116
|
+
@guid = h[:guid]
|
551
117
|
@category = h[:category]
|
552
118
|
@title = h[:name]
|
553
119
|
@description = h[:description]
|
@@ -702,7 +268,7 @@ class Macro
|
|
702
268
|
r = tp.find_trigger trigger
|
703
269
|
puts 'r: ' + r.inspect if @debug
|
704
270
|
#o = r[0].new([description, self]) if r
|
705
|
-
o = object_create(r[0], [description, self]) if r
|
271
|
+
o = object_create(r[0], [description, self, r[1]]) if r
|
706
272
|
puts 'after o' if @debug
|
707
273
|
o
|
708
274
|
|
@@ -748,7 +314,6 @@ class Macro
|
|
748
314
|
|
749
315
|
end
|
750
316
|
|
751
|
-
|
752
317
|
|
753
318
|
ap = ActionsNlp.new self
|
754
319
|
|
@@ -791,7 +356,7 @@ class Macro
|
|
791
356
|
|
792
357
|
end
|
793
358
|
|
794
|
-
def match?(triggerx, detail={
|
359
|
+
def match?(triggerx, detail={}, model=nil )
|
795
360
|
|
796
361
|
if @triggers.any? {|x| x.type == triggerx and x.match?(detail, model) } then
|
797
362
|
|
@@ -922,8 +487,6 @@ EOF
|
|
922
487
|
s = x.to_s(colour: colour)
|
923
488
|
#puts 's: ' + s.inspect
|
924
489
|
|
925
|
-
|
926
|
-
|
927
490
|
r = if indent <= 0 then
|
928
491
|
|
929
492
|
lines = s.lines
|
@@ -976,9 +539,6 @@ EOF
|
|
976
539
|
|
977
540
|
end.join("\n")
|
978
541
|
|
979
|
-
|
980
|
-
|
981
|
-
|
982
542
|
a << actions
|
983
543
|
|
984
544
|
|
@@ -989,10 +549,6 @@ EOF
|
|
989
549
|
end.join("\n")
|
990
550
|
end
|
991
551
|
|
992
|
-
|
993
|
-
|
994
|
-
|
995
|
-
|
996
552
|
a.join("\n") + "\n"
|
997
553
|
|
998
554
|
end
|
@@ -1036,8 +592,8 @@ EOF
|
|
1036
592
|
|
1037
593
|
private
|
1038
594
|
|
1039
|
-
def
|
1040
|
-
'-' + rand(1..9).to_s + 18.times.map { rand 9 }.join
|
595
|
+
def generate_guid()
|
596
|
+
('-' + rand(1..9).to_s + 18.times.map { rand 9 }.join).to_i
|
1041
597
|
end
|
1042
598
|
|
1043
599
|
def object(h={})
|
@@ -1059,9 +615,6 @@ EOF
|
|
1059
615
|
|
1060
616
|
end
|
1061
617
|
|
1062
|
-
end
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
618
|
+
end
|
1066
619
|
|
1067
620
|
end
|