Skip to content

Commit

Permalink
implement doorlock daemon
Browse files Browse the repository at this point in the history
  • Loading branch information
akiroz committed Aug 12, 2016
1 parent 3f54813 commit 9f48be4
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 33 deletions.
38 changes: 28 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# doorlock

Project Structure:
**Project Structure:**
```
.
└── embedded Embedded System & Hardware
Expand All @@ -11,30 +11,48 @@ Project Structure:
Circuit diagrams are drawn with this [Circuit Simulator](http://www.falstad.com/circuit/).<br/>
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-<version>-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
3 changes: 1 addition & 2 deletions embedded/doorlock.service
Original file line number Diff line number Diff line change
Expand Up @@ -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
4 changes: 2 additions & 2 deletions embedded/project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -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)
61 changes: 42 additions & 19 deletions embedded/src/com/oursky/doorlock/core.clj
Original file line number Diff line number Diff line change
@@ -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 [<! go-loop timeout]]
))
[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 <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
[]
(<! (timeout 2000))
(toggle! unlock-port)
(recur))
(defn -main [& args]
; 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")

(go-loop
[]
(log/info (<! button-chan))
(recur))
; button event listener
; hold down for atleast 200ms to trigger
; will emit event every 25000ms if held down
(go-loop []
(if (= 1 (read-string (:out (sh "gpio" "read" "0"))))
(sh "gpio" "wfi" "0" "falling")
(<! (timeout 2500)))
(<! (timeout 200))
(when (= 0 (read-string (:out (sh "gpio" "read" "0"))))
(>! 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 (<! unlock-chan)))

(run-server http-handler {:ip "0.0.0.0" :port 8090})

(log/info "=== Daemon Started ==="))

0 comments on commit 9f48be4

Please sign in to comment.