How To: A Spotify Alarm Clock for Raspberry Pi

Alarm clocks are the devil and I hate them. Sleeping is the best, and I don't know why we willingly ruin such a delightful activity with terrible auditory violence. But I'm here to tell you there's something else: a Spotify Alarm Clock.

If I'm being honest, one day I hope to awaken in the mornings like a prince of Zamunda. Some day...

Until then, I'm making do with what I have.


[note: I'm no longer using my Raspberry Pi as my music playing alarm clock. As such, these instructions are no longer being updated; hopefully they will be helpful for at least a few more years. A fellow Raspberry Pi Alarm Clock maker reached out with some additional notes they used to troubleshoot the project and get it working. That person's notes will immediately follow, with the original post continuing afterward. ~CK]


Notes from a fellow clock maker

1) I couldn't get things to work (mpc commands would just say 'Could not connect' or something like that) so I installed a fork of mopidy-spotify instead of using the main branch, because people on this thread suggested I should. Here's how I did it:

git clone git@github.com:BlackLight/mopidy-spotify.git
cd mopidy-spotify
git checkout fix/incompatible_playlists
[sudo] python2 setup.py build install

It's possible this made no difference at all, since I still had to fix a bunch more things afterwards so I can't actually tell if mopidy-spotify was responsible for my woes. But the discussion on the above linked thread suggests that Spotify playlists wouldn't have worked without using BlackLight's fork.

2) I deleted all Spotify playlists with unconventional characters because I saw some errors in mopidy-spotify related to weird characters (e.g. emojis etc.). Again, not sure if this actually helped.

3) The following step was definitely necessary: I added mopidy as a user to video group. Until I did that, everything up to and including the point of doing 'mopidy add someplaylistidhere' worked, but 'mpc play' never did - it immediately said mpd error: disconnected or similar.

https://github.com/mopidy/mopidy-spotify/issues/168

This is only a problem with running mopidy as a service via systemctl.

4) This step was also definitely necessary. I wasn't hearing any audio, but I knew from mpc that my Pi was playing it. I had to change audio settings in mopidy.conf (the version of it for mopidy as a service).

This thread showed me how:

https://discourse.mopidy.com/t/no-sound-coming-from-mopidy-on-raspberry-pi-not-on-musicbox/1585/16

Specifically, I added this to my mopidy.conf:

[audio]
mixer = none
#mixer_volume =
output = alsasink
#buffer_time =

The original post continues, starting here...

My previous waking routine was powered by an old smartphone[1] and an app that played locally stored music. My new and improved waking routine is powered by a Raspberry Pi, the Mopidy music server, and Spotify playlists.

All told, the process wasn't too difficult: I got it working in about 20 calendar days, tinkering with it every few days.

I wasn't able to find one resource that walked me through the entire project; however, there are sites that do an amazing job of explaining particular parts of the process. When appropriate, I'll send you off to those other sites so you can read their amazing work in its native space.

  1. Hardware and software I used
  2. Raspberry Pi assembly
  3. Installing Raspbian
  4. SSH access and basic configuration
  5. Sound Check: can your Pi produce sound?
  6. Install Mopidy and configure as service
  7. Mopidy-MPD extension
  8. Mopidy Check: does it run?
  9. Mopidy-Spotify extension
  10. Install mpc
  11. Sound Check: a Spotify playlist
  12. Create playlists, grab URIs
  13. A file that executes mpc commands
  14. More files that execute mpc commands
  15. Set the alarm: automation via crontab
  16. Updating Raspbian and your Raspberry Pi
  17. Parting Thoughts

Hardware and software I used

This isn't necessarily what you need to complete this project, just a list of the things that I happened to use for my particular setup.

Hardware

  • CanaKit Raspberry Pi 3 Complete Starter Kit - 32 GB Edition (Amazon Link)
  • Ethernet cable
  • Network router
  • Laptop with an SD slot[2]
  • SD to Micro SD converter
  • Old set of computer speakers

