johp778
Posts: 12
Joined: Sat Apr 22, 2017 3:35 pm

PiLarm Help

Sat Apr 22, 2017 3:55 pm

Hi All
I'd been looking to create an alarm for my garage using a Raspberry Pi and whilst searching online, I found the PiLarm (http://makezine.com/projects/pilarm-por ... oom-alarm/), which I thought with a bit of tweaking to suite my needs would be perfect. So far I have the alarm setup up for testing, I've changed the pass/halt codes no problem and removed the twitter posting, however I want to use the raspberry pi camera, which I already have set up and following the guides, have successfully tested it to capture 5 images and also tested capturing video.

It's at this point where I need help, as I'm new to python, I am struggling to add the picamera into the code, to get it to take a video when motion is detected and also send me an alert email. Every time I add some code that i believe will do the trick, it not only doesn't record, but it also seems to affect the motion sensor, leaving me a little confused as to what is the problem, I did consider a separate script to deal with the video and email on motion detect, however I only want it to take a video when the system is armed, as I don't want a video every time we go in the garage.

This is the original code by Jeff Highsmith, as stated I've already removed the get_cam and tweetpony sections and assume I just need to enter my new picamera and gmail code where it was?

Code: Select all

#!/usr/bin/python

import subprocess
import datetime
import time
import os 
import RPi.GPIO as io
import tweetpony

api = tweetpony.API(consumer_key = "abcd", consumer_secret = "efgh", access_token = "ijkl", access_token_secret = "mnop")

io.setmode(io.BCM)

pir_pin = 18
flashingLight_pin = 7

io.setup(pir_pin, io.IN)
io.setup(flashingLight_pin, io.OUT)
io.output(flashingLight_pin, io.LOW)

# --------- Main Program ---------
previous_pir=0

while True:
	current_pir=io.input(pir_pin)	
	if previous_pir==0 and current_pir==1:
		with open("/home/pi/Alarm/armed.txt", "r") as fo:
                    fo.seek(0, 0)
                    status = fo.read(1)
                fo.closed
                print "Motion detected, armed status: " + str(status)
		if (status == "1"):
		    subprocess.call("mpg123 /home/pi/Alarm/motiondetect.mp3", shell=True)
                    time.sleep(10)
		    with open("/home/pi/Alarm/armed.txt", "r") as fo:
                        fo.seek(0, 0)
                        status = fo.read(1)
                    fo.closed 
		    if (status == "1"):
		        print "Correct passcode not entered, emailing picture and sounding alarm."
                       grab_cam = subprocess.Popen("sudo fswebcam -r 640x480 -d /dev/video0 -q /home/pi/Alarm/pictures/%m-%d-%y-%H%M.jpg", shell=True)
                        grab_cam.wait()
                        todays_date = datetime.datetime.today()
                        image_name = todays_date.strftime('%m-%d-%y-%H%M')
                        image_path = '/home/pi/Alarm/pictures/' + image_name + '.jpg'
                        subprocess.Popen('echo "Here is your intruder:" | mail -a ' + image_path + ' -s "Intruder Alert" muddysdad@gmail.com', shell=True)

		        try:
		            api.update_status_with_media(status = ("Intruder alert: " + todays_date.strftime('%m-%d-%y-%H%M')), media= image_path)
		        except tweetpony.APIError as err:
		            print "Oops, something went wrong! Twitter returned error #%i and said: %s" % (err.code, err.description)

                        io.output(flashingLight_pin, io.HIGH)
		        subprocess.call("mpg123 /home/pi/Alarm/alarm.mp3", shell=True)
                        subprocess.call("mpg123 /home/pi/Alarm/surrender.mp3", shell=True)
                        subprocess.call("mpg123 /home/pi/Alarm/alarm.mp3", shell=True)                       
                        io.output(flashingLight_pin, io.LOW)
                        del_img = subprocess.Popen("sudo rm -rf  " + image_path, shell=True)
                        del_img.wait()
	previous_pir=current_pir
	time.sleep(1)
RasPiVan Creator, but Python Novice

johp778
Posts: 12
Joined: Sat Apr 22, 2017 3:35 pm

Re: PiLarm Help

Sat Apr 22, 2017 8:28 pm

