Sonos Command Line Controller Available (Python soco-cli)


Userlevel 7
Badge +20
  • Virtuoso
  • 1873 replies

I’ve created a simple command line control program for Sonos, implemented in Python. I find it very useful for creating a variety of Sonos control scripts (e.g., using cron to run scripts at specific times), and sometimes just for quickly controlling my Sonos systems when I don’t want to start the app.

It works with S1, S2, and split Sonos systems, and it should run on any OS that supports Python 3.

If you’re comfortable using Python and the command line, you may find it useful, too. It’s quite powerful, with a wide range of control actions, yet simple to install and use.

GitHubhttps://github.com/avantrec/soco-cli

PyPihttps://pypi.org/project/soco-cli

This is an early release, so expect some bugs and limitations. I’d welcome your feedback and suggestions.


55 replies

Userlevel 7
Badge +20

@pwt Very nice piece of software!

When using the http-api-server, I am not able to add a sharelink (e.g. the one you provided in the docs: https://music.apple.com/dk/album/black-velvet/217502930?i=217503142)

http://api.example.com:8000/Dachgeschoss/sharelink/https%3A%2F%2Fmusic.apple.com%2Fdk%2Falbum%2Fblack-velvet%2F217502930%3Fi%3D217503142

Always returns { "detail": "Not Found" }

Defect raised at: https://github.com/avantrec/soco-cli/issues/38

Fixed in v0.4.51.

Userlevel 7
Badge +20

@pwt Very nice piece of software!

When using the http-api-server, I am not able to add a sharelink (e.g. the one you provided in the docs: https://music.apple.com/dk/album/black-velvet/217502930?i=217503142)

http://api.example.com:8000/Dachgeschoss/sharelink/https%3A%2F%2Fmusic.apple.com%2Fdk%2Falbum%2Fblack-velvet%2F217502930%3Fi%3D217503142

Always returns { "detail": "Not Found" }

Defect raised at: https://github.com/avantrec/soco-cli/issues/38

@pwt Very nice piece of software!

When using the http-api-server, I am not able to add a sharelink (e.g. the one you provided in the docs: https://music.apple.com/dk/album/black-velvet/217502930?i=217503142)

http://api.example.com:8000/Dachgeschoss/sharelink/https%3A%2F%2Fmusic.apple.com%2Fdk%2Falbum%2Fblack-velvet%2F217502930%3Fi%3D217503142

Always returns { "detail": "Not Found" }

What am I doing wrong? Do I need to encode the link or somehow escape it?

Regards
Christian

 

Userlevel 7
Badge +20

For anyone using SoCo-CLI’s HTTP API server feature, I’ve now added the ability to parameterise macros. This is quite a powerful feature and is available in v0.4.38 and later. The details are in the documentation at:

https://github.com/avantrec/soco-cli/blob/master/README.md#macro-arguments

Any questions or problems, just let me know ...

Awesome PWT!  This is great.  Thank you.

Userlevel 7
Badge +20

The HTTP API Server macro feature is now released as part of SoCo-CLI v0.4.34. @FlipLewis , this should satisfy your doorbell use case.

Documentation is at:

https://github.com/avantrec/soco-cli/blob/master/README.md#macros-defining-custom-http-api-server-actions

Feedback welcome, and let me know of any issues (ideally over at the GitHub site, not here).

Userlevel 7
Badge +20

The HTTP server doesn’t currently accept sequential actions. I’ll have a think about how to add this, but it’s not particularly simple.

I’ve now added a ‘macros’ feature that allows one to define custom actions and sequences of actions to be executed by the HTTP API server. For example, for this use case one might define a ‘doorbell’ macro:

http://192.168.xx.xx:8000/macro/doorbell

This would invoke the necessary sequence of actions, defined in a local macros file at the server end.

I’ve implemented the feature and I’ll release it later today once it’s documented.

Userlevel 7
Badge +20

I’m glad you’re finding SoCo-CLI useful. Thanks for the feedback.

The HTTP server doesn’t currently accept sequential actions. I’ll have a think about how to add this, but it’s not particularly simple.

So, as you’ve noted, three separate calls to the web server are required (as below).

http://192.168.xx.xx:8000/Pool/party_mode
http://192.168.xx.xx:8000/Pool/play_file/Law-and-order-sound.mp3
http://192.168.xx.xx:8000/Pool/ungroup_all

Right now, to perform this in one go via an HTTP call, you’d need to run your own simple web server with one or more GET paths that invoke the sonos sequential action lists that you require. This is not particularly hard to do, but does require a bit of know-how.

First let me say great work @pwt on putting this all together.  It’s been very helpful.  

So I have 99% of this figured out, but am stuck on the last step of running a script from on the webserver I hope someone can help with a recommendation / advice.

Background:  I have configured a doorbell to chime the sonos speakers that is called via the API webserver.  I do all this using Container on my QNAP NAS and running the sonos-http-api-server.  That way I have a dedicated machine always waiting for a command.

A sample call would look something like this:

http://192.168.xx.xx:8000/Pool/play_file/Law-and-order-sound.mp3

So this is the same as sonos Pool play_file Law-and-order-sound.mp3 in Python.   

Pretty cool, it plays the Law and Order sound on my Sonos Speaker called Pool.  The problem i have is that I need to play the sound on all the speakers in the house.

So example would be:

sonos Pool group Garage : sp2 group Garage : Garage play_File Law-and-order-sound.mp3 : Garage ungroup

 

I just need to know how to call something like that from the Web Server.  Should I do a bash command to run a script?  Should I execute a python script to get it to work?   

Any advice or help would be appreciated.

 

Userlevel 7
Badge +20

FYI: SoCo-CLI v0.4.26 adds the ability to enable/disable subs and surround speakers.

Note to those upgrading: upgrade SoCo as well, to v0.25.0. (I forgot to update the version dependency before I made the release).

I’m currently working on a nice Plex integration, now that SoCo has a Plex plugin. More details once it’s released.

Userlevel 7
Badge +20

SoCo-CLI v0.4.18 adds the ability to play share links from Deezer. Share links can refer to tracks, albums or playlists, which are added to the Sonos queue. This feature is considered experimental and feedback is welcome.

Example:

> sonos Kitchen sharelink “https://www.deezer.com/en/playlist/5390258182”
> sonos Kitchen play_from_queue

Documentationhttps://github.com/avantrec/soco-cli#spotify-tidal-and-deezer-share-links 

Userlevel 7
Badge +20

SoCo-CLI v0.4.10 does a more comprehensive job of listing information when using the track, track_follow and track_follow_compact actions.

For example, radio streams will now show the Channel and Radio Show metadata (where present), Audio Books will show Author, Chapter, etc., and Podcasts will show the Podcast Series Title and Release Date.

Suggestions and feedback welcome, as always!

Userlevel 7
Badge +20

SoCo-CLI v0.4.4 introduces the ability to play share links from Spotify and Tidal. This feature is considered experimental for the time being, and feedback on your experience is welcome.

Example:

sonos Kitchen sharelink "https://open.spotify.com/track/6cpcorzV5cmVjBsuAXq4wD"
sonos Kitchen play_from_queue

Documentationhttps://github.com/avantrec/soco-cli#spotify-and-tidal-share-links

Fantastic,

used it to stereo pair a Five with a Play:5 gen2. 

Works great!

Userlevel 7
Badge +20

SoCo-CLI version 0.4.0 introduces an HTTP REST API server mode.

This means that SoCo-CLI can be run as an HTTP server, responding to HTTP GET requests by performing actions on your Sonos system. This is useful for some automation scenarios; the functionality is similar to that offered by the node-sonos-http-api application.

More details at: https://github.com/avantrec/soco-cli/blob/v0.4.0/README.md#the-soco-cli-http-api

Userlevel 7
Badge +20

SoCo-CLI versions 0.3.45+ introduce support for the track_follow action. This will print out the currently playing track, and each subsequent track when the track changes. e.g.:

(soco-cli) pwt@pwt-mba ~ % sonos study track_follow     

Album: Takk...
Artist: Sigur Rós
Duration: 0:04:30
Position: 30
Title: Hoppípolla

Album: OK Computer
Artist: Radiohead
Duration: 0:04:27
Position: 31
Title: Exit Music (For A Film)

Album: Heaven or Las Vegas
Artist: Cocteau Twins
Duration: 0:04:58
Position: 32
Title: Heaven or Las Vegas

Playback is stopped or paused

Album: Heaven or Las Vegas
Artist: Cocteau Twins
Duration: 0:04:58
Position: 32
Title: Heaven or Las Vegas

...

track_follow is available in both command line and interactive modes.

Userlevel 7
Badge +20

SoCo-CLI version 0.3.43 introduces support for imported local library playlists.

There are new actions to list library playlists, list the tracks in a library playlist, and to add a library playlist to the queue:

  • list_library_playlists or llp
  • list_library_playlist_tracks <playlist_name> or llpt
  • add_library_playlist_to_queue <playlist_name> or alpq

The actions operate in the same way as the existing ones for Sonos playlists.

Userlevel 7
Badge +20

FYI, folks: SoCo-CLI version 0.3.40 introduces the ability to snooze playing alarms, e.g.:

sonos bedroom snooze_alarm 10       <-- Snoozes for 10 mins
sonos bedroom snooze alarm 30m <-- Snoozes for 30 mins
sonos bedroom snooze_alarm 01:20:00 <-- Snoozes for 1hr 20 mins

Support for alarms management is now quite comprehensive: see the documentation at:

https://github.com/avantrec/soco-cli#alarms

Userlevel 7
Badge +20

I am getting a 

Error: 1: list index out of range | 2: list index out of range 

when I run

sonos -l office play_favourite_number 28

The number is valid - I run 

sonos -l office list_favs

to verify and I get back 40 items.

You may want to take this discussion over to GitHub (https://github.com/avantrec/soco-cli/issues), where it’s generally easier to work on issues.

Either way, (A) could you provide the output of the following:

  1. sonos -v
  2. sonos -l office play_favourite number 28 --log=info

(B) Could you try ‘play_favourite’ using the favourite name instead of its number, and report whether this works.

(C) What type of favourite are you trying to play?

(D) Is it only #28 that fails, or is it a problem across all favourite numbers.

(It may be worth noting that not all Sonos Favourites are playable using SoCo-CLI; e.g., single tracks from Spotify will work, but not albums. That’s not the problem you’re seeing, however.)

Thanks!

I am getting a 

Error: 1: list index out of range | 2: list index out of range 

when I run

sonos -l office play_favourite_number 28

The number is valid - I run 

sonos -l office list_favs

to verify and I get back 40 items.

 

 

 

Userlevel 7
Badge +20

The most concise way to find a speaker’s current state is to use the state action, i.e.:

sonos -l office state

I’ve now moved the details of the state action to a more sensible section of the documentation:

https://github.com/avantrec/soco-cli/blob/v0.3.37/README.md#speaker-and-sonos-system-information

  • state (or statusplayback): Returns the current playback state for the speaker, one of: PAUSED_PLAYBACKPLAYINGSTOPPED, or TRANSITIONING.

In the next SoCo-CLI release, I’ll modify the info and sysinfo actions so they correctly report the state of slave speakers.

This change is now released in SoCo-CLI v0.3.37.

Userlevel 7
Badge +20

The info action isn’t redirected to the group coordinator, so it just dumps the data for the target speaker. When a speaker is a slave in a group, Sonos doesn’t bother to keep the playback state correct.

In the next SoCo-CLI release, I’ll modify the info and sysinfo actions so they correctly report the state of slave speakers.

Userlevel 7
Badge +20

What is the best way to find if a speaker is playing something already? I tried sonos -l office info and then grep’ing for PLAYING but grouped speakers return PLAYING even if they are not (?)

The most concise way to find a speaker’s current state is to use the state action, i.e.:

sonos -l office state

This will return a short description of the player state, and if directed at a slave speaker in a group it will be redirected to report the state of the group coordinator. The track action also reports playback state, along with details of what’s playing.

The info action isn’t redirected to the group coordinator, so it just dumps the data for the target speaker. When a speaker is a slave in a group, Sonos doesn’t bother to keep the playback state correct.

What is the best way to find if a speaker is playing something already? I tried sonos -l office info and then grep’ing for PLAYING but grouped speakers return PLAYING even if they are not (?)

Amazing utility! I’ve incorporated it into the Apple Home app via Homebridge with buttons to play a certain radio station and another for power nap - pause music, set a once only alarm, resume. A cron’ed job groups certain rooms. Command line rules!

Reply