SOMA Connect + shairport-sync

I’ve reorganized my bedroom and as part of it I decided to finally address the ongoing issues with my audio setup in there. I have an old AirPort Express which I was using as an AirPlay receiver so that I could play music and podcasts and such on the (rather nice) hi-fi speakers, but it’s been super unreliable as of late, and even when it does remain connected, it generates random popping noises on the speakers — not great when I’m trying to sleep!

So anyway I was looking up various aftermarket AirPlay receivers, and most of them are pretty expensive, but then I realized that there’s probably a way of receiving AirPlay on a Raspberry Pi, and yes, there is, and then just as I was about to look for used Raspberry Pis to install this on, I remembered I already have a Raspberry Pi, in my bedroom, in the very same nightstand I would be putting a new one in: because I have SOMA’s older smart shades which use a rebadged Raspberry Pi as their Bluetooth-to-HomeKit bridge.

And the SOMA Connect image is just running Linux (specifically Rasbian 10) and some proprietary software.

First attempt

Originally I just rooted the SOMA Connect (which isn’t hard to do, SOMA even provides instructions) and tried building shairport-sync for it. But even though the Pi came with a 16GB SD card, the SOMA Connect image limits it to only 2GB for some reason. So, I expanded the partition to 16GB and also cleaned up a bunch of stuff, and went through the shairport build and install process. Which went okay, but I couldn’t get iTunes to connect to it.

So I tried rebooting… and the device wouldn’t come back up.

Part of the build instructions involved doing an apt update && apt upgrade which would normally be okay but this is actually something I’d run into before with this device and hadn’t thought about: the latest Rasbian kernel causes SOMA Connect to fail to boot. Oops.

So I took a different tactic.

The correct(?) approach

First, I used the Raspberry Pi Imager to build a stock image for the SOMA Connect (Pi 3, enable ssh + audio), and then flashed it onto the SD.

Then I installed shairport-sync from apt (as it’s a current-enough version), and… iTunes was unable to play to it, although it could connect.

I did a lot of debugging steps (including using mpg123 to play audio directly from the command line, which worked fine) until I finally figured out that the problem is that stock Rasbian installs pulseaudio, which in turn restricts the speakers to only be accessible by the current GUI user, which a headless daemon is not. There is a lengthy GitHub thread that eventually discusses the issues and potential fixes for it, but in my case I realized there’s no reason to run pulseaudio on this device, so I just apt remove pulseaudio and then suddenly shairport worked just fine. Yay!

Actually getting the SOMA Connect software running was a bit more challenging.

Before I reimaged the device I made a full backup of the filesystem, although this isn’t strictly necessary as if you have a Linux device you should be able to mount the disk image and extract data from it.

SOMA does have a Debian package repository for their stuff, but it’s not open to the public; clearly it’s only meant to be accessed from their image building process.

There’s also a HOOBS soma-connect repository but the package they provide is both very old and very broken, and didn’t actually help with getting anything to work.

So anyway, I copied the following files off of the SOMA Connect image into their appropriate places:

  • /var/soma-connect/ (empty directly normally, although I preserved my previous settings)
  • /etc/soma-connect-crontab.conf (which turns out to be empty and is probably just a stray file)
  • /etc/rsyslog.d/soma-connect.conf
  • /usr/lib/systemd/system/soma-connect.service
  • /usr/lib/soma-connect/ (which contains the actual binaries for some reason)

Then I tried running /usr/lib/soma-connect/soma-connect and got an error about an unresolved library. But ldd said that it was not a dynamic binary.

After a bit more poking I came to realize that the binary is 32-bit, and I’d installed 64-bit Rasbian. So my choices were to either downgrade to 32-bit rasbian, or to get multiarch running. Fortunately, multiarch is pretty easy to do on ARM:

  1. sudo dpkg --add-architecture armhf
  2. sudo apt update && sudo apt upgrade
  3. Install all of the missing libraries with an :armhf designation. Unfortunately, ldd still doesn’t work across architectures1, so I kept running it and got errors for missing libraries. Here is what I ended up installing; I don’t know if all of these were necessary:

    sudo apt install gcc-12-base:armhf ifplugd:armhf libatomic1:armhf \
        libc++-dev:armhf libc++1:armhf libc6:armhf libstdc++6:armhf
    

Anyway, now the soma-connect binary runs, and the iOS app is able to connect to it over Bluetooth. So activating the service just takes:

sudo systemctl enable soma-connect
sudo systemctl start soma-connect

The only thing I haven’t managed to get working is… HomeKit being able to actually talk to the curtains, which is, y'know, the entire point to having the SOMA Connect in the first place. But that’s something that’s always been a bit unreliable anyway (and the worst part of the SOMA experience), and probably just requires resetting all of the related HomeKit connections and so on. Watching the soma-connect logs might also be educational in this regard.

For now I’m fine with just using the SOMA app to maintain the curtain schedules anyway, which is what I’d been doing most of the time (the HomeKit thing is just nice to have sometimes).

Anyway, the obvious next thing to do is to run DOOM.