As soon as @bourryto and I moved into our flat share, we wanted to improve our key sharing and door opening concept, especially since I tend to forget my keys quite a lot. We live on the third floor of a four floor appartment building, so we were able to change the key cylinder of our appartment itself but obviously not the one being used for opening the front door. So, here’s what our approach to the front door is.

What do I need?

  • A Raspberry Pi Zero W
    • and obv a MicroUSB plus brick and a MicroSD
  • 5V/220V 2 Channel Optocouplers Relay Module
    • I bought some cheapish ones off eBay
  • Jumper Wires
    • mine are ace-colored, this wasn’t intended

How to set these things up?

Building a working set-up with this was quiet easy, unless you still want to use a physical button to open the door, that would require some soldering, you bascially just have to:

  1. make sure which two cables are being used for the strikes button mechanism
  2. connect the wires to the relay and the relay control pins to the Raspberry Pi
  3. If you’re using RPi.GPIO in python and let’s say the GPIO-PIN 17 you’re most likely to open your door now via:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    
    	# import things
    	import RPi.GPIO as GPIO
    	import time
    
    	# config relay things
    	GPIO.setmode(GPIO.BCM)
    	CONTROL_PIN = 17
    	GPIO.setup(CONTROL_PIN, GPIO.OUT)
    	GPIO.output(CONTROL_PIN, GPIO.HIGH)
    
    	GPIO.output(CONTROL_PIN, GPIO.LOW) # open the door   
    	time.sleep(3) # remain in this state for three seconds   
    	GPIO.output(CONTROL_PIN, GPIO.HIGH) # close the door again
    
    	[even more code]
    	

But isn’t it annoying having to SSH on your Pi via VPN/Local Network at first?

Yes it is, and we want to use functions as well since the script above is really low effort.

So here’s a better one:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# import things
import RPi.GPIO as GPIO
import time

# config relay things
GPIO.cleanup()
GPIO.setmode(GPIO.BCM)
CONTROL_PIN = 17
GPIO.setup(CONTROL_PIN, GPIO.OUT)
GPIO.output(CONTROL_PIN, GPIO.HIGH)

# flask magic
from flask import Flask
app = Flask(__name__)

@app.route('/open')
def open():
    GPIO.output(CONTROL_PIN, GPIO.LOW)
    time.sleep(3)
    GPIO.output(CONTROL_PIN, GPIO.HIGH)    
    return 'Hi!'

@app.route('/close')
def reset():
    GPIO.output(CONTROL_PIN, GPIO.HIGH)
    return 'Bye!'

@app.route('/info')
def info():
    return 'this door opening system was build by your favorite lipstick lesbian: @rachel@cybre.space'

if __name__ == '__main__':
    app.run()

Introducing pink fluffy gunicorns

Using the development server of flask isn’t recommended for production use. So we’re going to need a callable WSGI application object:

1
2
3
4
from adoorabell import app

if __name__ == "__main__":
        app.run()

and a systemd service file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
[Unit]
Description=Gunicorn instance for adoorabell
After=network.target

[Service]
User=pi
Group=pi
WorkingDirectory=/home/pi/adoorabell
ExecStart=/home/pi/adoorabell/gunicorn --bind 0.0.0.0:5000 wsgi:app

[Install]
WantedBy=multi-user.target

If you enable and start the service you’ll spin up a webserver running on port 5000.

How to use the web service?

  • xx.xx.xx.xx:5000/open to open the door
  • xx.xx.xx.xx:5000/close to reset/debug the door
  • xx.xx.xx.xx:5000/info to show the info page