简体   繁体   中英

Python 3 Joining Code Together - Raspberry Pi

I have a problem on joining these 3 bunch of codes together. This project is a Smoke System Alarm. When the Smoke sensor detects smoke, a photo will be taken and email will be sent with the attachment of the photo. The thing i am confused about is how to join the 3 codes together.

Thanks for the Help!

Camera Code:

#!/usr/bin/python
import os
import pygame, sys

from pygame.locals import *
import pygame.camera

width = 480
height = 360

#initialise pygame   
pygame.init()
pygame.camera.init()
cam = pygame.camera.Camera("/dev/video0",(width,height))
cam.start()

#setup window
windowSurfaceObj = pygame.display.set_mode((width,height),1,16)
pygame.display.set_caption('Camera')

#take a picture
image = cam.get_image()
cam.stop()

#display the picture
catSurfaceObj = image
windowSurfaceObj.blit(catSurfaceObj,(0,0))
pygame.display.update()

#save picture
pygame.image.save(windowSurfaceObj,'picture.jpg')

Email Code:

#!/usr/bin/env python
# encoding: utf-8
import os
import smtplib
from email import encoders
from email.mime.base import MIMEBase
from email.mime.multipart import MIMEMultipart

COMMASPACE = ', '

def main():
    sender = ''
    gmail_password = ''
    recipients = ['']

    # Create the enclosing (outer) message
    outer = MIMEMultipart()
    outer['Subject'] = 'SMOKE HAS BEEN DETECTED!'
    outer['To'] = COMMASPACE.join(recipients)
    outer['From'] = sender
    outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'

    # List of attachments
    attachments = ['']

    # Add the attachments to the message
    for file in attachments:
        try:
            with open(file, 'rb') as fp:
                msg = MIMEBase('application', "octet-stream")
                msg.set_payload(fp.read())
            encoders.encode_base64(msg)
            msg.add_header('Content-Disposition', 'attachment', filename=os.path.basename(file))
            outer.attach(msg)
        except:
            print("Unable to open one of the attachments. Error: ", sys.exc_info()[0])
            raise

    composed = outer.as_string()

    # Send the email
    try:
        with smtplib.SMTP('smtp.gmail.com', 587) as s:
            s.ehlo()
            s.starttls()
            s.ehlo()
            s.login(sender, gmail_password)
            s.sendmail(sender, recipients, composed)
            s.close()
        print("Email sent!")
    except:
        print("Unable to send the email. Error: ", sys.exc_info()[0])
        raise

if __name__ == '__main__':
    main()

MQ2 Smoke Sensor Code:

import time
import botbook_mcp3002 as mcp #

smokeLevel= 0

def readSmokeLevel():
global smokeLevel
smokeLevel= mcp.readAnalog()

def main():
while True: #
readSmokeLevel() #
print ("Current smoke level is %i " % smokeLevel) #
if smokeLevel > 120:
print("Smoke detected")
time.sleep(0.5) # s

if_name_=="_main_":
main()

It seems like you might benefit from doing a Python tutorial or two :)

The easiest way (but not necessarily the best way) to do what you want would be to make a single file, put all the import statements at the top and then do this:

Add the camera code, but convert it to a function:

def take_picture():
    width = 480
    height = 360

    # initialise pygame   
    pygame.init()
    [etc.]

Note, the leading whitespace is important.

The function could also be written to specify the filename when it is called (like Roland's example does). That would be a better way to do it in case you want to save more than one image.

Then add in the e-mail code, but here you should change the name of the main function to something else like email_picture . Also, you will need to fill in the details like eg changing the attachments variable to match the name of the file that the take_picture function is saving. (Again, it would be better to allow the caller to specify things like sender/recipient addresses and file name(s) like in Roland's example. Also don't include the if __name__ == "__main__" part here.

eg:

COMMASPACE = ', '

def email_picture():
    sender = 'Your@Email.address'
    gmail_password = 'YourGmailPassword'
    recipients = ['Your@Email.address']

    # Create the enclosing (outer) message
    outer = MIMEMultipart()
    outer['Subject'] = 'SMOKE HAS BEEN DETECTED!'
    outer['To'] = COMMASPACE.join(recipients)
    outer['From'] = sender
    outer.preamble = 'You will not see this in a MIME-aware mail reader.\n'

    # List of attachments
    # This must match what the take_picture funtion is saving the file as
    attachments = ['picture.jpg']
    [etc.]

Then add the smoke detection code. The code in your post is a bit mangled. It is missing the leading spaces and some double underscores have been changed to single underscores.

Add calls to the camera code and email code in to the smoke detection code. Also you probably want to add in a sleep after sending the e-mail when smoke is detected so that your script doesn't send you hundreds/thousands of e-mails whenever it detects smoke.

It should look more like this (although the global variable seems unnecessary):

smokeLevel = 0

def readSmokeLevel():
    global smokeLevel
    smokeLevel = mcp.readAnalog()

def main():
    while True: # Loop forever
        readSmokeLevel() #
        print("Current smoke level is %i " % smokeLevel) #
        if smokeLevel > 120:
            print("Smoke detected")
            take_picture()
            email_picture()
            time.sleep(600) # Cut down on emails when smoke detected
        time.sleep(0.5) # seconds

if __name__ == "__main__":
    main()

Probably the easiest way is to use subprocess.run on Python 3.5 (or subprocess.call on earlier versions) to launch first the photo program and then the e-mail program from the smoke detection program.

Another way that would also work is to convert the camera program and the e-mail program to modules .

A camera module could look like this;

"""Camera module"""

import pygame


def picture(filename):
    """Take a picture.

    Arguments:
        filename: Path where to store the picture
    """
    pygame.init()
    pygame.camera.init()
    cam = pygame.camera.Camera("/dev/video0", (480, 360))
    cam.start()
    image = cam.get_image()
    cam.stop()
    pygame.image.save(image, filename)

In the same way you could create an email module with a function send_mail(sender, password, recipient, attachments) .

In the smoke-detection program, you could then do;

import camera
import email

# if smoke detected...
imagename = 'smoke.jpg'
camera.picture(imagename)
email.send_mail('foo@bar.com', 'sfwrterger', 'you@erewhon.com',
                [imagename])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM