Pinterest Stumbleupon Whatsapp

The dream of any smart home enthusiast is a home you can talk to, but the reality is a long way off from that.

Amazon Echo, for instance, allows you to use any number of voice controlled features, but dialog must be initiated by you with a question – you can’t just have her announce an important message.

You can do this with a Sonos system though, and a bit of DIY Raspberry Pi magic. Today I’ll show you how to set up voice notifications on your Sonos system, introducing a couple of useful IFTTT recipes, OpenHAB integrations, and more, to make use of the notification feature.

Note that there is a native Sonos binding for OpenHAB available, but it’s known to cause memory issues due to a faulty uPnP library. I’d suggest skipping that for now, and using the method in this tutorial instead.

A Raspberry Pi running Raspian linux is ideal for this tutorial, but it should also work on any linux-based home server you have running. In this case, I’m using the same Raspberry Pi that runs OpenHAB, the open source home automation system Getting Started with OpenHAB Home Automation on Raspberry Pi Getting Started with OpenHAB Home Automation on Raspberry Pi OpenHAB is a mature, open source home automation platform that runs on a variety of hardware and is protocol agnostic, meaning it can connect to nearly any home automation hardware on the market today. Read More . The rest of this tutorial assumes you’re also running this on a Raspberry Pi, and either have a local terminal window open on the desktop, or are logged-in remotely using SSH Setting Up Your Raspberry Pi For Headless Use With SSH Setting Up Your Raspberry Pi For Headless Use With SSH The Raspberry Pi can accept SSH commands when connected to a local network (either by Ethernet or Wi-Fi), enabling you to easily set it up. The benefits of SSH go beyond upsetting the daily screening... Read More .

You’ll Need

  • Raspberry Pi 2 (older models should work, but check for specific changes in the instructions)
  • At least one Sonos speaker (other audio systems are not supported, this is a tutorial for Sonos only)
  • Free account at Register then find your API key, which we’ll need later to generate the voice messages.

Install Node Latest

Check which version of Node you have by typing:

node -v

Note that version 6 is not supported. If you have Node 6, you’ll to first remove it, then follow the instructions below to install v5.5. 

If you don’t have v5 or if you get a not found error, follow these instructions to install Node. The following command assumes a Raspberry Pi 2; for older models, use armv6l instead of armv7l.

tar -xvf node-v5.12.0-linux-armv7l.tar.gz
cd node-v5.12.0-linux-armv7l
sudo cp -R * /usr/local

Confirm again by typing:

node -v

And you should see v5.12 (or whatever the latest was that you downloaded).

Next, we have some Node modules to install. We also want the Node Package Manager.

sudo apt-get install npm
sudo npm install -g npm
sudo npm install -g node-gyp

That’s the pre-requisites out of the way, now onto the fun stuff.


The Sonos HTTP API creates a web server on the local network, which allows us to ping a URL with a message to announce on a Sonos (and to control it remotely if you want, though this tutorial focuses only on the voice notification aspect).

git clone sonos
cd sonos
npm install --production
npm start

If you see a message about such-and-such module not found, just do another npm install and the module name, then try npm start again. If you experience errors relating to “requires a C++11 compiler”, fix with the following commands:

sudo apt-get install gcc-4.8 g++-4.8
sudo update-alternatives --install/usr/bin/gccgcc/usr/bin/gcc-4.6 20
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.8 50
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.6 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.8 50

Eventually you should see something like this:

sonos-http-api working

The server is now running, interfacing with Sonos. The format of this API is easy:

http://[SERVER IP]:5005/[ROOM NAME]/[ACTION]

Or as a specific example:

The action we’re interested is the “say” command, used as follows:

You’ll hear an error message about having to register to an API key at You should have already done this, so type out the following and paste in your API key as appropirate:

nano settings.json



(Hit CTRL-X, Y, to save the file)

Restart the server, and ping the URL again. After a few seconds, you should hear a delightful English voice (though you change the end of the URL to en-us if you’d rather). To make the Sonos HTTP API server start again when the Pi is restarted:

sudo nano /etc/rc.local

Add a line before the exit 0:

