#! /usr/bin/env racket #lang racket/base (require racket/cmdline racket/stream racket/tcp net/url "ebus/layer7.rkt" "util/json.rkt") (define logger (make-logger 'ebus-inserter (current-logger))) (define connect-host? (make-parameter null)) (define connect-port? (make-parameter null)) (define insert? (make-parameter #f)) (define baseurl? (make-parameter "http://localhost:8080/api")) ;; Send field and value to database server (define (insert-field sensor-name datatype offset value) (define type (cond ((member datatype (list "data1c" "data2b" "data2c")) "float") ((member datatype (list "bit" "byte" "data1b" "word" "bcd")) "int") ((member datatype (list "byteEnum")) "string"))) (set! value (cond ((string=? type "float") (real->decimal-string value)) ((string=? type "int") (number->string value)) (else value))) (put-pure-port (string->url (format "~a/value/~a" (baseurl?) sensor-name)) (string->bytes/utf-8 value))) (define (handle-packet packet) (for ([field packet]) (log-message logger 'info (format "Field: ~a" field) #t) (when (insert?) (with-handlers ([exn:fail? (lambda (exn) (log-message logger 'error (format "Failed to insert ~a: ~a" field exn) #t))] [exn:fail:read? (lambda (exn) (log-message logger 'error (format "TCP Read exception ~a" exn) #t))] [exn:fail:network? (lambda (exn) (log-message logger 'error (format "TCP Exception ~a" exn) #t))]) (apply insert-field field))))) (define-namespace-anchor repl-ns-anchor) (define (main) ;; Parse commandline (command-line #:once-each [("-c" "--connect") host port "Connect to server " (connect-host? host) (connect-port? (string->number port))] ["--insert" "Do Insert into Database" (insert? #t)] ["--baseurl" url "Database server http url" (baseurl? url)]) ;; Connect, replacing input with tcp connection (if (or (null? (connect-host?)) (null? (connect-port?))) (log-message (current-logger) 'info "Using stdin" #t) (let-values ([(cin cout) (tcp-connect (connect-host?) (connect-port?))]) (log-message logger 'info (format "Connected to ~s ~s ~n" (connect-host?) (connect-port?)) #t) (current-input-port cin))) ;; Process Ebus Packets (for ([packet (make-stream (current-input-port))]) (when (not (or (void? packet) (eof-object? packet))) (handle-packet packet)) (when (eof-object? packet) (exit 1))) ) (define (make-stream port) (stream-cons (with-handlers ([exn:fail? (lambda (exn) (log-message logger 'error (format "Failed to parse paket: ~a" exn) #t) (void))]) (layer7-read-ebus port)) (make-stream port))) (exit (main))