[Pirate Audio] Extending 'raspberry-gpio' Mopidy plugin

Hi folks,

I’ve bought a Pi Zero W and Pirate Audio line-out to build a simple Mopidy-spotify powered music box for my daughter (6).

I did this previously with a Pi1B, using python scripts calling out to MPC, with reasonable success, tho in use it was a little fragile. With the Pi1B having died, I’m starting again and hoping to deliver something better.

So, I’ve setup the pi+hat successfully per the guide, Iris works (tho won’t be used in day to day use). Can confirm quality of the audio output is far superior to using the onboard equipment on the Pi1.

I’ve connected the boards with wire rather than the headers, so that I can break out to larger buttons on the case.

So far, so good.

What I’m struggling with is modifying the raspberry-gpio plugin.

I’d like to add a button handler to the extension, to select between Spotify playlists. Each press it should empty the queue and load the next playlist on a list.

I probably also need to add an ‘on start’ method, to load an initial playlist on power-up.

However, my experimentation thus far has been… Unsuccessful. Reading the Mopidy API guide, and guessing as to how that would translate into Python had resulted in a non-functional plugin, and I can’t find any helpful examples to crib from.

Anyone with experience of the Mopidy API in Python who can advise, with suggestions, example code, etc - I’d be absolutely delighted to receive it! I shall continue to experiment in the meanwhile!

I can’t help you with the Modipy stuff, but I can pass on what I did to add my own buttons to my Pirate Radio setup. I put a ProtoZero on a stacking header between my Pi Zero W and pHat Beat.

Then wired my mini arcade buttons to the Proto Zero. My buttons just do the default stuff, play pause volume up down etc.
DSCF1063

1 Like

Actually, that’s a much better method than my mass of wire. I’ll look into it, thanks.

Can’t ‘go into production’ until I solve the Mopidy bit tho :)

I lucked out in that the pHat Beat buttons go to dedicated GPIO pins.


All I had to do was wire my buttons to those pins and set it up so they ground that pin when pressed. Easy peasy.

I hope you get yours sorted, there are some smart people here on the forums. Sometimes you just have to be patient to get an answer back though. Its hit or miss sometimes.

EDIT: Have a look at this, might help with some of the buttons. The A, B, X and Y are mapped out to GPIO pins.

Yep, same for the Pirate Audio, plus spare pins for additional buttons should I need them (I don’t immediately).

The default software approach by the Pimoroni folks (everything as Mopidy extensions) is really well thought through, if only I could work out how to extend the extensions.

If/When i do. I’ll post a GitHub of my mods.

Ah, Ha!

Kids out at a party today, so a little time to experiment, and I’ve had some success. For anyone looking to do the same in future, here’s the approach.

Editing the python scripts for mopidy_raspberry_gpio

Edit ‘pinconfig.py’ - and add names for each capability you want to add to the pluging to the ValidList structure (e.g. for me i’ve added ‘default_playlist’ and ‘next_playlist’).

Edit ‘frontend.py’ - and add a function for each name you added to ValidList in ‘pinconfig.py’ using the naming scheme handler_ (e.g. for me I added ‘handler_default_playlist’ and ‘handler_next_playlist’.

Each function should then hold the code you need to execute to achieve the goal. I was doing this bit right on Friday, just didn’t get the pinconfig.py piece, which meant the plugin was failing to load.

Here, for example, is my current default_playlist function (it’ll change before it goes into production):

def handle_default(self):
    self.core.tracklist.clear()
    self.core.tracklist.add(uris=["spotify:playlist:4kL4uW0nggy4oPXWpA1U4t"]
    self.core.playback.play()

Everyting from here is just standard python coding. Delighted!

Next job, once i’m happy with these edits, is going to be modifying the other pirate audio provided plugin, for the screen, as I won’t need a volume display (powered speakers have their own volume control).

G.

Really nice work. A handy addition.

1 Like

I’ve completed my modification of the GPIO plugin now.

Plugging in and hitting play once it’s finished starting up will get you a default spotify playlist, a button on pin 20 (prev volume up) will rotate through a list of spotify playlists (provided in a text file), otherwise Play/Pause and Skip Track remain unchanged.

First real experience of Python as an Object Oriented language - bit of a learning curve, not sure I particularly like it in that mode.

Made a start on the graphic display side now. FWIW, the Mopidy-PiDi plugin is more complex than the GPIO one, as in addition to the Mopidy-PiDI plugin, there are a few other Python libraries in play here, each of which one needs to get to grips with to understand and modify the setup.

Progress thus far, for any future reader trying to do similar:

  • I’ve changed the ‘not running’ text from the URL of the Web-GUI, to a friendly welcome message - keeping Iris in place, against my daughter getting older and wanting greater direct control. I’ve also installed and configured raspotify allowing you to target the device in her room from Spotify on the phone, minor config change required to use the Pirate Audio DAC to achieve that.
  • I’ve removed the volume bar easily enough (simply commented out a few lines so far, but I have a ToDo list item to see if i can hand that real-estate over to the text display to allow for larger fonts, or see below).
  • I can see where it’s doing the alpha-blend for the Play/Pause piece - this is something I want to retain, but may look into making the icon larger and moving its location, as it’s the only icon I really want to retain on the screen.
  • I haven’t, yet, located where it’s adding the ‘skip track’ or ‘volume’ icon - neither of these are desirable on the screen when your’e not using the buttons on the Pirate Audio board. Current guess is they’re done at the ‘Album Artwork Load’ phase (as, unlike Play/Pause, they’re static), but ran out of time to really step through, locate and digest that piece of the code.

Of-course, if anyone reading has experience in this codebase, I’d love to hear from you!