diff --git a/scontrini.rkt b/scontrini.rkt new file mode 100644 index 0000000..ac0bbcd --- /dev/null +++ b/scontrini.rkt @@ -0,0 +1,53 @@ +#lang racket + +(require racket/tcp) +(require json) + +(define serial-port-device "/dev/ttyUSB0") +(define port 4444) +(define hostname "127.0.0.1") + +; Print the to-print string on the printer +; TODO add synchronization to avoid race conditions +(define (printer-print to-print) + (let ((file (open-output-file serial-port-device #:exists 'append))) + (display (string-replace to-print "\n" "\n\n") file) ; always add an extra newline because the printer is a little messed up + (close-output-port file))) + +; Format the pizzas array from the JSON in a human-readable way +(define (format-pizza pizzas-list) + (let ((str "")) + (for-each (lambda (pizza-hashmap) + (set! str (string-append str (format "~a : ~s\n" (hash-ref pizza-hashmap 'quantity) (hash-ref pizza-hashmap 'name))))) + pizzas-list) + str)) + +; Parse the commands given in the JSON +(define (parse-json message) + (let ((parsed-json (with-input-from-string message (lambda () (read-json))))) ; parse the JSON + (case (hash-ref parsed-json 'command) + (("print") (printer-print (hash-ref parsed-json 'text))) + (("pizza") (printer-print (format-pizza (hash-ref parsed-json 'pizzas))))))) + +; Receive the JSON message and execute the specified command +(define (get-message input) + (let ((message "")) + (let loop-until-eof ((str (read-string 1 input))) + (if (eof-object? str) + (begin + (close-input-port input) + (parse-json message)) + (begin + (set! message (string-append message str)) + (loop-until-eof (read-string 1 input))))))) + +; Wait on a port and spawn new threads on each connection +(define (wait-for-connection) + (let ((listener (tcp-listen port 4 #t hostname))) + (let infinite-loop () + (let-values (((input output) (tcp-accept listener))) + (close-output-port output) ; we don't need it + (thread (lambda () (get-message input))) + (infinite-loop))))) + +(wait-for-connection)