Используем камеру Raspberry Pi для отправки электронных писем

Схема подключения датчика движения к 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), следуя инструкции:

  1. Войдите в свой Gmail-аккаунт, используя логин и пароль.

  2. Кликните по аватару своего профиля, после чего выберите «Google account».

  3. В блоке «Вход и безопасность» (англ. - Sign-in and Security) перейдите к пункту «Подключенные приложения и сайты» (англ. - Connected apps and sites).

  4. Включите опцию «Разрешить менее безопасные приложения» (англ. - 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()

На этом всё. Удачных проектов!