Hacking a Mopidy media player.

The aim is to have a number of buttons that can control the player. Main functions are:

  1. Stop/Start player.
  2. Next/Previous track
  3. Volume up/Down
  4. Select Genre. The RFID tag will select the genre.
  5. Scroll through Albums from those available.
  6. Play an album.
  7. Control display
  8. … Lots more.

Pirate Audio software gives a start, but I need to reverse engineer it to see how it works. First question is where is it located? How is it built? There is a lot of good documentation on the Mopidy site, but lacks the file locations I need to get my head round.

Only one hit for sudo find / -name rotencoder.py shows this location. Here are the relevant folders:

/usr/local/lib/python3.9/dist-packages/mopidy
/usr/local/lib/python3.9/dist-packages/mopidy_raspberry_gpio/
/usr/local/lib/python3.9/dist-packages/mopidy_irisĀ 
/usr/local/lib/python3.9/dist-packages/mopidy_local
/usr/local/lib/python3.9/dist-packages/mopidy_pidi 
/usr/local/lib/python3.9/dist-packages/musicbrainzngs
/usr/local/lib/python3.9/dist-packages/pidi_display_pil
/usr/local/lib/python3.9/dist-packages/pidi_display_st7789
/usr/local/lib/python3.9/dist-packages/uritools

Make the files easier to remote edit:

sudo su

find /etc/mopidy -exec chmod o+w {} \;

find /usr/local/lib/python3.9/dist-packages/mopidy_raspberry_gpio/  -exec chmod o+w {} \;

find /usr/local/lib/python3.9/dist-packages/mopidy_irisĀ   -exec chmod o+w {} \;

find /usr/local/lib/python3.9/dist-packages/mopidy_local /usr/local/lib/python3.9 -exec chmod o+w {} \;

find /usr/locallib/python3.9/dist-packages/mopidy_pidi -exec chmod o+w {} \;

find /usr/local/lib/python3.9/dist-packages/musicbrainzngs  -exec chmod o+w {} \;

find /usr/local/lib/python3.9/dist-packages/pidi_display_pil  -exec chmod o+w {} \;

find /usr/local/lib/python3.9/dist-packages/pidi_display_st7789  -exec chmod o+w {} \;

find /usr/localfind /lib/python3.9/dist-packages/uritools -exec chmod o+w {} \;

find /etc/mopidy -exec chmod o+w {} \;

Looking at the Pirate Audio installer script. It does the following:

  • Modify /etc/modipy/modpi.cont
  • Installs the following python libraries:
    • python3-rpi.gpio- Extensions for GPIO
    • python3-spidev- Extensions for the SPI interface used by display
    • python3-pip- PIP installer
    • python3-pil- Package installer for Python.
    • python3-numpy- Package for dealing with arrays.
    • libopenjp2-7 – JPEG and JPG200 image library.
    • Enables SPI interface
    • Modifies config.txt for GPIO pins and the DAC.
    • Installs Mopidy and spotify plugins.
    • Installs and updates modpi_iris for image display.
    • Installs plugins for Pirate Audio:
      • Mopidy-PiDi
      • Mopidy-Local
      • pidi-display-pil
      • pidi-display-st7789
      • mopidy-raspberry-gpio
      • mopidy_iris
    • Modifies the mopidy config file to configure the various modules:
      • raspberry-gpio – define pin mappings
      • file – specify where to find music files
      • pidi – specify display controller
      • mpd – music player daemon on local machine.
      • http – web server interface
      • audio – output audio device & volume
      • spotify – connection details

So now I start to see what is needed. I need:

  • mopidy_raspberry_gpio
    Replace with mopidy_Chronos to map the IR to mopidy commands .
  • modipy local

 

Display is handled

 

 

IR detection with Raspberry Pi

Previous post showed how I stripped down a Pure Chronos CD/Radio and showed how the various buttons on the chassis were transmitted to the motherboard as a pseudo IR signal. Now its time to decode the signal on the Raspberry PI.

This article seems to be reasonably up to date:

https://www.digikey.co.uk/en/maker/blogs/2021/how-to-send-and-receive-ir-signals-with-a-raspberry-pi

Here is the circuit they use:

First step is to edit /boot/config.txt to specify the IO pins I am reading IR signal on GPIO pin 19.

dtoverlay=gpio-ir,gpio_pin=19 # for receiving data
##dtoverlay=gpio-ir-tx,gpio_pin=26 # for sending commands

Reboot:

sudo reboot now

Install some helper libraries:

sudo apt update
sudo apt install ir-keytable

Test:
This command will read IR reciever and print parsed commands.

sudo ir-keytable -c -p all -t

Investigate if this fails when you send some signals. After fixing incorrect wiring, I get something like this:

pi@raspberrypiMP3:~ $ sudo ir-keytable -c -p all -t
Old keytable cleared
Protocols changed to unknown other lirc rc-5 rc-5-sz jvc sony nec sanyo mce_kbd rc-6 sharp xmp cec imon rc-mm
Loaded BPF protocol xbox-dvd
Testing events. Please, press CTRL-C to abort.
246.860112: lirc protocol(nec): scancode = 0x8099
246.860168: event type EV_MSC(0x04): scancode = 0x8099
246.860168: event type EV_SYN(0x00).
246.920145: lirc protocol(nec): scancode = 0x8099 repeat
246.920207: event type EV_MSC(0x04): scancode = 0x8099

Yea, I can now read the various button presses from the Chronos chassis and read them with the RP. I could go further ans install the main lirc library, but enough for now. Time to reassemble the hardware and try to hack the music player software. Not sure if I will require LIRC as I dont need to translate the keycodes, but it may be helpful to get the data into the player software.

Install lirc for the main library:

sudo apt install lirc


Edit the configuration file so set the sensor up as a device:

sudo nano /etc/lirc/lirc_options.conf
... and add...
driver = default
device = /dev/lirc0

Reboot and test:

sudo systemctl stop lircd.service
sudo mode2 -d /dev/lirc0

… and so it goes on…