remotedroid 0.4.1 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dd7b7c4614e48123ecdc155abc68d996445d62d997df99dc65fe2969b9260c79
4
- data.tar.gz: a4de25cf022d6bdaacc221f9b986a0244e1ea8b5faad38f151713825417b004c
3
+ metadata.gz: ffd9a9a0c4d6d86dcf23408d9345c0a57bef2b6a516b8effcce7dc4b2b8bb0d3
4
+ data.tar.gz: e752e40ee31bf64505e84dc7c2e49a45f61185d3e2573dfb1f4b73526c8a5cb5
5
5
  SHA512:
6
- metadata.gz: 0467d4f2441f460e6428ba1457637643fc707ec1f6c4aeb66e15f7d8cc75f2fec4284915d3b5f0bd3ea1b7fc9818305ed4a54b00fc07913ec5d01746b73d1ad4
7
- data.tar.gz: 385c2c1d6b7a78954eadf6c01d03382cfe16986ac27c218fc1a8ac01e2350d814df6de0909bd0c084e1e36cc53398cd974bc9c49537dc24f51ea9d98621f5067
6
+ metadata.gz: '090b89b8e66c0b6368015741e4db9b9344f6714c96f393efaa40a0a019f467fd04b078a716ae2a9ca2af6e687ea328eccbf67e1d87eee0a278281b34d72e0394'
7
+ data.tar.gz: ed2ca4e908800cb5f88c34d5352cde163168959d994bf82c66a3f90b0e5bc187ccc6b73c9afcf24cd6fbe00fb52a668c3b2d5b29a09410f7ac7eb9614c401a79
@@ -1,4 +1 @@
1
- ?���,���l
2
- �"�=r�Kg�PD��^j�4md�Ε=ψ����!�p+�,q��No8&Bѕ�Q�x;�eAx���z��+���L=tUP�_���֑ʇOi.�� mBG��|�~Ey
3
- y������Y/�]���3!]�����]�m��8�ۛ�a�P��D���u���g�] ������~*Y����)���̊��J���E��_y��%�G���h �.g��Vs�XF�QU����G,�Ƣ�hQ~) �c\��l���f5��W�פ�o�!Ղ P W/��Y�"���w�����i�d2�v������\��U6 �5�!�F\{eл�u�W�#hT��Y���<zk�W�D
4
- p�p\�o'+��.�j(��J
1
+ bB2�۰)�x��6=˕8aؖ��G ��$o!�ӏ�y��I��r��-���Ɂ�^X%9G��Ǚʑ��8�U�/�=Q�xZ햠څ[[�iQmN^��Pw ��N�|��A,o��a}�^W��� ]��l\�����@.PQ6�CߗU;��Ri��'�c�� �%��b8'�pt JL��WpL�ʬe
data.tar.gz.sig CHANGED
Binary file
@@ -8,20 +8,48 @@ 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
+ #
27
+ # ## Device Events
28
+ #
29
+ # * screen on
30
+ #
16
31
  # ## Sensors
17
- #
32
+ #
33
+ # * Activity Recognition
18
34
  # * proximity (near)
19
35
  # * shake device
20
36
  #
37
+ # ## User Input
38
+ #
39
+ # * Swipe Screen
40
+ #
21
41
  # ------------------------------------
22
42
  #
23
43
  # # Actions
24
44
  #
45
+ # ## Camera/Photo
46
+ #
47
+ # * Take Picture
48
+ #
49
+ # ## Connectivity
50
+ #
51
+ # * Enable HotSpot
52
+ #
25
53
  # ## Date/Time
26
54
  #
27
55
  # * Say Current Time
@@ -36,6 +64,10 @@ require 'ruby-macrodroid'
36
64
  #
37
65
  # * Share Location
38
66
  #
67
+ # ## MacroDroid specific
68
+ #
69
+ # * Disable Macro
70
+ #
39
71
  # ## Media
40
72
  #
41
73
  # * Play sound (Doda)
@@ -46,6 +78,7 @@ require 'ruby-macrodroid'
46
78
  #
47
79
  # ## Screen
48
80
  #
81
+ # * Keep Device Awake
49
82
  # * Screen On
50
83
  #