sudo node /home/pi/sonos/server.js < /dev/null &

You now have the ability to create a voice message from anywhere on the local network simply by pinging a URL, so the possibilities are wide open at this point. If you’re struggling for ideas though, read on for a few useful notifications I’ve got set up.

OpenHAB Notifications on Events

Let’s take a simple example first: motion detection. This is a common use case for activating lights, but you might want a voice notification too if it’s a motion sensor in a low-traffic area, or perhaps as a forward warning that someone is coming up the garden path.

rule "Garden motion detected"
  Item Garden_Motion changed 
  var String message = "You have a visitor"

You should see how you can integrate these simple voice notifications into any of your rules, but let’s try something a little more complex.

Daily Weather Report from IFTTT to OpenHAB to Sonos

In this recipe, we’ll have Sonos announce a daily weather report at your prefered time.

You’ll need the My.OpenHAB binding enabled, since this creates a secure connection between your internal OpenHAB server and the external IFTTT service. Set that up if you haven’t already – you can refer to part 1 of our OpenHAB guide Getting Started with OpenHAB Home Automation on Raspberry Pi Getting Started with OpenHAB Home Automation on Raspberry Pi OpenHAB is a mature, open source home automation platform that runs on a variety of hardware and is protocol agnostic, meaning it can connect to nearly any home automation hardware on the market today. Read More for full instructions, otherwise I’ll assume you’ve already got it setup with persistence enabled for all items.

Next, create a new String item in your OpenHAB install, which will store the daily weather report. Before this is visible in the My.OpenHAB channel, we’ll need to initialize it with some default variable. Ping the following URL (change raspberrypi.local to your OpenHAB server, or just use it’s IP address, and Todays_Weather to whatever you named the String):


Log in to My.OpenHAB and check the Items list to ensure the variable has now been exported.

my openhab item export check

Back on IFTTT, create a new recipe, and use the Weather channel as the trigger at your preferred time of day. You’ll need to set your location first if you’ve never used it before.

Select My.OpenHAB as the action, and choose the Todays_Weather as the variable to update.

ifttt weather report

For now, just pick the next half hour slot for testing – you can update the recipe later once you know it’s working.

Sure enough, at the test time (in fact, a little before), I got today’s forecast updated successfully.

2016-02-27 10:28:01.689 [DEBUG] [o.o.i.m.i.MyOpenHABServiceImpl] - Received command Mostly Cloudy today! With a high of 7C and a low of 1C. Repeat. Conditions will be Mostly Cloudy today, with a high of 7C and a low of 1C. for item Todays_Weather
2016-02-27 10:28:01.697 [DEBUG] [o.o.i.m.i.MyOpenHABServiceImpl] - store(Todays_Weather), state = Mostly Cloudy today! With a high of 7C and a low of 1C. Repeat. Conditions will be Mostly Cloudy today, with a high of 7C and a low of 1C.

Next up, we need an OpenHAB rule to send this variable to the Sonos “say” URL. The following should do it:

rule "Announce daily weather report"
  Item Todays_Weather received update

This is simple enough: whenever the Todays_Weather variable is updated (which it will be, automatically, at 8am every day), ping the URL. We use encode(“UTF-8”) String function to make the sentence from IFTTT suitable for use in a URL. To manually test this part of the system, just use the OpenHAB HTTP API again:

http://raspberrypi.local:8080/CMD?Todays_Weather=Cloudy, with a chance of meatballs.

Connect to IFTTT Without OpenHAB, Using If-This-Then-Node

Finally, let’s look at how to connect from any IFTTT recipe without the OpenHAB intermediary. Instead, we’ll install another web server, and expose that to the open Internet. This is not without risk: any kind of open server is a security risk, but we’re mitigating this by not running a complete server stack, just a small specific service that only accepts certain commands in a safe JSON data packet format (so no SQL injection or authentication attacks will be possible). Once we’re done, you’ll have a public URL to which you can send messages from the IFTTT Maker channel.

