raspberry-pi-iot-cat-doorbell icon indicating copy to clipboard operation
raspberry-pi-iot-cat-doorbell copied to clipboard

A cat doorbell based on AWS IOT + Tensorflow

Table of Contents

  • Overview
  • Technical Description
  • High Level Design
  • Pictures
  • Prerequisites
  • Construction
  • Parts List
  • Hardware Notes
  • FAQ

Overview

This is a setup to alert me when our cat is meowing at the door and wants to be let in. If the door is closed, and the cat goes 'meow' while outside, then I get text message on my cell phone.

Technical Description

This is an Amazon Web Services (AWS) Internet of Things (IoT) application. A single Raspberry Pi is defined as a "thing" on AWS in the IoT Core service. AWS software is loaded on the Raspberry Pi which has an attached microphone. Onboard the Raspberry Pi is a small Machine Learning (ML) application called Tensorflow Lite. Along with Tensorflow, there is a small database of sounds it is able to identify. When the correct sound (in this case a cat meowing) is detected, the Tensorflow recognizes it and forwards a message to AWS. AWS IoT intercepts the message and sends the message to an AWS Lambda function for formatting. The Lambda function then forwards the message to an SNS (Simple Notification Service) topic which then sends it as an SMS text message to my cell phone.

High Level Design




Pictures


Here is the RPi attaching the USB connection to a USB-to-RJ45 connection. THe cable it attaches to is a standard cat5e cable.


This is the "doorbell" portion. It is situated outside next to the location where a cat is expected to be meowing for entry.


This is what is inside the box. Note the small microphone at the end of the USB-to-RJ45 connector.


These are holes drilled into the box to allow sound to be heard by the microphone.


The doorbell in use



Prerequisites

  1. An AWS (Amazon Web Services) account
  2. A Raspberry Pi 4 (see hardware parts listed below)
  3. Raspberry Pi imaging software

Construction

STEP 1: Raspberry Pi Initial Configuration

  1. Load the operating system. See the procedure here
    NOTE: Install the new 64-bit version of the operating system.

  2. SSH to your Raspberry Pi once you have it configured

  3. Clone a copy of this repository

    git clone https://github.com/gamename/raspberry-pi-iot-cat-doorbell.git
  1. Using Python, install the required packages
    cd ~/raspberry-pi-iot-cat-doorbell/raspberry_pi
    pip install -r requirements.txt
  1. Install the AWS CLI (Command Line Interface)
    pip install awscli
  1. Add this to the bottom of your shell startup file (.bashrc or .zshrc):
    export PATH=${HOME}/.local/bin:${PATH}
  1. Using your AWS account, create and install the access and secret keys as described here
    aws configure
  1. Verify you have everything configured by issuing this command (below). If you do not get any errors, you are configured correctly.
    aws s3 ls



STEP 2: AWS Configuration

NOTES:
- This cookbook assumes AWS region us-east-1
- Somtimes 'cat' is spelled 'kat' below. Ignore it. Always assume 'cat'. I had to do that to keep from conflicting with existing definitions.

  1. Create the "thing" definition on AWS by following the directions.
  2. When offered, select "Python" as the IoT SDK type
  3. Download the thing configuration zip file to the Raspberry Pi. Probably the easiest way to do this is:
    a. Download the zip file to your laptop. Do NOT unzip it

    b. sftp from your laptop to the RPi
    c. 'put' the thing configuration zip file to the Raspberry Pi from the laptop

  4. Unzip the file on the Raspberry Pi. It should look something like this:

  5. Continue following the directions and run the start.sh script.
  6. You should see test messages on AWS being sent from the start.sh script:

  7. Update the security policy by going here:

  8. Then edit your policy by selecting it on the left and hitting the "Edit" button:

  9. Click on the "JSON" button on the right, and you should see something like this:

  10. In the first "Resource" definition, you should add the following:
    "arn:aws:iot:us-east-1:<your-aws-id>:topic/<your-initials>/bot/kat-doorbell"
    
  11. In the second "Resource" definition, you should add this:
     "arn:aws:iot:us-east-1:<your-aws-id>:topicfilter/<your-initials>/bot/kat-doorbell"
    
  12. In the third "Resource" definition, you should add the following:
        "arn:aws:iot:us-east-1:<your-aws-id>:client/doorbell",
        "arn:aws:iot:us-east-1:<your-aws-id>:client/doorbell-test"
    
  13. The finished product should be:

  14. Save the finished product as the new version

  15. Now, click on the message routing rules

  16. Click on "Create Rule", then name your rule "kat_doorbell" and hit "Next"
  17. Set the SQL statement to the following:
    select message from '<your-initials>/bot/kat-doorbell' Where startswith(message, 'MSG002')
  18. Hit the "Next" button and choose "Lambda" from the fold-down list of actions
  19. Click on "Create Lambda Function"
  20. Name the function "kat-doorbell" and select Python as the runtime:
  21. Click on "Create Function"
  22. In the code IDE provided, paste the contents of the file cat-doorbell-msg-munger.py:

  23. Click the "Deploy" button.
  24. Now go back to the message routing tab. Click on the update circle button and then select the new lambda function from the list:

  25. Click on the "Next" button and click "Create" on the next page:

  26. Now, we need to create the Simple Notification Service (SNS) topic. This is used to pass messages to SMS for text messages.
  27. Go to SNS Topics.
  28. Create a new "standard" topic called "kat-doorbell":

  29. Now, copy the ARN of the topic:

  30. Go back to the lambda function "kat-doorbell".
  31. Click on "Configuration", then "Environment Variables":

  32. Edit the environment variables. Create a new one called "CAT_DOORBELL_SNS_TOPIC_ARN".

  33. Click on "Save"
  34. Next, we need to create a new phone number so that we can send SMS messages.

  35. On the provided screen, select the options shown below

  36. Go to SNS and add your new phone number:


  37. In SNS, create a new subscription:

  38. Next, we need to set permissions for us to send SNS messages.
  39. Go to the Identity and Access Management (IAM) page in AWS.
  40. Click on "Roles" on the left.

  41. In the search field, type in "kat-doorbell". You should get something like this:

  42. Click on the entry, and then click on the long policy name:

  43. Then, click on "Edit Policy":

  44. Replace the entire contents with this:
    {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Effect": "Allow",
                "Action": [
                    "logs:CreateLogGroup",
                    "logs:CreateLogStream",
                    "logs:PutLogEvents",
                    "SNS:Publish"
                ],
                "Resource": "*"
            }
        ]
    }
    
  45. Click on "Review" and then save the policy contents.