Software

Note: I set up and run my Raspberry Pi without a keyboard or monitor.

Raspberry Pi assembly

Unboxing and assembling your Raspberry Pi is fairly straight forward. The instructions included in the box worked decently for me, if I remember correctly.

Learn from my mistakes
There were, however, two things that were confusing:

  1. You'll get two tiny heat sinks in the package -- they go onto the main processor chip and the wifi chip.

    I knew, generally speaking, that heat sinks were for regulating heat. However, I'd never dealt with one up close and personal. As such, I wasn't exactly sure what to do with them.
  2. Getting the Raspberry Pi into the CanaKit case was a touch tricky. The case is rectangular; on one of the short sides, the corners have lips that cut diagonally across the corner. You need to slide the Raspberry Pi under those two lips. Once you do that, the rest of the Pi drops into place and the top should snap on quite nicely.

Installing Raspbian

These links will help:

The easiest way to install an OS on your Raspberry Pi is to use the Micro SD card that comes with the CanaKit Raspberry Pi.

I did not use the easy way.

The Raspberry Pi kit I grabbed came with a 32 GB Micro SD card, preloaded with NOOBS. NOOBS is an installer that installs Raspbian, a Linux distribution built for Raspberry Pi.[3] Certainly, using that card would have been an easy solution; I didn't touch it for a couple of reasons:

  1. You need a keyboard and monitor to install NOOBS, neither of which I was using.
  2. I wanted to keep that clean copy of NOOBS intact, just in case things went sideways. I figured, worst case scenario, I could always go to a friend's house and use their keyboard and monitor as a last resort.

So I grabbed another 32GB card and went about installing Raspbian.

There are a a couple of choices on the Raspbian download page; I grabbed Raspbian Lite. I believe the only difference between the two is that the Lite version doesn't have a GUI... you have to access it via SSH, which was fine for my purposes.

After you've downloaded a copy of Raspbian to your computer, you can go about installing it onto your Micro SD card.[4] Instructions for that can be found in the link at the top of this section. More detailed instructions can be found on Raspberry Pi's page for installing images.

I used Etcher to get Raspbian onto my Micro SD card, which was quick and easy. Once Etcher has done its part, the only thing left is enabling SSH within Raspbian.

By default, at least as of July 2017, Raspbian has SSH access disabled. To enable SSH access to your Raspberry Pi, place a file called "ssh" on the root of the card. You can find a nice picture, and further instructions, on this Hacker Noon post (Step 3). The file should be empty and should only be named "ssh" (no file extension).

At this point, you should be be able to eject the Micro SD card from your laptop and insert it into your Raspberry Pi. When you insert it, the label should face out/away from the Pi.
Micro-SD-direction-1

Finally, plug in your Ethernet cable, plug in the power, and your Pi should boot up in a few moments.

SSH access and basic configuration

In order to SSH into your Raspberry Pi, you'll need to know the IP address of your Pi. Once your Raspberry Pi is on and connected to your router, your router will assign it an IP address; you'll need to figure out what that address is.

Step 5 of the Hacker Noon post noted in the above section has a picture that may be helpful. Essentially, you'll want to:

  • Login to your router's admin area,
  • Poke around the DCHP section for an area that lists devices that are connected to your network. (I found my device in an area called Client List.)

Armed with its IP address, you can use SSH to access your Raspberry Pi. In a terminal window, type: ssh pi@<ip address>. For example: $ ssh pi@192.168.05.500.[5]

The default password is "raspberry"; you'll want to change it to something else. (If I'm remembering correctly, at some point I was prompted to change it.)

Once you have access to your Raspberry Pi, you'll want to do some basic configuration of Raspbian. Mopidy offers some good guidance for that part of the process.

Sound Check: can your Pi produce sound?

This is a great opportunity to check your Raspberry Pi's sound. Use $ aplay /usr/share/sounds/alsa/Front_Center.wav to see if sound is working, at all, on your Pi. Mopidy offers some additional documentation for testing and changing your audio settings, as well.

