remotedroid 0.4.0 → 0.5.0

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: 3bc29943617484d1dd660a519cf38b3eb0658d69c8a2cadadc92f1f8fa7b036f
4
- data.tar.gz: 9b529677442b0905636fddd8d0b985df57f0115d6b5861b958749917886bcdb3
3
+ metadata.gz: ec97faa80816c99a0b7beed8f4274c90f9b3015d6a0db1586a520e3167849351
4
+ data.tar.gz: 73734010ed7db6576c84988d909ca21aed08e8561b7a9e55e3d657bcdabd0b33
5
5
  SHA512:
6
- metadata.gz: efadc0c0d423e937603ade768551e8796d8d6061dbdc2cfaee3c2d4fa11befb711da2d9fc157a898969cfbe5c8b05106f4db212ee4d2f36e67f94d87f1345e2a
7
- data.tar.gz: 43e65afff822006b49452d3633d2bc05e42c1cbdbe76fd3b264c8761426fad724085972be1b88376953d00ab0cd6d9bfccf2ae52e9f86f8ac55192f050f0d9e6
6
+ metadata.gz: a493dc47aa1c0cbe51c87e7189f1504eb0734088f6ae679da563fee60ea8ae45c4225d1f77909bfb91266b78f81614c89bdba6dec1dfaabedf5c3da0be1bc33e
7
+ data.tar.gz: 8ff28ae91aaccf51919732e516c3915c136acf8be4511b0acfad80ef44447ee5e4b35796003ba0a010da4ed7559674caff94786434e9ba83811cff56e828af75
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -8,11 +8,16 @@ 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
+ # ## Device Events
18
+ #
19
+ # * screen on
20
+ #
16
21
  # ## Sensors
17
22
  #
18
23
  # * proximity (near)
@@ -22,6 +27,14 @@ require 'ruby-macrodroid'
22
27
  #
23
28
  # # Actions
24
29
  #
30
+ # ## Camera/Photo
31
+ #
32
+ # * Take Picture
33
+ #
34
+ # ## Connectivity
35
+ #
36
+ # * Enable HotSpot
37
+ #
25
38
  # ## Date/Time
26
39
  #
27
40
  # * Say Current Time
@@ -36,6 +49,10 @@ require 'ruby-macrodroid'
36
49
  #
37
50
  # * Share Location
38
51
  #
52
+ # ## MacroDroid specific
53
+ #
54
+ # * Disable Macro
55
+ #
39
56
  # ## Media
40
57
  #
41
58
  # * Play sound (Doda)
@@ -44,6 +61,10 @@ require 'ruby-macrodroid'
44
61
  #
45
62
  # * Popup Message
46
63
  #
64
+ # ## Screen
65
+ #
66
+ # * Keep Device Awake
67
+ # * Screen On
47
68
  #
48
69
 
49
70
  # Variables which can be queried
@@ -125,6 +146,42 @@ m: play doda
125
146
  t: webhook
126
147
  a: play: Doda
127
148
 
149
+ m: Screen
150
+ v: on: false
151
+ t: WebHook
152
+ a:
153
+ If on = True
154
+ Screen On
155
+ Else
156
+ Screen Off
157
+ End If
158
+
159
+ m: Hotspot
160
+ v: enable: false
161
+ t: WebHook
162
+ a:
163
+ If enable = True
164
+ Enable Hotspot
165
+ Else
166
+ Disable Hotspot
167
+ End If
168
+
169
+ m: Take Picture
170
+ t: webhook
171
+ a:
172
+ Take Picture
173
+ Rear Facing
174
+ a: wait 2 seconds
175
+ a: webhook
176
+
177
+ m: stay awake
178
+ t: webhook
179
+ a: stay awake
180
+
181
+ m: stay awake off
182
+ t: webhook
183
+ a: stay awake off
184
+
128
185
  m: Share location
129
186
  t:
130
187
  WebHook
@@ -137,7 +194,16 @@ a:
137
194
  HTTP GET
138
195
  identifier: location
139
196
  coords: [lv=coords]
