> ## Documentation Index
> Fetch the complete documentation index at: https://docs.moorcheh.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Bluetooth speaker (manual setup)

> Pair a Bluetooth speaker on Linux edge hardware and point Moorcheh voice playback at it.

## Overview

Moorcheh voice can play TTS through a **Bluetooth speaker** on Linux (e.g. Arduino UNO Q) by setting `"playback": "bluetooth"` in `~/.moorcheh-edge/voice/audio.json`.

Pairing is done **manually with `bluetoothctl`** on the board. There is no fully automated CLI wizard today - headless boards often need the pairing agent registered in the same interactive session.

<Note>
  Keep the **USB mic** on ALSA (`plughw:…`) for capture. Only **playback** switches to Bluetooth.
</Note>

## Prerequisites

```bash theme={null}
sudo apt-get update
sudo apt-get install -y bluez pulseaudio-utils
sudo systemctl enable --now bluetooth
sudo usermod -aG bluetooth $USER
```

Log out of SSH and back in (or reboot) after adding yourself to the `bluetooth` group.

Verify the adapter:

```bash theme={null}
bluetoothctl show
```

Expect `Powered: yes`.

## Pair the speaker (interactive)

Put the speaker in **pairing mode**, then:

```bash theme={null}
bluetoothctl
```

Inside the `bluetoothctl` prompt:

```
power on
pairable on
agent NoInputNoOutput
default-agent
scan on
```

Leave **`scan on`** running. With the speaker in pairing mode, wait **10-15 seconds** so it appears in the scan results.

### Pick your speaker and note its MAC

Still inside `bluetoothctl`, list discovered devices:

```
devices
```

Example output (yours will differ):

```
Device AA:BB:CC:DD:EE:FF JBL Flip 5
Device 11:22:33:44:55:66 Some-Other-Phone
```

1. Find the line for **your Bluetooth speaker** - read the **name** at the end of the line (e.g. `JBL Flip 5`).
2. Copy the **MAC address** from the start of that same line - six pairs of hex digits like `AA:BB:CC:DD:EE:FF`.

If your speaker does not appear, keep it in pairing mode, wait a few more seconds, and run `devices` again.

Optional: stop scanning once you have the MAC:

```
scan off
```

### Pair, trust, and connect

Replace `AA:BB:CC:DD:EE:FF` with the MAC you copied from `devices`:

```
pair AA:BB:CC:DD:EE:FF
trust AA:BB:CC:DD:EE:FF
connect AA:BB:CC:DD:EE:FF
quit
```

Expect `Pairing successful` and `Connection successful` before you run `quit`.

<Warning>
  Run `agent NoInputNoOutput` and `default-agent` **in the same `bluetoothctl` session** before `pair`. If you see **“No agent is registered”**, exit and start over in one session.
</Warning>

## Point Moorcheh at Bluetooth playback

Edit `~/.moorcheh-edge/voice/audio.json`:

```json theme={null}
{
  "capture": "plughw:0,0",
  "playback": "bluetooth",
  "bt_device": "AA:BB:CC:DD:EE:FF"
}
```

* **`capture`** - USB mic (from [`voice setup`](/cli/voice/setup) or [`voice check`](/cli/voice/check))
* **`playback`** - must be `"bluetooth"` for PipeWire/BlueZ output
* **`bt_device`** - optional MAC hint when multiple `bluez_output` sinks exist

Test:

```bash theme={null}
moorcheh-edge voice speak --text "Bluetooth speaker test."
moorcheh-edge voice check
```

Restart the voice server after changing audio config:

```bash theme={null}
moorcheh-edge voice serve --port 8766
```

## Switch back to wired USB speaker

```bash theme={null}
moorcheh-edge voice setup
```

Or edit `audio.json` manually:

```json theme={null}
{
  "capture": "plughw:0,0",
  "playback": "plughw:0,0"
}
```

Remove `bt_device` when using wired playback.

## PipeWire session on UNO Q

On some UNO Q images the Bluetooth **sink** appears under the **`lightdm`** session while you SSH as **`arduino`**. Moorcheh tries the current user first, then `lightdm`, when `"playback": "bluetooth"`.

If playback fails but `pactl list sinks short` shows a sink under another user:

```bash theme={null}
export MOORCHEH_PULSE_RUNTIME_USER=lightdm
moorcheh-edge voice speak --text "Test"
```

Optional env vars:

| Variable                      | Purpose                                          |
| ----------------------------- | ------------------------------------------------ |
| `MOORCHEH_BT_DEVICE`          | MAC filter (same as `bt_device` in `audio.json`) |
| `MOORCHEH_PULSE_RUNTIME_USER` | Force PipeWire session user                      |
| `MOORCHEH_AUDIO_PLAYBACK`     | Override playback (`bluetooth` or `plughw:…`)    |

## Related

* [`voice setup`](/cli/voice/setup)
* [`voice check`](/cli/voice/check)
* [Voice CLI overview](/cli/voice/introduction)
* [Arduino UNO Q](/guides/arduino-uno-q)
