Sonos Touchscreen Controller


A touchscreen controller for Sonos, using a Hyperpixel 4” touch LCD display and a Raspberry Pi Zero WH.

Using https://github.com/maru-sama/sonoscontroller.  Pi configuration based on http://www.weigu.lu/sb-computer/pitoucon/index.html, with mods for touch rotation.

Provides a full-time desktop display of what’s currently playing, along with basic control.

 


26 replies

It’s quite basic compared to Jivelite on piCorePlayer, but it’s written in Python with Kivy, using the Soco lib ( @pwt ), so should be fairly straightforward to improve, should someone want to spend time doing so. I have pretty much switched to LMS with the Material Skin and this Jivelite display, a FAR better experience overall than the Sonos controller, IMO. 

 

Userlevel 7
Badge +17

Hi @chicks 

Thanks for sharing!

Mucking around with the Kivy layout results in a much nicer UI. Pigpiod installed allows the screen backlight to be turned off in Python when nothing is playing, auto on when a track starts. It’s becoming useful. 

 

 

Kivy has a bit of a learning curve, but getting the hang of it.  Greatly improved UI.  

I used to use my CR-100 strictly as a monitor, to see what’s currently playing.  It was a clunky controller compared to the Sonos app (and especially compared to the LMS Material Skin), but it displayed what’s playing after the phone’s screen timed out.  FAR more convenient.  That’s the purpose of this, simply to display what’s playing, never blanking out until nothing is playing.  Automatically starts displaying when music starts playing again.  Simple, inexpensive.  Something Sonos ought to sell, and used to, with the CR-100 and -200.

 

So this isn’t a tablet, just  pi connect to an LCD screen?  Any reason you couldn’t set this with an HDMI input to a TV screen?

Well, a TV screen is WAY bigger than a 4” LCD, wouldn’t fit on my desktop, would consume lots more power, and isn’t touchscreen, so how would you select the speaker, or pause/start, etc?  But, if you can get around those limitations, yes, a Pi can use an HDMI display. 
 

This is a simple, fun, but highly useful project, to me at least.  It fills a niche need that Sonos abandoned.  

Size perspective. Sitting on a Sonos Play:1. 
 

 

As a quick test, switched to HDMI safe mode in the Pi Zero’s config.txt. Yes, it will display on an HDMI monitor. 
 

 

Userlevel 7
Badge +20

I like this.  A bigger touch screen monitor would be great to show off album art

Something like this maybe? :-

15.6 Inch Portable Monitor with Retractable Stand, IPS HDR 1080P External Monitor with Type C/HDMI

