A RFID based access control system written in Go for Raspberry Pi + MFRCC522 tag readers + MIFARE Classic 1K RFID tags.
Craftdoor is a software suite for an RFID-powered door access system on a federation of Raspberry Pi devices. With the exception of the "master", each Raspberry Pi is connected to an RFID reader and a door. Registered members may tap the RFID reader with their MIFARE RFID tag to open the adjacent door.
The system is administered via a WebUI interface and accompanying REST API served by the master device. Persistent state is stored in a SQLite database on the master device. See below for valid endpoints.
Instructions below for building, configuring, and launching the webserver.
Note: At time of writing, only a single "master" Raspberry Pi is supported.
To start the software suite, do the following on your development machine,
- Connect RC522 to master Raspberry Pi's hardware SPI interface. Follow instructions here.
- Download
golang
from https://golang.org. Follow installation instructions here. Verify that go is installed by runninggo version
in a terminal. Expect to see >= 1.14. - Install GCC cross-compiler,
$ sudo apt install gcc-arm-linux-gnueabi libc6-armel-cross \
libc6-dev-armel-cross binutils-arm-linux-gnueabi
- Run
scripts/build.sh
. This will create a folder,release/
, containing everything needed to run the server on a Raspberry pi$ bash scripts/build.sh
- Turn on your Raspberry Pi and ensure it's connected to your local network.
Follow the instructions
here.
Ensure that you can SSH into the Raspberry Pi under hostname
raspberrypi
. You can setup an SSH config entry like so in$HOME/.ssh/config
,Host raspberrypi Hostname 192.168.0.9 # Your IP address may vary! User pi
- Copy the contents of
release/
to/home/pi/craftdoor
on the Raspberry Pi and run it. This will launch a webserver on port :8080.$ bash scripts/deploy.sh
Note: If the RC522 RFID reader is not detected, a fake, dummy interface will be used. This dummy interface cannot interact with RFID tags.
If you'd like to interact with the REST API from your development machine, you can run the following. Note that the only the dummy interface is available in this context.
- Run
cmd/master/main.go
. This will launch a webserver listening on port 8080.
$ git clone https://github.com/pakohan/craftdoor.git
$ cd craftdoor
$ export CRAFTDOOR_ROOT=$(pwd)/assets
$ go run cmd/master/main.go --config=assets/develop.json
Craftdoor includes a systemd
service definition. This can be used to ensure
that craftdoor
is launched on Raspberry Pi's system startup. To use it, do
the following,
- Deploy
craftdoor
to the Raspberry Pi as shown above. - Add a symlink in
/etc/systemd/system
forassets/craftdoor.service
.
$ ssh raspberrypi
$ sudo systemctl link $HOME/craftdoor/craftdoor.service
- Launch
craftdoor
. Ensure it's working correctly. if you see something like the following, it's working!
$ sudo systemctl start craftdoor.service
$ sudo systemctl status craftdoor.service
● craftdoor.service - Craftdoor Service
Loaded: loaded (/home/pi/craftdoor/craftdoor.service; linked; vendor preset: enabled)
Active: active (running) since Sun 2020-08-23 04:39:37 PDT; 4min 17s ago
Main PID: 3707 (main)
Tasks: 8 (limit: 2065)
CGroup: /system.slice/craftdoor.service
└─3707 /home/pi/craftdoor/main --config=/home/pi/craftdoor/develop.json
Aug 23 04:46:03 raspberrypi main[3964]: "sqlite_schema_file": "/home/pi/craftdoor/schema.sql",
Aug 23 04:46:03 raspberrypi main[3964]: "listen_http": ":8080"
Aug 23 04:46:03 raspberrypi main[3964]: }
Aug 23 04:46:03 raspberrypi main[3964]: /home/duckworthd/Desktop/craftwerk/craftdoor/rfid/mfrc522.go:74: Halting Reader.
Aug 23 04:46:03 raspberrypi main[3964]: /home/duckworthd/Desktop/craftwerk/craftdoor/rfid/mfrc522.go:92: Successfully halted Reader.
Aug 23 04:46:03 raspberrypi main[3964]: /home/duckworthd/Desktop/craftwerk/craftdoor/rfid/mfrc522.go:48: Initializing Reader.
Aug 23 04:46:03 raspberrypi main[3964]: /home/duckworthd/Desktop/craftwerk/craftdoor/rfid/mfrc522.go:68: Successfully initialized Reader.
Aug 23 04:46:03 raspberrypi main[3964]: /home/duckworthd/Desktop/craftwerk/craftdoor/cmd/master/main.go:75: Initializing rpi reader
Aug 23 04:46:03 raspberrypi main[3964]: /home/duckworthd/Desktop/craftwerk/craftdoor/service/service.go:86: Starting DoorAccessLoop()...
Aug 23 04:46:03 raspberrypi main[3964]: /home/duckworthd/Desktop/craftwerk/craftdoor/cmd/master/main.go:92: listening on :8080
- Stop
craftdoor
. This step isn't strictly necessary, but you can use this to restart the service if changes have been made.
$ sudo systemctl stop craftdoor.service
- Ask
systemd
to startcraftdoor
on system launch,
$ sudo systemctl enable craftdoor.service
You can also monitor the state of craftdoor
at any time from your local
machine with journalctl
,
$ ssh raspberrypi 'journalctl -u craftdoor.service -b' | tail -n 20
Once main.go
is launched, the following endpoints are available via the HTTP
webserver,
GET /
: Get the details of the next RFID tag put in front of the reader.
For doors,
GET /members
: list doors in databaseGET /members/<id>
: get detailed information about a single member.POST /members
: Create a new member.PUT /members/<id>
: Update an existing member.DELETE /members/<id>
: Delete an existing member.
Similar to doors, one can query and manage keys via /keys
.
assets/
craftdoor.service # systemd service definition for craftdoor
develop.json # config file when developing.
develop.db # sqlite database used during development
schema.sql # schema definition for initializing database.
cmd/
debug/
read.go # debug binary for reading all data on an RFID tag.
master/
main.go # main binary for this project
config/
config.go # JSON config file API
controller/
controller.go # HTTP request handling logic.
...
door/ # wrapper for doors
door.go # interface for interacting with doors.
dummy.go # dummy implementation for interface Door
rpi.go # Raspberry Pi implementation of interface Door
lib/
db.go # initialize database schema
state.go # State of the system.
model/ # database definitions, API
model.go # interface for interacting with the database.
...
rfid/ # wrapper for RFID readers/writers
dummy.go # dummy implementation of interface Reader
fmt.go # format contents of an RFID tag as a string.
mfrc522.go # MFRC522 implementation of interface Reader
reader.go # interface for interacting with RFID readers.
service/ # business logic for adding/removing keys, doors, etc
service.go # door-opening loop, access to RFID reader.
vendor/ # third-party code
...
The Raspberry Pi is connected to 3 devices: an RC522 RFID reader, a "latch"-style lock connected to a door, and a "bolt"-style lock connected to the same door. The latch and bolt are both turned on when an authorized RFID tag is presented to the RC522 reader. The bolt is also turned on during Craftwerk's opening hours (5am to 11pm GMT+2).
Purpose Pin Pin Purpose
---------------------------+----------------------------
Bolt + Latch Relay VCC 01 | 02
03 | 04
05 | 06
07 | 08
09 | 10
11 | 12
Bolt Relay IN 13 | 14 Bolt, Latch Relay GND
Latch Relay IN 15 | 16 (Auth failed signal)
MFRC522 VCC 17 | 18 MFRC522 IRQ
MFRC522 MOSI 19 | 20 MFRC522 GND
MFRC522 MISO 21 | 22 MFRC522 RST
MFRC522 SCK 23 | 24 MFRC522 NSS or SDA
---------------------------+----------------------------
See this wiring diagram for further details.