Files
shawn b4237f2f1d Add Network + Bluetooth config in Web UI
- src/system/network.py: WiFi scan/connect/hotspot via nmcli + iwlist fallback
- src/system/bluetooth.py: BT scan/pair/connect/MIDI via bluetoothctl
- REST endpoints: /api/wifi/* and /api/bluetooth/* (16 endpoints)
- Web UI: tabbed settings with Network + Bluetooth panels
- network.js: WiFi scan, connect modal, saved nets, hotspot
- bluetooth.js: BT scan, pair/unpair, connect, MIDI service
- style.css: tabs, network list, BT device list, signal indicators
- scripts/setup-bt-midi.sh: BT MIDI systemd bridge service
- tests/test_network.py: 22 tests (nmcli/iwlist, fallback, hotspot)
- tests/test_bt.py: 24 tests (status, scan, pair, MIDI, edge cases)
- _gather_state includes wifi + bluetooth sub-objects
- All 93 tests pass
2026-06-09 01:14:41 -04:00

231 lines
9.1 KiB
Bash

#!/usr/bin/env bash
# ── Pi Multi-FX Pedal — Bluetooth MIDI Service Setup ──────────────
# Configures BlueZ for Bluetooth MIDI (BLE MIDI) on the Pi.
#
# This sets up:
# 1. BlueZ ALSA MIDI bridge (bluez-alsa-utils for classic BT MIDI)
# 2. A systemd service that auto-starts the BT MIDI bridge on boot
#
# Usage:
# sudo bash scripts/setup-bt-midi.sh # Install + enable
# sudo bash scripts/setup-bt-midi.sh --uninstall # Remove service
#
# Requirements:
# - Raspberry Pi with built-in Bluetooth (Pi 3/4/5/Zero 2W)
# - bluez installed (usually present on RPi OS / DietPi)
#
# After setup:
# - Systemd service 'pi-bt-midi' is enabled and starts on boot
# - Bluetooth MIDI devices can pair via the web UI
# - MIDI data flows through ALSA sequencer (port 14:0)
# ────────────────────────────────────────────────────────────────────
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
# ── Colors ────────────────────────────────────────────────────────────
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'
info() { echo -e "${CYAN}[INFO]${NC} $1"; }
ok() { echo -e "${GREEN}[OK]${NC} $1"; }
warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
fail() { echo -e "${RED}[FAIL]${NC} $1"; }
# ── Config ────────────────────────────────────────────────────────────
SERVICE_NAME="pi-bt-midi"
SERVICE_PATH="/etc/systemd/system/${SERVICE_NAME}.service"
# ── Parse args ────────────────────────────────────────────────────────
UNINSTALL=false
while [[ $# -gt 0 ]]; do
case "$1" in
--uninstall) UNINSTALL=true; shift ;;
--help|-h) echo "Usage: $0 [--uninstall]"; exit 0 ;;
*) echo "Unknown: $1"; exit 1 ;;
esac
done
# ═══════════════════════════════════════════════════════════════════════
# UNINSTALL
# ═══════════════════════════════════════════════════════════════════════
if [ "$UNINSTALL" = true ]; then
info "Removing Bluetooth MIDI service..."
sudo systemctl stop "${SERVICE_NAME}" 2>/dev/null || true
sudo systemctl disable "${SERVICE_NAME}" 2>/dev/null || true
sudo rm -f "$SERVICE_PATH"
sudo systemctl daemon-reload
# Remove the bt-midi script if it was copied
sudo rm -f /usr/local/bin/bt-midi-bridge.sh 2>/dev/null || true
ok "Bluetooth MIDI service removed."
exit 0
fi
# ═══════════════════════════════════════════════════════════════════════
# INSTALL
# ═══════════════════════════════════════════════════════════════════════
echo ""
echo "╔═══════════════════════════════════════════════╗"
echo "║ Pi Multi-FX Pedal — Bluetooth MIDI Setup ║"
echo "╚═══════════════════════════════════════════════╝"
echo ""
# ── 1. Check prerequisites ────────────────────────────────────────────
info "Checking prerequisites..."
if ! command -v bluetoothctl &>/dev/null; then
fail "bluetoothctl not found. Install bluez: sudo apt install bluez"
exit 1
fi
if ! systemctl is-active --quiet bluetooth; then
warn "Bluetooth service is not running. Starting it..."
sudo systemctl start bluetooth
sleep 1
fi
ok "BlueZ is available"
# ── 2. Install bluez-alsa-utils for ALSA MIDI bridge ─────────────────
if ! command -v bluealsa &>/dev/null; then
info "Installing bluez-alsa-utils for ALSA MIDI bridge..."
sudo apt-get update -qq
sudo apt-get install -y -qq bluez-alsa-utils
ok "bluez-alsa-utils installed"
else
ok "bluez-alsa-utils already installed"
fi
# ── 3. Create the MIDI bridge helper script ───────────────────────────
info "Creating bt-midi-bridge helper..."
sudo tee /usr/local/bin/bt-midi-bridge.sh > /dev/null << 'BRIDGESCRIPT'
#!/usr/bin/env bash
# ── Bluetooth MIDI Bridge ──────────────────────────────────────────
# Launched by systemd (pi-bt-midi.service).
# Keeps bluealsa MIDI running and handles reconnection.
#
# The ALSA sequencer port for BlueALSA MIDI is typically 14:0.
# Our pedal app reads MIDI from this port.
set -euo pipefail
# Log to systemd journal
exec > >(logger -t bt-midi-bridge) 2>&1
echo "Starting Bluetooth MIDI bridge..."
# Ensure Bluetooth is powered on
bluetoothctl power on
# Start bluealsa service (MIDI profiles)
if command -v bluealsa &>/dev/null; then
# bluealsa runs as a system service; just verify it's running
if systemctl is-active --quiet bluealsa; then
echo "bluealsa is running"
else
echo "Starting bluealsa..."
sudo systemctl start bluealsa
fi
fi
# Register with ALSA sequencer for MIDI connections
# This makes our app visible as an ALSA MIDI port
if command -v aconnect &>/dev/null; then
echo "ALSA sequencer available"
# List MIDI ports for debugging
aconnect -i -o
fi
echo "Bluetooth MIDI bridge ready."
# Keep running (systemd will restart if needed)
while true; do
# Check Bluetooth health and reconnect if needed
if ! bluetoothctl show | grep -q "Powered: yes"; then
echo "BT not powered, re-powering..."
bluetoothctl power on
fi
sleep 30
done
BRIDGESCRIPT
sudo chmod +x /usr/local/bin/bt-midi-bridge.sh
ok "Bridge script created at /usr/local/bin/bt-midi-bridge.sh"
# ── 4. Create systemd service ─────────────────────────────────────────
info "Creating systemd service..."
sudo tee "$SERVICE_PATH" > /dev/null << SERVICECONTENT
# Pi Multi-FX Pedal — Bluetooth MIDI Bridge
# Installed by scripts/setup-bt-midi.sh
# Auto-starts BlueALSA MIDI bridge for wireless MIDI controllers
[Unit]
Description=Pi Multi-FX Pedal — Bluetooth MIDI Bridge
Documentation=https://gitea.ourpad.casa/shawn/pi-multifx-pedal
After=bluetooth.service bluealsa.service
Wants=bluetooth.service
BindsTo=multi-fx-pedal.target
[Service]
Type=simple
User=pi
Group=audio
ExecStart=/usr/local/bin/bt-midi-bridge.sh
Restart=on-failure
RestartSec=5
TimeoutStopSec=10
[Install]
WantedBy=multi-fx-pedal.target
multi-user.target
SERVICECONTENT
ok "Service unit created at ${SERVICE_PATH}"
# ── 5. Enable and start ───────────────────────────────────────────────
info "Enabling and starting Bluetooth MIDI service..."
sudo systemctl daemon-reload
sudo systemctl enable "${SERVICE_NAME}"
sudo systemctl start "${SERVICE_NAME}" 2>/dev/null || true
sleep 1
if systemctl is-active --quiet "${SERVICE_NAME}"; then
ok "Bluetooth MIDI service is running"
else
warn "Service created but not yet active. Check: sudo systemctl status ${SERVICE_NAME}"
fi
# ═══════════════════════════════════════════════════════════════════════
# DONE
# ═══════════════════════════════════════════════════════════════════════
echo ""
echo "╔═══════════════════════════════════════════════╗"
echo "║ Bluetooth MIDI Setup Complete 🎸 ║"
echo "╚═══════════════════════════════════════════════╝"
echo ""
echo " 🎵 BT MIDI bridge: ${SERVICE_NAME}"
echo " 📋 Service status: sudo systemctl status ${SERVICE_NAME}"
echo " 🔗 Logs: sudo journalctl -u ${SERVICE_NAME} -n 30 --no-pager"
echo ""
echo "To remove:"
echo " sudo bash $0 --uninstall"
echo ""