ruby-macrodroid 0.9.7 → 0.9.12
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 +56 -35
- data/lib/ruby-macrodroid/actions.rb +150 -53
- data/lib/ruby-macrodroid/actionsnlp.rb +244 -0
- data/lib/ruby-macrodroid/base.rb +7 -5
- data/lib/ruby-macrodroid/constraintsnlp.rb +75 -0
- data/lib/ruby-macrodroid/macro.rb +26 -462
- data/lib/ruby-macrodroid/triggers.rb +5 -0
- data/lib/ruby-macrodroid/triggersnlp.rb +150 -0
- metadata +5 -2
- metadata.gz.sig +0 -0
@@ -0,0 +1,244 @@
|
|
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 /^Set Variable$/i do
|
226
|
+
[SetVariableAction, {}]
|
227
|
+
end
|
228
|
+
|
229
|
+
get /^wait (\d+) seconds$/i do |seconds|
|
230
|
+
[PauseAction, {delay_in_seconds: seconds.to_i}]
|
231
|
+
end
|
232
|
+
|
233
|
+
# -- Screen ------------------------------------------------
|
234
|
+
#
|
235
|
+
get /^Screen (On|Off)$/i do |state|
|
236
|
+
[ScreenOnAction, {screen_off: state.downcase == 'off'}]
|
237
|
+
end
|
238
|
+
|
239
|
+
end
|
240
|
+
|
241
|
+
alias find_action run_route
|
242
|
+
|
243
|
+
|
244
|
+
end
|
data/lib/ruby-macrodroid/base.rb
CHANGED
@@ -34,7 +34,9 @@ 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
|
+
|
39
|
+
if r[1].any? and not nested then
|
38
40
|
|
39
41
|
macro.add r[0].new(r[1])
|
40
42
|
|
@@ -44,7 +46,7 @@ module ObjectX
|
|
44
46
|
#o = r[0].new([description, self]) if r
|
45
47
|
index = macro.actions.length
|
46
48
|
macro.add Action.new
|
47
|
-
o = object_create(r[0],[description, macro]) if r
|
49
|
+
o = object_create(r[0],[description, macro, r[1]]) if r
|
48
50
|
macro.actions[index] = o
|
49
51
|
puts 'after o' if debug
|
50
52
|
o
|
@@ -194,11 +196,11 @@ class MacroObject
|
|
194
196
|
private
|
195
197
|
|
196
198
|
def hashify(h)
|
197
|
-
puts 'h: ' + h.inspect
|
199
|
+
#puts 'h: ' + h.inspect
|
198
200
|
h2 = h.inject({}) do |r,x|
|
199
|
-
puts 'x: ' + x.inspect #if $debug
|
201
|
+
#puts 'x: ' + x.inspect #if $debug
|
200
202
|
key, value = x
|
201
|
-
puts 'key: ' + key.inspect #if $debug
|
203
|
+
#puts 'key: ' + key.inspect #if $debug
|
202
204
|
new_key = key.to_s.gsub(/\w_\w/){|x| x[0] + x[-1].upcase}
|
203
205
|
new_key = new_key.prepend 'm_' unless @list.include? new_key
|
204
206
|
new_key = 'm_SIGUID' if new_key == 'm_siguid'
|
@@ -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,439 +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
|
-
# e.g. at 7:30pm daily
|
73
|
-
get /^(?:at )?(\d+:\d+(?:[ap]m)?) daily/i do |time, days|
|
74
|
-
[TimerTrigger, {time: time,
|
75
|
-
days: %w(Mon Tue Wed Thu Fri Sat Sun).join(', ')}]
|
76
|
-
end
|
77
|
-
|
78
|
-
get /^(?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)/i do |time, days|
|
79
|
-
[TimerTrigger, {time: time, days: days}]
|
80
|
-
end
|
81
|
-
|
82
|
-
# time.is? 'at 18:30pm on Mon or Tue'
|
83
|
-
get /^time.is\? ['"](?:at )?(\d+:\d+(?:[ap]m)?) (?:on )?(.*)['"]/i do |time, days|
|
84
|
-
[TimerTrigger, {time: time, days: days.gsub(' or ',', ')}]
|
85
|
-
end
|
86
|
-
|
87
|
-
get /^shake[ _]device\??$/i do
|
88
|
-
[ShakeDeviceTrigger, {}]
|
89
|
-
end
|
90
|
-
|
91
|
-
get /^Flip Device (.*)$/i do |motion|
|
92
|
-
facedown = motion =~ /Face Up (?:->|to) Face Down/i
|
93
|
-
[FlipDeviceTrigger, {face_down: facedown }]
|
94
|
-
end
|
95
|
-
|
96
|
-
get /^flip_device_down\?$/i do
|
97
|
-
[FlipDeviceTrigger, {face_down: true }]
|
98
|
-
end
|
99
|
-
|
100
|
-
get /^flip_device_up\?$/i do
|
101
|
-
[FlipDeviceTrigger, {face_down: false }]
|
102
|
-
end
|
103
|
-
|
104
|
-
get /^Failed Login Attempt$/i do
|
105
|
-
[FailedLoginTrigger, {}]
|
106
|
-
end
|
107
|
-
|
108
|
-
get /^failed_login?$/i do
|
109
|
-
[FailedLoginTrigger, {}]
|
110
|
-
end
|
111
|
-
|
112
|
-
get /^Geofence (Entry|Exit) \(([^\)]+)/i do |direction, name|
|
113
|
-
enter_area = direction.downcase.to_sym == :entry
|
114
|
-
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
115
|
-
end
|
116
|
-
|
117
|
-
get /^location (entered|exited) \(([^\)]+)/i do |direction, name|
|
118
|
-
enter_area = direction.downcase.to_sym == :entered
|
119
|
-
[GeofenceTrigger, {name: name, enter_area: enter_area}]
|
120
|
-
end
|
121
|
-
|
122
|
-
# eg. Proximity Sensor (Near)
|
123
|
-
#
|
124
|
-
get /^Proximity Sensor \(([^\)]+)\)/i do |distance|
|
125
|
-
|
126
|
-
[ProximityTrigger, {distance: distance}]
|
127
|
-
end
|
128
|
-
|
129
|
-
# eg. Proximity near
|
130
|
-
#
|
131
|
-
get /^Proximity (near|far|slow wave|fast wave)/i do |distance|
|
132
|
-
|
133
|
-
[ProximityTrigger, {distance: distance}]
|
134
|
-
end
|
135
|
-
|
136
|
-
get /^WebHook \(Url\)/i do
|
137
|
-
[WebHookTrigger, params]
|
138
|
-
end
|
139
|
-
|
140
|
-
get /^WebHook/i do
|
141
|
-
[WebHookTrigger, params]
|
142
|
-
end
|
143
|
-
|
144
|
-
get /^wh/i do
|
145
|
-
[WebHookTrigger, params]
|
146
|
-
end
|
147
|
-
|
148
|
-
# MacroDroid specific ---------------------------------------------------------------
|
149
|
-
|
150
|
-
get /^EmptyTrigger$/i do
|
151
|
-
[EmptyTrigger, params]
|
152
|
-
end
|
153
|
-
|
154
|
-
end
|
155
|
-
|
156
|
-
alias find_trigger run_route
|
157
|
-
|
158
|
-
def to_s(colour: false)
|
159
|
-
'TriggersNlp ' + @h.inspect
|
160
|
-
end
|
161
|
-
|
162
|
-
alias to_summary to_s
|
163
|
-
end
|
164
|
-
|
165
|
-
class ActionsNlp
|
166
|
-
include AppRoutes
|
167
|
-
|
168
|
-
def initialize(macro=nil)
|
169
|
-
|
170
|
-
super()
|
171
|
-
|
172
|
-
params = {macro: macro}
|
173
|
-
actions(params)
|
174
|
-
|
175
|
-
end
|
176
|
-
|
177
|
-
def actions(params)
|
178
|
-
|
179
|
-
# -- Connectivity ------------------------------------------------------
|
180
|
-
|
181
|
-
get /^(Enable|Disable) HotSpot/i do |state|
|
182
|
-
enable, state = if state.downcase == 'enable' then
|
183
|
-
[true, 0]
|
184
|
-
else
|
185
|
-
[false, 1]
|
186
|
-
end
|
187
|
-
[SetHotspotAction, {turn_wifi_on: enable, state: state }]
|
188
|
-
end
|
189
|
-
|
190
|
-
# e.g. message popup: hello world!
|
191
|
-
get /^message popup: (.*)/i do |msg|
|
192
|
-
[ToastAction, {msg: msg}]
|
193
|
-
end
|
194
|
-
|
195
|
-
# e.g. Popup Message 'hello world!'
|
196
|
-
get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
|
197
|
-
[ToastAction, {msg: msg}]
|
198
|
-
end
|
199
|
-
|
200
|
-
# e.g. Popup Message\n hello world!
|
201
|
-
get /^Popup Message\n\s+(.*)/im do |msg|
|
202
|
-
[ToastAction, {msg: msg}]
|
203
|
-
end
|
204
|
-
|
205
|
-
# e.g. Popup Message
|
206
|
-
get /^Popup Message$/i do
|
207
|
-
[ToastAction, {}]
|
208
|
-
end
|
209
|
-
|
210
|
-
# e.g. say current time
|
211
|
-
get /^say current[ _]time/i do
|
212
|
-
[SayTimeAction, {}]
|
213
|
-
end
|
214
|
-
|
215
|
-
get /^Torch :?(.*)/i do |onoffstate|
|
216
|
-
state = %w(on off toggle).index onoffstate.downcase
|
217
|
-
[CameraFlashLightAction, {state: state}]
|
218
|
-
end
|
219
|
-
|
220
|
-
get /^Take Picture/i do
|
221
|
-
[TakePictureAction, {}]
|
222
|
-
end
|
223
|
-
|
224
|
-
get /^take_picture/i do
|
225
|
-
[TakePictureAction, {}]
|
226
|
-
end
|
227
|
-
|
228
|
-
# -- DEVICE ACTIONS ------------------------------------------------------
|
229
|
-
|
230
|
-
get /^Speak text \(([^\)]+)\)/i do |text|
|
231
|
-
[SpeakTextAction, {text: text}]
|
232
|
-
end
|
233
|
-
|
234
|
-
get /^Speak text ['"]([^'"]+)/i do |text|
|
235
|
-
[SpeakTextAction, {text: text}]
|
236
|
-
end
|
237
|
-
|
238
|
-
get /^Speak text$/i do |text|
|
239
|
-
[SpeakTextAction, {}]
|
240
|
-
end
|
241
|
-
|
242
|
-
get /^Vibrate \(([^\)]+)/i do |pattern|
|
243
|
-
[VibrateAction, {pattern: pattern}]
|
244
|
-
end
|
245
|
-
|
246
|
-
get /^Vibrate$/i do |pattern|
|
247
|
-
[VibrateAction, {pattern: 'short buzz'}]
|
248
|
-
end
|
249
|
-
|
250
|
-
# e.g. Display Notification: Hi there: This is the body of the message
|
251
|
-
get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
|
252
|
-
[NotificationAction, {subject: subject, text: text}]
|
253
|
-
end
|
254
|
-
|
255
|
-
|
256
|
-
# e.g. Enable Wifi
|
257
|
-
get /^(Enable|Disable) Wifi$/i do |raw_state|
|
258
|
-
|
259
|
-
state = raw_state.downcase.to_sym == :enable ? 0 : 1
|
260
|
-
[SetWifiAction, {state: state}]
|
261
|
-
|
262
|
-
end
|
263
|
-
|
264
|
-
# e.g. Play: Altair
|
265
|
-
get /^Play: (.*)$/i do |name|
|
266
|
-
|
267
|
-
[PlaySoundAction, {file_path: name}]
|
268
|
-
|
269
|
-
end
|
270
|
-
|
271
|
-
# e.g. Launch Settings
|
272
|
-
get /^Launch (.*)$/i do |application|
|
273
|
-
|
274
|
-
h = {
|
275
|
-
application_name: application,
|
276
|
-
package_to_launch: 'com.android.' + application.downcase
|
277
|
-
}
|
278
|
-
[LaunchActivityAction, h]
|
279
|
-
|
280
|
-
end
|
281
|
-
|
282
|
-
# e.g. HTTP GET http://someurl.com/something
|
283
|
-
get /^HTTP GET ([^$]+)$/i do |url|
|
284
|
-
|
285
|
-
[OpenWebPageAction, url_to_open: url]
|
286
|
-
|
287
|
-
end
|
288
|
-
|
289
|
-
get /^HTTP GET$/i do
|
290
|
-
|
291
|
-
[OpenWebPageAction, {}]
|
292
|
-
|
293
|
-
end
|
294
|
-
|
295
|
-
# e.g. webhook entered_kitchen
|
296
|
-
#
|
297
|
-
get /(?:webhook|HTTP GET) ([^$]+)$/i do |s|
|
298
|
-
key = s =~ /^http/ ? :url_to_open : :identifier
|
299
|
-
[OpenWebPageAction, {key => s}]
|
300
|
-
end
|
301
|
-
|
302
|
-
#
|
303
|
-
get /^WebHook \(Url\)/i do
|
304
|
-
[OpenWebPageAction, {}]
|
305
|
-
end
|
306
|
-
|
307
|
-
# e.g. webhook entered_kitchen
|
308
|
-
#
|
309
|
-
get /^webhook$/i do
|
310
|
-
[OpenWebPageAction, {}, params[:macro]]
|
311
|
-
end
|
312
|
-
|
313
|
-
# -- Location ---------------------------------------------------------
|
314
|
-
|
315
|
-
get /^Force Location Update$/i do
|
316
|
-
[ForceLocationUpdateAction, params]
|
317
|
-
end
|
318
|
-
|
319
|
-
get /^Share Location$/i do
|
320
|
-
[ShareLocationAction, {}]
|
321
|
-
end
|
322
|
-
|
323
|
-
#a: Keep Device Awake Screen On Until Disabled
|
324
|
-
#
|
325
|
-
get /Keep Device Awake Screen On Until Disabled/i do
|
326
|
-
[KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
|
327
|
-
end
|
328
|
-
|
329
|
-
|
330
|
-
#a: Keep Device Awake Screen On 1h 1m 1s
|
331
|
-
#
|
332
|
-
get /Keep Device Awake Screen On ([^$]+)/i do |duration|
|
333
|
-
|
334
|
-
a = duration.split.map(&:to_i)
|
335
|
-
secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
|
336
|
-
|
337
|
-
h = {
|
338
|
-
permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
|
339
|
-
}
|
340
|
-
[KeepAwakeAction, h]
|
341
|
-
end
|
342
|
-
|
343
|
-
get /Keep Device Awake$/i do
|
344
|
-
[KeepAwakeAction, {}]
|
345
|
-
end
|
346
|
-
|
347
|
-
#a: Disable Keep Awake
|
348
|
-
#
|
349
|
-
get /Disable Keep Awake/i do
|
350
|
-
[KeepAwakeAction, {enabled: false, screen_option: 0}]
|
351
|
-
end
|
352
|
-
|
353
|
-
#e.g a: if Airplane mode enabled
|
354
|
-
#
|
355
|
-
get /if (.*)/i do
|
356
|
-
[IfConditionAction, {}]
|
357
|
-
end
|
358
|
-
|
359
|
-
get /else/i do
|
360
|
-
[ElseAction, {}]
|
361
|
-
end
|
362
|
-
|
363
|
-
get /End If/i do
|
364
|
-
[EndIfAction, {}]
|
365
|
-
end
|
366
|
-
|
367
|
-
# -- MacroDroid Specific ------------------------------------------------
|
368
|
-
#
|
369
|
-
get /^Set Variable$/i do
|
370
|
-
[SetVariableAction, {}]
|
371
|
-
end
|
372
|
-
|
373
|
-
# -- Screen ------------------------------------------------
|
374
|
-
#
|
375
|
-
get /^Screen (On|Off)$/i do |state|
|
376
|
-
[ScreenOnAction, {screen_off: state.downcase == 'off'}]
|
377
|
-
end
|
378
|
-
|
379
|
-
end
|
380
|
-
|
381
|
-
alias find_action run_route
|
382
|
-
|
383
|
-
|
384
|
-
end
|
385
|
-
|
386
|
-
class ConstraintsNlp
|
387
|
-
include AppRoutes
|
388
|
-
|
389
|
-
def initialize()
|
390
|
-
|
391
|
-
super()
|
392
|
-
params = {}
|
393
|
-
constraints(params)
|
394
|
-
|
395
|
-
end
|
396
|
-
|
397
|
-
def constraints(params)
|
398
|
-
|
399
|
-
# Device State
|
400
|
-
|
401
|
-
get /^Device (locked|unlocked)/i do |state|
|
402
|
-
[DeviceLockedConstraint, {locked: state.downcase == 'locked'}]
|
403
|
-
end
|
404
|
-
|
405
|
-
get /^airplane mode (.*)/i do |state|
|
406
|
-
[AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
|
407
|
-
end
|
408
|
-
|
409
|
-
#
|
410
|
-
|
411
|
-
# -- MacroDroid specific -----------------------------------------------------------------------
|
412
|
-
|
413
|
-
get /^(\w+) (=) (\[?\w+\]?)/i do |loperand, operator, roperand|
|
414
|
-
|
415
|
-
h = {
|
416
|
-
loperand: loperand,
|
417
|
-
operator: operator,
|
418
|
-
roperand: roperand
|
419
|
-
}
|
420
|
-
|
421
|
-
[MacroDroidVariableConstraint, h]
|
422
|
-
|
423
|
-
end
|
424
|
-
|
425
|
-
# -- Sensors -----------------------------------
|
426
|
-
#
|
427
|
-
get /^Light Sensor (Less|Greater) than (50.0)lx/i do |operator, val|
|
428
|
-
|
429
|
-
level, option = operator.downcase == 'less' ? [-1,0] : [1,1]
|
430
|
-
|
431
|
-
h = {
|
432
|
-
light_level: level,
|
433
|
-
light_level_float: val,
|
434
|
-
option: option
|
435
|
-
}
|
436
|
-
|
437
|
-
[LightLevelConstraint, h]
|
438
|
-
end
|
439
|
-
|
440
|
-
get /^Proximity Sensor: (Near|Far)/i do |distance|
|
441
|
-
[ProximitySensorConstraint, {near: distance.downcase == 'near'}]
|
442
|
-
end
|
443
|
-
|
444
|
-
|
445
|
-
# -- Screen and Speaker ---------------------------
|
446
|
-
#
|
447
|
-
get /^Screen (On|Off)/i do |state|
|
448
|
-
[ScreenOnOffConstraint, {screen_on: state.downcase == 'on'}]
|
449
|
-
end
|
450
|
-
|
451
|
-
end
|
452
|
-
|
453
|
-
alias find_constraint run_route
|
454
|
-
|
455
|
-
end
|
456
|
-
|
457
|
-
|
458
20
|
class MacroError < Exception
|
459
21
|
end
|
460
22
|
|
@@ -464,19 +26,21 @@ class Macro
|
|
464
26
|
include ObjectX
|
465
27
|
|
466
28
|
attr_reader :local_variables, :triggers, :actions, :constraints,
|
467
|
-
:guid, :deviceid
|
468
|
-
attr_accessor :title, :description, :remote_url
|
29
|
+
:guid, :deviceid, :parent
|
30
|
+
attr_accessor :title, :description, :remote_url, :picture_path
|
469
31
|
|
470
|
-
def initialize(name=nil, geofences: nil, deviceid: nil, remote_url: nil,
|
471
|
-
debug: false)
|
32
|
+
def initialize(name=nil, geofences: nil, deviceid: nil, remote_url: nil, \
|
33
|
+
picture_path: nil, parent: nil, debug: false)
|
472
34
|
|
473
35
|
@title, @geofences, @deviceid, @debug = name, geofences, deviceid, debug
|
474
|
-
@remote_url = remote_url
|
36
|
+
@remote_url, @picture_path, @parent = remote_url, picture_path, parent
|
475
37
|
|
476
38
|
puts 'inside Macro#initialize' if @debug
|
477
39
|
|
478
40
|
@local_variables, @triggers, @actions, @constraints = {}, [], [], []
|
479
41
|
@h = {}
|
42
|
+
@guid = generate_guid()
|
43
|
+
@enabled = true
|
480
44
|
|
481
45
|
end
|
482
46
|
|
@@ -502,6 +66,18 @@ class Macro
|
|
502
66
|
end
|
503
67
|
|
504
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
|
505
81
|
|
506
82
|
def to_h()
|
507
83
|
|
@@ -518,9 +94,9 @@ class Macro
|
|
518
94
|
m_description: '',
|
519
95
|
m_name: title(),
|
520
96
|
m_excludeLog: false,
|
521
|
-
m_GUID: guid
|
97
|
+
m_GUID: @guid,
|
522
98
|
m_isOrCondition: false,
|
523
|
-
m_enabled:
|
99
|
+
m_enabled: @enabled,
|
524
100
|
m_descriptionOpen: false,
|
525
101
|
m_headingColor: 0
|
526
102
|
}
|
@@ -537,6 +113,7 @@ class Macro
|
|
537
113
|
puts 'h:' + h.inspect
|
538
114
|
end
|
539
115
|
|
116
|
+
@guid = h[:guid]
|
540
117
|
@category = h[:category]
|
541
118
|
@title = h[:name]
|
542
119
|
@description = h[:description]
|
@@ -737,7 +314,6 @@ class Macro
|
|
737
314
|
|
738
315
|
end
|
739
316
|
|
740
|
-
|
741
317
|
|
742
318
|
ap = ActionsNlp.new self
|
743
319
|
|
@@ -911,8 +487,6 @@ EOF
|
|
911
487
|
s = x.to_s(colour: colour)
|
912
488
|
#puts 's: ' + s.inspect
|
913
489
|
|
914
|
-
|
915
|
-
|
916
490
|
r = if indent <= 0 then
|
917
491
|
|
918
492
|
lines = s.lines
|
@@ -965,9 +539,6 @@ EOF
|
|
965
539
|
|
966
540
|
end.join("\n")
|
967
541
|
|
968
|
-
|
969
|
-
|
970
|
-
|
971
542
|
a << actions
|
972
543
|
|
973
544
|
|
@@ -978,10 +549,6 @@ EOF
|
|
978
549
|
end.join("\n")
|
979
550
|
end
|
980
551
|
|
981
|
-
|
982
|
-
|
983
|
-
|
984
|
-
|
985
552
|
a.join("\n") + "\n"
|
986
553
|
|
987
554
|
end
|
@@ -1025,8 +592,8 @@ EOF
|
|
1025
592
|
|
1026
593
|
private
|
1027
594
|
|
1028
|
-
def
|
1029
|
-
'-' + 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
|
1030
597
|
end
|
1031
598
|
|
1032
599
|
def object(h={})
|
@@ -1048,9 +615,6 @@ EOF
|
|
1048
615
|
|
1049
616
|
end
|
1050
617
|
|
1051
|
-
end
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
618
|
+
end
|
1055
619
|
|
1056
620
|
end
|