openclaw/skills/bluetooth/SKILL.md
Control Bluetooth devices and audio routing on the Mac Mini. Use when asked about Bluetooth, connecting speakers, headphones, audio output, switching audio, or listing paired devices.
npx skillsauth add Dbochman/dotfiles bluetoothInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Control Bluetooth devices and audio routing on the Mac Mini (macOS Tahoe 26.x).
| Name | MAC Address | Type | |------|-------------|------| | Kitchen speaker | ${KITCHEN_SPEAKER_MAC} | Audio | | Magic Keyboard with Numeric Keypad | ${MAGIC_KEYBOARD_MAC} | Keyboard | | Magic Trackpad 2 | ${MAGIC_TRACKPAD_MAC} | Trackpad |
On macOS 26.x, the IOBluetooth API reports wrong power/connection state over SSH. All connect/disconnect operations must run via open /tmp/bt_op.command which launches in the GUI (Aqua) session where IOBluetooth works correctly.
Read operations (list devices, check status, audio switching) work directly over SSH via system_profiler and SwitchAudioSource.
ssh dylans-mac-mini "echo 'connect ${KITCHEN_SPEAKER_MAC}' > /tmp/bt_command.txt && rm -f /tmp/bt_result.txt /tmp/bt_exit.txt && open /tmp/bt_op.command && sleep 12 && cat /tmp/bt_exit.txt"
Exit code 0 = success. Wait 12 seconds for the Bluetooth connection to establish.
ssh dylans-mac-mini "echo 'connect ${KITCHEN_SPEAKER_MAC}' > /tmp/bt_command.txt && rm -f /tmp/bt_result.txt /tmp/bt_exit.txt && open /tmp/bt_op.command"
sleep 12
ssh dylans-mac-mini "export PATH=/opt/homebrew/bin:\$PATH && SwitchAudioSource -s 'Kitchen speaker' -t output"
ssh dylans-mac-mini "echo 'disconnect ${KITCHEN_SPEAKER_MAC}' > /tmp/bt_command.txt && rm -f /tmp/bt_result.txt /tmp/bt_exit.txt && open /tmp/bt_op.command && sleep 12 && cat /tmp/bt_exit.txt"
ssh dylans-mac-mini "export PATH=/opt/homebrew/bin:\$PATH && SwitchAudioSource -s 'Mac mini Speakers' -t output"
ssh dylans-mac-mini "echo 'disconnect ${KITCHEN_SPEAKER_MAC}' > /tmp/bt_command.txt && rm -f /tmp/bt_result.txt /tmp/bt_exit.txt && open /tmp/bt_op.command"
ssh dylans-mac-mini "system_profiler SPBluetoothDataType -json" | python3 -c "
import json, sys
data = json.load(sys.stdin)
bt = data.get('SPBluetoothDataType', [{}])[0]
for section in ['device_connected', 'device_not_connected']:
devices = bt.get(section, [])
if isinstance(devices, list):
for group in devices:
if isinstance(group, dict):
for name, props in group.items():
connected = 'Yes' if section == 'device_connected' else 'No'
addr = props.get('device_address', '?')
print(f'{name}: {addr} connected={connected}')
"
ssh dylans-mac-mini "system_profiler SPBluetoothDataType 2>&1 | grep -B2 'Kitchen speaker'"
If it appears under "Connected:" it's connected. Under "Not Connected:" it's not.
These work directly over SSH (no GUI workaround needed).
ssh dylans-mac-mini "export PATH=/opt/homebrew/bin:\$PATH && SwitchAudioSource -a -t output"
ssh dylans-mac-mini "export PATH=/opt/homebrew/bin:\$PATH && SwitchAudioSource -c -t output"
# To Kitchen speaker
ssh dylans-mac-mini "export PATH=/opt/homebrew/bin:\$PATH && SwitchAudioSource -s 'Kitchen speaker' -t output"
# To Mac Mini speakers
ssh dylans-mac-mini "export PATH=/opt/homebrew/bin:\$PATH && SwitchAudioSource -s 'Mac mini Speakers' -t output"
ssh dylans-mac-mini "export PATH=/opt/homebrew/bin:\$PATH && SwitchAudioSource -m toggle"
ssh dylans-mac-mini "export PATH=/opt/homebrew/bin:\$PATH && SwitchAudioSource -m mute"
ssh dylans-mac-mini "export PATH=/opt/homebrew/bin:\$PATH && SwitchAudioSource -m unmute"
ssh dylans-mac-mini "system_profiler SPBluetoothDataType 2>&1 | grep 'State:'"
The /tmp/bt_op.command file is a shell script that:
/tmp/bt_command.txtblueutil --connect or --disconnect with the MAC address/tmp/bt_exit.txtUsing open to launch it ensures it runs in the macOS GUI session where blueutil has proper IOBluetooth API access and TCC (Bluetooth) permission.
open /tmp/bt_op.command pattern instead. Direct SSH calls to blueutil fail on Tahoe because IOBluetooth reports power=0.BLUEUTIL_USE_SYSTEM_PROFILER=1 blueutil --paired or system_profiler SPBluetoothDataType.| Path | Purpose |
|------|---------|
| /tmp/bt_op.command | Reusable GUI-session launcher for blueutil |
| /tmp/bt_command.txt | Input: command + MAC address |
| /tmp/bt_result.txt | Output: command result |
| /tmp/bt_exit.txt | Output: exit code |
| ~/.openclaw/bin/bt_connect | Swift IOBluetooth helper (used by launchd agent) |
| ~/Library/LaunchAgents/com.openclaw.bt-connect.plist | LaunchAgent for Bluetooth ops |
tools
Use exact configured Reolink cameras through the local Home Hub for availability and power status, fresh stills, visual commentary, protected Dylan/Julia/household sharing, and reversible spotlight control. Supports trusted owner tasks and explicitly scoped proactive automations; not for Nest or Ring cameras, arbitrary recipients, recordings, account changes, or raw camera APIs.
data-ai
Privately manage Dylan and Julia's household plant inventory and care history by physical location, bed, and exact Flower Cam view. Use for confirmed plant onboarding from camera conversations, camera- or bed-filtered inventory, record corrections, individual or whole-bed care, and private filtered exports. Pair with reolink-camera when an owner asks about plants visible in Flower Cam images.
testing
Inspect and control the physically secured Reachy Mini at Crosstown through ClawBody. Use for requests to check Reachy, look around, express an emotion, play any official emotion or dance preset, speak proactively, mute or unmute its microphone, stop movement, or describe what its camera sees.
tools
Handle Reachy/iMessage handoffs, selective durable memory, forgetting, and diagnostics; automatic context comes from the gateway plugin.