Используем камеру Raspberry Pi для отправки электронных писем
Задействуем модуль камеры Raspberry Pi совместно с датчиком движения, чтобы отправлять фотоснимки на Gmail-аккаунт.
Комплектующие
Raspberry Pi 3 B
Модуль камеры Raspberry Pi
Сенсор движения
В этой статье разберемся, как отправлять электронные письма с прикрепленными изображениями при помощи Raspberry Pi, детектора движения и языка Python. Мы задействуем датчик обнаружения движения: при срабатывании камера Raspberry Pi сделает фотографию и автоматически отправит письмо с вложенным снимком.
Данное руководство совместимо исключительно с Gmail-аккаунтами, поэтому перед началом работы убедитесь, что такой аккаунт у вас есть. Также советуем завести для этих целей отдельную учетную запись Gmail во избежание проблем с безопасностью.
Настройка параметров по умолчанию Gmail
По умолчанию Google блокирует отправку и получение писем, содержащих Python-код. Для изменения этой настройки активируйте параметр «Разрешить менее безопасные приложения» (англ. - Allow less secure apps), следуя инструкции:
Войдите в свой Gmail-аккаунт, используя логин и пароль.
Кликните по аватару своего профиля, после чего выберите «Google account».
В блоке «Вход и безопасность» (англ. - Sign-in and Security) перейдите к пункту «Подключенные приложения и сайты» (англ. - Connected apps and sites).
Включите опцию «Разрешить менее безопасные приложения» (англ. - Allow less secure apps).
После этого вы сможете использовать Gmail для получения писем, содержащих Python-код.
Подключаем датчик движения к Raspberry Pi
Соедините выводы VCC и GND датчика движения с 5V и GND на Raspberry Pi соответственно, а вывод OUT датчика подключите к GPIO17. Проверьте, что камера подключена к Raspberry Pi и активирована. Используйте приведенную ниже схему соединений.
Код Python для отправки писем
Перед запуском убедитесь, что в коде указаны корректные адреса электронной почты отправителя и получателя, а также пароль отправителя. Программа считывает показания датчика (при обнаружении движения), делает снимок и сохраняет его в папку.
При первом запуске программа автоматически создаст необходимую папку. Сразу после того как камера сделает снимок, изображение будет приложено к электронному письму и отправлено на указанный адрес.
Скопируйте приведенный ниже код в новый файл с расширением .py (к примеру, dvizhenie.py) и запустите его командой:
python dvizhenie.py
Код программы:
import os
import glob
import picamera
import RPi.GPIO as GPIO
import smtplib
from time import sleep
# Importing modules for sending mail
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email import encoders
sender = 'example@gmail.com'
password = 'abcd1234'
receiver = 'example@gmail.com'
DIR = './Database/'
FILE_PREFIX = 'image'
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.IN) # Read output from PIR motion sensor
def send_mail():
print 'Sending E-Mail'
# Create the directory if not exists
if not os.path.exists(DIR):
os.makedirs(DIR)
# Find the largest ID of existing images.
# Start new images after this ID value.
files = sorted(glob.glob(os.path.join(DIR, FILE_PREFIX + '[0-9][0-9][0-9].jpg.webp')))
count = 0
if len(files) > 0:
# Grab the count from the last filename.
count = int(files[-1][-7:-4])+1
# Save image to file
filename = os.path.join(DIR, FILE_PREFIX + '%03d.jpg.webp' % count)
# Capture the face
with picamera.PiCamera() as camera:
pic = camera.capture(filename)
# Sending mail
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = receiver
msg['Subject'] = 'Movement Detected'
body = 'Picture is Attached.'
msg.attach(MIMEText(body, 'plain'))
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= %s' % filename)
msg.attach(part)
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(sender, password)
text = msg.as_string()
server.sendmail(sender, receiver, text)
server.quit()
while True:
i = GPIO.input(11)
if i == 0: # When output from motion sensor is LOW
print "No intruders", i
sleep(0.3)
elif i == 1: # When output from motion sensor is HIGH
print "Intruder detected", i
send_mail()
После запуска программы, когда Raspberry Pi фиксирует движение, происходит следующее:
Объяснение кода
Рассмотрим, за что отвечает каждая часть программы. Вначале подключаем пакеты и модули, необходимые для данного проекта. Пакет GPIO обеспечивает управление контактами GPIO на Raspberry Pi. Пакет Picamera отвечает за работу с камерой Raspberry Pi, а пакет Smtplib позволяет настроить подключение к серверу Gmail.
import os
import glob
import picamera
import RPi.GPIO as GPIO
import smtplib
from time import sleep
Для отправки электронных писем с Raspberry Pi на Gmail потребуются четыре модуля:
from email.MIMEMultipart import MIMEMultipart
from email.MIMEText import MIMEText
from email.MIMEBase import MIMEBase
from email import encoders
Необходимо указать e-mail адрес получателя, а также адрес и пароль отправителя:
sender = 'example@gmail.com'
password = 'abcd1234'
receiver = 'example@gmail.com'
Далее задаем путь к каталогу и префикс файлов, куда будут сохраняться фотографии:
DIR = './Database/'
FILE_PREFIX = 'image'
Поскольку мы считываем выходной сигнал датчика, вывод 11 объявляется входным. Предупреждения GPIO при этом отключаются.
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.IN) # Считать вывод с датчика движения PIR (пассивный инфракрасный датчик)
Внутри функции send_mail() программа сначала проверяет, существует ли каталог для файлов; если его нет — создает. Затем определяет идентификатор последнего изображения и сохраняет новый снимок с очередным номером. После этого свежее изображение прикрепляется к письму и отправляется получателю.
def send_mail():
print 'Sending E-Mail'
# Create the directory if not exists
if not os.path.exists(DIR):
os.makedirs(DIR)
# Find the largest ID of existing images.
# Start new images after this ID value.
files = sorted(glob.glob(os.path.join(DIR, FILE_PREFIX + '[0-9][0-9][0-9].jpg.webp')))
count = 0
if len(files) > 0:
# Grab the count from the last filename.
count = int(files[-1][-7:-4])+1
# Save image to file
filename = os.path.join(DIR, FILE_PREFIX + '%03d.jpg.webp' % count)
# Capture the face
with picamera.PiCamera() as camera:
pic = camera.capture(filename)
# Sending mail
msg = MIMEMultipart()
msg['From'] = sender
msg['To'] = receiver
msg['Subject'] = 'Movement Detected'
body = 'Picture is Attached.'
msg.attach(MIMEText(body, 'plain'))
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= %s' % filename)
msg.attach(part)
server = smtplib.SMTP('smtp.gmail.com', 587)
server.starttls()
server.login(sender, password)
text = msg.as_string()
server.sendmail(sender, receiver, text)
server.quit()
В цикле while программа непрерывно опрашивает вывод 11, и при получении значения 1 вызывается функция send_mail() для отправки письма.
while True:
i = GPIO.input(11)
if i == 0: # When output from motion sensor is LOW
print "No intruders", i
sleep(0.3)
elif i == 1: # When output from motion sensor is HIGH
print "Intruder detected", i
send_mail()
На этом всё. Удачных проектов!