197
+ cell: [cell_id]
198
+ ssid: [ssid]
199
+ alt: [last_loc_alt]
200
+ time: [last_loc_age_timestamp]
201
+ mph: [last_loc_speed_mph]
202
+ kph: [last_loc_speed_kmh]
203
+ device: [device_model]
204
+ battery: [battery]
140
205
  type: query
206
+
141
207
 
142
208
  m: query
143
209
  t: WebHook
@@ -190,510 +256,19 @@ a:
190
256
  webhook
191
257
  identifier: proximity
192
258
  option: 0
193
-
194
- EOF
195
-
196
- module RemoteDroid
197
-
198
- class Model
199
- include AppRoutes
200
-
201
- def initialize(obj=nil, root: 'device1', debug: false)
202
-
203
- super()
204
- @root, @debug = root, debug
205
- @location = nil
206
-
207
- if obj then
208
-
209
- s = obj.strip
210
-
211
- puts 's: ' + s.inspect if @debug
212
-
213
- if s[0] == '<' or s.lines[1][0..1] == ' ' then
214
-
215
- puts 'before easydom' if @debug
216
-
217
- s2 = if s.lines[1][0..1] == ' ' then
218
-
219
- lines = s.lines.map do |line|
220
- line.sub(/(\w+) +is +(\w+)$/) {|x| "#{$1} {switch: #{$2}}" }
221
- end
222
-
223
- lines.join
224
-
225
- else
226
- s
227
- end
228
-
229
- @ed = EasyDom.new(s2)
230
- else
231
- build(s, root: root)
232
- end
233
-
234
- end
235
-
236
- end
237
-
238
- def build(raw_requests, root: @root)
239
-
240
- @ed = EasyDom.new(debug: false, root: root)
241
- raw_requests.lines.each {|line| request(line) }
242
-
243
- end
244
-
245
-
246
- def get_thing(h)
247
-
248
- h[:thing].gsub!(/ /,'_')
249
-
250
- if not h.has_key? :location then
251
- location = false
252
- h[:location] = find_path(h[:thing])
253
- else
254
- location = true
255
- end
256
-
257
- puts 'h: ' + h.inspect if @debug
258
-
259
- a = []
260
- a += h[:location].split(/ /)
261
- a << h[:thing]
262
- status = a.inject(@ed) {|r,x| r.send(x)}.send(h[:action])
263
-
264
- if location then
265
- "The %s %s is %s." % [h[:location], h[:thing], status]
266
- else
267
- "%s is %s." % [h[:thing].capitalize, status]
268
- end
269
-
270
- end
271
-
272
- # Object Property (op)
273
- # Helpful for accessing properites in dot notation
274
- # e.g. op.livingroom.light.switch = 'off'
275
- #
276
- def op()
277
- @ed
278
- end
279
-
280
- def query(s)
281
- @ed.e.element(s)
282
- end
283
-
284
- # request accepts a string in plain english
285
- # e.g. request 'switch the livingroom light on'
286
- #
287
- def request(s)
288
-
289
- params = {request: s}
290
- requests(params)
291
- h = find_request(s)
292
-
293
- method(h.first[-1]).call(h).gsub(/_/,' ')
294
-
295
- end
296
-
297
- def set_thing(h)
298
-
299
- h[:thing].gsub!(/ /,'_')
300
- h[:location] = find_path(h[:thing]) unless h.has_key? :location
301
-
302
- a = []
303
- a += h[:location].split(/ /)
304
- a << h[:thing]
305
-
306
- a.inject(@ed) {|r,x| r.send(x)}.send(h[:action], h[:value])
307
-
308
- end
309
-
310
- def to_sliml(level: 0)
311
-
312
- s = @ed.to_sliml
313
-
314
- return s if level.to_i > 0
315
-
316
- lines = s.lines.map do |line|
317
-
318
- line.sub(/\{[^\}]+\}/) do |x|
319
-
320
- a = x.scan(/\w+: +[^ ]+/)
321
- if a.length == 1 and x[/switch:/] then
322
-
323
- val = x[/(?<=switch: ) *["']([^"']+)/,1]
324
- 'is ' + val
325
- else
326
- x
327
- end
328
-
329
- end
330
- end
331
-
332
- lines.join
333
-
334
- end
335
-
336
- def to_xml(options=nil)
337
- @ed.xml(pretty: true).gsub(' style=\'\'','')
338
- end
339
-
340
- alias xml to_xml
341
-
342
- # to_xml() is the preferred method
343
-
344
- protected
345
-
346
- def requests(params)
347
-
348
- # e.g. switch the livingroom gas_fire off
349
- #
350
- get /(?:switch|turn) the ([^ ]+) +([^ ]+) +(on|off)$/ do |location, device, onoff|
351
- {type: :set_thing, action: 'switch=', location: location, thing: device, value: onoff}
352
- end
353
-
354
- # e.g. switch the gas _fire off
355
- #
356
- get /(?:switch|turn) the ([^ ]+) +(on|off)$/ do |device, onoff|
357
- {type: :set_thing, action: 'switch=', thing: device, value: onoff}
358
- end
359
-
360
- # e.g. is the livingroom gas_fire on?
361
- #
362
- get /is the ([^ ]+) +([^ ]+) +(?:on|off)\??$/ do |location, device|
363
- {type: :get_thing, action: 'switch', location: location, thing: device}
364
- end
365
-
366
- # e.g. enable airplane mode
367
- #
368
- get /((?:dis|en)able) ([^$]+)$/ do |state, service|
369
- {type: :set_thing, action: 'switch=', thing: service, value: state + 'd'}
370
- end
371
-
372
- # e.g. switch airplane mode off
373
- #
374
- get /switch (.*) (on|off)/ do |service, rawstate|
375
-
376
- state = rawstate == 'on' ? 'enabled' : 'disabled'
377
- {type: :set_thing, action: 'switch=', thing: service, value: state}
378
-
379
- end
380
-
381
- # e.g. is airplane mode enabed?
382
- #
383
- get /is (.*) +(?:(?:dis|en)abled)\??$/ do |service|
384
- {type: :get_thing, action: 'switch', thing: service.gsub(/ /,'_')}
385
- end
386
-
387
- # e.g. is the gas_fire on?
388
- #
389
- get /is the ([^ ]+) +(?:on|off)\??$/ do |device|
390
- location = find_path(device)
391
- {type: :get_thing, action: 'switch', location: location, thing: device}
392
- end
393
-
394
- # e.g. fetch the livingroom temperature reading
395
- #
396
- get /fetch the ([^ ]+) +([^ ]+) +(?:reading)$/ do |location, device|
397
- {type: :get_thing, action: 'reading', location: location, thing: device}
398
- end
399
-
400
- # e.g. fetch the temperature reading
401
- #
402
- get /fetch the ([^ ]+) +(?:reading)$/ do |device|
403
- location = find_path(device)
404
- {type: :get_thing, action: 'reading', location: location, thing: device}
405
- end
406
-
407
- end
408
-
409
- private
410
-
411
- def find_path(s)
412
- puts 'find_path s: ' + s.inspect if @debug
413
- found = query('//'+ s)
414
- return unless found
415
- a = found.backtrack.to_xpath.split('/')
416
- a[1..-2].join(' ')
417
- end
418
-
419
- alias find_request run_route
420
-
421
- end
422
-
423
- class Controller
424
-
425
- attr_reader :model, :control
426
- attr_accessor :title, :macros, :store
427
-
428
- def initialize(mcs, model=MODEL, deviceid: nil, debug: false)
429
-
430
- @debug = debug
431
- @syslog = []
432
-
433
- @control = Control.new(deviceid)
434
- @macros = mcs.macros
435
-
436
- if model then
437
- @model = Model.new(model)
438
- end
439
-
440
- @store = {}
441
- @query = Query.new(self)
442
-
443
- end
444
-
445
- def export(s)
446
- @macros = MacroDroid.new(s).macros
447
- end
448
-
449
- def invoke(name, options={})
450
-
451
- if @control.respond_to? name.to_sym then
452
- @control.method(name.to_sym).call(options)
453
- else
454
- @control.http_exec name.to_sym, options
455
- end
456
- end
457
-
458
- # Object Property (op)
459
- # Helpful for accessing properites in dot notation
460
- # e.g. op.livingroom.light.switch = 'off'
461
- #
462
- def op()
463
- @model.op
464
- end
465
-
466
- def query(id=nil)
467
-
468
- return @query unless id
469
-
470
- @store[id] = nil
471
-
472
- sys = %i(accelerometer_rotation)
473
-
474
- global = [:airplane_mode_on, :bluetooth_on, :cell_on, :device_name, \
475
- :usb_mass_storage_enabled, :wifi_on]
476
-
477
- secure = %i(bluetooth_name flashlight_enabled)
478
-
479
-
480
- # send http request via macrodroid.com API
481
-
482
- if id.downcase.to_sym == :location then
483
- @control.http_exec id
484
- elsif sys.include? id
485
- @control.http_exec :'query-setting-system', {qvar: id}
486
- elsif global.include? id
487
- @control.http_exec :'query-setting-global', {qvar: id}
488
- elsif secure.include? id
489
- @control.http_exec :'query-setting-secure', {qvar: id}
490
- else
491
- @control.http_exec :query, {qvar: id}
492
- end
493
-
494
- # wait for the local variable to be updated
495
- # timeout after 5 seoncds
496
- t = Time.now
497
-
498
- begin
499
- sleep 1
500
- end until @store[id] or Time.now > t + 5
501
-
502
- return {warning: 'HTTP response timeout'} if Time.now > t+5
503
-
504
- return @store[id]
505
-
506
-
507
- end
508
-
509
- def request(s)
510
- @model.request s
511
- end
512
-
513
259
 
514
- def trigger(name, detail={time: Time.now})
515
-
516
- macros = @macros.select do |macro|
517
-
518
- puts 'macro: ' + macro.inspect if @debug
519
-
520
- # fetch the associated properties from the model if possible and
521
- # merge them into the detail.
522
- #
523
- valid_trigger = macro.match?(name, detail, @model.op)
524
-
525
- puts 'valid_trigger: ' + valid_trigger.inspect if @debug
526
-
527
- if valid_trigger then
528
- @syslog << [Time.now, :trigger, name]
529
- @syslog << [Time.now, :macro, macro.title]
530
- end
531
-
532
- valid_trigger
533
-
534
- end
535
-
536
- puts 'macros: ' + macros.inspect if @debug
537
-
538
- macros.flat_map(&:run)
539
- end
540
-
541
- alias trigger_fired trigger
542
-
543
- def update(id, val)
544
- key = id == :location ? id : val.keys.first.to_sym
545
- @store[key] = val
546
- end
547
-
548
-
549
- end
550
-
551
- class Service
552
- def initialize(callback)
553
- @callback = callback
554
- end
555
- end
556
-
557
- class Bluetooth
558
- def enable()
559
- end
560
- end
561
-
562
- class Toast < Service
563
-
564
- def invoke()
565
- @callback.call :toast
566
- end
567
-
568
- end
569
-
570
- class Torch < Service
571
-
572
- def toggle()
573
- @callback.http_exec :torch
574
- end
575
-
576
- end
260
+ m: Power connected
261
+ t: Power Connected: Any
262
+ a: webhook
577
263
 
578
- class Control
579
-
580
- def initialize(dev=nil, deviceid: dev, remote_url: nil, debug: false)
581
-
582
- @deviceid, @remote_url, @debug = deviceid, remote_url, debug
583
- @torch = Torch.new(self)
584
- end
585
-
586
- def bluetooth()
587
- @bluetooth
588
- end
589
-
590
- def camera_flash_light(options={})
591
- http_exec 'camera-flash-light', options
592
- end
593
-
594
- def http_exec(command, options={})
595
-
596
- url = "https://trigger.macrodroid.com/%s/%s" % [@deviceid, command]
597
-
598
- if options and options.any? then
599
- h = options
600
- url += '?' + \
601
- URI.escape(h.map {|key,value| "%s=%s" % [key, value]}.join('&'))
602
- end
603
-
604
- s = open(url).read
605
-
606
- end
607
-
608
- def location(options={})
609
- http_exec 'location'
610
- end
611
-
612
- def say_current_time(options={})
613
- http_exec 'say-current-time'
614
- end
615
-
616
- alias say_time say_current_time
617
-
618
- def share_location(options={})
619
- http_exec 'share-location'
620
- end
621
-
622
- def speak_text(obj)
623
-
624
- options = case obj
625
- when String
626
- {text: obj}
627
- when Hash
628
- obj
629
- end
630
-
631
- http_exec 'speak-text', options
632
- end
633
-
634
- alias say speak_text
635
-
636
- def toast(options={})
637
- http_exec :toast, options
638
- end
639
-
640
- def torch(options={})
641
- http_exec :torch
642
- end
643
-
644
- def vibrate(options={})
645
- http_exec :vibrate
646
- end
264
+ m: screen on off
265
+ t: screen on
266
+ a: webhook
647
267
 
268
+ EOF
648
269
 
649
- def write(s)
650
-
651
- MacroDroid.new(RD_MACROS, deviceid: @deviceid,
652
- remote_url: @remote_url, debug: @debug).export s
653
-
654
- end
655
-
656
- alias export write
657
-
658
- def method_missing2(method_name, *args)
659
- http_exec(method_name, args.first)
660
- end
661
-
662
- end
663
-
664
- class Query
665
-
666
- def initialize(callback)
667
- @callback = callback
668
- end
669
-
670
- def battery()
671
- q(:battery).to_i
672
- end
673
-
674
- def current_brightness()
675
- q(:current_brightness).to_i
676
- end
677
270
 
678
- alias brightness current_brightness
679
-
680
- def cell_id()
681
- q(:cell_id)
682
- end
683
-
684
- alias cell_tower cell_id
685
-
686
- def ip()
687
- q(:ip)
688
- end
689
-
690
- private
691
-
692
- def q(id)
693
- @callback.query(id)[id]
694
- end
695
-
696
- end
271
+ module RemoteDroid
697
272
 
698
273
  class Server
699
274
 
@@ -710,44 +285,7 @@ module RemoteDroid
710
285
  end
711
286
 
712
287
  end
713
-
714
- class Client
715
-
716
- def initialize(host='127.0.0.1')
717
- @drb = OneDrb::Client.new host: host, port: '5777'
718
- end
719
-
720
- def control
721
- @drb.control
722
- end
723
-
724
- def export(s)
725
- @drb.export(s)
726
- end
727
288
 
728
- def invoke(s, *args)
729
- @drb.invoke(s, *args)
730
- end
731
-
732
- def query(id=nil)
733
-
734
- return @drb.query unless id
735
- t = Time.now
736
- h = @drb.query(id)
737
- h.merge({latency: (Time.now - t).round(3)})
738
-
739
- end
740
-
741
- def update(key, val)
742
- @drb.update key.to_sym, val
743
- end
744
-
745
- def store()
746
- @drb.store
747
- end
748
-
749
- end
750
-
751
289
  class TriggerSubscriber < SPSSub
752
290
 
753
291
  def initialize(host: 'sps.home', drb_host: '127.0.0.1')
@@ -803,6 +341,7 @@ module RemoteDroid
803
341
  super(topic: topic) do |msg|
804
342
 
805
343
  json, id = msg.split(/:\s+/,2).reverse
344
+
806
345
  h = JSON.parse(json, symbolize_names: true)
807
346
  id ||= h.keys.first
808
347
  @remote.update id.to_sym, h
@@ -813,3 +352,12 @@ module RemoteDroid
813
352
 
814
353
  end
815
354
  end
355
+
356
+ # PASTE_END
357
+
358
+
359
+ require 'remotedroid/model'
360
+ require 'remotedroid/query'
361
+ require 'remotedroid/control'
362
+ require 'remotedroid/controller'
363
+ require 'remotedroid/client'