This is also a great opportunity to turn up the main volume of your Raspberry Pi.

An example of the command I use to control my Pi's main volume is:
$ amixer sset 'PCM' 75%

The PCM you see in the above command is text that may vary, depending on your set up. If you run $ amixer scontrols, your system should return some text. On my system, it returns: Simple mixer control 'PCM',0. If your system returns something other than PCM, you should try using that text in your command, instead. (Related Stack Exchange Post)

Personally, I have my main volume set to 100%. Later, you'll be able to control the music's volume via Mopidy's volume settings. If you ever want to see your current volume setting, $ amixer should return your current volume percentage, along with some other stats.

Install Mopidy and configure as service

To install Mopidy, you can follow the Mopidy documentation for Debian installs. Their four quick commands will get you up and running.

# wget -q -O - https://apt.mopidy.com/mopidy.gpg | sudo apt-key add -

# sudo wget -q -O /etc/apt/sources.list.d/mopidy.list https://apt.mopidy.com/jessie.list

# sudo apt-get update

# sudo apt-get install mopidy

The slightly tricker part is configuring Mopidy. It looks like I ran the command # mopidy[6] after installing the software, which would have created a basic configuration file. For the moment, let's just skip to the end; here is a complete configuration file:

[core]
cache_dir = /var/cache/mopidy
config_dir = /etc/mopidy
data_dir = /var/lib/mopidy

[logging]
config_file = /etc/mopidy/logging.conf
debug_file = /var/log/mopidy/mopidy-debug.log

[local]
media_dir = /var/lib/mopidy/media

[m3u]
playlists_dir = /var/lib/mopidy/playlists

[spotify]
username = my-spotify-alarm-account
password = tHePaSsWoRdIsPaSsWoRd
client_id = hexdata0-0000-0000-0000-000000000000
client_secret = alongstringofrandomcharactersasfarasicantell
private_session = true

[mpd]
enabled = true
hostname = 127.0.0.1
port = 6600
password =
max_connections = 20
connection_timeout = 60
zeroconf = Mopidy MPD server on $hostname
command_blacklist = listall,listallinfo
default_playlist_scheme = m3u

