Introduction: Birthday Text Reminder - RaspberryPi

I'm not great at remembering birthdays of friends and family. No matter how many ways I've tried... paper calendars (too manual), spreadsheets (not automated), social media (too...social media), I always end up forgetting to let the person I care about know that I also care about the day they came into the world.

Solution: get one of the 5 RaspberryPis I have doing various jobs to pick up my slack and send me a text the morning of my loved one's birthday. Simple.

Supplies

  1. Twilio trial account
  2. RaspberryPi connected to internet (I recommend this one - affiliate link, when the supply comes back...)
  3. Spreadsheet program of your choice (optionalish)
  4. About 20 minutes to invest in never forgetting another birthday again

Step 1: Twilio Trial Account Setup

Head over to twilio.com/try-twilio (disclosure: my referral link; you get credit, I get credit)

  1. Name, email address and password
  2. Confirm the email
  3. Confirm the phone number you'll be sending texts to
  4. Fill out a survey

Once you are at your dashboard:

1. Select 'Get Trial Number' - this will be the number that texts your 'verified' phone number

You will need two pieces of information from your dashboard to place in your code:

1. 'Account SID'

2. 'Auth Token'

BOOM! We are well on the way to impressing our friends and family with our amazing birthday remembering skillz.

Step 2: Pre-requisites for Your Pi

Not going to cover the basics of getting over to your RaspberryPi, so check this out if you need a boost:

https://magpi.raspberrypi.org/articles/ssh-remote-control-raspberry-pi

Once you are in (I use PuTTY), you will need to install a few dependencies.

For this app I use the following:

1. Twilio Python - for talking to our new trial account, more info:

pip install twilio  

or

easy_install twilio

2. Pandas - for really easy reading of files, doing some math, etc., more info:

pip install python-pandas

or

sudo apt-get install pandas

3. Samba (optional) - easy for me to just treat a folder on the RPi as a shared drive, more info:

sudo apt-get install samba samba-common-bin

Step 3: Samba Configuration (optionalish)

In order to easily get birthday information to the RaspberryPi I just use Samba to create a "share drive" folder that windows can see, so both the Python script and the Birthday list are really easy to access on my windows machine (assume would work similarly on a Mac).

Look, I realize that birthdays don't change much, you could very easily just dump the csv file with names and birthdays in a location and leave it alone. I chose this way because I end up editing / adding / removing birthdays I want to track a few times a year (new nieces/nephews, new friends, new anniversaries, etc). Choose what makes sense for you and your style! :)

If you installed (or already have) Samba installed, just need to tweak some configurations to enable a "shared drive" location.

In PuTTY,

First, create a shared location:

mkdir -p ~/share

Then edit the configuration:

sudo nano /etc/samba/smb.conf

Page down to the end of the file and add the following - many options, but these generally cause the least amount of problems with security on the windows side (so much more info):

[PiShare]
comment=Raspberry Pi Share
path=/home/pi/share
browseable=Yes
writeable=Yes
only guest=no
create mask=0777
directory mask=0777
public=Yes
Guest ok=Yes

Exit with save from Nano with:

CTRL-X, Y, ENTER

Restart the Samba service

sudo /etc/init.d/samba restart

Add permissions:

sudo chmod -R 777 ~/share

Step 4: Windows Network Location (optionalish)

Now that you have Samba all configured, you want to add a "shared drive" on the windows side.

  1. Check that you are in the same 'WORKGROUP' as the RaspberryPi. You can check this by hitting your windows button and just type "Workgroup", will come up with a list of options
  2. Next go to your network locations, make sure you have 'Network discovery enabled' and you should now see your RaspberryPi sitting there ready to do your work. If not, try a quick restart of your machine or quick google. You may have some unique securities settings.
  3. If all goes well, you should also see the folder "PiShare". Right-click and 'map network drive'; I chose 'P:' for obvious reasons. :)

You now have a "shared drive" to drop the files you need for this set-up. Plus, you can use this to share anything else that you want. I find it pretty useful for other things as well.

Drop the '.csv' and the '.py' files attached in this location. You can now open them up in the editor of your choice!

Step 5: Walk Through the Code

First section, importing all the stuff using - probably overkill, but the easiest way I would hack this stuff together

import pandas as pd #dataframes for easy / overkill math
import numpy as np #pandas dependency
from twilio.rest import Client #twilio python
import datetime as dt #get & manipulate dates & time
from dateutil.relativedelta import relativedelta #used to add a 'buffer' to the time
from sys import exit #used to exit if no birthday reminder to send


