Raspberry Pi: Motion Detection with Email Notifications (Python)

In this project, you’ll learn how to send email notifications with the Raspberry Pi when it detects motion. We’ll program the Raspberry Pi using Python and to read from the PIR motion sensor we’ll use the gpiozero interface.

Raspberry Pi Motion Detection with Email Notifications Python

Table of Contents

Throughout this tutorial, we’ll cover the following main topics:

  1. Setting Up the Sender Email Account
  2. Wiring the Circuit (Raspberry Pi with PIR Motion Sensor)
  3. Motion Detector with Email Notifications – Python Script

Prerequisites

Before continuing with this tutorial, check the following prerequisites.

  1. Get familiar with the Raspberry Pi board—if you’re not familiar with the Raspberry Pi, you can read our Raspberry Pi Getting Started Guide here.
  2. You must know how to run and create Python files on your Raspberry Pi. We like to program our Raspberry Pi via SSH using an extension on VS Code. We have a detailed tutorial about that subject: Programming Raspberry Pi Remotely using VS Code (Remote-SSH).
  3. Know how to use the Raspberry Pi GPIOs so that you know how to wire the circuit properly. Read the following tutorial: Raspberry Pi Pinout Guide: How to use the Raspberry Pi GPIOs?

We also have tutorials about how to send emails and how to use a PIR motion sensor that you might want to follow first:

Project Overview

In this project, we’ll create a motion detector with email notifications. The project has the following features:

Raspberry Pi Motion Sensor with Email Notifications Circuit
  • When motion is detected, you’ll receive an alert message on your email account.
  • There’s a button in the circuit so that you can enable/disable the motion sensor. For example, turn it off when you’re in the room, and turn it on when you go out.
  • There’s an LED that indicates whether the motion sensor is active (LED on) or deactivated (LED off).

Setting Up the Sender Email Account

We recommend creating a new email account to send the emails to your main personal email address. Do not use your main personal email to send emails via a Python script. If something goes wrong in your code or if by mistake you make too many requests, you can be banned or have your account temporarily disabled.

We’ll use a newly created Gmail.com account to send the emails, but you can use any other email provider. The receiver email can be your personal email without any problem.

Create a Sender Email Account

Create a new email account for sending emails using a Python script. If you want to use a Gmail account, go to this link to create a new one.

Gmail Create a new account

Create an App Password

You need to create an app password so that new devices can send emails using your Gmail account. An App Password is a 16-digit passcode that gives a less secure app or device permission to access your Google Account. Learn more about sign-in with app passwords here.

An app password can only be used with accounts that have 2-step verification turned on.

  1. Open your Google Account.
  2. In the navigation panel, select Security.
  3. Under “Signing in to Google,” select 2-Step Verification > Get started.
  4. Follow the on-screen steps.

After enabling 2-step verification, you can create an app password.

  1. Open your Google Account.
  2. In the navigation panel, select Security.
  3. Under “Signing in to Google,” select App Passwords.

If you don’t find this option, use the search tool on that page and search for App passwords.

Create app password gmail
  1. In the Select app field, choose mail. For the device, select Other and give it a name, for example Raspberry Pi. Then, click on Generate. It will pop-up a window with a password that you’ll use on the Python script to send emails. Save that password (even though it says you won’t need to remember it) because you’ll need it later.
Generated App password gmail

Now, you should have an app password that you can use on your Python script to send emails.

If you’re using another email provider, check how to create an app password. You should be able to find the instructions with a quick Google search “your_email_provider + create app password”.

Raspberry Pi with PIR Motion Sensor – Wiring the Circuit

For this project, we’ll use the following components.

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

We’ll connect the LED to GPIO 14, the button to GPIO 4 and the PIR motion sensor to GPIO 18.

ComponentRaspberry Pi
LEDGPIO 14
ButtonGPIO 4
PIR Motion SensorGPIO 18
Raspberry Pi with PIR Motion Sensor Wiring the Circuit

