Stuff & Nonsense

DIY security keypad

After my couple of hours of tinkering with python yesterday (see here) I started pondering how to expand on what I’d done.  Some sort of keypad would be handy, so I could just tap in a code and disable my cameras…. and then I’d need something to run the code on and connect the keypad to….Oh, and some way of indicating whether the cameras are currently enabled or disabled would be nice.

Luckily, I still had my trusty raspberry pi sat around doing nothing, so that solved the platform issue quite nicely.  The debian install for the pi already comes with python, so it was trivial to get my code up and running…. now I just needed a keypad.  I did look at something like this:

£10 from amazon might seem like a bargain, but I already had a spare usb keyboard sat around.  If only I could use that.  Well, that’s where some hacking came in handy:

2013-05-28 19.31.43

 

 

Somewhat astonishingly, the numpad bit of the keyboard still worked after my delicate surgery (I got lucky and happened to have a keyboard that responded well to being cut in half.  your mileage may vary).  So now we have a platform for the code to run on, and a number pad to enable or disable the cameras…it would be nice if we could determine whether the cameras are enabled or disabled though.  Handily, we can!  Pretty much every keyboard has a selection of LEDs on it to indicate the status of the ‘locking’ keys (caps lock, num lock and scroll lock) and my hastily hacked up masterpiece was no exception.  And it turns out it’s fairly straightforward to control these lights in python (although you do need to have root privileges to do so.  Why?  because linux that’s why) .

So, with a bit more googling and some slapping together of code here’s how it all works.

The pi is set to login automatically on boot (using the info here) and starts the python script (source below).  The script then queries motion for the current status, and sets the scroll lock LED accordingly, before waiting for the user to enter a passcode.  If the passcode is incorrect the lights on the keyboard flash on and off, before returning the user to the ‘enter passcode’ bit again.

Here’s a couple of images of the ‘mounted’ number pad (sellotape is brilliant!):

cameras off / cameras on.

 

2013-05-28 21.04.36 2013-05-28 21.04.43

As well as some tidying up, I want to do some more work on the python script (I’d quite like it to poll the cameras while waiting for input, and flash the capslock key as a ‘heartbeat’ indicator) but here’s what the code looks like so far:

 

#!/usr/bin/python
import getpass
import requests
import os
import fcntl
import time
import pwd
import grp

KDSETLED = 0x4B32
SCR_LED  = 0x01
NUM_LED  = 0x02
CAP_LED  = 0x04

def get_status():
        response = requests.get(url= host+"/1/detection/status")
        if response.status_code == 200:
                if "PAUSE" in response.text:
                        return 0
                else:
                        return 1
        else:
                return -1

def toggle_status(current_status):
        if current_status == -1:
                return
        if current_status == 0:
                path = "/detection/start"
                out = " started"
        else:
                path = "/detection/pause"
                out = " stopped"
        for x in range(1,camCount+1):
                response = requests.get(url= host+"/"+str(x)+path)
                if response.status_code == 200:
                        print "Camera "+str(x)+out
                else:
                        print "Error with camera "+str(x)

camCount = 2
password = "PASSWORD"
host = "http://HOST:PORT"
console_fd = os.open('/dev/console', os.O_NOCTTY)
enabled = SCR_LED | NUM_LED
disabled = NUM_LED
error = CAP_LED
all_off = 0
all_on = SCR_LED | NUM_LED | CAP_LED

while True:
        os.system('cls' if os.name=='nt' else 'clear')
        status = get_status()
        if status == 0:
                print "Motion detection disabled"
                fcntl.ioctl(console_fd, KDSETLED, disabled)
        else:
                if status == 1:
                        print "Motion detection enabled"
                        fcntl.ioctl(console_fd, KDSETLED, enabled)

                else:
                        print "Error determining status"
                        fcntl.ioctl(console_fd, KDSETLED, error)
        input = getpass.getpass("Enter the passcode: ")
        if input == password:
                toggle_status(status)
        else:
                fcntl.ioctl(console_fd, KDSETLED, all_on)
                time.sleep(2)
                fcntl.ioctl(console_fd, KDSETLED, all_off)
                time.sleep(2)

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.