From 92db1fdac315a471bfd7a619a7f4efb1684df25e Mon Sep 17 00:00:00 2001 From: jdlugosz963 Date: Sat, 27 Jul 2024 20:43:21 +0200 Subject: Initial commit. --- build-on-non-guix.sh | 4 ++ build.sh | 4 ++ channels.scm | 11 ++++ create-smart-relay-containter.sh | 18 +++++++ manifest.scm | 114 +++++++++++++++++++++++++++++++++++++++ src/smart-relay.rtk | 48 +++++++++++++++++ src/smart-relay.sh | 5 ++ 7 files changed, 204 insertions(+) create mode 100755 build-on-non-guix.sh create mode 100755 build.sh create mode 100644 channels.scm create mode 100755 create-smart-relay-containter.sh create mode 100644 manifest.scm create mode 100644 src/smart-relay.rtk create mode 100755 src/smart-relay.sh 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 @@ +#!/bin/sh + +docker run --privileged --name tmp --rm -it -v $(pwd):/smart-relay -w /smart-relay metacall/guix sh -c './build.sh' + diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..52820f1 --- /dev/null +++ b/build.sh @@ -0,0 +1,4 @@ +#!/bin/sh + +cp $(guix time-machine -C channels.scm -- pack -f docker -m manifest.scm) docker-mqtt-smart-relay.tar.gz + diff --git a/channels.scm b/channels.scm new file mode 100644 index 0000000..9e22649 --- /dev/null +++ b/channels.scm @@ -0,0 +1,11 @@ +(list (channel + (name 'guix) + (url "https://git.savannah.gnu.org/git/guix.git") + (branch "master") + (commit + "8c6e724686ac37ff7955b97d9bfd03176b14d82a") + (introduction + (make-channel-introduction + "9edb3f66fd807b096b48283debdcddccfea34bad" + (openpgp-fingerprint + "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 @@ +#!/bin/sh + +if [[ ! $1 ]]; then + echo "Usage: " + echo " ./create-smart-relay-containter.sh [mqtt-password]" + exit; +fi; + +docker run \ + -d \ + --rm \ + --network host \ + -v /dev/ttyUSB0:/dev/ttyUSB0 \ + -v smart-relay-racket-files:/.local \ + --privileged \ + racket-smart-relay-bash-nss-certs \ + smart-relay "#:host \"mqtt.hack\" #:username \"iot_basic\" #:password \"$1\" #:topic-name \"hsp/bobma/smart-relay\"" + diff --git a/manifest.scm b/manifest.scm new file mode 100644 index 0000000..91100f3 --- /dev/null +++ b/manifest.scm @@ -0,0 +1,114 @@ +(use-modules (guix packages) + (guix git-download) + (guix build-system cmake) + (guix build-system copy) + (guix utils) + (guix gexp) + (gnu packages racket) + (gnu packages emacs-xyz) + ((guix licenses) #:prefix license:)) + +(define paho-mqtt-c + (package + (name "paho-mqtt-c") + (version "1.3.13") + (source (origin + (method git-fetch) + (uri (git-reference + (url "https://github.com/eclipse/paho.mqtt.c") + (commit (string-append "v" version)))) + (file-name (git-file-name name version)) + (sha256 + (base32 "1y5lsh41kszyjcrxrjshs838l23ncdyssxk848ij1bq0jix2g93l")))) + (build-system cmake-build-system) + (arguments + '(#:tests? #f)) ;; Disable tests + (synopsis "Eclipse Paho MQTT C client library") + (description + "Eclipse Paho MQTT C client library.") + (home-page "https://www.eclipse.org/paho/") + (license license:epl1.0))) + +(define (make-racket! package-to-inherit) + (package + (inherit package-to-inherit) + (arguments + (substitute-keyword-arguments (package-arguments package-to-inherit) + ((#:phases those-phases #~%standard-phases) + #~(modify-phases #$those-phases + (add-after 'install 'wrap-racket + (lambda* (#:key outputs inputs #:allow-other-keys) + (let* ((out (assoc-ref outputs "out")) + (bin (string-append out "/bin/racket")) + (libpaho (string-append (assoc-ref inputs "paho-mqtt-c") + "/lib"))) + (wrap-program bin + `("LD_LIBRARY_PATH" ":" prefix + ,(list libpaho)))))))))) + (inputs + (modify-inputs (package-inputs package-to-inherit) + (prepend paho-mqtt-c))))) + +(define racket-minimal! (make-racket! racket-minimal)) +(define racket! (make-racket! racket)) + +(define smart-relay + (package + (name "smart-relay") + (version "0.1.0") + (source + (local-file "src" #:recursive? #t)) + (build-system copy-build-system) + (arguments + `(#:phases + (modify-phases %standard-phases + (add-before 'install 'change-paths + (lambda* (#:key outputs #:allow-other-keys) + (let ((out (assoc-ref outputs "out"))) + (substitute* "smart-relay.sh" + (("smart-relay.rtk") + (string-append out "/share/smart-relay.rtk")))))) + (add-before 'install 'move-files + (lambda* (#:key inputs outputs #:allow-other-keys) + (let* ((out (assoc-ref outputs "out")) + (bin (string-append out "/bin/")) + (share (string-append out "/share/"))) + (mkdir-p bin) + (mkdir-p share) + (chmod "smart-relay.sh" #o555) + (copy-recursively "smart-relay.sh" + (string-append bin "smart-relay")) + (copy-recursively "smart-relay.rtk" + (string-append share "smart-relay.rtk")) + (delete-file-recursively "smart-relay.sh") + (delete-file-recursively "smart-relay.rtk"))))))) + (synopsis "Lisp program to control usb relay over mqtt") + (description "Lisp program to control usb relay over mqtt") + (home-page "https://git.jdlugosz.com/hsp/smart-relay") + (license license:unlicense))) + +(define emacs-geiser-racket! + (package + (inherit emacs-geiser-racket) + (inputs + (modify-inputs (package-inputs emacs-geiser-racket) + (delete "racket") + (prepend racket!))))) + + +(if (getenv "DEV_SHELL") + (concatenate-manifests + (list (packages->manifest + (list racket! + emacs-geiser-racket!)) + (specifications->manifest + (list "racket" + "emacs-racket-mode" + "emacs")))) + (concatenate-manifests + (list (packages->manifest + (list racket! + smart-relay)) + (specifications->manifest + (list "bash" + "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 @@ +(module smart-relay racket/base + (require mqtt-client) + (provide main) + + (define (make-send-to-dev data) + (lambda (dev) + (with-output-to-file dev + #:exists 'truncate + #:mode 'binary + (lambda () + (write-bytes data))))) + + (define send-message-on + (make-send-to-dev (bytes #xA0 #x01 #x01 #xA2))) + (define send-message-off + (make-send-to-dev (bytes #xA0 #x01 #x00 #xA1))) + + (define (make-toggle-relay dev) + (let ((turn-on? #t)) + (lambda () + (displayln (format "Relay on ~a toggled" dev)) + (if turn-on? + (send-message-on dev) + (send-message-off dev)) + (set! turn-on? (not turn-on?))))) + + (define (main #:host [host "localhost"] + #:username [username #f] + #:password [password #f] + #:client-name [client-name "smart-relay"] + #:topic-name [topic-name "hsp/bobma/smart-relay"] + #:relay-dev [relay-dev "/dev/ttyUSB0"]) + (define toggle-relay (make-toggle-relay relay-dev)) + (mqtt/with-client (host client-name) + (mqtt/with-connection (#:keep-alive-interval 20 + #:clean-session #t + #:username username + #:password password) + + (mqtt/subscribe topic-name) + (let loop () + (mqtt/with-message-recv (topic payload) + (displayln (format "Message \"~a\" recieved on topic \"~a\"" payload topic)) + (cond + ((string=? (bytes->string/utf-8 payload) + "toggle") + (toggle-relay)))) + (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 @@ +#!/bin/sh + +raco pkg install mqtt-client +racket -e "(begin (require (file \"smart-relay.rtk\")) (main $@))" + -- cgit v1.2.3