Scontrini-Daemon/scontrini.rkt

60 lines
2.0 KiB
Racket
Raw Normal View History

2023-10-25 17:45:57 +02:00
#lang racket
(require racket/tcp)
(require json)
(define serial-port-device "/dev/ttyUSB0")
(define port 4444)
(define hostname "127.0.0.1")
2023-10-25 19:54:45 +02:00
; Return a list of pizzas from the local file
(define (get-pizzas-list)
(let ((file (open-input-file "pizza_list.json")))
(read-json file)))
2023-10-25 17:45:57 +02:00
; 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
2023-10-25 19:54:45 +02:00
(define (parse-json message output)
2023-10-25 17:45:57 +02:00
(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)))
2023-10-25 19:54:45 +02:00
(("pizza") (printer-print (format-pizza (hash-ref parsed-json 'pizzas))))
(("get-pizzas") (write-json (get-pizzas-list) output)))))
2023-10-25 17:45:57 +02:00
2023-10-25 19:54:45 +02:00
; Execute the command specified in the JSON
(define (execute-commands input output)
2023-10-25 17:45:57 +02:00
(let ((message ""))
(let loop-until-eof ((str (read-string 1 input)))
(if (eof-object? str)
(begin
2023-10-25 19:54:45 +02:00
(parse-json message output)
2023-10-25 17:45:57 +02:00
(close-input-port input)
2023-10-25 19:54:45 +02:00
(close-output-port output))
2023-10-25 17:45:57 +02:00
(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)))
2023-10-25 19:54:45 +02:00
(thread (lambda () (execute-commands input output)))
2023-10-25 17:45:57 +02:00
(infinite-loop)))))
(wait-for-connection)