Motion Detector with Email Notifications – Python Script

Create a new Python file called motion_email_notifications.py and copy the following code.

You need to insert your sender email details and the recipient email.

# Complete Project Details: https://RandomNerdTutorials.com/raspberry-pi-motion-email-python/

#import necessary libraries
from gpiozero import LED, Button, MotionSensor
import smtplib
from email.message import EmailMessage
from signal import pause
from time import sleep

#create objects to refer to the LED, the button, and the PIR sensor
led_status = LED(14)
button = Button(4)
pir = MotionSensor(18)

#replace the next three lines with your credentials
from_email_addr = "REPLACE_WITH_SENDER_EMAIL_ADDRESS"
from_email_password = "REPLACE_WITH_SENDER_APP_PASSWORD"
to_email_addr = "REPLACE_WIH_RECIPIENT_EMAIL_ADDRESS"
email_subject = "[WARNING!] Intruder Alert!"
email_body = "Motion was detected in your room!"

#control variables
motion_sensor_status = False
email_sent = False

#arm or disarm the PIR sensor
def arm_motion_sensor():
    global email_sent
    global motion_sensor_status

    if motion_sensor_status == True:
       motion_sensor_status = False
       led_status.off()
       print("Motion Sensor OFF")
    else:
        motion_sensor_status = True
        email_sent = False
        led_status.on()
        print("Motion Sensor ON")

#send email when motion is detected and the PIR sensor is armed
def send_email():
    global email_sent
    global motion_sensor_status

    if(motion_sensor_status == True and email_sent == False):
        print("Motion Detected")
        #create a message object
        msg = EmailMessage()
        #set the email body
        msg.set_content(email_body)
        #set sender and recipient
        msg['From'] = from_email_addr
        msg['To'] = to_email_addr
        #set your email subject
        msg['Subject'] = email_subject
        #connect to server and send email
        #edit this line with your provider's SMTP server details
        server = smtplib.SMTP('smtp.gmail.com', 587)
        #comment out this line if your provider doesn't use TLS
        server.starttls()
        server.login(from_email_addr, from_email_password)
        server.send_message(msg)
        server.quit()
        email_sent = True
        print('Email sent')
        sleep(5)
        email_sent = False

#assign a function that runs when the button is pressed
button.when_pressed = arm_motion_sensor

#assign a function that runs when motion is detected
pir.when_motion = send_email

pause()

View raw code

How the Code Works

Continue reading to learn how the code works and what changes you need to make to the script to make it work for you.

Importing libraries

You start by importing the LED, Button and MotionSensor components from the gpiozero library.

from gpiozero import LED, Button, MotionSensor

Then, import the libraries for SMTP and email-related functions.

import smtplib
from email.message import EmailMessage

You also import the pause and sleep methods to add timers to the code.

from signal import pause
from time import sleep

Creating the LED, Motion Sensor and Button Components

After importing the required libraries, we create gpiozero objects to refer to our electronic components. The LED is connected to GPIO 14, the Button to GPIO 4, and the MotionSensor to GPIO18. If you’re using different GPIOs, adjust the code accordingly.

#create objects to refer to the LED, the button, and the PIR sensor
led_status = LED(14)
button = Button(4)
pir = MotionSensor(18)

If you want to learn in more detail how to use those components, check the tutorials below:

Sender and Recipient Emails

Next, you create variables for the email address to send from, that email’s app password (it’s the APP PASSWORD, not the email password, see these instructions), and an email address to send to. As we’ve mentioned previously, we recommend using an email account that is not your primary account to send the emails.

#replace the next three lines with your credentials
from_email_addr = "REPLACE_WITH_SENDER_EMAIL_ADDRESS"
from_email_password = "REPLACE_WITH_SENDER_APP_PASSWORD"
to_email_addr = "REPLACE_WIH_RECIPIENT_EMAIL_ADDRESS"

