How to make a build notification box with Raspberry Pi
Have you always thought it might be fun to have something that plays a sound every time a build fails or a deployment completes? Having it on your local machine can be fun, but wouldn’t it be great if it was a device in its own right (maybe even hooked up to a display). In this article, I show how using a raspberry pi hooked up to some speakers, the cloud and some Node.js code to do exactly that. You can find the finished code over on GitHub here:
https://github.com/matthewbill/mdb-build-notification
This article is the write up of a talk, which was presented at the Norwich Node User Group. If you would like me to do a talk at one of your events, then please get in touch. The slides for this talk can be found here:
Build/Hacking Projects
Like with any kind of hacking project, we will end up learning a whole bunch of different skills along the way. In this article we will learn about the following topics:
- Raspberry Pi
- AWS CLI
- Test-to-speech (say)
- Web Hosting (express)
- Decoupled Event-Based Architectures (SQS)
- Node Bin Applications
- Event Processors
- CI/CD Tools
For this simple app, we decided to do it as part of a lunchtime project to help a new team member learn about node and AWS. These types of projects can be a great way to learn and have fun at the same time.
The Raspberry Pi
A small and affordable computer that you can use to learn programming
A Raspberry Pi is essentially a super cheap mini computer, which fits in your hand and can be hooked up to all kinds of electronics via a row of General-Purpose Input/Output Pins (GPIO). This is similar to another device called the arduino, which is definitely worth checking out at some point too. It can run Raspbian as its operating system, which is a Debian based os. Being Linux based, it can run all of the programming tools you might expect, including python and in our case, node.
You can pick up a Raspberry Pi starter kit, including the power cable and a memory card with Raspbian, pre-installed for £50 — £60 pounds. This makes it a fantastic little device to play around with any IoT or electronics ideas you might have. For us, we can hook it up to some speakers and play notifications out to the office with a simple node app.
You can, however, run the app in this article on your computer or any old computer laying around the office. This is the beauty of node being so cross-platform. If you plan to do this, then you can skip over the Raspberry Pi sections and straight to the ‘Playing Sounds’ section.
If you want to delve deeper into pi’s, then W3schools.com has a great tutorial on how to use a pi to its full potential and how to access the GPIO pins. You are only limited by your imagination on what you can build!
Raspberry Pi Bits
You will need the following bits for your Raspberry Pi to run our app:
- The pi itself
- Power cable
- Memory card installed with Raspbian
- HDMI Cable & Some kind of display
- [Optional] Speakers & audio cable, if not running the sound through HDMI
Installing Node
One of the first things we need to do is to install node on our pi. Being Linux based, you can install it using apt-get. Rather than go into the details in this article, w3schools.com already has an excellent step by step guide:
https://www.w3schools.com/nodejs/nodejs_raspberrypi.asp
You can find out more about installing node on different devices/os here:
https://nodejs.org/en/download/
Playing Sounds
One of the first things we need to set up is the ability for our app to play sounds. There are two main options for this, we can have re-recorded sounds or use ‘text-to-speech’. The text-to-speech approach will allow us to send any kind of message (such as the name of the app/deployment number), so we will go with this approach. Luckily for us, there is a nice little package called ‘say’, which will make use of whatever text-to-speech library is on the running operating system:
npm install say
If you are using windows or mac, you will automatically already have a text-to-speech library. If you are using Linux or in our case a Raspian, you will need to install festival.
sudo apt-get install festival festvox-kallpc16k
For now, we are just installing the one voice to get us up and running, but you might want to go back and explore others. We can add the following class, which will take in some text and play it for us using say.
If you try it on different operating systems, you will find that the windows and mac text-to-speech is definitely of a higher quality than its Linux counterpart. On Linux it sounds a little… robotic! 🤖🤖🤖
Note: Another option might be to use a cloud-based text to speech service, such as Amazon Polly. This would require additional complexity, network load and probably slow things down for our use case though. Let’s keep it simple, stupid (KISS).
Raspberry Pi Audio
Sometimes you might get problems with the audio on your Raspberry Pi. To check that it's working correctly, just play a simple youtube video. If there is no audio, it is most likely one of two things.
- The wrong output (HDMI/Analog) is selected to what you have plugged in.
- You are using HDMI and a little setup is required:
You will need to make a change to the config.txt file found in:
/boot/config.txt
Uncomment “hdmi_drive=2” inside of this file and save it. You can easily do this through the nano editor:
sudo nano /boot/config.txt
You will then need to reboot your pi
sudo reboot
Your pi should now be set up for playing sound out of HDMI.
Creating an Endpoint
Now we have our app playing some sound, we need a way of sending messages for it to annoy (*cough*.. I mean notify) our colleagues. One of the simplest ways we can do this is to set up an HTTP endpoint using express, which calls our sound player.
After starting this app, we can now navigate to our endpoint to send a message:
localhost:3000/say?message=Hello World
Now comes the fun bit, where you can give out the local network IP to people in your office and see what kind of messages they send to your team. Oh, but wait, the remote workers can’t send any messages and our build server isn’t even on our local network. We need a new cunning plan!
Decoupled Architecture
We need a way to send messages to our device from anywhere in the world. There are so many different ways in which this can be done, but it tends to come down to, you can either:
- push messages to our app
- poll some kind of endpoint to see if there are any messages to play.
As we want to keep our app simple and don’t want to pay for any kind of hosting (for using web sockets), we are going to go use the polling approach.
SQS
Enter AWS SQS or ‘Simple Queue Service’, a fully managed queue service by Amazon which allows you to send messages to one end of the queue and read those messages at the other end (similar to Rabit MQ). People from anywhere around the world can send messages to the queue and then our app can poll that queue to see if there are any messages to play.
To create a new SQS queue, just log into the AWS console and head over to the SQS section. Once there, create a standard queue with your chosen name and click Quick-Create Queue. After this has been created, you will be able to see it on your list of queues, along with the details of the queue’s URL (make a note of this now).
Configure AWS Credentials
Before we start talking to SQS, we will need to configure the AWS credentials on the computer which will be running our app. One of the easiest ways to do this is to use the AWS CLI. If this is your first time working with AWS, you can find out more about setting up credentials over at the AWS docs.
There are a number of different ways to install the AWS CLI, but for our pi, the easiest way is to use pip:
sudo pip install awscli
You can then make sure it has installed properly by running the following:
aws — version
To configure our credentials run the following command and input your Access/Secret key info:
aws configure
To find out more details on our to install the CLI, you can visit the AWS documentation here: https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html
The Processor
Now we have an SQS queue created and our local credentials are configured, we need to create a processor to run in the background to periodically check if there are any new messages. To simplify the code for demonstration purposes, we are calling a ‘messageService’ class, which handles all the communication with SQS.
When a new message is detected, we use the sound player we created earlier to play the message that comes through. We finally delete the message off of the queue, so we do not accidentally play the same message again. To delete the message, we use the receipt handle of the received message, which acts as a unique identifier. Finally, we set the process method to be called again after a specified poll delay.
Installation
So we have created our app locally and it is working great, but how do we install it on our pi. We could go for the approach of copying over the files and run it by pointing to the file… but this is a bit of a chore! Instead, we can take advantage of the bin section in the package.json.
This means, when this package is installed using npm install, it will automatically link the mdb-build-notification.js node script file to the mdb-build-notification command. If we publish our package to npm using the npm publish command, it will be available for anyone to install using the following command:
sudo npm install mdb-build-notification -g
The binary will now exist globally and we can run it as if it were like any other command in the command line.
mdb-build-notification {endpointUrl} {pollDelay}
This will start the application running for our SQS endpoint and it will now start playing any messages that are sent to your queue. The pollDelay is in ms.
Upgrading
With this approach, it is super easy to upgrade if you ever need to as well. Just append the @latest tag at the end to force the latest version to be installed.
sudo npm install mdb-build-notification@latest -g
Sending Messages
There are a number of different ways in which you can send messages to your SQS queue. You can log into the AWS console and send one through the GUI, use the AWS CLI (already used to configure credentials) or use the AWS SDK for JavaScript. For example, to send a message through the AWS CLI, just use the following command:
aws sqs send-message — queue-url {queueUrl} — message-body “Build Complete”
You can use the same command as a build step within your Travis/Jenkins/Circle CI/etc builds to send a message after your build fails or a deployment completes. You will obviously have to make sure your build server/container has AWS CLI installed and the credentials set.
Summary
This simple app is built and ready to use. You can get up and running with the following steps:
- Create an SQS queue in AWS
- Configure your AWS Credentials
- Install the app
sudo npm install mdb-build-notification -g - Run the app
mdb-build-notification {endpointUrl} {pollDelay} - Start sending build/deployment notifications
You are more than welcome to take the code and extend upon it for your own needs. Once again, the code can be found over on GitHub:
Please share with all your friends on social media and hit that clap button below to spread the word. Leave a response letting us know when you have your build notification tool up and running. 👏
If you liked this post, then please follow me and check out some of my other articles.
About
Matthew Bill is a passionate technical leader and agile enthusiast from the UK. He enjoys disrupting the status quo to bring about transformational change and technical excellence. With a strong technical background in Polyglot Software Engineering, he solves complex problems by using innovative solutions and excels in implementing strong DevOps cultures.
He is an active member of the tech community, writing articles, presenting talks, contributing to open source and co-founding the Norwich Node User Group. If you would like him to speak at one of your conferences or write a piece for your publication, then please get in touch.
Find out more about Matthew and his projects at matthewbill.gihthub.io.
Thanks for reading!