Albeit a bit expensive :(

 

Well, a TV screen is WAY bigger than a 4” LCD, wouldn’t fit on my desktop, would consume lots more power, and isn’t touchscreen, so how would you select the speaker, or pause/start, etc?  But, if you can get around those limitations, yes, a Pi can use an HDMI display. 
 

This is a simple, fun, but highly useful project, to me at least.  It fills a niche need that Sonos abandoned.  

 

My application is a bit different.  Not really looking for a controller. so much just a display of what’s currently playing in the zone the TV sits in.   Control can be done via voice or the sonos app, but it would be nice to just get a visual confirmation of what’s playing.  Ideally, the HDMI port on Amp/Beam/Arc could do this and would work perfectly, that’s not a feature currently, or one that seems to be highly requested.

You know, that might actually be a better use case.  Everyone has an old HDMI display tucked away.  Total cost would include a $10 Pi Zero W and a couple of cables.  I have no idea how to blank or power down an HDMI monitor in code, but I’m certain it’s possible.  Without a touchscreen, the zone to monitor would need to be set in a config file. 

Anyone here have the know-how to create a distro image?  I’m running Chrome OS, so don’t think I can create one.  It would greatly simplify configuration vs all the downloading and installing of Kivy, etc.

You know, that might actually be a better use case.  Everyone has an old HDMI display tucked away.  Total cost would include a $10 Pi Zero W and a couple of cables.  I have no idea how to blank or power down an HDMI monitor in code, but I’m certain it’s possible.  Without a touchscreen, the zone to monitor would need to be set in a config file. 

 

 

Can it work in reverse?  By that I mean that the Pi would get power from the TVs USB port, and thus would turn on whenever the TV is turned on. Not sure if Pi device boot up fast enough or will be damaged if they are consistently powered on/off.  I personally wouldn’t want the TV to turn on whenever I’m playing music in the space, but I would like to be able to turn on the TV, set to the right HDMI input, and go from there.

And while I’m dreaming, it would be very cool if the device could also be a passthrough for HDMI-ARC/eARC.  In that way, it can sit in between your Beam/Amp/Arc and the TV, and instead of showing a useless screensaver image, you can an image of what’s currently playing.  I doubt that’s a real possibility for a DIY project, but I might see if HD Fury is interested. Honestly, I can see myself paying up to around $100 for such a device, and would probably get multiple of them.

II can see this being rather useful for me personal.  I often want to know what’s currently playing without going to my phone and pulling up the Sonos app.  Having the TV on and playing to the right input would be so easy.  I’ve thought about seeing if I can do this with Amazon music through a fireTV and amazon music app, but doubt I could get that to work.  Besides, no way it could be as easy to use, and it would be limited to Amazon music only.

 

 

 

Userlevel 6
Badge +13

Very interesting project.

Something like this would be great for the O2 Joggler devices... 

So, with the little DSI LCD displays, Kivy updates the album cover images lickety-split.  Never an album cover that doesn’t load.  With an HDMI display attached, at least on the rather slow Pi Zero, only about one in ten album covers gets displayed, before Kivy appears to just give up.  May work with a multi-core processor like on the Pi 3 or 4, but not on the Zero.  I’m sticking with developing for the small screens for now.  It’s what Kivy’s meant for, after all.

SImplified this a good deal, dumped Kivy, now draws directly to the Pi’s framebuffer.  Published the Python code on github.

https://github.com/retired-guy/Sonos-Remote

 

 

Without the Kivy framework, this works nicely on a 24” HDMI monitor.  I’ll publish the modified app to GitHub after a few days’ testing. No touchscreen this way, obviously. 
 

 

 

Userlevel 7
Badge +20

Chicks, many thanks for sharing this. It’s will make for my 3rd pi project.  
Those pi’s are breeding like my Sonos system has!

 

Did the removal of Kivy help with the reliability of Album art display?

Thanks for doing all this work @chicks!  Will your code work on a windows machine as well as Pi? My knowledge around this stuff is pretty poor, but I seem to have heard that python will run on windows.

Chicks, many thanks for sharing this. It’s will make for my 3rd pi project.  
Those pi’s are breeding like my Sonos system has!

 

Did the removal of Kivy help with the reliability of Album art display?

Yes, it’s 100% reliable now.  Not sure whether Kivy or the SDL2 layer was causing the issue, but both are eliminated now, greatly simplifying the build process.

Thanks for doing all this work @chicks!  Will your code work on a windows machine as well as Pi? My knowledge around this stuff is pretty poor, but I seem to have heard that python will run on windows.

No, this is written for the Pi, specifically for the $10 Pi Zero W.

Will also require an HDMI adapter cable and a Micro SD card.

@chicks  I noticed that you’re using an IP address to identify the zone it’s tied to.  Can that be done by room name?  I  don’t have my IPs reserved, and not sure I can easily identify the zone I want by IP.  If not, I can do reservations and figure out the the correct zone  with the ‘guess and check’ method, but it would be much easier to just use the room name.

Or I could just look at Soco and figure it out myself I suppose. 

edit:

It looks like you can use:

 from soco.discovery import by_name zone = by_name("Living Room")

Is that right?

@chicks  I noticed that you’re using an IP address to identify the zone it’s tied to.  Can that be done by room name?  I  don’t have my IPs reserved, and not sure I can easily identify the zone I want by IP.  If not, I can do reservations and figure out the the correct zone  with the ‘guess and check’ method, but it would be much easier to just use the room name.

Or I could just look at Soco and figure it out myself I suppose. 

edit:

It looks like you can use:

 from soco.discovery import by_name zone = by_name("Living Room")

Is that right?

I’m not super familiar with SoCo, but that looks about right.  

Tried this on my large TV screen.  Works, but starts to get jaggy above about a 24” screen, as we’re rendering at 800X480.  

Some album covers were meant to be displayed full size. ;)

 

 

Quick test at Python cmd prompt:

>>> from soco.discovery import by_name
>>> zone = by_name("Office")
>>> zone
SoCo("192.168.68.128")
>>> 

 

So, looks good.

 

 

@chicks  I noticed that you’re using an IP address to identify the zone it’s tied to.  Can that be done by room name?  I  don’t have my IPs reserved, and not sure I can easily identify the zone I want by IP.  If not, I can do reservations and figure out the the correct zone  with the ‘guess and check’ method, but it would be much easier to just use the room name.

Or I could just look at Soco and figure it out myself I suppose. 

edit:

It looks like you can use:

 from soco.discovery import by_name zone = by_name("Living Room")

Is that right?

I’m not super familiar with SoCo, but that looks about right.  

Tried this on my large TV screen.  Works, but starts to get jaggy above about a 24” screen, as we’re rendering at 800X480.  

Some album covers were meant to be displayed full size. ;)

 

Thanks for testing out using the room name.  

I’ll be upfront and tell you that although I love this idea, I am not 100% sure I’m going to use your code just yet.  I need to understand Pi and python a bit more, which is probably a good idea and general.  From what I understand, I’ll probably find other good uses for that knowledge.  The other issue is that my use case is primarily on an outside TV, and I’m not sure I have a good way to protect the pi from the elements,.     Although if I can’t use it outside, I may just use it inside.

Regarding the album art, I have two thoughts on that.  One, can you limit/control the size of the image?  I would assume you can’t programmatically know the display size, but perhaps add a parameter, similar to room name, for the display size intended.  Glancing at the code, it does look like ‘w’ and ‘h’ variables could be adjusted for that.  Somewhat related to that, I’m wondering if you can modify this code so that it can output what’s currently playing in multiple zones.  Perhaps a check to see what zones are playing currently, and report on those zones only.  Maybe up to 4 zones shown in 4 quadrants. Not really suggesting you make those changes, just some things I might look into at some point.

 

Also, if using an HDMI screen/TV, it’s probably more convenient to power the Pi via USB port on the TV. Don’t need an extra outlet available and Pi would only get power when the TV is on.  Although it looks like the Pi Zero W sellers don’t recommend something like that due to unreliable voltage. Might be something I would try anyways.

 

 

 

I’ve posted the HDMI version to github, with complete installation notes. I don’t plan to modify this any further, but it’s out there to do with as you wish.  https://github.com/retired-guy/Sonos-HDMI

Reply