I've had an idea that a separate python script (also running at startup) might be the solution, I'm thinking I could have a script watching the status of the pin the flashing light is connected to, (currently I've just connected a white led), as when the alarm is active and motion is detected, the flashing light pin will go high and therefore activate the additional script to take a video and send an email?

I've tried the below script starting off with just an image capture, however I'm getting the following warnings

this channel is already in use - added io.setwarnings(false) to try combat this

if io.output(flashingLight_pin:
TypeError: function takes exactly 2 arguments (1given) - I tried adding Else: Print, but still got error and believe else: is not the right solution?

Code: Select all

#!/usr/bin/python

from picamera import PiCamera
from time import sleep
import os
import RPi.GPIO as io

io.setmode(io.BCM)

flashingLight_pin = 7
camera = PiCamera()

io.setup(flashingLight_pin, io.OUT)
io.setwarnings(False)

while True:
               if io.output(flashingLight_pin):
                  camera.start_preview()
                  sleep(5)
                  camera.capture('/home/pi/PiLarm/pictures/image.jpg')
                  camera.stop_preview()
                  time.sleep(5)
RasPiVan Creator, but Python Novice

User avatar
paddyg
Posts: 2555
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: PiLarm Help

Sat Apr 22, 2017 9:30 pm

GPIO.output(port_or_pin, 1)
i.e. you need to provide a port_or_pin and what to set it to. Which you do in the first code listing but not the second. Python errors are normally very explicit about the cause and location of the problem. One of the exceptions is the number of arguments to class methods where 'self' confuses things (which isn't relevant here but lodge in the back of your mind for when you eventually come across it)
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

johp778
Posts: 12
Joined: Sat Apr 22, 2017 3:35 pm

Re: PiLarm Help

Sun Apr 23, 2017 9:46 am

Ok, so I've amended the code, I think I understood what you meant and added

io.output(flashingLight_pin, 0)

to tell it what state the pin needs to be at startup and ran the script, however I still get an error

File "/home/pi/PiLarm/PiLarmCapt.py", line 18, in <module>
if io.output(flashingLight_pin):
TypeError: function takes exactly 2 arguments (1 given)

I've now made a few more amendments as follows, but the flashingLight_pin is flickering, I want this script to just read the status of this pin and then either do nothing if the pin is currently low, but when my alarm code is active and turns this pin high, I want it to trigger the camera to take a video (testing with images first) and then email me the video (to come later once I get the code right).

I tried putting if io.ouput(flashingLight_pin, 0): first, but this then started the camera, turned the led on and I couldn't exit the camera, even using CTRL-C.

Code: Select all

#!/usr/bin/python

from picamera import PiCamera
from time import sleep
import os
import RPi.GPIO as io

io.setmode(io.BCM)

flashingLight_pin = 7
camera = PiCamera()

io.setup(flashingLight_pin, io.OUT)
io.output(flashingLight_pin, 0)
io.setwarnings(False)

while True:
               if io.output(flashingLight_pin, 1):
                  camera.start_preview()
                  sleep(5)
                  camera.capture('/home/pi/PiLarm/pictures/image.jpg')
                  camera.stop_preview()
                  time.sleep(5)
               if not io.output(flashingLight_pin, 0):
                  pass
RasPiVan Creator, but Python Novice

johp778
Posts: 12
Joined: Sat Apr 22, 2017 3:35 pm

Re: PiLarm Help

Sun Apr 23, 2017 9:52 am

I've also tried

Code: Select all

if io.output(flashingLight_pin) ==1:
if not io.output(flashingLight_pin) ==0:
RasPiVan Creator, but Python Novice

User avatar
paddyg
Posts: 2555
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: PiLarm Help

Sun Apr 23, 2017 11:52 am

You can't really use output() to check the state of a pin, but I wouldn't use input() in this case either as the status is something being set by your program (as yet unwritten). I would use a variable to hold the state of the pin (i.e. the state of your alarm code) and check that state rather than the pin, along the lines of

Code: Select all

#!/usr/bin/python

from picamera import PiCamera
from time import sleep
import os
import RPi.GPIO as io

io.setmode(io.BCM)

flashingLight_pin = 7
flp_status = 0
camera = PiCamera()

io.setup(flashingLight_pin, io.OUT)
io.output(flashingLight_pin, flp_status)
io.setwarnings(False)

while True:
               if flp_status == 1:
                  camera.start_preview()
                  sleep(5)
 ...
I'm not sure at all what you are trying to achieve with your second if statement! You can use output() to change the value output to a pin but I'm not sure what the returned value will be, often functions return something to represent an error condition or, by default, None. Sometimes the value being set.

Have you looked at using gpiozero? It has quite a bit of functionality built in that you might find useful for this project. Also, it's worth looking at making functions to do the different jobs you have in mind then using the event and callback functionality. Lots of examples https://gpiozero.readthedocs.io/en/stab ... led-camera

PS you noticed that the error message you copied points exactly to the problem i.e. line 18 had a function needing two arguments and you had only put one in.
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

johp778
Posts: 12
Joined: Sat Apr 22, 2017 3:35 pm

Re: PiLarm Help

Sun Apr 23, 2017 12:18 pm

Thank You, my lack of Python knowledge leaves me searching online & trying to modify someone else project to suit, but that also means i need help getting the code to work right and have therefore been searching online to try put my code together.

I want a garage alarm that can be actuvated/deactivated with keypad & email me video and/or picture if anyone breaks in, I'd not looked at pizero, as i already have a spare pi to use, but i'll do some more searching online.
RasPiVan Creator, but Python Novice

User avatar
paddyg
Posts: 2555
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: PiLarm Help

Sun Apr 23, 2017 12:34 pm

It's a confusing name, but nothing to do with the physical pizero. It's a python module that makes using the GPIO functionality much easier - see the above link.

Are you going to use just the camera to detect if someone's broken in - i.e. compare sequential frames to see if there's a significant difference or use an infrared movement detector. Also are you going to have a physical keypad input or a webpage keypad such as you could access using your phone?

If you're new to programming it's a good idea to do several mini projects getting the bits to work on their own i.e. just the gpio without the camera then just the camera without any confusion from gpio. In fact I would strongly recommend doing a short teach yourself python course before anything - it's frustrating not to get stuck straight in, but less frustrating in the long run!

Paddy
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

johp778
Posts: 12
Joined: Sat Apr 22, 2017 3:35 pm

Re: PiLarm Help

Sun Apr 23, 2017 1:15 pm

Ah right, I'll have a look.

I've already got the original PiLarm design pretty much setup, with keypad and PIR working fine, the final part is to add the pi camera (I've had the Pi camera working separately to take pictures or video) to take a video/picture if someone breaks in and then send me an email alert to notify me someone has broke in, hopefully it will never come to that.

I appreciate I should start from the bottom and work up and I did plan on learning Python, but I just never seem to find the time to start properly and this is not just a project, I just like paying over the top to buy an off the shelf system. I have experience with the Raspberry Pi, building my RasPiVan (https://youtu.be/cKDCO7Um4Nw), but this used the much simpler Scratch with a 4Tronix PiRoCon board to control it, it's also a little while since I've been using the Pi.
RasPiVan Creator, but Python Novice

johp778
Posts: 12
Joined: Sat Apr 22, 2017 3:35 pm

Re: PiLarm Help

Mon Apr 24, 2017 5:30 pm

After spending most of the day yesterday trying to get the picamera to work, at about 9pm last night it did, so if my motion sensor is trigger, it will now take 5 images and save them to the desktop. There's still some work I need to do, as I really want it to record a video instead of pictures and email it to me, plus there seems to be something not quite right with my door switch, I believe I've got it setup correctly, so when the door opens the switch, the circuit is broken, at present it's just 2 wires connected together and I would expect the alarm to sound when they are separated, however it appears nothing happens when you separate them, it's when you reconnect them, but if I had it setup wrong, then it would sound immediately, as they are originally connected?

Here's my working code so far

Code: Select all

#!/usr/bin/python

import subprocess
import datetime
import time
import os 
import RPi.GPIO as io
from picamera import PiCamera


io.setmode(io.BCM)

pir_pin = 18
flashingLight_pin = 7
doorswitch_pin = 2
camera = PiCamera()

io.setup(pir_pin, io.IN)
io.setup(flashingLight_pin, io.OUT)
io.output(flashingLight_pin, io.LOW)
io.setup(doorswitch_pin, io.IN)

# --------- Main Program ---------
previous_pir=0
previous_doorswitch=1

while True:
	current_pir=io.input(pir_pin)	
	if previous_pir==0 and current_pir==1:
		with open("/home/pi/PiLarm/armed.txt", "r") as fo:
                    fo.seek(0, 0)
                    status = fo.read(1)
                fo.closed
                print "Motion detected, armed status: " + str(status)
		if (status == "1"):
		    subprocess.call("mpg123 /home/pi/PiLarm/motiondetect.mp3", shell=True)
                    time.sleep(10)
		    with open("/home/pi/PiLarm/armed.txt", "r") as fo:
                        fo.seek(0, 0)
                        status = fo.read(1)
                    fo.closed 
		    if (status == "1"):
		        print "Correct passcode not entered, emailing picture and sounding alarm." 
                        camera.start_preview()
                        for i in range(5):
                                time.sleep(5)
                                camera.capture('/home/pi/Desktop/image%s.jpg' % i)
                        camera.stop_preview()
                        
                        io.output(flashingLight_pin, io.HIGH)
		        subprocess.call("mpg123 /home/pi/PiLarm/alarm.mp3", shell=True)
                        subprocess.call("mpg123 /home/pi/PiLarm/surrender.mp3", shell=True)
                        subprocess.call("mpg123 /home/pi/PiLarm/alarm.mp3", shell=True)                       
                        io.output(flashingLight_pin, io.LOW)

                        
	previous_pir=current_pir
	time.sleep(1)
	
        current_doorswitch=io.input(doorswitch_pin)
        if previous_doorswitch==1 and current_doorswitch==0:
                with open("/home/pi/PiLarm/armed.txt", "r") as fo:
                        fo.seek(0, 0)
                        status = fo.read(1)
                fo.closed
                print "Motion detected, armed status: " + str(status)
                if (status == "1"):
                        subprocess.call("mpg123 /home/pi/PiLarm/door.mp3", shell=True)
                        time.sleep(10)
                        with open("/home/pi/PiLarm/armed.txt", "r") as fo:
                                fo.seek(0, 0)
                                status = fo.read(1)
                        fo.closed
                        if (status == "1"):
                                print "correct passcode not entered, emailing picture and sounding alarm."

                                io.output(flashingLight_pin, io.HIGH)
                                subprocess.call("mpg123 /home/pi/PiLarm/alarm.mp3", shell=True)
                                subprocess.call("mpg123 /home/pi/PiLarm/surrender.mp3", shell=True)
                                subprocess.call("mpg123 /home/pi/PiLarm/alarm.mp3", shell=True)                       
                                io.output(flashingLight_pin, io.LOW)
	previous_doorswitch=current_doorswitch
	time.sleep(1)
RasPiVan Creator, but Python Novice

User avatar
paddyg
Posts: 2555
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: PiLarm Help

Mon Apr 24, 2017 9:40 pm

Well done. I normally connect GPIO pins to ground rather than +3.3V (just to be on the safe side) I set a pull up resistor so input() returns 1 when nothing's connected and 0 when something is connected. You don't say what your wires are connected to but if you do what I suggest then your code would be along the lines of

Code: Select all

io.setup(doorswitch_pin, io.IN, pull_up_down=io.PUD_UP)
...
    current_doorswitch=io.input(doorswitch_pin)
    if previous_doorswitch==0 and current_doorswitch==1: # stopped being grounded now pulled up
        with open("/home/pi/PiLarm/armed.txt", "r") as fo:
...
    previous_doorswitch = current_doorswitch
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

johp778
Posts: 12
Joined: Sat Apr 22, 2017 3:35 pm

Re: PiLarm Help

Tue Apr 25, 2017 8:39 pm

i tried the io.setup(doorswitch_pin, io.IN, pull_up_down=io.PUD_UP) method, but something wasn't right, as it kept detecting the door switch open, even when closed, but not sure if that could have been an error in my code, looking online & the place i bought the door switch from, there method was gpio to ground, with a 10k resistor connected from signal to 3.3v & this is what i have now, not sure its the safest option, but it can get confusing when your dealing with a switch that should be 1 until opened. The fact that currently my switch has to open & close again before the alarm sounds, means somethings still not quite right & i would prefer to use the onboard resistors, again i was getting slightly confused between pull up & pull down & wasn't sure if that had any relation to my switch being normally in the closed state, so some research/learning required on pull up/down resistors.
RasPiVan Creator, but Python Novice

User avatar
paddyg
Posts: 2555
Joined: Sat Jan 28, 2012 11:57 am
Location: UK

Re: PiLarm Help

Tue Apr 25, 2017 10:52 pm

You're setup sounds to be physically pulling the pin up, using a resistor connected to 3.3V which is fine (though you need to be very sure it's the 3.3V not the 5.0V) but it doesn't matter specifying PUD_UP as well. (They basically do exactly what you have done but using a resistor and switches inside the RPi chip)

That means the pin is pulled UP (to 1) when ground ISN'T connected. i.e. when the door is open. If you start your program with the door shut then the previous_doorswitch variable should be preset to 0 and current_doorswitch will keep reading 0 while the door is shut. When the door opens current_doorswitch will start reading 1 and your logic should be changed to catch that (as per my suggestion). With the logic the way round you had it in your original code you would have to open the door then close it again. Oh, wait a minute...

Paddy
also https://groups.google.com/forum/?hl=en-GB&fromgroups=#!forum/pi3d

johp778
Posts: 12
Joined: Sat Apr 22, 2017 3:35 pm

Re: PiLarm Help

Wed Apr 26, 2017 4:28 pm

Brilliant, Thank you for the explanation, that's exactly what's happening, i have to open the door then shut it again, i will change it.
RasPiVan Creator, but Python Novice

Return to “Python”