Raspberry Pi GPIO for Triggering Record based on Door Contacts

Support and queries relating to third party Live CDs and DVD, VM images and other packaged distributions
Post Reply
The00Dustin
Posts: 3
Joined: Tue Nov 22, 2016 9:54 pm

Raspberry Pi GPIO for Triggering Record based on Door Contacts

Post by The00Dustin »

I just spent the last two days writing a pretty simple Python program to monitor door contacts connected to a Raspberry Pi and trigger recording whenever a door is open. I went through several iterations (working with IRQs, forking, etc) before landing with what I have (individually named programs to run in the background without forking so it is easier to tell which process is doing what if monitoring multiple GPIO inputs). Now I'm wondering if I should post it here and/or on the wiki. I would be posting it primarily so other people could use it if they wanted, but I wouldn't mind input if I missed any Python best practices in its creation (programming isn't something I have much experience with). Thoughts?
User avatar
knight-of-ni
Posts: 2404
Joined: Thu Oct 18, 2007 1:55 pm
Location: Shiloh, IL

Re: Raspberry Pi GPIO for Triggering Record based on Door Contacts

Post by knight-of-ni »

Nice work.

If you are looking for feedback, then posting in the forum would be a good place. If, on the other hand, you want it in a place that won't eventually sink into oblivion then the Wiki would be a good place. What I'm getting at is, perhaps initially, you could post it in the forum for peer review, and following that post it in the wiki. If you wanted to be fancy you create a github account and place it there.
Visit my blog for ZoneMinder related projects using the Raspberry Pi, Orange Pi, Odroid, and the ESP8266
All of these can be found at https://zoneminder.blogspot.com/
The00Dustin
Posts: 3
Joined: Tue Nov 22, 2016 9:54 pm

Re: Raspberry Pi GPIO for Triggering Record based on Door Contacts

Post by The00Dustin »

Don't really need to be fancy, just want to be helpful, so here's the code for a normally open contact wired between GPIO11 and GND that triggers recording on monitor 4 while closed:

Code: Select all

#!/usr/bin/env python
import RPi.GPIO as GPIO
import signal
import socket
import time
#Define GPIO pin here:
thiscontact = 11
GPIO.setmode(GPIO.BCM)
GPIO.setup(thiscontact, GPIO.IN, pull_up_down=GPIO.PUD_UP)
def watchopen():
	thisposition = GPIO.input(thiscontact)
	if thisposition == True:
		while thisposition == True:
			time.sleep(0.1)
			thisposition = GPIO.input(thiscontact)
		watchclose()
	watchclose()
def watchclose():
	thisposition = GPIO.input(thiscontact)
	if thisposition == False:
		while thisposition == False:
			s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
			#Define ZoneMinder Server here:
			s.connect(("192.168.1.1", 6802))
			#Define ZoneMinder Monitor here:
			s.send("4|on+2|255")
			s.close()
			time.sleep(0.9)
			thisposition = GPIO.input(thiscontact)
		watchopen()
	watchopen()
def exit_handler(signal, frame):
	GPIO.cleanup()
	raise SystemExit
signal.signal(signal.SIGTERM, exit_handler)
signal.signal(signal.SIGINT, exit_handler)
watchopen()
Additionally, here is some important information to help understand what I have going on here:
  • I originally messed with forking in order to monitor multiple pins to control multiple monitors from one launch, but found no benefit vs launching separate programs. As such, this code is meant to be saved in a separate file and modified appropriately for each input to be monitored and door to be controlled. One benefit to launching them separately is that it is easier to tell which process is which if you need to kill them separately. I actually tested with two input pins on two separate programs and did not have any trouble, so hopefully that scales well.
  • I originally planned and programmed to just send the on command once instead of sending on+2 repeatedly, and in that scenario, I would subsequently send the off command when the contact re-opened. I decided sending on+2 repeatedly would be better so that power loss at the RPi couldn't lead to a very long recording and a door being propped open couldn't lead to a recording cut short.
  • Creating and closing a new TCP session every second IS intentional even though it seems wasteful. I found that if I left the connection open, there was a lag between the commands being sent and processed, so I would get multiple split overlapping videos for a single event.
  • The exit handler configuration was set up to properly shut down the GPIO pins (even though it's probably not necessary since there are no outputs) in two scenarios:
    1) Keyboard interrupt (CTRL+C [SIGINT]) when running in foreground
    2) Normal shutdown (kill [SIGTERM]) when running in background
If anyone would like to provide feedback, please do.

If anyone would like to post it in the Wiki, feel free (or ask me to and let me know where it would best fit).

Finally, while this list probably isn't all-encompassing, here are sources I noted prior to and during creation of this program (no prior python experience, but lots of iterations over a few days before settling with the above):
http://razzpisampler.oreilly.com/ch07.html (pretty sure I used other parts of the sampler from here as well)
http://raspi.tv/2013/rpi-gpio-basics-3- ... ct-your-pi
https://nattster.wordpress.com/2013/06/ ... in-python/
Post Reply