Email Subject and Body

The email_subject and email_body variables, as the names suggest, save the email subject and body. You can change the content to whatever message is suitable for your project.

email_subject = "[WARNING!] Intruder Alert!"
email_body = "Motion was detected in your room!"

Control Variables

We create two control variables. The motion_sensor_status to know whether the motion sensor should be activated or not (we’ll change it with the press of a button). By default, it’s set to False.

motion_sensor_status = False

The email_sent variable controls whether a notification email was sent a few seconds before.

email_sent = False

Activate the motion sensor (function)

The arm_motion_sensor() function arms and disarms the motion sensor when you press the pushbutton. It also turns on and the off the LED so that you have a visual indication of whether the motion sensor is activated or not.

#arm or disarm the PIR sensor
def arm_motion_sensor():
    global email_sent
    global motion_sensor_status

    if motion_sensor_status == True:
       motion_sensor_status = False
       led_status.off()
       print("Motion Sensor OFF")
    else:
        motion_sensor_status = True
        email_sent = False
        led_status.on()
        print("Motion Sensor ON")

Send Email (function)

The send_email() function sends an email when the sensor detects motion, as long as the sensor is armed and the email_sent variable is equal to False.

#send email when motion is detected and the PIR sensor is armed
def send_email():
    global email_sent
    global motion_sensor_status

    if(motion_sensor_status == True and email_sent == False):
        print("Motion Detected")
        #create a message object
        msg = EmailMessage()
        #set the email body
        msg.set_content(email_body)
        #set sender and recipient
        msg['From'] = from_email_addr
        msg['To'] = to_email_addr
        #set your email subject
        msg['Subject'] = email_subject
        #connect to server and send email
        #edit this line with your provider's SMTP server details
        server = smtplib.SMTP('smtp.gmail.com', 587)
        #comment out this line if your provider doesn't use TLS
        server.starttls()
        server.login(from_email_addr, from_email_password)
        server.send_message(msg)
        server.quit()
        email_sent = True
        print('Email sent')
        sleep(5)
        email_sent = False

For more details about how to set up and send an email using a Python script, check this tutorial:

Assign Functions to Events

Last, assign functions to events: the arm_motion_sensor() function is called when the pushbutton is pressed, and the send_email() function is called when motion is detected.

#assign a function that runs when the button is pressed
button.when_pressed = arm_motion_sensor

#assign a function that runs when motion is detected
pir.when_motion = send_email

The pause() function at the end of the code keeps the script running for events to be detected.

pause()

Demonstration

Save your Python file. Then run it on your Raspberry Pi. Run the following command on the directory of your project file (use the name of your file):

python motion_email_notifications.py

After running the script, press the pushbutton to arm the motion sensor. The LED will light up.

Raspberry Pi Motion Sensor with Email Notifications - activate motion sensor

Then, you can test the sensor by moving your hand in front of it.

Raspberry Pi Motion Sensor with Notifications Testing the Circuit

After a few seconds, you should receive a new message on your email account.

Raspberry Pi Motion Sensor with Email Notifications - Receive email

Wrapping Up

In this project, you learned how to use a PIR motion sensor to send an email notification when motion is detected. You can trigger any other events when motion is detected besides sending an email or you can send other types of notifications like WhatsApp messages or SMS (you’ll need to use other services).

For example, you can add a piezo buzzer to your alarm circuit so that when motion is detected not only is an email sent but an alarm is also sounded—the gpiozero library comes with a component for piezzo buzzer.

You can also use a relay and a photoresistor to make a security nightlight that turns on only when movement is detected in the dark—the gpiozero library also comes with a component for a light sensor.

We hope you’ve found this tutorial useful. If you want to learn more about how to control electronics using the Raspberry Pi, check the following tutorials:



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Enjoyed this project? Stay updated by subscribing our newsletter!

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.