Partlet

A Spotify wind-down routine for macOS

git clone https://code.vhata.net/sleepytime

Download: tar.gz ยท zip

Commit e7e4671cb99f, updated 2026-11-03T23:09:12-08:00

README.md7.4 KiB
sleepytime7.3 KiB

Sleepytime

A Spotify wind-down routine for macOS. The sleepytime Bash script uses launchd to start two playlists each night, then fade out and pause playback. It controls the Spotify desktop app through AppleScript.

Schedule

The current defaults, in the Mac's local time, are:

Time Cue Action
00:15 winddown Play the Wind Down playlist with repeat enabled.
00:45 bedtime Play the Bed Time playlist with repeat enabled.
01:00 fadeout Fade Spotify's volume to zero over 60 seconds, then pause.

The schedule runs daily. Playlist cues open Spotify in the background if needed and replace the current playback. The fade affects Spotify's own volume and restores its previous level after pausing. If Spotify is closed or not playing, the fade cue does nothing.

Cues have a 10-minute grace period after their scheduled time. A delayed cue outside that window is skipped, so waking the Mac much later does not start a missed playlist. The script does not arrange to wake the Mac.

Setup

You need macOS, the Spotify desktop app installed and signed in, and a logged-in graphical user session. The script uses macOS command-line tools; it requires no additional packages or Spotify API credentials.

  1. Keep this directory somewhere permanent. The installed jobs store the absolute path to the script.

  2. Edit the configuration near the top of sleepytime if you want different playlists, times, or fade settings (see below).

  3. From this directory, run a test while you can respond to a macOS permission prompt:

    ./sleepytime test
    

    This immediately starts the wind-down playlist through launchd. Allow the request to control Spotify if it appears. Check that playback starts and inspect the log output; the command returning alone does not prove the cue succeeded.

  4. Enable the nightly schedule:

    ./sleepytime on
    ./sleepytime status
    

Run these commands as your normal user, without sudo.

Configuration

Settings are constants near the top of sleepytime:

Setting Default Purpose
WINDDOWN_PLAYLIST spotify:playlist:37i9dQZF1FwRDZZVSbIBqz First playlist.
BEDTIME_PLAYLIST spotify:playlist:37i9dQZF1FwPghOHCcNTIB Second playlist.
WINDDOWN_AT 00:15 First playlist's start time.
BEDTIME_AT 00:45 Second playlist's start time.
FADEOUT_AT 01:00 Fade start time.
FADE_SECONDS 60 Fade duration in seconds.
GRACE_MINUTES 10 How late a scheduled cue may run.

Use 24-hour HH:MM times. These settings are edited in the script, rather than passed as command-line options or environment variables. Rerun ./sleepytime on after changing schedule times or moving the script to update the installed jobs.

Getting playlist URIs

If you already have playlists in mind, you can right-click on the playlist, go to "Share", and select "Copy link to playlist". Then take the ID after /playlist/, discard any query string beginning with ?, and prefix the ID with spotify:playlist:.

For example:

https://open.spotify.com/playlist/37i9dQZF1FwRDZZVSbIBqz?si=example
                         becomes
spotify:playlist:37i9dQZF1FwRDZZVSbIBqz

Paste that URI into WINDDOWN_PLAYLIST or BEDTIME_PLAYLIST, retaining the quotes.

Auto-creating playlists

If you would like fresh playlists generated every week, do the following:

The prompts used for this script are:

Late Night Wind Down

Mellow, warm music for the start of a late-night wind-down routine. Draw on artists and styles I already listen to, but only their calmest, slowest songs. Downtempo, soft acoustic, gentle electronic, slow jazz. Low energy, no loud choruses, no sudden drops or big builds, consistent volume from track to track. Vocals are fine if they're soft. Should feel familiar and comforting, like the evening is ending.

Pre-Sleep Minimal Ambient

Very quiet, slow ambient music for the time between finishing winding down and getting into bed. Mostly instrumental, no drums or percussion, no vocals, nothing with a strong beat or melody that grabs attention. Soft pads, gentle piano, slow drones, sparse textures. Noticeably calmer and emptier than a normal chill playlist. Consistent low volume throughout.

Commands

Run these from this directory:

Command Effect
./sleepytime on Write and load all three scheduled jobs, replacing previous definitions.
./sleepytime off Unload and remove all three scheduled jobs.
./sleepytime status Show whether each scheduled job is loaded and print the log path.
./sleepytime test [CUE] Run a cue immediately through a temporary launchd job; defaults to winddown.
./sleepytime cue CUE Run a cue directly, subject to its scheduled time and grace period.
./sleepytime cue CUE --force Run a cue directly regardless of the current time.

CUE must be winddown, bedtime, or fadeout. Both test and forced cues perform the real playback action. For example, ./sleepytime test fadeout fades and pauses whatever Spotify is currently playing.

off disables future scheduled cues; it does not pause Spotify or delete the log. Playlist cues enable repeat and do not restore the previous repeat setting.

Logs and troubleshooting

All scheduled and test cues write standard output and errors to:

~/Library/Logs/sleepytime.log

After the first test or scheduled run, follow the log with:

tail -f ~/Library/Logs/sleepytime.log

The three job files live at ~/Library/LaunchAgents/local.sleepytime.{winddown,bedtime,fadeout}.plist.