51
84
 
@@ -137,7 +170,33 @@ a:
137
170
  Else
138
171
  Screen Off
139
172
  End If
140
-
173
+
174
+ m: Hotspot
175
+ v: enable: false
176
+ t: WebHook
177
+ a:
178
+ If enable = True
179
+ Enable Hotspot
180
+ Else
181
+ Disable Hotspot
182
+ End If
183
+
184
+ m: Take Picture
185
+ t: webhook
186
+ a:
187
+ Take Picture
188
+ Rear Facing
189
+ a: wait 2 seconds
190
+ a: webhook
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
+
141
200
  m: Share location
142
201
  t:
143
202
  WebHook
@@ -150,7 +209,16 @@ a:
150
209
  HTTP GET
151
210
  identifier: location
152
211
  coords: [lv=coords]
212
+ cell: [cell_id]
213
+ ssid: [ssid]
214
+ alt: [last_loc_alt]
215
+ time: [last_loc_age_timestamp]
216
+ mph: [last_loc_speed_mph]
217
+ kph: [last_loc_speed_kmh]
218
+ device: [device_model]
219
+ battery: [battery]
153
220
  type: query
221
+
154
222
 
155
223
  m: query
156
224
  t: WebHook
@@ -207,559 +275,103 @@ a:
207
275
  m: Power connected
208
276
  t: Power Connected: Any
209
277
  a: webhook
210
-
211
-
212
- EOF
213
278
 
