aboutsummaryrefslogtreecommitdiff
path: root/tools/obu-guess-trip
blob: 478ba2b076f8071df319ce3a547aa14e873abeab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
#!/usr/bin/env gosh

(use rfc.http)
(use rfc.uri)
(use rfc.json)
(use file.util)
(use srfi-19)
(use gauche.collection)
(use gauche.parseopt)
(use gauche.process)


(define (main args)
  (let-args
   (cdr args)
   ((adir "d|dir=s")
    (baseurl "u|url=s")
    (statefile "s|statefile=s")
    (help "h|help" => (cut show-help (car args)))
    . restargs)
   (if (equal? baseurl #f)
       (show-help (car args))
       (guesstimate
        (if (equal? adir #f) "." adir)
        baseurl
        (if statefile statefile "./obu-state.edn")))
   (exit 0)))


(define (show-help progname)
  (display (format
"~a: tracktrain's on-board guesstimater for which trip you're on

Arguments:
 -u --url: base url of the tracktrain server [required]
 -s --statefile: state file
 -c --config: config file (default is /etc/tracktrain/obu.conf)
 -h --help: display this help
" progname))
  (exit 0))

(define (guesstimate dir url statefile)
  (define stops (fetch-stations url))
  (define pos
    (with-input-from-process `(obu-ping -s ,statefile -n 1 -d) read))
  (define trip (assoc-ref (closest-stop-to stops pos) 'trip))
  (display trip))

(define (closest-stop-to stops pos)
  (define stops-by-station
    (apply vector-append (vector->list
      (vector-map (lambda (trip)
                    (vector-map
                     (lambda (stop) (cons `(trip . ,(assoc-ref trip 'trip)) stop))
                     (assoc-ref trip 'stops)))
                  stops))))
  (find-min
   stops-by-station
   :key (lambda (stop)
          (+ (square (- (assoc-ref pos 'lat) (assoc-ref stop 'lat)))
             (square (- (assoc-ref pos 'lon) (assoc-ref stop 'lon)))))
   :default (vector-ref stops 0)))

(define (fetch-stations url)
  (define day (date->string (current-date) "~1"))
  (define tls
    (equal? (uri-ref url 'scheme) 'https))
  (parameterize
      ; replace all json keys with symbols; everything else is confusing
      ([json-object-handler
        (cut map (lambda p `(,(string->symbol (car (car p))) . ,(cdr (car p)))) <>)])
    (parse-json-string
     (values-ref (http-get (uri-ref url 'host+port)
                           (format "/api/timetable/stops/~a" day)
                           :secure tls) 2))))