Alarm Polly - Create your own alarm messages with AWS Polly and Raspberry Pi

Demo of Alarm Polly, setting an alarm and hearing audio playback.

Summary: Want to wake up to a weather forecast, a random or selected article source and your own daily reminders? Using Raspberry Pi, Python, LAMP and AWS Polly + APIs of your choice, you can write your own custom alarm messages which are read aloud to you using text to speech synthesis(TTS).

Note: This is intended for intermediate audiences, though beginners can also piece the various components along to make this work. This tutorial assumes you are interested in this setup of having speakers that are on/ready to play when you wake up/set your alarm.

Also note, this is generally free, assuming you’re eligible for the AWS free tier which lasts for a year. What can potentially cost money is the text to speech translation part (if you’re not eligible/have already used your AWS Free tier)

The basic front-end interface

Github Repo

Conceptually how does it work?

The basic concept is that you can pass a 1500 character string or less to AWS Polly and you will get back an audio file. It’s a stream really but the synthesize.py script will turn it into a file and save it onto your Raspberry Pi.

You can then feed this synthesizer with random data, such as a weather forecast, a news article or a message to remind yourself about something.

Technically, how does it work?

A CRON job runs every minute, and the job performs a database(MySQL) lookup against a time string eg. 011520180345PM and also checks if this alarm has already been played. The check is partial for the day, so multiple alarms can be shown eg. 01152018% is a wildcard search for any alarms set for this particular day.

Then the PHP script ~/generate-text/index.php generates all of the text files to be synthesized by a Python script ~/alarmPolly/get-articles-parse-synth.py which has a fixed array of sources (expected text files) to synthesize. You can add whatever sources you like. However please note, that you have to setup the endpoints (what generates these text files). I’ve only included two scripts that generate a weather forecast based on Yahoo’s API, and a news article sample from News API.

Once the audio files have been created, a loop plays the audio files till there aren’t any left to play. After the file has been played, it is removed. When all files are done playing, a state handler is updated to prevent trying to play these non-existent files until the next alarm is triggered.

The code I’ve included in the Repo is practically complete. It took me about two days or so to make it. Most of this work (particularly the TTS part) I had done in the past already for another project. But I did make sure to do a basic rundown of the AWS CLI setup on a new Pi.

Setting up AWS CLI, brief overview

As mentioned this requires an AWS account to access their AWS Polly feature. You can try to find a voice that you like here on their live demo. This assumes you’re logged into your AWS account.

You’ll then want to create an IAM user. You can view and setup your IAM user here. Then grant this user AmazonPollyFullAccess. (I don’t know if you need the full access but that’s what I’m using). When you create your user, you should get to a point where you’re provided you access key id and secret key. Please note: that the secret key is only shown once. After that you’ll have to generate a new one.

Now we can move onto the Raspberry Pi configuration. This assumes you’ve SSH’d into your Pi and are staring at a terminal.

The following will need to be installed: python, python-pip, awscli, boto3 sdk

$pip install awscli — user — upgrade

(those are supposed to be double dashes)

Add a PATH for AWS command line command to work

$export PATH=~/.local/bin:$PATH

Install boto3

$pip install boto3

Configure your AWS credentials, note you will need your aws access key id, aws secret key, and your aws service’s region (something like us-west-1). When asked for output preference, I selected JSON.

By default the ~.aws/credentials user is set to [default] though in my case I used [adminuser] keep track of that if you see an error. This part shouldn’t affect your installation if you don’t change the user. I actually don’t even know why I did.

Your credentials file should look something like this:

[default]

aws_secret_access_key = your secret key

region = your region

aws_access_key_id = your access key id

The synthesizer requires pygame so you’ll want to install that.

$sudo apt-get install python-pygame

The basic test to make sure everything is working is to edit the synthesize.py script and call the synthesize_text function by passing in a file_name argument such as test.mp3 and some sample text to be parsed. Then running the command $python synthesize.py should result in an audio file generated and saved in the same folder.

The rest of the code is the front-end for the date picker and interface to select what article you want to be read and a reminder message that you want to set for yourself. The 1500 character limit mentioned before is addressed in the synthesize.py script which truncates the text if necessary.

About the GitHub repo

The directory structure assumes the following:

The front-end code installed in /var/www/html/alarm-polly

The back-end code instaleld in /home/pi/alarmPolly

That you have a LAMP stack running, can create the database alarm_polly (utf8_unicode_ci) and import the table scheduled_alarms.sql

You will need to edit the environment file .db-credentials which is what the PHP scripts use to access your MySQL database. You’ll need to add your db_username and db_password

Then you’ll need to add some personal info to a couple of the scripts relevant to yourself such as your city-state for the weather API endpoint and your News API key if you decide to use those sources.

The check-alarm.php script which CRON runs has an ip-dependent component, so you’ll have to add your local ip to that.

If I missed anything I apologize, this is quite a bit of info/setup.

The front end interface is basic/responsive to some degree. I did make sure to have a date check (not allow past dates to be scheduled).

The CRON job(s)

In your crontab, you will add two scripts that run in sequence just like this:

# check scheduled alarms
* * * * * /usr/bin/php /var/www/html/alarm-polly/php/check-alarm.php && /usr/bin/python /home/pi/alarmPolly/get-articles-parse-synth.py

Requirements

  • Raspberry Pi (preferably with audio output to avoid hardware work)
  • LAMP-stack with PHPMyAdmin (easier to import database table)
  • Knowledge of using the terminal (SSH) to communicate with your Raspberry Pi
  • Python

Dependencies

  • AWS CLI (used to authenticate your TTS request)
  • Python Boto3 SDK (used to interact with AWS Polly)
  • Pygame (play soundfiles)

Mentions

  • Thanks to Adafruit and their tutorial on how to have sound output from a Pi Zero’s GPIO pins. At the time I didn’t have a Pi that had an audio jack.
  • A bit of this code was found on Stack Overflow/MDN so thanks to them as well
  • Thanks to Yahoo’s Weather API and News API
  • AWS and their free year tier, been using S3, Polly, and EC2 so far

Documentation

Amazon CLI installation guide

Amazon Boto3 SDK installation guide

AWS CLI configuration guide

--

--

Software developer and general technology tinkerer

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store