summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/mqtt-client.rkt34
-rw-r--r--src/smart-relay.rkt76
-rw-r--r--src/utils.rkt47
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)))