diff options
| author | jdlugosz963 <jdlugosz963@gmail.com> | 2024-07-30 11:57:23 +0200 |
|---|---|---|
| committer | jdlugosz963 <jdlugosz963@gmail.com> | 2024-07-30 11:57:23 +0200 |
| commit | 78740ba7206ec0895be4aebedd308d409bc1dbb5 (patch) | |
| tree | 96243f03c0d50841ccfd4096545543ac09381536 /src | |
| parent | 8f08fd044e505d63837fc747c31b2dbb1ab4688d (diff) | |
| download | smart-relay-78740ba7206ec0895be4aebedd308d409bc1dbb5.tar.gz smart-relay-78740ba7206ec0895be4aebedd308d409bc1dbb5.zip | |
Diffstat (limited to 'src')
| -rw-r--r-- | src/mqtt-client.rkt | 34 | ||||
| -rw-r--r-- | src/smart-relay.rkt | 76 | ||||
| -rw-r--r-- | src/utils.rkt | 47 |
3 files changed, 114 insertions, 43 deletions
diff --git a/src/mqtt-client.rkt b/src/mqtt-client.rkt new file mode 100644 index 0000000..dfe0a1f --- /dev/null +++ b/src/mqtt-client.rkt | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | #lang racket/base | ||
| 2 | |||
| 3 | (require racket/place) | ||
| 4 | (require racket/match) | ||
| 5 | (require mqtt-client) | ||
| 6 | (require (file "utils.rkt")) | ||
| 7 | |||
| 8 | (provide main) | ||
| 9 | |||
| 10 | (define (main c) | ||
| 11 | (displayln "MQTT WORKER") | ||
| 12 | (match (place-channel-get c) | ||
| 13 | [(list host username password client-name topic-name) | ||
| 14 | (mqtt/with-client (host client-name) | ||
| 15 | (mqtt/with-connection (#:keep-alive-interval 20 | ||
| 16 | #:clean-session #t | ||
| 17 | #:username username | ||
| 18 | #:password password) | ||
| 19 | |||
| 20 | |||
| 21 | (mqtt/with-qos ('qos-1) | ||
| 22 | (mqtt/subscribe topic-name) | ||
| 23 | (let loop () | ||
| 24 | (mqtt/with-message-recv (topic payload) | ||
| 25 | (displayln (format "Message \"~a\" recieved on topic \"~a\"" payload topic)) | ||
| 26 | (let* ((payload (bytes->string/utf-8 payload)) | ||
| 27 | (payload=? (lambda (what) | ||
| 28 | (string=? payload | ||
| 29 | what)))) | ||
| 30 | (when (or (payload=? "toggle") | ||
| 31 | (payload=? "toggle-blinker")) | ||
| 32 | (place-channel-put c (string->symbol payload))))) | ||
| 33 | (loop)))))])) | ||
| 34 | |||
diff --git a/src/smart-relay.rkt b/src/smart-relay.rkt index 270780a..2ce045f 100644 --- a/src/smart-relay.rkt +++ b/src/smart-relay.rkt | |||
| @@ -1,48 +1,38 @@ | |||
| 1 | (module smart-relay racket/base | 1 | #lang racket/base |
| 2 | (require mqtt-client) | ||
| 3 | (provide main) | ||
| 4 | 2 | ||
| 5 | (define (make-send-to-dev data) | 3 | (require racket/place) |
| 6 | (lambda (dev) | 4 | (require racket/match) |
| 7 | (with-output-to-file dev | 5 | (require (file "utils.rkt")) |
| 8 | #:exists 'truncate | ||
| 9 | #:mode 'binary | ||
| 10 | (lambda () | ||
| 11 | (write-bytes data))))) | ||
| 12 | 6 | ||
| 13 | (define send-message-on | 7 | (provide main) |
| 14 | (make-send-to-dev (bytes #xA0 #x01 #x01 #xA2))) | ||
| 15 | (define send-message-off | ||
| 16 | (make-send-to-dev (bytes #xA0 #x01 #x00 #xA1))) | ||
| 17 | 8 | ||
| 18 | (define (make-toggle-relay dev) | 9 | (define (main #:host [host "localhost"] |
| 19 | (let ((turn-on? #t)) | 10 | #:username [username #f] |
| 20 | (lambda () | 11 | #:password [password #f] |
| 21 | (displayln (format "Relay on ~a toggled" dev)) | 12 | #:client-name [client-name "smart-relay"] |
| 22 | (if turn-on? | 13 | #:topic-name [topic-name "hsp/bobma/smart-relay"] |
| 23 | (send-message-on dev) | 14 | #:relay-dev [relay-dev "/dev/ttyUSB0"]) |
| 24 | (send-message-off dev)) | 15 | (define toggle-relay |
| 25 | (set! turn-on? (not turn-on?))))) | 16 | (make-toggle-relay relay-dev)) |
| 26 | 17 | ||
| 27 | (define (main #:host [host "localhost"] | 18 | (define toggle-blinker-relay |
| 28 | #:username [username #f] | 19 | (make-toggle-blinker-relay toggle-relay)) |
| 29 | #:password [password #f] | ||
| 30 | #:client-name [client-name "smart-relay"] | ||
| 31 | #:topic-name [topic-name "hsp/bobma/smart-relay"] | ||
| 32 | #:relay-dev [relay-dev "/dev/ttyUSB0"]) | ||
| 33 | (define toggle-relay (make-toggle-relay relay-dev)) | ||
| 34 | (mqtt/with-client (host client-name) | ||
| 35 | (mqtt/with-connection (#:keep-alive-interval 20 | ||
| 36 | #:clean-session #t | ||
| 37 | #:username username | ||
| 38 | #:password password) | ||
| 39 | 20 | ||
| 40 | (mqtt/subscribe topic-name) | 21 | (define (make-mqtt-worker) |
| 41 | (let loop () | 22 | (let ((mqtt-worker (dynamic-place (string->path "mqtt-client.rkt") 'main))) |
| 42 | (mqtt/with-message-recv (topic payload) | 23 | (place-channel-put mqtt-worker (list host |
| 43 | (displayln (format "Message \"~a\" recieved on topic \"~a\"" payload topic)) | 24 | username |
| 44 | (cond | 25 | password |
| 45 | ((string=? (bytes->string/utf-8 payload) | 26 | client-name |
| 46 | "toggle") | 27 | topic-name)) |
| 47 | (toggle-relay)))) | 28 | mqtt-worker)) |
| 48 | (loop)))))) | 29 | |
| 30 | (define mqtt-worker (make-mqtt-worker)) | ||
| 31 | |||
| 32 | (let loop () | ||
| 33 | (match (place-channel-get mqtt-worker) | ||
| 34 | ['toggle | ||
| 35 | (toggle-relay)] | ||
| 36 | ['toggle-blinker | ||
| 37 | (toggle-blinker-relay)]) | ||
| 38 | (loop))) | ||
diff --git a/src/utils.rkt b/src/utils.rkt new file mode 100644 index 0000000..eaac52a --- /dev/null +++ b/src/utils.rkt | |||
| @@ -0,0 +1,47 @@ | |||
| 1 | #lang racket/base | ||
| 2 | |||
| 3 | (require racket/place) | ||
| 4 | |||
| 5 | (provide make-toggle-relay) | ||
| 6 | (provide make-toggle-blinker-relay) | ||
| 7 | |||
| 8 | (define (make-send-to-dev data) | ||
| 9 | (lambda (dev) | ||
| 10 | (with-output-to-file dev | ||
| 11 | #:exists 'truncate | ||
| 12 | #:mode 'binary | ||
| 13 | (lambda () | ||
| 14 | (write-bytes data))))) | ||
| 15 | |||
| 16 | (define send-message-on | ||
| 17 | (make-send-to-dev (bytes #xA0 #x01 #x01 #xA2))) | ||
| 18 | |||
| 19 | (define send-message-off | ||
| 20 | (make-send-to-dev (bytes #xA0 #x01 #x00 #xA1))) | ||
| 21 | |||
| 22 | (define (make-toggle-relay dev) | ||
| 23 | (let ((turn-on? #t)) | ||
| 24 | (lambda () | ||
| 25 | (displayln (format "Relay on ~a toggled" dev)) | ||
| 26 | (if turn-on? | ||
| 27 | (send-message-on dev) | ||
| 28 | (send-message-off dev)) | ||
| 29 | (set! turn-on? (not turn-on?))))) | ||
| 30 | |||
| 31 | (define (make-toggle-blinker-relay toggle-relay | ||
| 32 | #:delay [delay 3]) | ||
| 33 | (let ((blinker-thread #f)) | ||
| 34 | (lambda () | ||
| 35 | (if (and (thread? blinker-thread) | ||
| 36 | (not (thread-dead? blinker-thread))) | ||
| 37 | (if (thread-running? blinker-thread) | ||
| 38 | (thread-suspend blinker-thread) | ||
| 39 | (thread-resume blinker-thread)) | ||
| 40 | (set! blinker-thread | ||
| 41 | (thread | ||
| 42 | (lambda () | ||
| 43 | (let loop () | ||
| 44 | (toggle-relay) | ||
| 45 | (sleep delay) | ||
| 46 | (loop)))))) | ||
| 47 | blinker-thread))) | ||