Start by setting up one of the many free dynamic DNS services 5 Best Dynamic DNS Providers You Can Lookup for Free Today 5 Best Dynamic DNS Providers You Can Lookup for Free Today DynDNS was always a top mention when free dynamic DNSes were brought up. But now that it's gone, are there any good alternatives? There sure are. Read More out there – I recommend DuckDNS, specifically because it gives a simple set of instructions for Raspberry Pi, enabling it to update your IP adddress automatically. Follow along with these, and remember your URL for the next steps. Your router may also have a dynamic DNS function built-in, so check there first. In my case, I can get a * URL for free, so I’ve used that.

Next, find your router’s port forwarding What Is Port Forwarding & How Can It Help Me? [MakeUseOf Explains] What Is Port Forwarding & How Can It Help Me? [MakeUseOf Explains] Do you cry a little inside when someone tells you there’s a port forwarding problem and that’s why your shiny new app won’t work? Your Xbox won’t let you play games, your torrent downloads refuse... Read More configuration page; this is where we’ll tell it what to do with incoming requests. Forward all HTTP requests (port 80) to port 1337 on your Raspberry Pi server. I’m assuming you’ve got a IP address reserved already for your Raspberry Pi – if you haven’t, check your router’s config page for reserved IPs while you’re in there, as you don’t it to change next week and for the server to suddenly stop working.

router config port forwarding

Now to install the last bit of server software.
cd if-this-then-node/
npm install
node server.js

You should see the following.

if this then node default values error

That’s ok, that just means we need to update our details. Open up config.js in Nano and edit those details to anything other than the default, then save. When you run the server again, you should see this:

if this then node server running

Great. Test your machine is accessible from the outside world by typing in your dynamic DNS hostname, and append /ifttn/ to the end of the URL. If everything works, the message “IFTTN – if-this-then-node Version 2.0.1 is up and running!” will be displayed in you browser. Again, to make this script run on start-up, edit the /etc/rc.local file and add:

sudo node /home/pi/if-this-then-node/server.js < /dev/null &

If-This-Then-Node works through plugins – there’s a few default ones supplied, but there aren’t of interest to us. Instead, download this custom plugin that I’ve written for you with the following commands.

cd plugins

You’ll also need to install the request module.

npm install request

Then restart the server. The plugin is quite simple, but a little different to the URL we’re used so far. In this case, I’ve used the special “sayall” action, which sends the message to every Sonos device.

request('http://localhost:5005/sayall/'+params.message+'/en-gb', function (error, response, body)

If you’d rather be able to target specific devices, replace that line with:

request('http://localhost:5005/'+params.device+'/say/'+params.message+'/en-gb', function (error, response, body)

Add another line parameter called device to the JSON request below in which to specify the Sonos device name.

To test this out, I’m using the IFTTT “Do” button app. Create a new recipe, browse to channels, and select the Maker channel.

do button

Create a new recipe. Enter in the URL you configured earlier from a free dynamic DNS provider (including /ifttn/ at the end of the URL. Don’t forget those slashes). Select POST request, application/json content, and the body of the message as follows, replacing all variables as needed with those you previously configured:

"message":"Incoming message for everyone: Dinner is ready! Repeat. Dinner is ready. Get your asses upstairs now." 

Now I have a readily accessible button that will announce the message on every Sonos device in the house. You can of course pair this with any IFTTT channel you want to make a custom message using variables from that channel. You should even be able to replicate the weather report from above without using OpenHAB now, though it did take the extra effort of installing another server.

Note: hackers will automatically scan you. This happens all the time, but if you’re viewing logs, it can seem alarming. Below you can see someone systematically tried to ascertain if any of the standard PHPMyAdmin interfaces were accessible. Which they weren’t. Don’t be alarmed if you see something similar. It’s the internet equivalent of cold calling random phone numbers to see if anyone’s there.

web server hack attempts

What Will You Announce?

You should now have the tools and kwowledge to constantly bathe your entire house in voice notifications about everything you could possibly think of. Who needs music? Your only limit is 350 daily requests from – but that’s about one every 4 minutes, so you should be alright.

So what will you do with this? Share your ideas or IFTTT recipe in the comments!

Image Credits:coffee and woman by S_Photo via Shutterstock

Leave a Reply

Your email address will not be published. Required fields are marked *