Since you want Mopidy to run on its own, without any direct interaction on our part, you need to set it up as a service. The configuration process differs, slightly, between service and non-service setups. As you're reading through the main set of instructions, you'll want to cross-reference that information with the running-Mopidy-as-a-service page. (I'd read the running-as-a-service page, first, honestly.)

The stand out differences are between service and non-service setups are:

  • The configuration file lives in a different place. When running Mopidy as a service, the configuration file is located at /etc/mopidy/mopidy.conf (instead of the user’s home directory).
  • When running commands that normally start with mopidy you'll use sudo mopidyctl instead.

Mopidy-MPD extension

Mopidy won't be taking commands from you, directly... you'll need a client to deliver those commands for you. The Mopidy-MPD extension, which is automatically installed with Mopidy, allows MPD clients to speak to Mopidy.

To activate the extension, add an [mpd] section to your configuration file. That section has already been added in the configuration file sample above. You can see Mopidy's original sample and additional information on Mopidy's MPD extension page.

Mopidy Check: does it run?

This is a good point to see if Mopidy is working at all.  Run # sudo systemctl enable mopidy to set Mopidy up to run as a service whenever your Pi boots up. Then run # sudo systemctl start mopidy to start Mopidy immediately. The command # sudo systemctl status mopidy will show green active text if everything is working well.

For more documentation and details, begin with the "Service management with systemd" section of Mopidy's "Running as a service" page.

Learn from my mistake
I had some trouble when I ran #sudo systemctl enable mopidy:

# sudo systemctl enable mopidy
Synchronizing state for mopidy.service with sysvinit using update-rc.d...
Executing /usr/sbin/update-rc.d mopidy defaults
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LC_PAPER = "en_US.UTF-8",
	LC_ADDRESS = "en_US.UTF-8",
	LC_MONETARY = "en_US.UTF-8",
	LC_NUMERIC = "en_US.UTF-8",
	LC_TELEPHONE = "en_US.UTF-8",
	LC_IDENTIFICATION = "en_US.UTF-8",
	LC_MEASUREMENT = "en_US.UTF-8",
	LC_TIME = "en_US.UTF-8",
	LC_NAME = "en_US.UTF-8",
	LANG = "en_GB.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to a fallback locale ("en_GB.UTF-8").

I followed the instructions on this Ubuntu Forums page, which fixed things.

# locale-gen en_US en_US.UTF-8 hu_HU hu_HU.UTF-8

# dpkg-reconfigure locales

Mopidy-Spotify extension

The Mopidy-Spotify extension will allow you to play music from Spotify. Installation and configuration instructions can by found on the Mopidy-Spotify GitHub page

Installing it is straight forward: # sudo apt-get install mopidy-spotify

You'll need to insert into the configuration file your own values for:

  • Username
  • Password
  • client_id
  • client_secret

Username and password should be easy enough. To get the client_id and client_secret, you can visit Mopidy's music service authentication page. Once you login and authenticate, the text in step 2...

[spotify]
client_id = ...client_id goes here...
client_secret = ...client_secret goes here...

...will update to actual data you should copy and place into your config file.

client_id = hexdata0-0000-0000-0000-000000000000
client_secret = alongstringofrandomcharactersasfarasicantell

That should be all you need to get the extension up-and-running. I took the step of setting private_session to true, because obviously. You'll probably need to stop and restart Mopidy, now that you've updated the config file:

sudo systemctl stop mopidy
sudo systemctl start mopidy

Install mpc

You'll need to grab an MPD client to talk to Mopidy. I'm using mpc, which has worked well.[7]

I didn't leave myself many notes about installing mpc, nor did I bookmark any websites. As you'll see in my warning below, I'm not exactly certain I remember/understand how everything unfolded.

That said, my command line history tells me I installed mpc as root ($ sudo -i) with # apt-get install mpc. When it's done, you can type # exit to leave the admin user and return to your normal user.[8]

Word of warning

It was around this stage of the installation process that I was trying to play a sample playlist from Spotify, just to see if things were working, and things were not working. I came back to it a few days later, and things were miraculously working: unfortunately, I wasn't sure what I did to get it working. I may have been formatting the Spotify URIs incorrectly, or using a URI for a playlist that no longer existed.

It's also possible that MPD was the culprit.

Essentially, Mopidy uses the MPD standard but doesn't use MPD. The frustratingly-close-in-spelling mpc is software that uses the MPD standard to talk to music servers. At some point I definitely, accidentally, installed MPD when I meant to type-and-install mpc, which I didn't notice right away. At some later point, I uninstalled MPD. Also, at some later point, playing music in Mopidy, using mpc, started working.

Which is to say: make sure you install mpc and not MPD. While I have no idea if that was actually the wrench in my works, if you're having troubles, you may want to investigate if you have MPD installed.

Sound Check: a Spotify playlist

In theory, you can play music, now. This post on the Mopidy discussion board got me started; for additional commands, check out the mpc man page.

If everything is working correctly, the following 4 commands should play music.

$ mpc volume 100
$ mpc clear
$ mpc add spotify:user:ckdsnx:playlist:6joSqHbjcQ1CtasAQX5BWj
$ mpc play

If you're trying to troubleshoot, run $ mpc -- that should give you the current status of Mopidy. If a song is playing, you'll see something like the following:

Dixie Chicks - Cowboy Take Me Away
[playing] #11/14   0:02/4:47 (0%)
volume:100%   repeat: off   random: on    single: off   consume: off

Learn from my mistakes

It took me a while to find an active Spotify playlist to test my system. The URI above --$ mpc add spotify:user:ckdsnx:playlist:6joSqHbjcQ1CtasAQX5BWj -- links to a playlist on the CKDSN account and works as of:

  • 2017-09-16
  • 2017-09-24

Create playlists, grab URIs

I set up my own playlists for my alarm; you can do the same, or grab playlists that already exist. (I believe I read somewhere that playing playlists works much better than playing artists or albums.[9])

To convert a Spotify URI to the format that mpc uses, replace all / with : and start with spotify instead of *.spotify.com.

For example:
https://open.spotify.com/user/ckdsnx/playlist/6joSqHbjcQ1CtasAQX5BWj
becomes
spotify:user:ckdsnx:playlist:6joSqHbjcQ1CtasAQX5BWj

Finding a playlist's Spotify URI should be as easy as visiting the playlist via Spotify's web player. Otherwise, you should be able to "Copy Playlist link" from any given playlist's menu options.

Learn from my mistake
I'm not sure any song additions or subtractions I've made since Mopidy first accessed my playlists have been updated with Mopidy. In my tests, it certainly didn't happen immediately; it's possible that eventually everything syncs and it just takes a while.

You may want to make sure you have a playlist completely set before you have Mopidy play it for the first time. Worst case scenario: you can recreate the playlist in a new playlist, including any edits, and use that new playlist's URI.

A file that executes mpc commands

Now that you have your Raspberry Pi using mpc to control Mopidy to play Spotify playlists, let's create an executable file that will run those mpc commands.

This article from the Association of College and Research Libraries, a division of the American Library Association, helped me get started.

Create an empty file: $ > MyTestAlarmFile

Make that file an executable file: $ chmod +x MyTestAlarmFile

Run $ ls and Raspbian will list your current directory's contents, with any executable files listed in bold green. You should see your newly created file.

Run $ nano MyTestAlarmFile to open the file in the Nano text editor. A complete file is as simple as this:

#!/bin/bash

mpc clear
mpc add spotify:user:ckdsnx:playlist:6joSqHbjcQ1CtasAQX5BWj
mpc play

It's important to start with #!/bin/bash so Raspbian knows how to interpret what follows. With the rest of the file, you can type out the same commands you used earlier to play a test playlist.

Ctrl+O to save; Ctrl+X to exit.

Now, let's run the file and play our testing playlist again: $ ./MyTestAlarmFile.[10]

More files that execute mpc commands

At this point, you'll want to set up your own series of files that meet your particular needs, so you can play the right tunes at the right time. In my case that includes:

  • A file that plays spa music when it's time to go to bed; another file that stops the spa music when I'm asleep
  • A file that plays Gregorian chants in the morning; another file that slowly increases the music's volume
  • A file that plays a British Invasion playlist when I really need to get up

Examples:

A file that plays a playlist.

#!/bin/bash

mpc clear
mpc random on
mpc volume 10
mpc add spotify:user:ckdsnx:playlist:6joSqHbjcQ1CtasAQX5BWj
mpc play

A file that slowly increases the music's volume

#!/bin/bash

mpc volume 20
sleep 30

mpc volume 30
sleep 30

mpc volume 40
sleep 30

mpc volume 50
sleep 30

mpc volume 60

A file that stops the music and resets the volume

#!/bin/bash

mpc stop
mpc clear
mpc volume 10

Set the alarm: automation via crontab

The final step is automating the process using a crontab file. These crontab instructions at How-To Geek do a great job of walking you through the process.

To access your crontab file, run $ crontab -e. Here's an example of what you might include in your crontab file:[11]

# weekday mornings 1st alarm, with volume increase
43 6 * * 1-5 ./VolumeToZero
44 6 * * 1-5 ./WeekdayAlarm
45 6 * * 1-5 ./SlowVolumeIncrease

# all nights, on at 10pm off at 3am
0 22 * * * ./SpaTunes
0 3 * * * ./StopTheMusic

  • 43 6 tells the system what time to execute the command -- 6:43 am in this case.[12]
  • (* *) tells the system to execute every date of a month and all months of the year.
  • (1-5) tells the system to execute Monday through Friday
  • ./SlowVolumeIncrease tells the system which file to execute.

After you setup your crontab file to execute the appropriate files at the appropriate time,[13] your Raspberry Pi Spotify alarm clock should be complete!

Command line Raspberry Pi updates

[2018-01-01 update]
Doing system updates via the command line is quite easy.


$ sudo apt-get update
$ sudo apt-get upgrade

Once that runs, take a look through the resultant list and enter y if you want to upgrade everything. For good measure, I ran sudo apt-get autoremove, at the system's prompting.

To double check your work, run $ sudo apt-get upgrade one last time, and you should get something resembling the following, letting you know there's nothing to upgrade:

Reading package lists... Done
Building dependency tree        
Reading state information... Done
Calculating upgrade... Done
0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Parting Thoughts

Here are some final thoughts and a list of the sources I used for this project.

Audio Hiss
When I first set up my system, I had a weird audio hiss. There are a number of proposed solutions on the internet -- the solution that worked for me is on @superjamie's GitHub page: set audio_pwm_mode=2 in /boot/config.txt.

Set your levels
It took me a while to find the right volume levels for all of my playlists. If I were doing it again, I think I would figure out which playlist needs the most amplification, set it at mpc volume 100, and then set my real world speakers at an appropriate volume. From there, the playlists that need less amplification can have mpc volume levels that are <100%.

Volume reset on reboot
I believe the volume on your Raspberry Pi's main mixer resets with each reboot. To address that issue, I setup another executable file and crontab instruction that automatically sets my main volume on reboot.

In your executable file, you can use this:

#!/bin/bash
amixer sset 'PCM' 100%

Then in your crontab, you can add the following:

#on boot, automatically set ALSA volume to 100%
@reboot ./RebootVolumeSet

Wifi
At the moment, I'm hardwired into my router. I had some trouble setting up wifi on my Raspberry Pi and decided to continue with the ethernet cable and push ahead with the rest of the project. It wasn't mission critical and I can always come back to it.

List of Links
Here's a list of links I found helpful, in someway, during this project.


  1. My first smartphone, actually... an LG Lucid ↩︎

  2. I'm running Linux, guessing Windows or Apple machines work as well. ↩︎

  3. Which is also prepackaged on the SD card (as far as I can tell). ↩︎

  4. You're not installing the OS so much as you're placing it fully formed onto the Micro SD card. (aka "flashing the file") ↩︎

  5. If a command starts with a $, that means you're running it as a normal user. If it starts with a #, that means you're running it as a root/administrative user. There may be some commands that I ran as root that would work equally well (or better) as a normal user. ↩︎

  6. A note that will make sense in a second: I ran just "mopidy" and not "mopidyctl" ↩︎

  7. If you'd like to try something else, Mopidy has some recommendations. ↩︎

  8. At a certain point in this long process, the Raspbian/Mopidy instructions say you should be a root user for a certain group of commands. I can't tell if I intentionally installed mpc as root, or if I just happened to still be in root when I did the install. (Nor do I know, at the moment, if it makes a difference.) ↩︎

  9. Artists and albums may not work at all, actually. ↩︎

  10. I know there's a way to run the file without using ./ -- this AskUbuntu post has a link that should help. ↩︎

  11. I reset my volume often, just to make sure I don't accidentally scare myself awake. ↩︎

  12. Astute readers will notice I have the commands separate by a minute; I don't know that this is necessary. I'm guessing if I set them all for the same time, they would run sequentially. That said, I personally sleep better separating them by a minute instead of potentially generating an error, or having the music start really loud, a split second before the volume reset, etc. ↩︎

  13. It might be a good idea to run some tests, before you rely on this as your primary alarm clock. e.g. Set up your crontab to play and stop a playlist every 5 minutes, just to make sure everything works how you expect it to. ↩︎