Next, time to set-up some parameters:

# Find these values at <a href="https://twilio.com/user/account"> https://twilio.com/user/account</a><br>account_sid = 'YOUR ACCOUNT SID FROM STEP 1'
auth_token = 'YOUR AUTHENTICATION TOKEN FROM STEP 1'
to_phone = 'PHONE NUMBER TO GET REMINDERS' #twilio registered phone number 
from_phone = 'PHONE NUMBER SENDIG REMIDERS' #twilio trial phone number
#change this to remind you X days in advance
remind_buffer = 0 #I like to know the day of
#create the twilio client
client = Client(account_sid, auth_token)


The next section in a nutshell, creates a dataframe ('birthdays') and starts hydrating it with various bits and bobs of dates from your birthday list and today's date. It will then use that information to check if any birthday in your list has the same day and same month (i.e. birthday today + buffer):

#current date + buffer<br>today = pd.to_datetime(dt.date.today() + relativedelta(days=+remind_buffer)) #could also be: weeks, months, etc.
#pull in the birthday list 
birthdays = pd.read_csv("/home/pi/share/Birthday.csv" parse_dates=['Birthday']) #/home/pi/share/
birthdays['Today'] = today
#get the current month
birthdays['date_Month'] = today
birthdays['date_Month'] = birthdays['date_Month'].dt.month
#get the current day
birthdays['date_Day'] = today
birthdays['date_Day'] = birthdays['date_Day'].dt.day
#get the current month
birthdays['bd_Month'] = birthdays['Birthday'].dt.month
birthdays['bd_Day'] = birthdays['Birthday'].dt.day
#compute the age
birthdays['age'] = (birthdays['Today'] - birthdays['Birthday']) / np.timedelta64(1,'Y')
birthdays['age'] = birthdays['age'].round(0).astype('int64')
#isloate the birthdays that have the same day and month, ignore the year
celebrate = birthdays.loc[(birthdays['bd_Month'] == birthdays['date_Month']) & (birthdays['bd_Day'] == birthdays['date_Day'])]
#how many items are on the list
count_day = len(celebrate.index)


Then wrap up with creating and sending the text message!

#grammer police<br>if count_day > 1:
    s = 's'
else:
    s = ''
	
if remind_buffer != 0:
	remind_words = ' in ' + str(remind_buffer) +' day(s)!'
else:
	remind_words = ' today! '
	
#if no items, then just end, nothing to do
if count_day == 0:
    exit()
elif count_day != 0: #item about to expire, go ahead and draft the text message
    week_body = str(count_day) + ' birthday' + s + ' - '
    
    for index, row in celebrate.iterrows():
     week_body = week_body + ' ' + row['Name'] + " is " + str(row['age']) + remind_words
#create the message to phone    
client.api.account.messages.create(
    to= to_phone,
    from_= from_phone,
    body=week_body)

Step 6: Schedule Your Script to Run in CRON

We are going to use CRON to run this script everyday (I run mine every day at 8:30AM).

CRON is extremely awesome for automation / recurring tasks. More info here. You can configure your reminder for whenever and how often you'd like. I really like this scheduler helper.

Before I set-up CRON on any new script, I always test the script first - head over to your file and run:

python birthday_monitor.py

If it executes without error, you are good to keep going. If not, take a look and make sure you have all your dependent libraries installed.

Then...

Start by heading back into your SSH session:

crontab -e

It may prompt you (if your first time to use cron) which editor to you, just choose Nano.

Next you'll see a TON of words - ignore them and page down to the bottom with your arrow down key.

Each uncommented row will be a different 'job'.

Add something similar to your file - basically, how often, what to use (python) and where the file lives (share):

30 8 * * * /user/bin/python3 /home/pi/share/birthday_monitor.py
CTRL-X

That's it. Now this python script should run on its own every day at 8:30am! #cronforthewin

Step 7: Relax, the Robot Does the Rest

If all goes well, the script will run at the scheduled time, check for birthdays and shoot you a text similar to the one pictured (I have it direct to a google voice account).

This structure can be used for any type of reminder, really. For example, I have another file and script that has a list of our emergency food storage expirations dates. When something is about to expire, it warns us a week or so in advance so we can use it and replace it. Has worked well since the snowpocalipse of 2021.

And just like that, you have the best "memory" of your whole family.

Your welcome.

Raspberry Pi Contest

Participated in the
Raspberry Pi Contest