diff options
-rwxr-xr-x | build-on-non-guix.sh | 4 | ||||
-rwxr-xr-x | build.sh | 4 | ||||
-rw-r--r-- | channels.scm | 11 | ||||
-rwxr-xr-x | create-smart-relay-containter.sh | 18 | ||||
-rw-r--r-- | manifest.scm | 114 | ||||
-rw-r--r-- | src/smart-relay.rtk | 48 | ||||
-rwxr-xr-x | src/smart-relay.sh | 5 |
7 files changed, 204 insertions, 0 deletions
diff --git a/build-on-non-guix.sh b/build-on-non-guix.sh new file mode 100755 index 0000000..be81361 --- /dev/null +++ b/build-on-non-guix.sh | |||
@@ -0,0 +1,4 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | docker run --privileged --name tmp --rm -it -v $(pwd):/smart-relay -w /smart-relay metacall/guix sh -c './build.sh' | ||
4 | |||
diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..52820f1 --- /dev/null +++ b/build.sh | |||
@@ -0,0 +1,4 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | cp $(guix time-machine -C channels.scm -- pack -f docker -m manifest.scm) docker-mqtt-smart-relay.tar.gz | ||
4 | |||
diff --git a/channels.scm b/channels.scm new file mode 100644 index 0000000..9e22649 --- /dev/null +++ b/channels.scm | |||
@@ -0,0 +1,11 @@ | |||
1 | (list (channel | ||
2 | (name 'guix) | ||
3 | (url "https://git.savannah.gnu.org/git/guix.git") | ||
4 | (branch "master") | ||
5 | (commit | ||
6 | "8c6e724686ac37ff7955b97d9bfd03176b14d82a") | ||
7 | (introduction | ||
8 | (make-channel-introduction | ||
9 | "9edb3f66fd807b096b48283debdcddccfea34bad" | ||
10 | (openpgp-fingerprint | ||
11 | "BBB0 2DDF 2CEA F6A8 0D1D E643 A2A0 6DF2 A33A 54FA"))))) | ||
diff --git a/create-smart-relay-containter.sh b/create-smart-relay-containter.sh new file mode 100755 index 0000000..1eaa954 --- /dev/null +++ b/create-smart-relay-containter.sh | |||
@@ -0,0 +1,18 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | if [[ ! $1 ]]; then | ||
4 | echo "Usage: " | ||
5 | echo " ./create-smart-relay-containter.sh [mqtt-password]" | ||
6 | exit; | ||
7 | fi; | ||
8 | |||
9 | docker run \ | ||
10 | -d \ | ||
11 | --rm \ | ||
12 | --network host \ | ||
13 | -v /dev/ttyUSB0:/dev/ttyUSB0 \ | ||
14 | -v smart-relay-racket-files:/.local \ | ||
15 | --privileged \ | ||
16 | racket-smart-relay-bash-nss-certs \ | ||
17 | smart-relay "#:host \"mqtt.hack\" #:username \"iot_basic\" #:password \"$1\" #:topic-name \"hsp/bobma/smart-relay\"" | ||
18 | |||
diff --git a/manifest.scm b/manifest.scm new file mode 100644 index 0000000..91100f3 --- /dev/null +++ b/manifest.scm | |||
@@ -0,0 +1,114 @@ | |||
1 | (use-modules (guix packages) | ||
2 | (guix git-download) | ||
3 | (guix build-system cmake) | ||
4 | (guix build-system copy) | ||
5 | (guix utils) | ||
6 | (guix gexp) | ||
7 | (gnu packages racket) | ||
8 | (gnu packages emacs-xyz) | ||
9 | ((guix licenses) #:prefix license:)) | ||
10 | |||
11 | (define paho-mqtt-c | ||
12 | (package | ||
13 | (name "paho-mqtt-c") | ||
14 | (version "1.3.13") | ||
15 | (source (origin | ||
16 | (method git-fetch) | ||
17 | (uri (git-reference | ||
18 | (url "https://github.com/eclipse/paho.mqtt.c") | ||
19 | (commit (string-append "v" version)))) | ||
20 | (file-name (git-file-name name version)) | ||
21 | (sha256 | ||
22 | (base32 "1y5lsh41kszyjcrxrjshs838l23ncdyssxk848ij1bq0jix2g93l")))) | ||
23 | (build-system cmake-build-system) | ||
24 | (arguments | ||
25 | '(#:tests? #f)) ;; Disable tests | ||
26 | (synopsis "Eclipse Paho MQTT C client library") | ||
27 | (description | ||
28 | "Eclipse Paho MQTT C client library.") | ||
29 | (home-page "https://www.eclipse.org/paho/") | ||
30 | (license license:epl1.0))) | ||
31 | |||
32 | (define (make-racket! package-to-inherit) | ||
33 | (package | ||
34 | (inherit package-to-inherit) | ||
35 | (arguments | ||
36 | (substitute-keyword-arguments (package-arguments package-to-inherit) | ||
37 | ((#:phases those-phases #~%standard-phases) | ||
38 | #~(modify-phases #$those-phases | ||
39 | (add-after 'install 'wrap-racket | ||
40 | (lambda* (#:key outputs inputs #:allow-other-keys) | ||
41 | (let* ((out (assoc-ref outputs "out")) | ||
42 | (bin (string-append out "/bin/racket")) | ||
43 | (libpaho (string-append (assoc-ref inputs "paho-mqtt-c") | ||
44 | "/lib"))) | ||
45 | (wrap-program bin | ||
46 | `("LD_LIBRARY_PATH" ":" prefix | ||
47 | ,(list libpaho)))))))))) | ||
48 | (inputs | ||
49 | (modify-inputs (package-inputs package-to-inherit) | ||
50 | (prepend paho-mqtt-c))))) | ||
51 | |||
52 | (define racket-minimal! (make-racket! racket-minimal)) | ||
53 | (define racket! (make-racket! racket)) | ||
54 | |||
55 | (define smart-relay | ||
56 | (package | ||
57 | (name "smart-relay") | ||
58 | (version "0.1.0") | ||
59 | (source | ||
60 | (local-file "src" #:recursive? #t)) | ||
61 | (build-system copy-build-system) | ||
62 | (arguments | ||
63 | `(#:phases | ||
64 | (modify-phases %standard-phases | ||
65 | (add-before 'install 'change-paths | ||
66 | (lambda* (#:key outputs #:allow-other-keys) | ||
67 | (let ((out (assoc-ref outputs "out"))) | ||
68 | (substitute* "smart-relay.sh" | ||
69 | (("smart-relay.rtk") | ||
70 | (string-append out "/share/smart-relay.rtk")))))) | ||
71 | (add-before 'install 'move-files | ||
72 | (lambda* (#:key inputs outputs #:allow-other-keys) | ||
73 | (let* ((out (assoc-ref outputs "out")) | ||
74 | (bin (string-append out "/bin/")) | ||
75 | (share (string-append out "/share/"))) | ||
76 | (mkdir-p bin) | ||
77 | (mkdir-p share) | ||
78 | (chmod "smart-relay.sh" #o555) | ||
79 | (copy-recursively "smart-relay.sh" | ||
80 | (string-append bin "smart-relay")) | ||
81 | (copy-recursively "smart-relay.rtk" | ||
82 | (string-append share "smart-relay.rtk")) | ||
83 | (delete-file-recursively "smart-relay.sh") | ||
84 | (delete-file-recursively "smart-relay.rtk"))))))) | ||
85 | (synopsis "Lisp program to control usb relay over mqtt") | ||
86 | (description "Lisp program to control usb relay over mqtt") | ||
87 | (home-page "https://git.jdlugosz.com/hsp/smart-relay") | ||
88 | (license license:unlicense))) | ||
89 | |||
90 | (define emacs-geiser-racket! | ||
91 | (package | ||
92 | (inherit emacs-geiser-racket) | ||
93 | (inputs | ||
94 | (modify-inputs (package-inputs emacs-geiser-racket) | ||
95 | (delete "racket") | ||
96 | (prepend racket!))))) | ||
97 | |||
98 | |||
99 | (if (getenv "DEV_SHELL") | ||
100 | (concatenate-manifests | ||
101 | (list (packages->manifest | ||
102 | (list racket! | ||
103 | emacs-geiser-racket!)) | ||
104 | (specifications->manifest | ||
105 | (list "racket" | ||
106 | "emacs-racket-mode" | ||
107 | "emacs")))) | ||
108 | (concatenate-manifests | ||
109 | (list (packages->manifest | ||
110 | (list racket! | ||
111 | smart-relay)) | ||
112 | (specifications->manifest | ||
113 | (list "bash" | ||
114 | "nss-certs"))))) | ||
diff --git a/src/smart-relay.rtk b/src/smart-relay.rtk new file mode 100644 index 0000000..270780a --- /dev/null +++ b/src/smart-relay.rtk | |||
@@ -0,0 +1,48 @@ | |||
1 | (module smart-relay racket/base | ||
2 | (require mqtt-client) | ||
3 | (provide main) | ||
4 | |||
5 | (define (make-send-to-dev data) | ||
6 | (lambda (dev) | ||
7 | (with-output-to-file dev | ||
8 | #:exists 'truncate | ||
9 | #:mode 'binary | ||
10 | (lambda () | ||
11 | (write-bytes data))))) | ||
12 | |||
13 | (define send-message-on | ||
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 | |||
18 | (define (make-toggle-relay dev) | ||
19 | (let ((turn-on? #t)) | ||
20 | (lambda () | ||
21 | (displayln (format "Relay on ~a toggled" dev)) | ||
22 | (if turn-on? | ||
23 | (send-message-on dev) | ||
24 | (send-message-off dev)) | ||
25 | (set! turn-on? (not turn-on?))))) | ||
26 | |||
27 | (define (main #:host [host "localhost"] | ||
28 | #:username [username #f] | ||
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 | |||
40 | (mqtt/subscribe topic-name) | ||
41 | (let loop () | ||
42 | (mqtt/with-message-recv (topic payload) | ||
43 | (displayln (format "Message \"~a\" recieved on topic \"~a\"" payload topic)) | ||
44 | (cond | ||
45 | ((string=? (bytes->string/utf-8 payload) | ||
46 | "toggle") | ||
47 | (toggle-relay)))) | ||
48 | (loop)))))) | ||
diff --git a/src/smart-relay.sh b/src/smart-relay.sh new file mode 100755 index 0000000..af5fa26 --- /dev/null +++ b/src/smart-relay.sh | |||
@@ -0,0 +1,5 @@ | |||
1 | #!/bin/sh | ||
2 | |||
3 | raco pkg install mqtt-client | ||
4 | racket -e "(begin (require (file \"smart-relay.rtk\")) (main $@))" | ||
5 | |||