ruby-macrodroid 0.9.6 → 0.9.11
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 +53 -35
- data/lib/ruby-macrodroid/actions.rb +162 -55
- data/lib/ruby-macrodroid/actionsnlp.rb +244 -0
- data/lib/ruby-macrodroid/base.rb +7 -5
- data/lib/ruby-macrodroid/constraints.rb +11 -3
- data/lib/ruby-macrodroid/constraintsnlp.rb +75 -0
- data/lib/ruby-macrodroid/macro.rb +26 -451
- 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'
|
@@ -799,9 +799,17 @@ class MacroDroidVariableConstraint < Constraint
|
|
799
799
|
h[:variable][:name] = h[:loperand]
|
800
800
|
h[:variable][:type] = 2
|
801
801
|
|
802
|
-
|
803
|
-
|
804
|
-
|
802
|
+
if h[:roperand] =~ /true|false/i then
|
803
|
+
|
804
|
+
val = h[:roperand].downcase == 'true'
|
805
|
+
h[:boolean_value] = val
|
806
|
+
h[:variable][:type] = 0
|
807
|
+
h[:variable][:boolean_value] = val
|
808
|
+
h[:string_value] = h[:roperand].capitalize
|
809
|
+
else
|
810
|
+
h[:string_value] = h[:roperand]
|
811
|
+
end
|
812
|
+
|
805
813
|
end
|
806
814
|
|
807
815
|
options = {
|
@@ -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,428 +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
|
-
# e.g. message popup: hello world!
|
180
|
-
get /^message popup: (.*)/i do |msg|
|
181
|
-
[ToastAction, {msg: msg}]
|
182
|
-
end
|
183
|
-
|
184
|
-
# e.g. Popup Message 'hello world!'
|
185
|
-
get /^Popup[ _]Message ['"]([^'"]+)/i do |msg|
|
186
|
-
[ToastAction, {msg: msg}]
|
187
|
-
end
|
188
|
-
|
189
|
-
# e.g. Popup Message\n hello world!
|
190
|
-
get /^Popup Message\n\s+(.*)/im do |msg|
|
191
|
-
[ToastAction, {msg: msg}]
|
192
|
-
end
|
193
|
-
|
194
|
-
# e.g. Popup Message
|
195
|
-
get /^Popup Message$/i do
|
196
|
-
[ToastAction, {}]
|
197
|
-
end
|
198
|
-
|
199
|
-
# e.g. say current time
|
200
|
-
get /^say current[ _]time/i do
|
201
|
-
[SayTimeAction, {}]
|
202
|
-
end
|
203
|
-
|
204
|
-
get /^Torch :?(.*)/i do |onoffstate|
|
205
|
-
state = %w(on off toggle).index onoffstate.downcase
|
206
|
-
[CameraFlashLightAction, {state: state}]
|
207
|
-
end
|
208
|
-
|
209
|
-
get /^Take Picture/i do
|
210
|
-
[TakePictureAction, {}]
|
211
|
-
end
|
212
|
-
|
213
|
-
get /^take_picture/i do
|
214
|
-
[TakePictureAction, {}]
|
215
|
-
end
|
216
|
-
|
217
|
-
# -- DEVICE ACTIONS ------------------------------------------------------
|
218
|
-
|
219
|
-
get /^Speak text \(([^\)]+)\)/i do |text|
|
220
|
-
[SpeakTextAction, {text: text}]
|
221
|
-
end
|
222
|
-
|
223
|
-
get /^Speak text ['"]([^'"]+)/i do |text|
|
224
|
-
[SpeakTextAction, {text: text}]
|
225
|
-
end
|
226
|
-
|
227
|
-
get /^Speak text$/i do |text|
|
228
|
-
[SpeakTextAction, {}]
|
229
|
-
end
|
230
|
-
|
231
|
-
get /^Vibrate \(([^\)]+)/i do |pattern|
|
232
|
-
[VibrateAction, {pattern: pattern}]
|
233
|
-
end
|
234
|
-
|
235
|
-
get /^Vibrate$/i do |pattern|
|
236
|
-
[VibrateAction, {pattern: 'short buzz'}]
|
237
|
-
end
|
238
|
-
|
239
|
-
# e.g. Display Notification: Hi there: This is the body of the message
|
240
|
-
get /^Display Notification: ([^:]+): [^$]+$/i do |subject, text|
|
241
|
-
[NotificationAction, {subject: subject, text: text}]
|
242
|
-
end
|
243
|
-
|
244
|
-
|
245
|
-
# e.g. Enable Wifi
|
246
|
-
get /^(Enable|Disable) Wifi$/i do |raw_state|
|
247
|
-
|
248
|
-
state = raw_state.downcase.to_sym == :enable ? 0 : 1
|
249
|
-
[SetWifiAction, {state: state}]
|
250
|
-
|
251
|
-
end
|
252
|
-
|
253
|
-
# e.g. Play: Altair
|
254
|
-
get /^Play: (.*)$/i do |name|
|
255
|
-
|
256
|
-
[PlaySoundAction, {file_path: name}]
|
257
|
-
|
258
|
-
end
|
259
|
-
|
260
|
-
# e.g. Launch Settings
|
261
|
-
get /^Launch (.*)$/i do |application|
|
262
|
-
|
263
|
-
h = {
|
264
|
-
application_name: application,
|
265
|
-
package_to_launch: 'com.android.' + application.downcase
|
266
|
-
}
|
267
|
-
[LaunchActivityAction, h]
|
268
|
-
|
269
|
-
end
|
270
|
-
|
271
|
-
# e.g. HTTP GET http://someurl.com/something
|
272
|
-
get /^HTTP GET ([^$]+)$/i do |url|
|
273
|
-
|
274
|
-
[OpenWebPageAction, url_to_open: url]
|
275
|
-
|
276
|
-
end
|
277
|
-
|
278
|
-
get /^HTTP GET$/i do
|
279
|
-
|
280
|
-
[OpenWebPageAction, {}]
|
281
|
-
|
282
|
-
end
|
283
|
-
|
284
|
-
# e.g. webhook entered_kitchen
|
285
|
-
#
|
286
|
-
get /(?:webhook|HTTP GET) ([^$]+)$/i do |s|
|
287
|
-
key = s =~ /^http/ ? :url_to_open : :identifier
|
288
|
-
[OpenWebPageAction, {key => s}]
|
289
|
-
end
|
290
|
-
|
291
|
-
#
|
292
|
-
get /^WebHook \(Url\)/i do
|
293
|
-
[OpenWebPageAction, {}]
|
294
|
-
end
|
295
|
-
|
296
|
-
# e.g. webhook entered_kitchen
|
297
|
-
#
|
298
|
-
get /^webhook$/i do
|
299
|
-
[OpenWebPageAction, {}, params[:macro]]
|
300
|
-
end
|
301
|
-
|
302
|
-
# -- Location ---------------------------------------------------------
|
303
|
-
|
304
|
-
get /^Force Location Update$/i do
|
305
|
-
[ForceLocationUpdateAction, params]
|
306
|
-
end
|
307
|
-
|
308
|
-
get /^Share Location$/i do
|
309
|
-
[ShareLocationAction, {}]
|
310
|
-
end
|
311
|
-
|
312
|
-
#a: Keep Device Awake Screen On Until Disabled
|
313
|
-
#
|
314
|
-
get /Keep Device Awake Screen On Until Disabled/i do
|
315
|
-
[KeepAwakeAction, {enabled: true, permanent: true, screen_option: 0}]
|
316
|
-
end
|
317
|
-
|
318
|
-
|
319
|
-
#a: Keep Device Awake Screen On 1h 1m 1s
|
320
|
-
#
|
321
|
-
get /Keep Device Awake Screen On ([^$]+)/i do |duration|
|
322
|
-
|
323
|
-
a = duration.split.map(&:to_i)
|
324
|
-
secs = Subunit.new(units={minutes:60, hours:60, seconds: 60}, a).to_i
|
325
|
-
|
326
|
-
h = {
|
327
|
-
permanent: true, screen_option: 0, seconds_to_stay_awake_for: secs
|
328
|
-
}
|
329
|
-
[KeepAwakeAction, h]
|
330
|
-
end
|
331
|
-
|
332
|
-
get /Keep Device Awake$/i do
|
333
|
-
[KeepAwakeAction, {}]
|
334
|
-
end
|
335
|
-
|
336
|
-
#a: Disable Keep Awake
|
337
|
-
#
|
338
|
-
get /Disable Keep Awake/i do
|
339
|
-
[KeepAwakeAction, {enabled: false, screen_option: 0}]
|
340
|
-
end
|
341
|
-
|
342
|
-
#e.g a: if Airplane mode enabled
|
343
|
-
#
|
344
|
-
get /if (.*)/i do
|
345
|
-
[IfConditionAction, {}]
|
346
|
-
end
|
347
|
-
|
348
|
-
get /else/i do
|
349
|
-
[ElseAction, {}]
|
350
|
-
end
|
351
|
-
|
352
|
-
get /End If/i do
|
353
|
-
[EndIfAction, {}]
|
354
|
-
end
|
355
|
-
|
356
|
-
# -- MacroDroid Specific ------------------------------------------------
|
357
|
-
#
|
358
|
-
get /^Set Variable$/i do
|
359
|
-
[SetVariableAction, {}]
|
360
|
-
end
|
361
|
-
|
362
|
-
# -- Screen ------------------------------------------------
|
363
|
-
#
|
364
|
-
get /^Screen (On|Off)$/i do |state|
|
365
|
-
[ScreenOnAction, {screen_off: state.downcase == 'off'}]
|
366
|
-
end
|
367
|
-
|
368
|
-
end
|
369
|
-
|
370
|
-
alias find_action run_route
|
371
|
-
|
372
|
-
|
373
|
-
end
|
374
|
-
|
375
|
-
class ConstraintsNlp
|
376
|
-
include AppRoutes
|
377
|
-
|
378
|
-
def initialize()
|
379
|
-
|
380
|
-
super()
|
381
|
-
params = {}
|
382
|
-
constraints(params)
|
383
|
-
|
384
|
-
end
|
385
|
-
|
386
|
-
def constraints(params)
|
387
|
-
|
388
|
-
# Device State
|
389
|
-
|
390
|
-
get /^Device (locked|unlocked)/i do |state|
|
391
|
-
[DeviceLockedConstraint, {locked: state.downcase == 'locked'}]
|
392
|
-
end
|
393
|
-
|
394
|
-
get /^airplane mode (.*)/i do |state|
|
395
|
-
[AirplaneModeConstraint, {enabled: (state =~ /^enabled|on$/i) == 0}]
|
396
|
-
end
|
397
|
-
|
398
|
-
#
|
399
|
-
|
400
|
-
# -- MacroDroid specific -----------------------------------------------------------------------
|
401
|
-
|
402
|
-
get /^(\w+) (=) (\[?\w+\]?)/i do |loperand, operator, roperand|
|
403
|
-
|
404
|
-
h = {
|
405
|
-
loperand: loperand,
|
406
|
-
operator: operator,
|
407
|
-
roperand: roperand
|
408
|
-
}
|
409
|
-
|
410
|
-
[MacroDroidVariableConstraint, h]
|
411
|
-
|
412
|
-
end
|
413
|
-
|
414
|
-
# -- Sensors -----------------------------------
|
415
|
-
#
|
416
|
-
get /^Light Sensor (Less|Greater) than (50.0)lx/i do |operator, val|
|
417
|
-
|
418
|
-
level, option = operator.downcase == 'less' ? [-1,0] : [1,1]
|
419
|
-
|
420
|
-
h = {
|
421
|
-
light_level: level,
|
422
|
-
light_level_float: val,
|
423
|
-
option: option
|
424
|
-
}
|
425
|
-
|
426
|
-
[LightLevelConstraint, h]
|
427
|
-
end
|
428
|
-
|
429
|
-
get /^Proximity Sensor: (Near|Far)/i do |distance|
|
430
|
-
[ProximitySensorConstraint, {near: distance.downcase == 'near'}]
|
431
|
-
end
|
432
|
-
|
433
|
-
|
434
|
-
# -- Screen and Speaker ---------------------------
|
435
|
-
#
|
436
|
-
get /^Screen (On|Off)/i do |state|
|
437
|
-
[ScreenOnOffConstraint, {screen_on: state.downcase == 'on'}]
|
438
|
-
end
|
439
|
-
|
440
|
-
end
|
441
|
-
|
442
|
-
alias find_constraint run_route
|
443
|
-
|
444
|
-
end
|
445
|
-
|
446
|
-
|
447
20
|
class MacroError < Exception
|
448
21
|
end
|
449
22
|
|
@@ -453,19 +26,21 @@ class Macro
|
|
453
26
|
include ObjectX
|
454
27
|
|
455
28
|
attr_reader :local_variables, :triggers, :actions, :constraints,
|
456
|
-
:guid, :deviceid
|
457
|
-
attr_accessor :title, :description, :remote_url
|
29
|
+
:guid, :deviceid, :parent
|
30
|
+
attr_accessor :title, :description, :remote_url, :picture_path
|
458
31
|
|
459
|
-
def initialize(name=nil, geofences: nil, deviceid: nil, remote_url: nil,
|
460
|
-
debug: false)
|
32
|
+
def initialize(name=nil, geofences: nil, deviceid: nil, remote_url: nil, \
|
33
|
+
picture_path: nil, parent: nil, debug: false)
|
461
34
|
|
462
35
|
@title, @geofences, @deviceid, @debug = name, geofences, deviceid, debug
|
463
|
-
@remote_url = remote_url
|
36
|
+
@remote_url, @picture_path, @parent = remote_url, picture_path, parent
|
464
37
|
|
465
38
|
puts 'inside Macro#initialize' if @debug
|
466
39
|
|
467
40
|
@local_variables, @triggers, @actions, @constraints = {}, [], [], []
|
468
41
|
@h = {}
|
42
|
+
@guid = generate_guid()
|
43
|
+
@enabled = true
|
469
44
|
|
470
45
|
end
|
471
46
|
|
@@ -491,6 +66,18 @@ class Macro
|
|
491
66
|
end
|
492
67
|
|
493
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
|
494
81
|
|
495
82
|
def to_h()
|
496
83
|
|
@@ -507,9 +94,9 @@ class Macro
|
|
507
94
|
m_description: '',
|
508
95
|
m_name: title(),
|
509
96
|
m_excludeLog: false,
|
510
|
-
m_GUID: guid
|
97
|
+
m_GUID: @guid,
|
511
98
|
m_isOrCondition: false,
|
512
|
-
m_enabled:
|
99
|
+
m_enabled: @enabled,
|
513
100
|
m_descriptionOpen: false,
|
514
101
|
m_headingColor: 0
|
515
102
|
}
|
@@ -526,6 +113,7 @@ class Macro
|
|
526
113
|
puts 'h:' + h.inspect
|
527
114
|
end
|
528
115
|
|
116
|
+
@guid = h[:guid]
|
529
117
|
@category = h[:category]
|
530
118
|
@title = h[:name]
|
531
119
|
@description = h[:description]
|
@@ -726,7 +314,6 @@ class Macro
|
|
726
314
|
|
727
315
|
end
|
728
316
|
|
729
|
-
|
730
317
|
|
731
318
|
ap = ActionsNlp.new self
|
732
319
|
|
@@ -900,8 +487,6 @@ EOF
|
|
900
487
|
s = x.to_s(colour: colour)
|
901
488
|
#puts 's: ' + s.inspect
|
902
489
|
|
903
|
-
|
904
|
-
|
905
490
|
r = if indent <= 0 then
|
906
491
|
|
907
492
|
lines = s.lines
|
@@ -954,9 +539,6 @@ EOF
|
|
954
539
|
|
955
540
|
end.join("\n")
|
956
541
|
|
957
|
-
|
958
|
-
|
959
|
-
|
960
542
|
a << actions
|
961
543
|
|
962
544
|
|
@@ -967,10 +549,6 @@ EOF
|
|
967
549
|
end.join("\n")
|
968
550
|
end
|
969
551
|
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
552
|
a.join("\n") + "\n"
|
975
553
|
|
976
554
|
end
|
@@ -1014,8 +592,8 @@ EOF
|
|
1014
592
|
|
1015
593
|
private
|
1016
594
|
|
1017
|
-
def
|
1018
|
-
'-' + 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
|
1019
597
|
end
|
1020
598
|
|
1021
599
|
def object(h={})
|
@@ -1037,9 +615,6 @@ EOF
|
|
1037
615
|
|
1038
616
|
end
|
1039
617
|
|
1040
|
-
end
|
1041
|
-
|
1042
|
-
|
1043
|
-
|
618
|
+
end
|
1044
619
|
|
1045
620
|
end
|