Перейти к содержимому

Разработка и участие

Требуется Docker и Docker Compose. Bluetooth-колонка должна быть спарена с хостом до запуска.

Окно терминала
git clone https://github.com/trudenboy/sendspin-bt-bridge.git
cd sendspin-bt-bridge
# Собрать и запустить
docker compose up --build
# Просмотр логов
docker logs -f sendspin-client
# Веб UI
open http://localhost:8080

Запуск без Docker (требуются системные пакеты Bluetooth и аудио):

Окно терминала
pip install -r requirements.txt
python sendspin_client.py
sendspin_client.py # Точка входа: SendspinClient + main()
bluetooth_manager.py # BluetoothManager — BT подключения через bluetoothctl
config.py # Конфигурация, shared lock, load_config()
state.py # Общее runtime-состояние (список SendspinClient)
services/
bridge_daemon.py # BridgeDaemon — работает внутри subprocess; события потока, маршрутизация
daemon_process.py # Точка входа subprocess: читает args, запускает BridgeDaemon, шлёт JSON-статус
bluetooth.py # Async хелперы BT (D-Bus монитор)
pulse.py # PulseAudio хелперы (pulsectl + pactl): поиск синка, перемещение sink-inputs
routes/
api.py # Основные playback и громкость (6 маршрутов)
api_bt.py # Управление Bluetooth (9 маршрутов)
api_ma.py # Интеграция с Music Assistant (10 маршрутов)
api_config.py # Конфигурация (9 маршрутов)
api_status.py # Статус и диагностика (8 маршрутов)
views.py # Рендер HTML-страниц
auth.py # Опциональная парольная защита веб UI
entrypoint.sh # Docker entrypoint: D-Bus, аудио инициализация
ha-addon/ # Home Assistant addon конфигурация
lxc/ # LXC установочные скрипты (Proxmox и OpenWrt)

Архитектура: каждая Bluetooth-колонка работает как изолированный asyncio-subprocess (services/daemon_process.py) с переменной PULSE_SINK=<bt_sink_name> в окружении. Это даёт каждой колонке собственный PulseAudio-контекст — аудио направляется в нужную колонку с первого семпла, без move-sink-input при старте.

Запустите pytest для автоматических юнит-тестов:

Окно терминала
python3 -m pytest tests/ -v

Набор тестов содержит 187 тестов в 18 тест-файлах, покрывающих конфигурацию, маршрутизацию громкости, статус устройств, управление состоянием, аутентификацию, Ingress middleware, BT-сервисы, процесс демона, интеграцию с MA и кулдаун сканирования.

Окно терминала
ruff check . # Быстрый Python линтер
ruff format --check . # Проверка форматирования кода

Используйте этот чеклист при тестировании изменений:

  • Контейнер запускается без ошибок (docker logs -f sendspin-client)
  • Веб UI загружается на http://localhost:8080
  • Bluetooth-устройство подключается и отображается в веб UI
  • Music Assistant определяет плеер
  • Аудио воспроизводится через Bluetooth-колонку
  • Слайдер громкости в веб UI изменяет громкость колонки
  • Авто-переподключение срабатывает после отключения колонки (~10 с)
  • Изменения конфигурации через веб UI сохраняются после перезапуска контейнера
  • /api/status возвращает корректный JSON
  • /api/config GET возвращает текущую конфигурацию; POST с корректными данными сохраняет её

При изменениях HA аддона — дополнительно протестируйте через локальный репозиторий аддонов HA.

  • main — стабильная, всегда готова к релизу
  • Ветки фич — ответвляйтесь от main, называйте feat/<описание> или fix/<описание>
  • PR — направляйте в main

Откройте issue на GitHub. Укажите:

  • Метод деплоя (Docker / HA Addon / Proxmox LXC)
  • Релевантный вывод лога
  • ОС хоста, аудиосистему (PipeWire или PulseAudio), модель Bluetooth-адаптера
  • Шаги воспроизведения

Пуш тега v* в main автоматически:

  1. Собирает multi-platform Docker образ (linux/amd64, linux/arm64)
  2. Публикует в ghcr.io/trudenboy/sendspin-bt-bridge
  3. Синхронизирует версию в ha-addon/config.yaml

Проект вырос из loryanstrant/Sendspin-client. Благодарность команде Music Assistant за протокол Sendspin и CLI.

  • Архитектура — процессная модель, IPC-протокол, маршрутизация звука, автомат состояний Bluetooth, интеграция с MA, аутентификация и graceful degradation
  • HISTORY.ru.md — история эволюции проекта (v1 → v2, ключевые архитектурные решения)
  • CHANGELOG.md — полная история версий