remotedroid 0.4.3 → 0.5.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/remotedroid.rb +238 -688
- data/lib/remotedroid/client.rb +201 -0
- data/lib/remotedroid/control.rb +207 -0
- data/lib/remotedroid/controller.rb +170 -0
- data/lib/remotedroid/model.rb +227 -0
- data/lib/remotedroid/query.rb +60 -0
- metadata +9 -4
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df5d8ff42bcaa56e29104adb4e802afc9fea9df24e54e3861268f8120c59d754
|
4
|
+
data.tar.gz: 83c8653599215e33d641b414fc6dcfa4a7ad1711b462d098ccf8dbbcd654001c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2808afc3086dac37cf72544b2445ebe7b0dbcea42709a318e7b08c3da683f8353b893ea8048d05c69c0ddc78e7456e2f644a0bf158212335e150178b5bed16c2
|
7
|
+
data.tar.gz: d5852dade61330d9c16f498750f76100cd6517f51e04eef403945719031726a161ea610a3133b0e755c2e599068d3af0787515d4f63039ec34bf7f40da309d5c
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/lib/remotedroid.rb
CHANGED
@@ -8,20 +8,36 @@ require 'app-routes'
|
|
8
8
|
require 'sps-sub'
|
9
9
|
require 'ruby-macrodroid'
|
10
10
|
|
11
|
+
# PASTE_START
|
11
12
|
|
12
13
|
# Here's what's available so far:
|
13
14
|
#
|
14
15
|
# # Triggers
|
15
16
|
#
|
17
|
+
# ## Battery/Power
|
18
|
+
#
|
19
|
+
# * Power button toggle
|
20
|
+
#
|
21
|
+
# ## Connectivity
|
22
|
+
#
|
23
|
+
# ### Wifi State Change
|
24
|
+
#
|
25
|
+
# * Connected to Network
|
26
|
+
#
|
16
27
|
# ## Device Events
|
17
28
|
#
|
18
29
|
# * screen on
|
19
30
|
#
|
20
31
|
# ## Sensors
|
21
|
-
#
|
32
|
+
#
|
33
|
+
# * Activity Recognition
|
22
34
|
# * proximity (near)
|
23
35
|
# * shake device
|
24
36
|
#
|
37
|
+
# ## User Input
|
38
|
+
#
|
39
|
+
# * Swipe Screen
|
40
|
+
#
|
25
41
|
# ------------------------------------
|
26
42
|
#
|
27
43
|
# # Actions
|
@@ -48,6 +64,10 @@ require 'ruby-macrodroid'
|
|
48
64
|
#
|
49
65
|
# * Share Location
|
50
66
|
#
|
67
|
+
# ## MacroDroid specific
|
68
|
+
#
|
69
|
+
# * Disable Macro
|
70
|
+
#
|
51
71
|
# ## Media
|
52
72
|
#
|
53
73
|
# * Play sound (Doda)
|
@@ -58,6 +78,7 @@ require 'ruby-macrodroid'
|
|
58
78
|
#
|
59
79
|
# ## Screen
|
60
80
|
#
|
81
|
+
# * Keep Device Awake
|
61
82
|
# * Screen On
|
62
83
|
#
|
63
84
|
|
@@ -165,7 +186,58 @@ t: webhook
|
|
165
186
|
a:
|
166
187
|
Take Picture
|
167
188
|
Rear Facing
|
189
|
+
a: wait 2 seconds
|
190
|
+
a: webhook
|
168
191
|
|
192
|
+
m: stay awake
|
193
|
+
t: webhook
|
194
|
+
a: stay awake
|
195
|
+
|
196
|
+
m: stay awake off
|
197
|
+
t: webhook
|
198
|
+
a: stay awake off
|
199
|
+
|
200
|
+
m: Launch Google Play Music
|
201
|
+
t: webhook
|
202
|
+
a: Launch Google Play Music
|
203
|
+
|
204
|
+
|
205
|
+
m: Media Next
|
206
|
+
t: webhook
|
207
|
+
a:
|
208
|
+
Media Next
|
209
|
+
Simulate Media Button (Google Play Music)
|
210
|
+
|
211
|
+
m: Media Pause
|
212
|
+
t: webhook
|
213
|
+
a:
|
214
|
+
Media Pause
|
215
|
+
Simulate Media Button (Google Play Music)
|
216
|
+
|
217
|
+
m: Media Play
|
218
|
+
t: webhook
|
219
|
+
a:
|
220
|
+
Media Play
|
221
|
+
Simulate Media Button (Google Play Music)
|
222
|
+
|
223
|
+
m: Media Play Pause
|
224
|
+
t: webhook
|
225
|
+
a:
|
226
|
+
Media Play/Pause
|
227
|
+
Simulate Media Button (Google Play Music)
|
228
|
+
|
229
|
+
m: Media Previous
|
230
|
+
t: webhook
|
231
|
+
a:
|
232
|
+
Media Previous
|
233
|
+
Simulate Media Button (Google Play Music)
|
234
|
+
|
235
|
+
m: Media Stop
|
236
|
+
t: webhook
|
237
|
+
a:
|
238
|
+
Media Stop
|
239
|
+
Simulate Media Button (Google Play Music)
|
240
|
+
|
169
241
|
m: Share location
|
170
242
|
t:
|
171
243
|
WebHook
|
@@ -178,7 +250,16 @@ a:
|
|
178
250
|
HTTP GET
|
179
251
|
identifier: location
|
180
252
|
coords: [lv=coords]
|
253
|
+
cell: [cell_id]
|
254
|
+
ssid: [ssid]
|
255
|
+
alt: [last_loc_alt]
|
256
|
+
time: [last_loc_age_timestamp]
|
257
|
+
mph: [last_loc_speed_mph]
|
258
|
+
kph: [last_loc_speed_kmh]
|
259
|
+
device: [device_model]
|
260
|
+
battery: [battery]
|
181
261
|
type: query
|
262
|
+
|
182
263
|
|
183
264
|
m: query
|
184
265
|
t: WebHook
|
@@ -236,595 +317,157 @@ m: Power connected
|
|
236
317
|
t: Power Connected: Any
|
237
318
|
a: webhook
|
238
319
|
|
239
|
-
m:
|
320
|
+
m: Screen on
|
240
321
|
t: screen on
|
241
|
-
a: webhook
|
242
|
-
|
243
|
-
EOF
|
244
|
-
|
245
|
-
=begin
|
246
|
-
m: Screen
|
247
|
-
v: on: true
|
248
|
-
t: WebHook
|
249
322
|
a:
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
Screen Off
|
254
|
-
End If
|
255
|
-
|
256
|
-
=end
|
257
|
-
|
258
|
-
module RemoteDroid
|
259
|
-
|
260
|
-
class Model
|
261
|
-
include AppRoutes
|
262
|
-
|
263
|
-
def initialize(obj=nil, root: 'device1', debug: false)
|
264
|
-
|
265
|
-
super()
|
266
|
-
@root, @debug = root, debug
|
267
|
-
@location = nil
|
268
|
-
|
269
|
-
if obj then
|
270
|
-
|
271
|
-
s = obj.strip
|
272
|
-
|
273
|
-
puts 's: ' + s.inspect if @debug
|
274
|
-
|
275
|
-
if s[0] == '<' or s.lines[1][0..1] == ' ' then
|
276
|
-
|
277
|
-
puts 'before easydom' if @debug
|
278
|
-
|
279
|
-
s2 = if s.lines[1][0..1] == ' ' then
|
280
|
-
|
281
|
-
lines = s.lines.map do |line|
|
282
|
-
line.sub(/(\w+) +is +(\w+)$/) {|x| "#{$1} {switch: #{$2}}" }
|
283
|
-
end
|
284
|
-
|
285
|
-
lines.join
|
286
|
-
|
287
|
-
else
|
288
|
-
s
|
289
|
-
end
|
290
|
-
|
291
|
-
@ed = EasyDom.new(s2)
|
292
|
-
else
|
293
|
-
build(s, root: root)
|
294
|
-
end
|
295
|
-
|
296
|
-
end
|
297
|
-
|
298
|
-
end
|
299
|
-
|
300
|
-
def build(raw_requests, root: @root)
|
301
|
-
|
302
|
-
@ed = EasyDom.new(debug: false, root: root)
|
303
|
-
raw_requests.lines.each {|line| request(line) }
|
304
|
-
|
305
|
-
end
|
306
|
-
|
307
|
-
|
308
|
-
def get_thing(h)
|
309
|
-
|
310
|
-
h[:thing].gsub!(/ /,'_')
|
311
|
-
|
312
|
-
if not h.has_key? :location then
|
313
|
-
location = false
|
314
|
-
h[:location] = find_path(h[:thing])
|
315
|
-
else
|
316
|
-
location = true
|
317
|
-
end
|
318
|
-
|
319
|
-
puts 'h: ' + h.inspect if @debug
|
320
|
-
|
321
|
-
a = []
|
322
|
-
a += h[:location].split(/ /)
|
323
|
-
a << h[:thing]
|
324
|
-
status = a.inject(@ed) {|r,x| r.send(x)}.send(h[:action])
|
325
|
-
|
326
|
-
if location then
|
327
|
-
"The %s %s is %s." % [h[:location], h[:thing], status]
|
328
|
-
else
|
329
|
-
"%s is %s." % [h[:thing].capitalize, status]
|
330
|
-
end
|
331
|
-
|
332
|
-
end
|
333
|
-
|
334
|
-
# Object Property (op)
|
335
|
-
# Helpful for accessing properites in dot notation
|
336
|
-
# e.g. op.livingroom.light.switch = 'off'
|
337
|
-
#
|
338
|
-
def op()
|
339
|
-
@ed
|
340
|
-
end
|
341
|
-
|
342
|
-
def query(s)
|
343
|
-
@ed.e.element(s)
|
344
|
-
end
|
345
|
-
|
346
|
-
# request accepts a string in plain english
|
347
|
-
# e.g. request 'switch the livingroom light on'
|
348
|
-
#
|
349
|
-
def request(s)
|
350
|
-
|
351
|
-
params = {request: s}
|
352
|
-
requests(params)
|
353
|
-
h = find_request(s)
|
354
|
-
|
355
|
-
method(h.first[-1]).call(h).gsub(/_/,' ')
|
356
|
-
|
357
|
-
end
|
358
|
-
|
359
|
-
def set_thing(h)
|
360
|
-
|
361
|
-
h[:thing].gsub!(/ /,'_')
|
362
|
-
h[:location] = find_path(h[:thing]) unless h.has_key? :location
|
363
|
-
|
364
|
-
a = []
|
365
|
-
a += h[:location].split(/ /)
|
366
|
-
a << h[:thing]
|
367
|
-
|
368
|
-
a.inject(@ed) {|r,x| r.send(x)}.send(h[:action], h[:value])
|
369
|
-
|
370
|
-
end
|
371
|
-
|
372
|
-
def to_sliml(level: 0)
|
373
|
-
|
374
|
-
s = @ed.to_sliml
|
375
|
-
|
376
|
-
return s if level.to_i > 0
|
377
|
-
|
378
|
-
lines = s.lines.map do |line|
|
379
|
-
|
380
|
-
line.sub(/\{[^\}]+\}/) do |x|
|
381
|
-
|
382
|
-
a = x.scan(/\w+: +[^ ]+/)
|
383
|
-
if a.length == 1 and x[/switch:/] then
|
384
|
-
|
385
|
-
val = x[/(?<=switch: ) *["']([^"']+)/,1]
|
386
|
-
'is ' + val
|
387
|
-
else
|
388
|
-
x
|
389
|
-
end
|
390
|
-
|
391
|
-
end
|
392
|
-
end
|
393
|
-
|
394
|
-
lines.join
|
395
|
-
|
396
|
-
end
|
397
|
-
|
398
|
-
def to_xml(options=nil)
|
399
|
-
@ed.xml(pretty: true).gsub(' style=\'\'','')
|
400
|
-
end
|
401
|
-
|
402
|
-
alias xml to_xml
|
403
|
-
|
404
|
-
# to_xml() is the preferred method
|
405
|
-
|
406
|
-
protected
|
407
|
-
|
408
|
-
def requests(params)
|
409
|
-
|
410
|
-
# e.g. switch the livingroom gas_fire off
|
411
|
-
#
|
412
|
-
get /(?:switch|turn) the ([^ ]+) +([^ ]+) +(on|off)$/ do |location, device, onoff|
|
413
|
-
{type: :set_thing, action: 'switch=', location: location, thing: device, value: onoff}
|
414
|
-
end
|
415
|
-
|
416
|
-
# e.g. switch the gas _fire off
|
417
|
-
#
|
418
|
-
get /(?:switch|turn) the ([^ ]+) +(on|off)$/ do |device, onoff|
|
419
|
-
{type: :set_thing, action: 'switch=', thing: device, value: onoff}
|
420
|
-
end
|
421
|
-
|
422
|
-
# e.g. is the livingroom gas_fire on?
|
423
|
-
#
|
424
|
-
get /is the ([^ ]+) +([^ ]+) +(?:on|off)\??$/ do |location, device|
|
425
|
-
{type: :get_thing, action: 'switch', location: location, thing: device}
|
426
|
-
end
|
427
|
-
|
428
|
-
# e.g. enable airplane mode
|
429
|
-
#
|
430
|
-
get /((?:dis|en)able) ([^$]+)$/ do |state, service|
|
431
|
-
{type: :set_thing, action: 'switch=', thing: service, value: state + 'd'}
|
432
|
-
end
|
433
|
-
|
434
|
-
# e.g. switch airplane mode off
|
435
|
-
#
|
436
|
-
get /switch (.*) (on|off)/ do |service, rawstate|
|
437
|
-
|
438
|
-
state = rawstate == 'on' ? 'enabled' : 'disabled'
|
439
|
-
{type: :set_thing, action: 'switch=', thing: service, value: state}
|
440
|
-
|
441
|
-
end
|
442
|
-
|
443
|
-
# e.g. is airplane mode enabed?
|
444
|
-
#
|
445
|
-
get /is (.*) +(?:(?:dis|en)abled)\??$/ do |service|
|
446
|
-
{type: :get_thing, action: 'switch', thing: service.gsub(/ /,'_')}
|
447
|
-
end
|
448
|
-
|
449
|
-
# e.g. is the gas_fire on?
|
450
|
-
#
|
451
|
-
get /is the ([^ ]+) +(?:on|off)\??$/ do |device|
|
452
|
-
location = find_path(device)
|
453
|
-
{type: :get_thing, action: 'switch', location: location, thing: device}
|
454
|
-
end
|
455
|
-
|
456
|
-
# e.g. fetch the livingroom temperature reading
|
457
|
-
#
|
458
|
-
get /fetch the ([^ ]+) +([^ ]+) +(?:reading)$/ do |location, device|
|
459
|
-
{type: :get_thing, action: 'reading', location: location, thing: device}
|
460
|
-
end
|
461
|
-
|
462
|
-
# e.g. fetch the temperature reading
|
463
|
-
#
|
464
|
-
get /fetch the ([^ ]+) +(?:reading)$/ do |device|
|
465
|
-
location = find_path(device)
|
466
|
-
{type: :get_thing, action: 'reading', location: location, thing: device}
|
467
|
-
end
|
468
|
-
|
469
|
-
end
|
470
|
-
|
471
|
-
private
|
472
|
-
|
473
|
-
def find_path(s)
|
474
|
-
puts 'find_path s: ' + s.inspect if @debug
|
475
|
-
found = query('//'+ s)
|
476
|
-
return unless found
|
477
|
-
a = found.backtrack.to_xpath.split('/')
|
478
|
-
a[1..-2].join(' ')
|
479
|
-
end
|
480
|
-
|
481
|
-
alias find_request run_route
|
482
|
-
|
483
|
-
end
|
484
|
-
|
485
|
-
class Controller
|
486
|
-
|
487
|
-
attr_reader :model, :control
|
488
|
-
attr_accessor :title, :macros, :store
|
489
|
-
|
490
|
-
def initialize(mcs, model=MODEL, deviceid: nil, debug: false)
|
491
|
-
|
492
|
-
@debug = debug
|
493
|
-
@syslog = []
|
494
|
-
|
495
|
-
@control = Control.new(deviceid)
|
496
|
-
@macros = mcs.macros
|
497
|
-
|
498
|
-
if model then
|
499
|
-
@model = Model.new(model)
|
500
|
-
end
|
501
|
-
|
502
|
-
@store = {}
|
503
|
-
@query = Query.new(self)
|
504
|
-
|
505
|
-
end
|
506
|
-
|
507
|
-
def export(s)
|
508
|
-
@macros = MacroDroid.new(s).macros
|
509
|
-
end
|
510
|
-
|
511
|
-
def invoke(name, options={})
|
512
|
-
|
513
|
-
if @control.respond_to? name.to_sym then
|
514
|
-
@control.method(name.to_sym).call(options)
|
515
|
-
else
|
516
|
-
@control.http_exec name.to_sym, options
|
517
|
-
end
|
518
|
-
end
|
519
|
-
|
520
|
-
# Object Property (op)
|
521
|
-
# Helpful for accessing properites in dot notation
|
522
|
-
# e.g. op.livingroom.light.switch = 'off'
|
523
|
-
#
|
524
|
-
def op()
|
525
|
-
@model.op
|
526
|
-
end
|
527
|
-
|
528
|
-
def query(id=nil)
|
529
|
-
|
530
|
-
return @query unless id
|
531
|
-
|
532
|
-
@store[id] = nil
|
323
|
+
webhook
|
324
|
+
identifier: screen_on_off
|
325
|
+
screen_on: true
|
533
326
|
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
:usb_mass_storage_enabled, :wifi_on]
|
538
|
-
|
539
|
-
secure = %i(bluetooth_name flashlight_enabled)
|
327
|
+
m: Power Button Toggle3
|
328
|
+
t: Power Button Toggle (3)
|
329
|
+
a: webhook
|
540
330
|
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
if id.downcase.to_sym == :location then
|
545
|
-
@control.http_exec id
|
546
|
-
elsif sys.include? id
|
547
|
-
@control.http_exec :'query-setting-system', {qvar: id}
|
548
|
-
elsif global.include? id
|
549
|
-
@control.http_exec :'query-setting-global', {qvar: id}
|
550
|
-
elsif secure.include? id
|
551
|
-
@control.http_exec :'query-setting-secure', {qvar: id}
|
552
|
-
else
|
553
|
-
@control.http_exec :query, {qvar: id}
|
554
|
-
end
|
555
|
-
|
556
|
-
# wait for the local variable to be updated
|
557
|
-
# timeout after 5 seoncds
|
558
|
-
t = Time.now
|
559
|
-
|
560
|
-
begin
|
561
|
-
sleep 1
|
562
|
-
end until @store[id] or Time.now > t + 5
|
563
|
-
|
564
|
-
return {warning: 'HTTP response timeout'} if Time.now > t+5
|
565
|
-
|
566
|
-
return @store[id]
|
331
|
+
m: Power Button Toggle4
|
332
|
+
t: Power Button Toggle (4)
|
333
|
+
a: webhook
|
567
334
|
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
def request(s)
|
572
|
-
@model.request s
|
573
|
-
end
|
574
|
-
|
575
|
-
|
576
|
-
def trigger(name, detail={time: Time.now})
|
577
|
-
|
578
|
-
macros = @macros.select do |macro|
|
579
|
-
|
580
|
-
puts 'macro: ' + macro.inspect if @debug
|
335
|
+
m: Power Button Toggle5
|
336
|
+
t: Power Button Toggle (5)
|
337
|
+
a: webhook
|
581
338
|
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
@syslog << [Time.now, :trigger, name]
|
591
|
-
@syslog << [Time.now, :macro, macro.title]
|
592
|
-
end
|
593
|
-
|
594
|
-
valid_trigger
|
595
|
-
|
596
|
-
end
|
597
|
-
|
598
|
-
puts 'macros: ' + macros.inspect if @debug
|
599
|
-
|
600
|
-
macros.flat_map(&:run)
|
601
|
-
end
|
602
|
-
|
603
|
-
alias trigger_fired trigger
|
604
|
-
|
605
|
-
def update(id, val)
|
606
|
-
key = id == :location ? id : val.keys.first.to_sym
|
607
|
-
@store[key] = val
|
608
|
-
end
|
609
|
-
|
339
|
+
m: Connected to network
|
340
|
+
t:
|
341
|
+
Connected to network
|
342
|
+
Any Network
|
343
|
+
a: wait 2 seconds
|
344
|
+
a:
|
345
|
+
webhook
|
346
|
+
ssid: [ssid]
|
610
347
|
|
611
|
-
|
348
|
+
m: In Vehicle
|
349
|
+
t:
|
350
|
+
Activity - In Vehicle
|
351
|
+
Confidence >= 50%
|
352
|
+
a:
|
353
|
+
webhook
|
354
|
+
identifier: activity
|
355
|
+
index: 0
|
612
356
|
|
613
|
-
|
614
|
-
|
615
|
-
|
616
|
-
|
617
|
-
|
618
|
-
|
619
|
-
|
620
|
-
|
621
|
-
end
|
622
|
-
end
|
623
|
-
|
624
|
-
class Toast < Service
|
625
|
-
|
626
|
-
def invoke()
|
627
|
-
@callback.call :toast
|
628
|
-
end
|
629
|
-
|
630
|
-
end
|
631
|
-
|
632
|
-
class Torch < Service
|
633
|
-
|
634
|
-
def toggle()
|
635
|
-
@callback.http_exec :torch
|
636
|
-
end
|
637
|
-
|
638
|
-
end
|
639
|
-
|
640
|
-
class ControlHelper
|
357
|
+
m: On Bicycle
|
358
|
+
t:
|
359
|
+
Activity - On Bicycle
|
360
|
+
Confidence >= 50%
|
361
|
+
a:
|
362
|
+
webhook
|
363
|
+
identifier: activity
|
364
|
+
index: 1
|
641
365
|
|
642
|
-
|
643
|
-
|
644
|
-
|
645
|
-
|
366
|
+
m: Running
|
367
|
+
t:
|
368
|
+
Activity - Running
|
369
|
+
Confidence >= 50%
|
370
|
+
a:
|
371
|
+
webhook
|
372
|
+
identifier: activity
|
373
|
+
index: 2
|
646
374
|
|
647
|
-
|
648
|
-
|
649
|
-
|
650
|
-
|
651
|
-
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
def bluetooth()
|
656
|
-
@bluetooth
|
657
|
-
end
|
658
|
-
|
659
|
-
def camera_flash_light(options={})
|
660
|
-
http_exec 'camera-flash-light', options
|
661
|
-
end
|
662
|
-
|
663
|
-
def hotspot(state=nil)
|
664
|
-
|
665
|
-
if state then
|
666
|
-
http_exec 'hotspot', {enable: state == :enable}
|
667
|
-
else
|
375
|
+
m: Walking
|
376
|
+
t:
|
377
|
+
Activity - Walking
|
378
|
+
Confidence >= 50%
|
379
|
+
a:
|
380
|
+
webhook
|
381
|
+
identifier: activity
|
382
|
+
index: 3
|
668
383
|
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
def self.disable()
|
678
|
-
http_exec 'hotspot', {enable: false}
|
679
|
-
end
|
680
|
-
|
681
|
-
def self.off()
|
682
|
-
self.disable
|
683
|
-
end
|
684
|
-
|
685
|
-
self
|
686
|
-
|
687
|
-
end
|
688
|
-
end
|
689
|
-
|
690
|
-
def http_exec(command, options={})
|
691
|
-
|
692
|
-
url = "https://trigger.macrodroid.com/%s/%s" % [@deviceid, command]
|
693
|
-
|
694
|
-
if options and options.any? then
|
695
|
-
h = options
|
696
|
-
url += '?' + \
|
697
|
-
URI.escape(h.map {|key,value| "%s=%s" % [key, value]}.join('&'))
|
698
|
-
end
|
699
|
-
|
700
|
-
s = open(url).read
|
701
|
-
|
702
|
-
end
|
703
|
-
|
704
|
-
def location(options={})
|
705
|
-
http_exec 'location'
|
706
|
-
end
|
707
|
-
|
708
|
-
def say_current_time(options={})
|
709
|
-
http_exec 'say-current-time'
|
710
|
-
end
|
711
|
-
|
712
|
-
alias say_time say_current_time
|
713
|
-
|
714
|
-
def screen(state=nil)
|
715
|
-
|
716
|
-
if state then
|
717
|
-
http_exec 'screen', {on: state == :on}
|
718
|
-
else
|
719
|
-
|
720
|
-
def self.on()
|
721
|
-
http_exec 'screen', {on: true}
|
722
|
-
end
|
723
|
-
|
724
|
-
def self.off()
|
725
|
-
http_exec 'screen', {on: false}
|
726
|
-
end
|
727
|
-
|
728
|
-
self
|
729
|
-
|
730
|
-
end
|
731
|
-
end
|
732
|
-
|
733
|
-
def share_location(options={})
|
734
|
-
http_exec 'share-location'
|
735
|
-
end
|
736
|
-
|
737
|
-
def speak_text(obj)
|
738
|
-
|
739
|
-
options = case obj
|
740
|
-
when String
|
741
|
-
{text: obj}
|
742
|
-
when Hash
|
743
|
-
obj
|
744
|
-
end
|
745
|
-
|
746
|
-
http_exec 'speak-text', options
|
747
|
-
end
|
384
|
+
m: Still
|
385
|
+
t:
|
386
|
+
Activity - Still
|
387
|
+
Confidence >= 83%
|
388
|
+
a:
|
389
|
+
webhook
|
390
|
+
identifier: activity
|
391
|
+
index: 4
|
748
392
|
|
749
|
-
|
750
|
-
|
751
|
-
|
752
|
-
|
753
|
-
|
393
|
+
m: Swipe top left across
|
394
|
+
t:
|
395
|
+
Swipe Screen
|
396
|
+
Top Left - Across
|
397
|
+
a:
|
398
|
+
webhook
|
399
|
+
identifier: swipe
|
400
|
+
start: 0
|
401
|
+
motion: 0
|
402
|
+
|
403
|
+
m: Swipe top left diagonal
|
404
|
+
t:
|
405
|
+
Swipe Screen
|
406
|
+
Top Left - Diagonal
|
407
|
+
a:
|
408
|
+
webhook
|
409
|
+
identifier: swipe
|
410
|
+
start: 0
|
411
|
+
motion: 1
|
412
|
+
|
413
|
+
m: Swipe top left down
|
414
|
+
t:
|
415
|
+
Swipe Screen
|
416
|
+
Top Left - Down
|
417
|
+
a:
|
418
|
+
webhook
|
419
|
+
identifier: swipe
|
420
|
+
start: 0
|
421
|
+
motion: 2
|
422
|
+
|
423
|
+
m: Swipe top right across
|
424
|
+
t:
|
425
|
+
Swipe Screen
|
426
|
+
Top Right - Across
|
427
|
+
a:
|
428
|
+
webhook
|
429
|
+
identifier: swipe
|
430
|
+
start: 1
|
431
|
+
motion: 0
|
754
432
|
|
755
|
-
alias take_photo take_picture
|
756
433
|
|
757
|
-
|
758
|
-
|
759
|
-
|
760
|
-
|
761
|
-
|
762
|
-
|
763
|
-
|
764
|
-
|
765
|
-
|
766
|
-
|
767
|
-
|
768
|
-
|
434
|
+
m: Swipe top right diagonal
|
435
|
+
t:
|
436
|
+
Swipe Screen
|
437
|
+
Top Right - Diagonal
|
438
|
+
a:
|
439
|
+
webhook
|
440
|
+
identifier: swipe
|
441
|
+
start: 1
|
442
|
+
motion: 1
|
443
|
+
|
444
|
+
m: Swipe top right down
|
445
|
+
t:
|
446
|
+
Swipe Screen
|
447
|
+
Top Right - Down
|
448
|
+
a:
|
449
|
+
webhook
|
450
|
+
identifier: swipe
|
451
|
+
start: 1
|
452
|
+
motion: 2
|
769
453
|
|
454
|
+
m: flip from up to down
|
455
|
+
t: Flip Device Face Up -> Face Down
|
456
|
+
a:
|
457
|
+
webhook
|
458
|
+
identifier: flip_device
|
459
|
+
facedown: true
|
770
460
|
|
771
|
-
|
772
|
-
|
773
|
-
|
774
|
-
|
775
|
-
|
776
|
-
|
777
|
-
|
778
|
-
alias export write
|
779
|
-
|
780
|
-
def method_missing2(method_name, *args)
|
781
|
-
http_exec(method_name, args.first)
|
782
|
-
end
|
783
|
-
|
784
|
-
end
|
785
|
-
|
786
|
-
class Query
|
787
|
-
|
788
|
-
def initialize(callback)
|
789
|
-
@callback = callback
|
790
|
-
end
|
791
|
-
|
792
|
-
def airplane_mode_enabled?()
|
793
|
-
q(:airplane_mode_on).to_i > 0
|
794
|
-
end
|
795
|
-
|
796
|
-
def battery()
|
797
|
-
q(:battery).to_i
|
798
|
-
end
|
799
|
-
|
800
|
-
def current_brightness()
|
801
|
-
q(:current_brightness).to_i
|
802
|
-
end
|
461
|
+
m: flip from down to up
|
462
|
+
t: Flip Device Face Down -> Face Up
|
463
|
+
a:
|
464
|
+
webhook
|
465
|
+
identifier: flip_device
|
466
|
+
facedown: false
|
467
|
+
EOF
|
803
468
|
|
804
|
-
alias brightness current_brightness
|
805
|
-
|
806
|
-
def cell_id()
|
807
|
-
q(:cell_id)
|
808
|
-
end
|
809
|
-
|
810
|
-
alias cell_tower cell_id
|
811
|
-
|
812
|
-
def ip()
|
813
|
-
q(:ip)
|
814
|
-
end
|
815
|
-
|
816
|
-
def location()
|
817
|
-
@callback.query(:location)[:coords]
|
818
|
-
end
|
819
469
|
|
820
|
-
|
821
|
-
private
|
822
|
-
|
823
|
-
def q(id)
|
824
|
-
@callback.query(id)[id]
|
825
|
-
end
|
826
|
-
|
827
|
-
end
|
470
|
+
module RemoteDroid
|
828
471
|
|
829
472
|
class Server
|
830
473
|
|
@@ -841,121 +484,7 @@ module RemoteDroid
|
|
841
484
|
end
|
842
485
|
|
843
486
|
end
|
844
|
-
|
845
|
-
class Client
|
846
|
-
|
847
|
-
def initialize(host='127.0.0.1')
|
848
|
-
@drb = OneDrb::Client.new host: host, port: '5777'
|
849
|
-
end
|
850
|
-
|
851
|
-
def control
|
852
|
-
@drb.control
|
853
|
-
end
|
854
|
-
|
855
|
-
def export(s)
|
856
|
-
@drb.export(s)
|
857
|
-
end
|
858
|
-
|
859
|
-
def invoke(s, *args)
|
860
|
-
@drb.invoke(s, *args)
|
861
|
-
end
|
862
|
-
|
863
|
-
def query(id=nil)
|
864
|
-
|
865
|
-
return @drb.query unless id
|
866
|
-
t = Time.now
|
867
|
-
h = @drb.query(id)
|
868
|
-
h.merge({latency: (Time.now - t).round(3)})
|
869
|
-
|
870
|
-
end
|
871
|
-
|
872
|
-
def update(key, val)
|
873
|
-
@drb.update key.to_sym, val
|
874
|
-
end
|
875
|
-
|
876
|
-
def store()
|
877
|
-
@drb.store
|
878
|
-
end
|
879
|
-
|
880
|
-
# -- helpful methods -----------------
|
881
|
-
|
882
|
-
def battery()
|
883
|
-
query.battery
|
884
|
-
end
|
885
|
-
|
886
|
-
def cell_tower()
|
887
|
-
query.cell_tower
|
888
|
-
end
|
889
|
-
|
890
|
-
def hotspot(state=nil)
|
891
|
-
control.hotspot state
|
892
|
-
end
|
893
|
-
|
894
|
-
def location()
|
895
|
-
query.location
|
896
|
-
end
|
897
|
-
|
898
|
-
def photo()
|
899
|
-
take_picture
|
900
|
-
end
|
901
|
-
|
902
|
-
def say(text)
|
903
|
-
control.speak_text text
|
904
|
-
end
|
905
|
-
|
906
|
-
def say_time()
|
907
|
-
control.say_time
|
908
|
-
end
|
909
|
-
|
910
|
-
alias saytime say_time
|
911
|
-
|
912
|
-
def screen(state=nil)
|
913
|
-
control.screen state
|
914
|
-
end
|
915
|
-
|
916
|
-
def screen_on()
|
917
|
-
screen :on
|
918
|
-
end
|
919
|
-
|
920
|
-
def screen_off()
|
921
|
-
screen :off
|
922
|
-
end
|
923
|
-
|
924
|
-
def take_picture(ftp_src: nil, fileout: '.')
|
925
|
-
|
926
|
-
screen.on
|
927
|
-
r = control.take_picture
|
928
|
-
|
929
|
-
if ftp_src then
|
930
|
-
|
931
|
-
# the sleep statement will be replaced in the near future,
|
932
|
-
# but it's fine to demonstrate it works
|
933
|
-
sleep 8
|
934
|
-
|
935
|
-
credentials, dir = ftp_src.match(/(ftp:\/\/[^\/]+)\/([^$]+)/).captures
|
936
|
-
ftp = MyMediaFTP.new(credentials)
|
937
|
-
ftp.cd dir
|
938
|
-
filename = ftp.ls.sort_by {|x| x[:ctime]}.last[:name]
|
939
|
-
ftp.cp filename, fileout
|
940
|
-
|
941
|
-
end
|
942
|
-
|
943
|
-
end
|
944
|
-
|
945
|
-
def take_photo()
|
946
|
-
control.take_photo
|
947
|
-
end
|
948
|
-
|
949
|
-
def torch()
|
950
|
-
control.torch
|
951
|
-
end
|
952
487
|
|
953
|
-
def vibrate
|
954
|
-
control.vibrate
|
955
|
-
end
|
956
|
-
|
957
|
-
end
|
958
|
-
|
959
488
|
class TriggerSubscriber < SPSSub
|
960
489
|
|
961
490
|
def initialize(host: 'sps.home', drb_host: '127.0.0.1')
|
@@ -990,8 +519,19 @@ module RemoteDroid
|
|
990
519
|
|
991
520
|
context, json = msg.split(/:\s+/,2)
|
992
521
|
category, action = context.split('/',2)
|
993
|
-
|
994
|
-
|
522
|
+
|
523
|
+
h = JSON.parse(json, symbolize_names: true)
|
524
|
+
|
525
|
+
if action == 'force_macro_run' and h[:serverside] then
|
526
|
+
|
527
|
+
a = @remote.run_macro(h)
|
528
|
+
a.each {|msg| self.notice 'macrodroid/action: ' + msg }
|
529
|
+
|
530
|
+
else
|
531
|
+
|
532
|
+
@remote.control.method(action.to_sym).call(h)
|
533
|
+
|
534
|
+
end
|
995
535
|
|
996
536
|
end
|
997
537
|
|
@@ -1011,6 +551,7 @@ module RemoteDroid
|
|
1011
551
|
super(topic: topic) do |msg|
|
1012
552
|
|
1013
553
|
json, id = msg.split(/:\s+/,2).reverse
|
554
|
+
|
1014
555
|
h = JSON.parse(json, symbolize_names: true)
|
1015
556
|
id ||= h.keys.first
|
1016
557
|
@remote.update id.to_sym, h
|
@@ -1021,3 +562,12 @@ module RemoteDroid
|
|
1021
562
|
|
1022
563
|
end
|
1023
564
|
end
|
565
|
+
|
566
|
+
# PASTE_END
|
567
|
+
|
568
|
+
|
569
|
+
require 'remotedroid/model'
|
570
|
+
require 'remotedroid/query'
|
571
|
+
require 'remotedroid/control'
|
572
|
+
require 'remotedroid/controller'
|
573
|
+
require 'remotedroid/client'
|