214
- =begin
215
- m: Screen
216
- v: on: true
217
- t: WebHook
218
- a:
219
- If on = true
220
- Screen On
221
- Else
222
- Screen Off
223
- End If
224
-
225
- =end
226
-
227
- module RemoteDroid
228
-
229
- class Model
230
- include AppRoutes
231
-
232
- def initialize(obj=nil, root: 'device1', debug: false)
233
-
234
- super()
235
- @root, @debug = root, debug
236
- @location = nil
237
-
238
- if obj then
239
-
240
- s = obj.strip
241
-
242
- puts 's: ' + s.inspect if @debug
243
-
244
- if s[0] == '<' or s.lines[1][0..1] == ' ' then
245
-
246
- puts 'before easydom' if @debug
247
-
248
- s2 = if s.lines[1][0..1] == ' ' then
249
-
250
- lines = s.lines.map do |line|
251
- line.sub(/(\w+) +is +(\w+)$/) {|x| "#{$1} {switch: #{$2}}" }
252
- end
253
-
254
- lines.join
255
-
256
- else
257
- s
258
- end
259
-
260
- @ed = EasyDom.new(s2)
261
- else
262
- build(s, root: root)
263
- end
264
-
265
- end
266
-
267
- end
268
-
269
- def build(raw_requests, root: @root)
270
-
271
- @ed = EasyDom.new(debug: false, root: root)
272
- raw_requests.lines.each {|line| request(line) }
273
-
274
- end
275
-
276
-
277
- def get_thing(h)
278
-
279
- h[:thing].gsub!(/ /,'_')
280
-
281
- if not h.has_key? :location then
282
- location = false
283
- h[:location] = find_path(h[:thing])
284
- else
285
- location = true
286
- end
287
-
288
- puts 'h: ' + h.inspect if @debug
289
-
290
- a = []
291
- a += h[:location].split(/ /)
292
- a << h[:thing]
293
- status = a.inject(@ed) {|r,x| r.send(x)}.send(h[:action])
294
-
295
- if location then
296
- "The %s %s is %s." % [h[:location], h[:thing], status]
297
- else
298
- "%s is %s." % [h[:thing].capitalize, status]
299
- end
300
-
301
- end
302
-
303
- # Object Property (op)
304
- # Helpful for accessing properites in dot notation
305
- # e.g. op.livingroom.light.switch = 'off'
306
- #
307
- def op()
308
- @ed
309
- end
310
-
311
- def query(s)
312
- @ed.e.element(s)
313
- end
314
-
315
- # request accepts a string in plain english
316
- # e.g. request 'switch the livingroom light on'
317
- #
318
- def request(s)
319
-
320
- params = {request: s}
321
- requests(params)
322
- h = find_request(s)
323
-
324
- method(h.first[-1]).call(h).gsub(/_/,' ')
325
-
326
- end
327
-
328
- def set_thing(h)
329
-
330
- h[:thing].gsub!(/ /,'_')
331
- h[:location] = find_path(h[:thing]) unless h.has_key? :location
332
-
333
- a = []
334
- a += h[:location].split(/ /)
335
- a << h[:thing]
336
-
337
- a.inject(@ed) {|r,x| r.send(x)}.send(h[:action], h[:value])
338
-
339
- end
340
-
341
- def to_sliml(level: 0)
342
-
343
- s = @ed.to_sliml
344
-
345
- return s if level.to_i > 0
346
-
347
- lines = s.lines.map do |line|
348
-
349
- line.sub(/\{[^\}]+\}/) do |x|
350
-
351
- a = x.scan(/\w+: +[^ ]+/)
352
- if a.length == 1 and x[/switch:/] then
353
-
354
- val = x[/(?<=switch: ) *["']([^"']+)/,1]
355
- 'is ' + val
356
- else
357
- x
358
- end
359
-
360
- end
361
- end
362
-
363
- lines.join
364
-
365
- end
366
-
367
- def to_xml(options=nil)
368
- @ed.xml(pretty: true).gsub(' style=\'\'','')
369
- end
370
-
371
- alias xml to_xml
372
-
373
- # to_xml() is the preferred method
374
-
375
- protected
376
-
377
- def requests(params)
378
-
379
- # e.g. switch the livingroom gas_fire off
380
- #
381
- get /(?:switch|turn) the ([^ ]+) +([^ ]+) +(on|off)$/ do |location, device, onoff|
382
- {type: :set_thing, action: 'switch=', location: location, thing: device, value: onoff}
383
- end
384
-
385
- # e.g. switch the gas _fire off
386
- #
387
- get /(?:switch|turn) the ([^ ]+) +(on|off)$/ do |device, onoff|
388
- {type: :set_thing, action: 'switch=', thing: device, value: onoff}
389
- end
390
-
391
- # e.g. is the livingroom gas_fire on?
392
- #
393
- get /is the ([^ ]+) +([^ ]+) +(?:on|off)\??$/ do |location, device|
394
- {type: :get_thing, action: 'switch', location: location, thing: device}
395
- end
396
-
397
- # e.g. enable airplane mode
398
- #
399
- get /((?:dis|en)able) ([^$]+)$/ do |state, service|
400
- {type: :set_thing, action: 'switch=', thing: service, value: state + 'd'}
401
- end
402
-
403
- # e.g. switch airplane mode off
404
- #
405
- get /switch (.*) (on|off)/ do |service, rawstate|
406
-
407
- state = rawstate == 'on' ? 'enabled' : 'disabled'
408
- {type: :set_thing, action: 'switch=', thing: service, value: state}
409
-
410
- end
411
-
412
- # e.g. is airplane mode enabed?
413
- #
414
- get /is (.*) +(?:(?:dis|en)abled)\??$/ do |service|
415
- {type: :get_thing, action: 'switch', thing: service.gsub(/ /,'_')}
416
- end
417
-
418
- # e.g. is the gas_fire on?
419
- #
420
- get /is the ([^ ]+) +(?:on|off)\??$/ do |device|
421
- location = find_path(device)
422
- {type: :get_thing, action: 'switch', location: location, thing: device}
423
- end
424
-
425
- # e.g. fetch the livingroom temperature reading
426
- #
427
- get /fetch the ([^ ]+) +([^ ]+) +(?:reading)$/ do |location, device|
428
- {type: :get_thing, action: 'reading', location: location, thing: device}
429
- end
430
-
431
- # e.g. fetch the temperature reading
432
- #
433
- get /fetch the ([^ ]+) +(?:reading)$/ do |device|
434
- location = find_path(device)
435
- {type: :get_thing, action: 'reading', location: location, thing: device}
436
- end
279
+ m: screen on off
280
+ t: screen on
281
+ a: webhook
437
282
 
438
- end
439
-
440
- private
441
-
442
- def find_path(s)
443
- puts 'find_path s: ' + s.inspect if @debug
444
- found = query('//'+ s)
445
- return unless found
446
- a = found.backtrack.to_xpath.split('/')
447
- a[1..-2].join(' ')
448
- end
449
-
450
- alias find_request run_route
283
+ m: Power Button Toggle3
284
+ t: Power Button Toggle (3)
285
+ a: webhook
451
286
 
452
- end
287
+ m: Power Button Toggle4
288
+ t: Power Button Toggle (4)
289
+ a: webhook
453
290
 
454
- class Controller
455
-
456
- attr_reader :model, :control
457
- attr_accessor :title, :macros, :store
291
+ m: Power Button Toggle5
292
+ t: Power Button Toggle (5)
293
+ a: webhook
458
294
 
459
- def initialize(mcs, model=MODEL, deviceid: nil, debug: false)
460
-
461
- @debug = debug
462
- @syslog = []
463
-
464
- @control = Control.new(deviceid)
465
- @macros = mcs.macros
466
-
467
- if model then
468
- @model = Model.new(model)
469
- end
470
-
471
- @store = {}
472
- @query = Query.new(self)
295
+ m: Connected to network
296
+ t:
297
+ Connected to network
298
+ Any Network
299
+ a: wait 2 seconds
300
+ a:
301
+ webhook
302
+ ssid: [ssid]
303
+
304
+ m: In Vehicle
305
+ t:
306
+ Activity - In Vehicle
307
+ Confidence >= 50%
308
+ a: webhook
309
+
310
+ m: On Bicycle
311
+ t:
312
+ Activity - On Bicycle
313
+ Confidence >= 50%
314
+ a: webhook
473
315
 
474
- end
475
-
476
- def export(s)
477
- @macros = MacroDroid.new(s).macros
478
- end
479
-
480
- def invoke(name, options={})
481
-
482
- if @control.respond_to? name.to_sym then
483
- @control.method(name.to_sym).call(options)
484
- else
485
- @control.http_exec name.to_sym, options
486
- end
487
- end
316
+ m: Running
317
+ t:
318
+ Activity - Running
319
+ Confidence >= 50%
320
+ a: webhook
488
321
 
489
- # Object Property (op)
490
- # Helpful for accessing properites in dot notation
491
- # e.g. op.livingroom.light.switch = 'off'
492
- #
493
- def op()
494
- @model.op
495
- end
496
-
497
- def query(id=nil)
498
-
499
- return @query unless id
500
-
501
- @store[id] = nil
322
+ m: Walking
323
+ t:
324
+ Activity - Walking
325
+ Confidence >= 50%
326
+ a: webhook
502
327
 
503
- sys = %i(accelerometer_rotation)
504
-
505
- global = [:airplane_mode_on, :bluetooth_on, :cell_on, :device_name, \
506
- :usb_mass_storage_enabled, :wifi_on]
507
-
508
- secure = %i(bluetooth_name flashlight_enabled)
328
+ m: Still
329
+ t:
330
+ Activity - Still
331
+ Confidence >= 83%
332
+ a: webhook
509
333
 
510
-
511
- # send http request via macrodroid.com API
512
-
513
- if id.downcase.to_sym == :location then
514
- @control.http_exec id
515
- elsif sys.include? id
516
- @control.http_exec :'query-setting-system', {qvar: id}
517
- elsif global.include? id
518
- @control.http_exec :'query-setting-global', {qvar: id}
519
- elsif secure.include? id
520
- @control.http_exec :'query-setting-secure', {qvar: id}
521
- else
522
- @control.http_exec :query, {qvar: id}
523
- end
524
-
525
- # wait for the local variable to be updated
526
- # timeout after 5 seoncds
527
- t = Time.now
528
-
529
- begin
530
- sleep 1
531
- end until @store[id] or Time.now > t + 5
532
-
533
- return {warning: 'HTTP response timeout'} if Time.now > t+5
534
-
535
- return @store[id]
334
+ m: Swipe top left across
335
+ t:
336
+ Swipe Screen
337
+ Top Left - Across
338
+ a: webhook
536
339
 
537
-
538
- end
539
-
540
- def request(s)
541
- @model.request s
542
- end
543
-
544
-
545
- def trigger(name, detail={time: Time.now})
546
-
547
- macros = @macros.select do |macro|
548
-
549
- puts 'macro: ' + macro.inspect if @debug
340
+ m: Swipe top left diagonal
341
+ t:
342
+ Swipe Screen
343
+ Top Left - Diagonal
344
+ a: webhook
550
345
 
551
- # fetch the associated properties from the model if possible and
552
- # merge them into the detail.
553
- #
554
- valid_trigger = macro.match?(name, detail, @model.op)
555
-
556
- puts 'valid_trigger: ' + valid_trigger.inspect if @debug
557
-
558
- if valid_trigger then
559
- @syslog << [Time.now, :trigger, name]
560
- @syslog << [Time.now, :macro, macro.title]
561
- end
562
-
563
- valid_trigger
564
-
565
- end
566
-
567
- puts 'macros: ' + macros.inspect if @debug
568
-
569
- macros.flat_map(&:run)
570
- end
571
-
572
- alias trigger_fired trigger
573
-
574
- def update(id, val)
575
- key = id == :location ? id : val.keys.first.to_sym
576
- @store[key] = val
577
- end
578
-
346
+ m: Swipe top left down
347
+ t:
348
+ Swipe Screen
349
+ Top Left - Down
350
+ a: webhook
579
351
 
580
- end
352
+ m: Swipe top right across
353
+ t:
354
+ Swipe Screen
355
+ Top Right - Across
356
+ a: webhook
581
357
 
582
- class Service
583
- def initialize(callback)
584
- @callback = callback
585
- end
586
- end
587
-
588
- class Bluetooth
589
- def enable()
590
- end
591
- end
592
-
593
- class Toast < Service
594
-
595
- def invoke()
596
- @callback.call :toast
597
- end
598
-
599
- end
600
-
601
- class Torch < Service
602
-
603
- def toggle()
604
- @callback.http_exec :torch
605
- end
606
-
607
- end
608
-
609
- class ControlHelper
610
-
611
- def initialize(callback)
612
- @callback
613
- end
614
- end
358
+ m: Swipe top right diagonal
359
+ t:
360
+ Swipe Screen
361
+ Top Right - Diagonal
362
+ a: webhook
615
363
 
616
- class Control
617
-
618
- def initialize(dev=nil, deviceid: dev, remote_url: nil, debug: false)
619
-
620
- @deviceid, @remote_url, @debug = deviceid, remote_url, debug
621
- @torch = Torch.new(self)
622
- end
623
-
624
- def bluetooth()
625
- @bluetooth
626
- end
627
-
628
- def camera_flash_light(options={})
629
- http_exec 'camera-flash-light', options
630
- end
631
-
632
- def http_exec(command, options={})
633
-
634
- url = "https://trigger.macrodroid.com/%s/%s" % [@deviceid, command]
635
-
636
- if options and options.any? then
637
- h = options
638
- url += '?' + \
639
- URI.escape(h.map {|key,value| "%s=%s" % [key, value]}.join('&'))
640
- end
641
-
642
- s = open(url).read
643
-
644
- end
645
-
646
- def location(options={})
647
- http_exec 'location'
648
- end
649
-
650
- def say_current_time(options={})
651
- http_exec 'say-current-time'
652
- end
653
-
654
- alias say_time say_current_time
655
-
656
- def screen(state=nil)
657
-
658
- if state then
659
- http_exec 'screen', {on: state == :on}
660
- else
661
-
662
- def self.on()
663
- http_exec 'screen', {on: true}
664
- end
665
-
666
- def self.off()
667
- http_exec 'screen', {on: false}
668
- end
669
-
670
- self
671
-
672
- end
673
- end
674
-
675
- def share_location(options={})
676
- http_exec 'share-location'
677
- end
678
-
679
- def speak_text(obj)
680
-
681
- options = case obj
682
- when String
683
- {text: obj}
684
- when Hash
685
- obj
686
- end
687
-
688
- http_exec 'speak-text', options
689
- end
690
-
691
- alias say speak_text
692
-
693
- def toast(options={})
694
- http_exec :toast, options
695
- end
696
-
697
- def torch(options={})
698
- http_exec :torch
699
- end
700
-
701
- def vibrate(options={})
702
- http_exec :vibrate
703
- end
364
+ m: Swipe top right down
365
+ t:
366
+ Swipe Screen
367
+ Top Right - Down
368
+ a: webhook
704
369
 
705
370
 
706
- def write(s)
707
-
708
- MacroDroid.new(RD_MACROS, deviceid: @deviceid,
709
- remote_url: @remote_url, debug: @debug).export s
710
-
711
- end
712
-
713
- alias export write
714
-
715
- def method_missing2(method_name, *args)
716
- http_exec(method_name, args.first)
717
- end
718
-
719
- end
720
-
721
- class Query
722
-
723
- def initialize(callback)
724
- @callback = callback
725
- end
726
-
727
- def airplane_mode_enabled?()
728
- q(:airplane_mode_on).to_i > 0
729
- end
730
-
731
- def battery()
732
- q(:battery).to_i
733
- end
734
-
735
- def current_brightness()
736
- q(:current_brightness).to_i
737
- end
371
+ EOF
738
372
 
739
- alias brightness current_brightness
740
-
741
- def cell_id()
742
- q(:cell_id)
743
- end
744
-
745
- alias cell_tower cell_id
746
-
747
- def ip()
748
- q(:ip)
749
- end
750
-
751
- def location()
752
- @callback.query(:location)[:coords]
753
- end
754
373
 
755
-
756
- private
757
-
758
- def q(id)
759
- @callback.query(id)[id]
760
- end
761
-
762
- end
374
+ module RemoteDroid
763
375
 
764
376
  class Server
765
377
 
@@ -776,88 +388,7 @@ module RemoteDroid
776
388
  end
777
389
 
778
390
  end
779
-
780
- class Client
781
-
782
- def initialize(host='127.0.0.1')
783
- @drb = OneDrb::Client.new host: host, port: '5777'
784
- end
785
-
786
- def control
787
- @drb.control
788
- end
789
-
790
- def export(s)
791
- @drb.export(s)
792
- end
793
-
794
- def invoke(s, *args)
795
- @drb.invoke(s, *args)
796
- end
797
-
798
- def query(id=nil)
799
-
800
- return @drb.query unless id
801
- t = Time.now
802
- h = @drb.query(id)
803
- h.merge({latency: (Time.now - t).round(3)})
804
-
805
- end
806
-
807
- def update(key, val)
808
- @drb.update key.to_sym, val
809
- end
810
-
811
- def store()
812
- @drb.store
813
- end
814
-
815
- # -- helpful methods -----------------
816
-
817
- def battery()
818
- query.battery
819
- end
820
-
821
- def cell_tower()
822
- query.cell_tower
823
- end
824
-
825
- def location()
826
- query.location
827
- end
828
-
829
- def say(text)
830
- control.say text
831
- end
832
391
 
833
- def say_time()
834
- control.say_time
835
- end
836
-
837
- alias saytime say_time
838
-
839
- def screen(state=nil)
840
- control.screen state
841
- end
842
-
843
- def screen_on()
844
- screen :on
845
- end
846
-
847
- def screen_off()
848
- screen :off
849
- end
850
-
851
- def torch()
852
- control.torch
853
- end
854
-
855
- def vibrate
856
- control.vibrate
857
- end
858
-
859
- end
860
-
861
392
  class TriggerSubscriber < SPSSub
862
393
 
863
394
  def initialize(host: 'sps.home', drb_host: '127.0.0.1')
@@ -913,6 +444,7 @@ module RemoteDroid
913
444
  super(topic: topic) do |msg|
914
445
 
915
446
  json, id = msg.split(/:\s+/,2).reverse
447
+
916
448
  h = JSON.parse(json, symbolize_names: true)
917
449
  id ||= h.keys.first
918
450
  @remote.update id.to_sym, h
@@ -923,3 +455,12 @@ module RemoteDroid
923
455
 
924
456
  end
925
457
  end
458
+
459
+ # PASTE_END
460
+
461
+
462
+ require 'remotedroid/model'
463
+ require 'remotedroid/query'
464
+ require 'remotedroid/control'
465
+ require 'remotedroid/controller'
466
+ require 'remotedroid/client'