Mauricio Wolff

Mauricio Wolff

Turning my turntable on with Siri

I wanted to say one very normal thing:

“Hey Siri, turn on the Turntable.”

And have the turntable start playing through the HomePods in the living room.

I was connecting via VNC to the Mac mini, opening Airfoil, finding the right speakers and selecting them. Then I could put on a record and hear it through the HomePods. A bit much every time I wanted to listen to a record, isn’t it?

A vinyl record on a turntable
Photo by Alessandro Nofi on Pexels.

This is one of those tiny home-automation problems that sounds almost silly until you try to make it feel natural.

The Shortcut almost worked

The turntable is connected to a Mac mini. Airfoil can pick its USB audio input and send it to my Living Room HomePod group, so the actual Mac part was straightforward. It’s a bit overkill to use a Mac mini just for that, I agree. But it is also running gemma-4-e2b-it-4bit via oMLX, serving a chat app I’m experimenting with and outputting 50 tokens per second… but that’s a story for another post.

Back to the turntable, I first made an iPhone Shortcut that ran a script over SSH. Tap it, and it worked.

But Siri has its own ideas about language. Say “turn the turntable on” and it hears a HomeKit accessory command, not a request to run a Shortcut. I could say “Run Turntable On,” but that is not how I want to talk in my own house.

So the real solution was not a better Shortcut. It was making Turntable a HomeKit accessory.

Airfoil was the easy bit

Airfoil exposes AppleScript, which meant I could select the turntable input, called USB AUDIO CODEC, and connect the Living Room speakers like this:

tell application "Airfoil"
    set current audio source to first device source whose name is "USB AUDIO  CODEC"
    connect to (every speaker whose name is "Living Room")
end tell

Turning it off is just disconnecting that group:

tell application "Airfoil"
    disconnect from (every speaker whose name is "Living Room")
end tell

That part was pleasantly uneventful. The fun started when Siri got involved.

A virtual switch named Turntable

I run Homebridge on the Mac mini, with the homebridge-script2 plugin. It exposes a normal switch called Turntable, whose on and off actions run two shell scripts.

{
  "accessory": "Script2",
  "name": "Turntable",
  "on": "/Users/<user>/.homebridge/scripts/airfoil-on.sh",
  "off": "/Users/<user>/.homebridge/scripts/airfoil-off.sh",
  "fileState": "/Users/<user>/.homebridge/scripts/turntable-on.flag"
}

Now Siri knows what the Turntable is. That small naming change was the whole point.

HomeKit is impatient

My first version asked Airfoil whether Living Room was connected whenever HomeKit asked for the switch state. Reasonable, right?

Not really. AppleEvents to Airfoil can take longer than HomeKit is willing to wait. Siri would understand the command, start doing the right thing, then tell me the accessory had “failed to respond.” Annoying, especially while the music was literally about to play.

The fix was to separate the immediate answer from the slower action. The flag file is the HomeKit state. Touch it when turning on, remove it when turning off, and run Airfoil in the background.

airfoil-on.sh:

#!/bin/bash
set -euo pipefail

flag=/Users/<user>/.homebridge/scripts/turntable-on.flag
log=/Users/<user>/.homebridge/logs/airfoil-actions.log
touch "$flag"

/usr/bin/osascript <<'APPLESCRIPT' >>"$log" 2>&1 &
with timeout of 30 seconds
    tell application "Airfoil"
        set current audio source to first device source whose name is "USB AUDIO  CODEC"
        connect to (every speaker whose name is "Living Room")
    end tell
end timeout
APPLESCRIPT

And off:

#!/bin/bash
set -euo pipefail

flag=/Users/<user>/.homebridge/scripts/turntable-on.flag
log=/Users/<user>/.homebridge/logs/airfoil-actions.log
rm -f "$flag"

/usr/bin/osascript <<'APPLESCRIPT' >>"$log" 2>&1 &
with timeout of 30 seconds
    tell application "Airfoil"
        disconnect from (every speaker whose name is "Living Room")
    end tell
end timeout
APPLESCRIPT

This is slightly optimistic. HomeKit gets an immediate “yes, it is on,” then Airfoil catches up in the background. For this setup, it feels much better than waiting for a perfect answer and getting a timeout instead.

The bridge that Home did not see

Then Homebridge was running perfectly, but it would not show up in Apple Home under Add Accessory → More Options.

The clue was in the logs: its built-in multicast advertiser was getting EHOSTUNREACH while trying to advertise the service.

I worked around that by using macOS’s native Bonjour tool, dns-sd, to advertise Homebridge’s existing HAP service. After that, it appeared in Apple Home and paired normally.

I keep both pieces alive with LaunchAgents, one for Homebridge and another for the mDNS advertisement. The second one runs advertise-homebridge.sh, which reads Homebridge’s persistent state and publishes the required _hap._tcp TXT records.

One important thing, if you end up down this rabbit hole: publish your own HAP identity, setup hash and pairing code. Those are part of the bridge’s identity, not values to copy from another machine.

The command I wanted

The bridge is called Mac mini Bridge. The accessory Siri controls is Turntable.

“Hey Siri, turn on the Turntable.”

“Hey Siri, turn off the Turntable.”

That is it. The Mac mini needs to stay on and reachable, and Caffeine takes care of that. macOS also needs permission for osascript to control Airfoil. Once that is in place, the interaction disappears, which is exactly what I wanted.

Now I can put on a record and say one sentence. A tiny bit ridiculous, maybe. Also very satisfying.

Check other postsGo home