diff --git a/README.md b/README.md index 8787233..d549322 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # doorlock -Project Structure: +**Project Structure:** ``` . └── embedded Embedded System & Hardware @@ -11,30 +11,48 @@ Project Structure: Circuit diagrams are drawn with this [Circuit Simulator](http://www.falstad.com/circuit/).
Diagrams are saved as `txt` files, you can import them under `File > Import From Text`. -Relay Board: +**Relay Board:** ![](https://github.com/oursky/doorlock/raw/master/embedded/circuit.png) -Embedded System: Raspberry Pi 3 +**Embedded System:** Raspberry Pi 3 -Connections: +**Connections:** * Release Button: GPIO0/Ground * Release Signal: GPIO1/Ground ## Embedded System -**System:** ArchLinux ARM + +### Build + +**Dependencies:** + +* clojure +* leiningen + +**Build:** +``` +[~/]$ git clone ... +[~/doorlock/embedded]$ lein uberjar + +``` +The standalone JAR is now in `doorlock/embedded/target/doorlock--standalone.jar`. + +### Deploy +**Embedded OS:** ArchLinux ARM **Dependencies:** -* nodejs -* npm +* java * wiringpi-git (AUR) **Install as systemd service:** +1. copy the standalone JAR to `/home/oursky/` +2. copy `doorlock.service` to `/etc/systemd/system/` +3. enable and start the service: ``` -[oursky ~/]$ git clone ... -[oursky ~/]$ sudo cp doorlock/embedded/doorlock.service /etc/systemd/system/ [oursky ~/]$ sudo systemctl enable doorlock [oursky ~/]$ sudo systemctl start doorlock ``` -**Note: ** If your username is not `oursky`, you need to edit `doorlock.service` accordingly. + +**Note:** If your username is not `oursky`, you need to edit `doorlock.service` accordingly. ## App diff --git a/embedded/doorlock.service b/embedded/doorlock.service index c4e9e9d..be576e6 100644 --- a/embedded/doorlock.service +++ b/embedded/doorlock.service @@ -3,8 +3,7 @@ Description=Doorlock Controller Daemon [Service] User=oursky -WorkingDirectory=/home/oursky/doorlock/embedded -ExecStart=/usr/bin/npm start +ExecStart=/usr/bin/java -jar /home/oursky/doorlock-1.0.0-SNAPSHOT-standalone.jar [Install] WantedBy=multi-user.target diff --git a/embedded/project.clj b/embedded/project.clj index 9846974..d878d03 100644 --- a/embedded/project.clj +++ b/embedded/project.clj @@ -3,7 +3,7 @@ :dependencies [[org.clojure/clojure "1.8.0"] [org.clojure/core.async "0.2.385"] [com.taoensso/timbre "4.7.0"] - [clj-gpio "0.2.0"] + [http-kit "2.2.0"] ] - :profiles {:uberjar {:aot :all}} + :aot :all :main com.oursky.doorlock.core) diff --git a/embedded/src/com/oursky/doorlock/core.clj b/embedded/src/com/oursky/doorlock/core.clj index a76cb19..601a7a1 100644 --- a/embedded/src/com/oursky/doorlock/core.clj +++ b/embedded/src/com/oursky/doorlock/core.clj @@ -1,27 +1,50 @@ (ns com.oursky.doorlock.core (:require [taoensso.timbre :as log] - [gpio.core :refer [open-port open-channel-port write-value! toggle!]] [clojure.java.shell :refer [sh]] - [clojure.core.async :refer [! >!! alts! go-loop chan timeout]] + [org.httpkit.server :refer [run-server]] + ) + (:gen-class)) -; setup GPIO via wiringpi CLI interface -; the clj-gpio library does not support internal pull-up -(sh "gpio" "mode" "0" "up") -(sh "gpio" "mode" "1" "out") +; unlock triggering channel +; identify the trigger source by sending {:source } +(def unlock-chan (chan)) -(def button-chan (open-channel-port 0)) -(def unlock-port (open-port 1)) +(defn http-handler [req] + (>!! unlock-chan {:source :network}) + {:status 200}) -(go-loop - [] - (! unlock-chan {:source :button})) + (recur)) -(log/info "=== Daemon Started ===") + ; listen on unlock-chan for unlock events + ; if a new unlock event is revieved before the 3000ms timeout, the door is kept open. + (go-loop [unlock nil] + (when unlock + (sh "gpio" "write" "1" "1") + (loop [[trigger _] [unlock nil]] + (when trigger + (log/info (str "Unlock triggered by " (:source trigger))) + (recur (alts! [unlock-chan (timeout 3000)])))) + (sh "gpio" "write" "1" "0") + (log/info "Door Locked")) + (recur (