STEP 3: Test IoT Functionality

  1. Go to your IoT settings on AWS.
  2. Copy the "Endpoint" value:

  3. ssh to your Raspberry Pi and edit the raspberry-pi-iot-cat-doorbell/raspberry_pi/test/drive-doorbell-test.sh file:
  4. Paste the endpoint value in the --endpoint field and update the --topic field accordingly.
  5. Run the drive-doorbell-test.sh command. You should see the results on your cell phone. :)
  6. If you DO NOT see a message on your cell phone, look at the CloudWatch logs for clues about what went wrong.



STEP 4: Assembly

  1. Update the raspberry-pi-iot-cat-doorbell/raspberry_pi/start-doorbell.sh file like you did in STEP 3 (above).
  2. Now we will make sure the doorbell is active at boot time. To do that, update the Raspberry Pi file /etc/rc.local with this change:
sudo su -c "/home/your-id/raspberry-pi-iot-cat-doorbell/raspberry_pi/start-doorbell.sh" -s /bin/sh your-id 

Example:

#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
sudo su -c "/home/tennis/raspberry-pi-iot-cat-doorbell/raspberry_pi/start-doorbell.sh" -s /bin/sh tennis

exit 0
  1. Attach the USB-to-RJ45 adapter to one of the USB2.0 ports.
  2. Connect the RJ45 cable to the adapter and run it to your termination spot (i.e. where your cat will be yelling to be let in).
  3. Attach the RJ45-to-USB adapter to the other end of the RJ45 cable.
  4. Then attach the microphone to the USB connector.
  5. Test the whole thing by playing this video while holding your phone near the microphone.

Parts List

  1. Raspberry Pi 4
  2. Micro SD Card
  3. RPi Chassis
  4. Microphone
  5. RJ45 ethernet cable (to extend the USB connection)
  6. Raspberry Pi 4 power supply
  7. Hobby box (to house the microphone outside)
  8. silicone caulk
  9. Drill
  10. 1/4" drill bit
  11. RJ45-to-USB adapters
  12. 2 wood screws (to secure the microphone-in-a-box to the door frame)
  13. cable wire clips
  14. double-sided tape
  15. micro SD card reader (maybe not needed if your laptop already has a reader)
  16. RJ45 crimping tool
  17. Cord hiders



Hardware Notes

  1. Use the rj45/ethernet cable to extend the USB connection to the microphone. The USB-to-RJ45 adapters enable you to go up to about 150 feet from the RPi to the microphone.
  2. Since the rj45 needs to connect to the microphone inside the hobby box, I had to cut off the RJ45 adapter, run the cable into the box via a hole, then reattach a new RJ45 adapter. YMMV

FAQ

Q. How long does this take to set up?
A. Once you have all the parts - including the new phone number - you could probably do it in an afternoon


Q. Could this be used for a dog?
A. Yes. Change "Cat" on line 138 in doorbell.py to "Dog"


Q. Why didn't you do this using Terraform?
A. Terraform is an excellent tool, but not everyone knows how to use it. So, I opted for a manual approach to be accessible to a wider audience.


Q. Why did I use AWS for SMS instead of IFTTT or some other service?
A. I'm exploring AWS for lots of different services, so I wanted to try it this way instead.


Q. Why not just make your cat an indoor cat and avoid this whole problem?
A. Technically, he is and indoor cat. His name is "Milo", by the way. The outside area we let Milo roam is a gated back patio which lets him think he is really outside.


Q. What's the monthly cost of this configuration?
A. About $11.00 (including the toll-free number from Amazon)


Q. Do I really need a Raspberry Pi 4 for this?
A. Unfortunately, yes. Tensorflow requires it.


Q. Can the Amazon toll-free number be used for other IoT applications?
A. Yes, I have another project which does just that.


Q. What happens if you have multiple cats? Will this still work?
A. Yes. The Tensorflow library doesn't differentiate between different cats. A meow is a meow as far as its concerned. Ditto dogs and barks.


Q. Outside where my cat will be is pretty noisy. Will Tensorflow be able to discern the meow under those conditions?
A. We have a loud air conditioner and Tensorflow can still pick up the meow sound. So its likely you can still make it work. YMMV!