Настройка
Sendspin Bluetooth Bridge хранит постоянные настройки в config.json внутри директории /config. Управлять этими значениями можно через веб-интерфейс, через вкладку настройки аддона Home Assistant или напрямую через файл.
Поверхности конфигурации
Заголовок раздела «Поверхности конфигурации»Есть два основных способа управлять настройками:
| Поверхность | Для чего подходит | Что важно |
|---|---|---|
| Веб-интерфейс | Ежедневное управление устройствами, адаптерами, auth и runtime-поведением | Работает для Docker, LXC и аддона |
| Configuration таб аддона HA | Supervisor-managed параметры аддона | Удобен для HA-native редактирования |
Конфигурация через веб-интерфейс
Заголовок раздела «Конфигурация через веб-интерфейс»
Новый раздел конфигурации разбит на пять вкладок вместо одной длинной формы.
| Вкладка | Что в ней находится |
|---|---|
| General | Имя bridge, timezone, latency, web/UI-порты, smooth restart, update policy |
| Devices | Таблица колонок, сканирование, импорт paired-устройств |
| Bluetooth | Имена адаптеров, reconnect policy, codec preference |
| Music Assistant | Token flows, endpoint MA, monitor, routing toggles |
| Security | Local auth, session timeout, защита от перебора |
Вкладка General
Заголовок раздела «Вкладка General»General содержит настройки всего экземпляра bridge:
- Bridge name — добавляется к именам плееров как
Player @ Name. - Timezone — с live preview текущего времени.
- PulseAudio latency (ms) — больше значение = выше устойчивость на слабом железе.
- Web UI port — порт прямого доступа в браузере для Docker / LXC / systemd. Игнорируется в режиме HA addon: Supervisor назначает ingress-порт динамически.
- Base player listen port — стартовый порт для автоматически назначаемых sendspin listener’ов устройств.
- Smooth restart — mute перед перезапуском и показ прогресса.
- Check for updates / Auto-update — доступны вне режима HA addon.
Если оставить поля портов пустыми, standalone-режим использует 8080 для web UI и 8928 для listener’ов плееров. В режиме Home Assistant addon все три канала (stable / rc / beta) поставляются с ingress_port: 0, поэтому Supervisor назначает свободный порт во время запуска — это изменение появилось в v2.55.0, чтобы варианты аддона перестали конфликтовать с Matter / Thread и другими addons на host-network. Per-channel дефолты для базового listener-порта (8928 / 9028 / 9128) сохраняются — они нужны, чтобы listener’ы устройств не пересекались, когда несколько вариантов аддона работают одновременно. WEB_PORT, заданный внутри аддона, игнорируется; UI открывается из боковой панели Home Assistant.
Вкладка Devices
Заголовок раздела «Вкладка Devices»
Devices разделена на две роли:
- Device fleet — основная таблица повседневных изменений.
- Discovery & import — поиск nearby speakers и импорт уже спаренных устройств.
Каждая строка устройства хранит:
| Поле | Для чего нужно |
|---|---|
| Enabled | Временно исключить устройство из старта |
| Player name | Имя в Music Assistant |
| MAC | Bluetooth-адрес колонки |
| Adapter | Привязка к конкретному контроллеру |
| Port | Опциональный listen_port; иначе bridge использует BASE_LISTEN_PORT + индекс устройства |
| Delay | static_delay_ms — компенсация hw-задержки за sink’ом (0–5 000 мс, дефолт 300 для новых устройств) |
| Live | Runtime badge вроде Playing, Connected, Released или Not seen |
В advanced-части строки доступны:
- Preferred format вроде
flac:44100:16:2. - Listen host (
listen_host) для переопределения advertised-адреса устройства. - Keepalive interval (
keepalive_interval) для колонок, которые слишком быстро уходят в сон.
Текущее runtime-поведение завязано на интервале: любой положительный keepalive_interval включает keepalive-тишину, значения меньше 30 секунд поднимаются до 30, а 0 или пустое поле keepalive выключают. В старых конфигурациях Home Assistant addon ещё может встречаться legacy-флаг keepalive_silence, но актуальное поведение bridge определяется через keepalive_interval > 0.
Вкладка Bluetooth
Заголовок раздела «Вкладка Bluetooth»
Bluetooth объединяет inventory и политику восстановления:
- Понятные имена адаптеров для dashboard.
- Ручные записи адаптеров, если автоопределение неполное.
- Refresh detection.
- Настройку BT check interval.
- Настройку Auto-disable threshold. При достижении порога устройство сохраняется как disabled, пока вы не включите его снова.
- Переключатель Prefer SBC codec.
Вкладка Music Assistant
Заголовок раздела «Вкладка Music Assistant»

Music Assistant объединяет состояние соединения и auth helper’ы:
- summary Connection status,
- действие Reconfigure прямо в карточке статуса соединения — основной способ осознанно переоткрыть auth-flow после первичной настройки,
- Discover для поиска сервера или повторного использования уже известного URL,
- Get token с логином/паролем MA. При успехе bridge сохраняет
MA_API_URL, long-livedMA_API_TOKENиMA_USERNAME, но не сохраняет пароль, - fallback через Home Assistant OAuth / MFA, если экземпляр MA работает поверх HA и прямой логин MA этого требует,
- Get token automatically для HA-backed MA. Этот helper показывается только в addon/Ingress-режиме, потому что silent bootstrap токена зависит от живой browser-session Home Assistant. В HA Ingress UI сначала пробует silent auth через текущий HA browser token, а затем при необходимости переходит к popup-flow,
- ручное поле MA API token,
- поля MA server и MA WebSocket port,
- переключатели WebSocket monitor, Route volume through MA, Route mute through MA.
Когда bridge уже подключён, auth controls убираются с глаз до тех пор, пока вы не нажмёте Reconfigure или не попадёте сюда по guidance-CTA, который явно просит обновить токен.
Вкладка Security
Заголовок раздела «Вкладка Security»В standalone-режиме вкладка Security управляет локальным доступом к веб-интерфейсу:
- Enable web UI authentication,
- Session timeout (1–168 часов),
- Brute-force protection,
- поля Max attempts, Window и Lockout,
- flow Set password.
Standalone-login использует CSRF-защищённые формы и cookie с SameSite=Lax + HttpOnly. В режиме Home Assistant addon доступ всегда контролирует сам HA / Ingress, поэтому standalone-контролы скрываются.
Действия в footer
Заголовок раздела «Действия в footer»Нижняя панель общая для всех вкладок:
- Save записывает
config.json. - Save & Restart сохраняет и сразу перезапускает сервис. Используйте это для изменений портов, auth/session-настроек и любых параметров, применяемых на старте.
- Cancel восстанавливает последние сохранённые значения формы.
- Download экспортирует share-safe JSON-файл с timestamp и без секретов вроде
MA_API_TOKEN, password hash и secret key. - Upload импортирует ранее сохранённый config и сохраняет существующие password hash, secret key и MA token на стороне сервера.
Параметры аддона Home Assistant
Заголовок раздела «Параметры аддона Home Assistant»
В режиме аддона Home Assistant Supervisor показывает собственную вкладку Configuration.
Откройте Настройки → Аддоны → Sendspin Bluetooth Bridge → Configuration.
Основные поля аддона:
| Параметр | Назначение |
|---|---|
| sendspin_server | Хост/IP Music Assistant (без префикса схемы, без порта, без пути — просто 192.168.1.11 или ma.local), или auto для mDNS |
| sendspin_port | Порт Sendspin WebSocket — по умолчанию 8927, совпадает с дефолтом провайдера Sendspin в Music Assistant. Старые конфиги с 9000 продолжают работать: бридж пробует настроенный порт и автоматически переключается, если он закрыт |
| web_port | Читается, но не применяется в режиме аддона: Supervisor назначает ingress-порт динамически. Поле оставлено в схеме ради совместимости — можно оставить пустым. |
| base_listen_port | Стартовый порт для автоматически назначаемых listener’ов устройств |
| bridge_name | Необязательная метка экземпляра bridge |
| tz | Часовой пояс IANA |
| pulse_latency_msec | Подсказка размера аудиобуфера |
| prefer_sbc_codec | Предпочтение более лёгкого кодека |
| bt_check_interval | Интервал polling-проверки |
| bt_max_reconnect_fails | Порог auto-disable |
| auth_enabled | Standalone-style auth toggle для прямого доступа; в HA addon mode auth всё равно принудительно контролируется HA |
| ma_api_url / ma_api_token | REST-интеграция с Music Assistant |
| ma_auto_silent_auth | Разрешить addon/Ingress-страницам пробовать silent-создание HA-backed MA-токена при открытии |
| volume_via_ma / mute_via_ma | Маршрутизация управления через MA |
| update_channel | Выбор release-lane для in-app update checks и предупреждений |
| log_level | Базовый уровень логирования |


Через addon form доступны и полные структуры Bluetooth devices и Bluetooth adapters. Старые addon-конфиги могут по-прежнему сохранять legacy-поле keepalive_silence при трансляции, но текущее runtime-поведение определяется через keepalive_interval.
Что важно для addon-режима:
- auth в Home Assistant / Ingress всегда принудительно включена;
- пользовательский
web_portв addon-режиме игнорируется — Supervisor назначает ingress-порт динамически (ingress_port: 0); параллельный прямой listener bridge сейчас не открывает; - silent bootstrap токена HA для Music Assistant доступен только при открытом UI через аутентифицированную HA/Ingress browser-session.
Стратегия портов и listener’ов
Заголовок раздела «Стратегия портов и listener’ов»Верхнеуровневые web- и listen-порты
Заголовок раздела «Верхнеуровневые web- и listen-порты»Bridge поддерживает два необязательных top-level override-поля:
| Ключ | К чему применяется | Значение по умолчанию | Что важно |
|---|---|---|---|
WEB_PORT | listener веб-интерфейса | 8080 вне HA addon mode | Игнорируется в режиме HA addon. Supervisor назначает ingress-порт динамически (в манифесте аддона стоит ingress_port: 0), фиксированного addon-порта, который можно было бы переопределить через WEB_PORT, больше нет. UI открывается через сайдбар Home Assistant. |
BASE_LISTEN_PORT | автоматически назначаемые per-device Sendspin listener’ы | 8928 вне HA addon mode | Стартовый порт, если устройство не задаёт собственный listen_port. Учитывается во всех runtime-режимах, включая HA addon. |
В Home Assistant addon mode listener-диапазоны специально разведены по каналам, чтобы несколько вариантов аддона могли уживаться на одном HAOS-хосте, не конфликтуя по per-device listener-портам:
| Установленный трек аддона | Channel base listen port | Channel web-port fallback |
|---|---|---|
| Stable | 8928 | 8080 |
| RC | 9028 | 8081 |
| Beta | 9128 | 8082 |
Колонка base listen port — это активный дефолт для канала, он напрямую виден в URL listener’ов устройств. Колонка web-port fallback — резервное значение, используемое только в случае, если bridge не смог обратиться к /addons/self/info Supervisor REST API за динамически назначенным ingress-портом. В обычной работе пользователь эти числа не увидит — Supervisor возвращает свой runtime-порт, и UI отдаётся на нём.
Используйте overrides только когда нужно:
- нестандартный web-порт для Docker / LXC / systemd (HA addon mode сейчас не поддерживает прямой не-Ingress listener —
WEB_PORTчитается, но не применяется); - иной стартовый диапазон device-listener’ов на том же хосте (например, два non-addon bridge-экземпляра).
Персональные listener overrides устройств
Заголовок раздела «Персональные listener overrides устройств»Каждое Bluetooth-устройство может также задавать собственные listen_host и listen_port.
Используйте device-level overrides, если:
- конкретной колонке нужен стабильный известный порт;
- вы делите устройства между несколькими bridge-экземплярами и хотите явный план портов;
- нужно убрать коллизию, не двигая весь базовый диапазон bridge.
Справочник по config.json
Заголовок раздела «Справочник по config.json»Основные ключи
Заголовок раздела «Основные ключи»| Ключ | Тип | Описание |
|---|---|---|
SENDSPIN_SERVER | string | Хост Music Assistant или auto |
SENDSPIN_PORT | integer | Порт Sendspin WebSocket |
WEB_PORT | integer или null | Override прямого web-порта |
BASE_LISTEN_PORT | integer или null | Необязательный base port для автоматически назначаемых listener’ов устройств |
BRIDGE_NAME | string | Необязательная метка экземпляра |
TZ | string | Часовой пояс IANA |
PULSE_LATENCY_MSEC | integer | Подсказка аудиобуфера |
BT_CHECK_INTERVAL | integer | Интервал проверки Bluetooth |
BT_MAX_RECONNECT_FAILS | integer | Порог auto-disable; 0 — без ограничений |
BT_CHURN_THRESHOLD | integer | Порог изоляции частых переподключений; 0 отключает |
BT_CHURN_WINDOW | number | Окно времени в секундах для обнаружения churn (по умолчанию 300) |
PREFER_SBC_CODEC | boolean | Предпочтение кодека с меньшей нагрузкой |
DISABLE_PA_RESCUE_STREAMS | boolean | Выгрузить PulseAudio module-rescue-streams при старте, чтобы предотвратить смещение sink при переподключении |
DUPLICATE_DEVICE_CHECK | boolean | Обнаружение дублирующихся устройств между bridge-экземплярами |
AUTH_ENABLED | boolean | Включить локальную auth-защиту вне HA addon mode; в HA addon mode auth всегда принудительно включена |
SESSION_TIMEOUT_HOURS | integer | Срок жизни browser-сессии |
BRUTE_FORCE_PROTECTION | boolean | Включить временную блокировку после неудачных входов |
BRUTE_FORCE_MAX_ATTEMPTS | integer | Максимум попыток в окне |
BRUTE_FORCE_WINDOW_MINUTES | integer | Rolling window для неудачных входов |
BRUTE_FORCE_LOCKOUT_MINUTES | integer | Длительность блокировки |
MA_API_URL | string | URL REST API Music Assistant |
MA_API_TOKEN | string | Токен Music Assistant API |
MA_USERNAME | string | Username, использованный при последнем успешном MA login-flow |
MA_AUTO_SILENT_AUTH | boolean | Разрешить addon/Ingress-страницам пробовать silent-создание HA-backed MA-токена при открытии |
MA_WEBSOCKET_MONITOR | boolean | Live monitor now-playing и очереди |
VOLUME_VIA_MA | boolean | Пропускать volume через MA |
MUTE_VIA_MA | boolean | Пропускать mute через MA |
SMOOTH_RESTART | boolean | Mute перед перезапуском и показ прогресса |
UPDATE_CHANNEL | string | Канал обновлений: stable, rc или beta |
AUTO_UPDATE | boolean | Разрешить auto-update там, где он поддерживается |
CHECK_UPDATES | boolean | Включить проверку обновлений |
LOG_LEVEL | string | Базовый уровень логирования: DEBUG, INFO, WARNING, ERROR |
HA_AREA_NAME_ASSIST_ENABLED | boolean | Автоматическое определение имён зон Home Assistant для адаптеров |
STARTUP_BANNER_GRACE_SECONDS | integer | Секунды до появления баннера запуска (0–300) |
RECOVERY_BANNER_GRACE_SECONDS | integer | Секунды до появления баннеров восстановления/ошибок (0–300) |
TRUSTED_PROXIES | array | Дополнительные proxy IP, которым разрешено передавать trusted Ingress headers |
Автоматически управляемые ключи
Заголовок раздела «Автоматически управляемые ключи»Следующие ключи записываются bridge во время работы и обычно не требуют ручного редактирования:
| Ключ | Тип | Описание |
|---|---|---|
CONFIG_SCHEMA_VERSION | integer | Внутренняя версия схемы для миграций конфига |
AUTH_PASSWORD_HASH | string | PBKDF2-SHA256 хеш пароля веб-интерфейса |
SECRET_KEY | string | Ключ шифрования сессий Flask; генерируется автоматически при первом запуске |
LAST_VOLUMES | object | Сохранённая громкость устройств (MAC → integer) |
LAST_SINKS | object | Сохранённое имя PulseAudio-sink устройства (MAC → string) |
MA_AUTH_PROVIDER | string | Провайдер авторизации текущего подключения к MA ("ha" и т.д.) |
MA_TOKEN_INSTANCE_HOSTNAME | string | Hostname экземпляра MA, выдавшего токен |
MA_TOKEN_LABEL | string | Понятная метка сохранённого MA-токена |
MA_ACCESS_TOKEN | string | Текущий OAuth access token MA |
MA_REFRESH_TOKEN | string | OAuth refresh token MA для автоматического обновления |
HA_ADAPTER_AREA_MAP | object | Привязка MAC адаптера → зона Home Assistant |
Чувствительные поля:
AUTH_PASSWORD_HASH,SECRET_KEY,MA_ACCESS_TOKENиMA_REFRESH_TOKENудаляются из скачиваемого конфига. Upload сохраняет серверные значения этих ключей.
Bluetooth-устройства
Заголовок раздела «Bluetooth-устройства»{ "BLUETOOTH_DEVICES": [ { "mac": "AA:BB:CC:DD:EE:FF", "player_name": "Колонка в гостиной", "adapter": "hci0", "static_delay_ms": 300, "listen_host": "0.0.0.0", "listen_port": 8928, "preferred_format": "flac:44100:16:2", "keepalive_interval": 60, "enabled": true } ]}| Поле | Описание |
|---|---|
mac | Bluetooth MAC колонки |
player_name | Имя в Music Assistant |
adapter | ID или MAC адаптера |
static_delay_ms | Декларирует hw-задержку, которую колонка добавляет за sink’ом, в мс (0–5 000). Sendspin-клиент вычитает это значение из времени проигрывания каждого чанка, поэтому аудио выходит на железо раньше ровно на эту величину и приходит на запланированный таймштамп после того, как железо добавит свою реальную задержку. Дефолт для новых устройств — 300; увеличивайте для колонок, которые стабильно отстают от группы, уменьшайте — для тех, что опережают. См. Delay tuning и keepalive и Измерение латентности каждой колонки через MassDroid. |
listen_host | Переопределение advertised host для listener’а этого устройства |
listen_port | Пользовательский порт listener’а; если не задан, runtime использует BASE_LISTEN_PORT + индекс устройства |
preferred_format | Предпочтительный аудиоформат |
keepalive_silence | Legacy-совместимый флаг из старых addon-конфигов; отдельного переключателя для него в текущем web UI нет |
keepalive_interval | Интервал keepalive-тишины в секундах; любое положительное значение включает keepalive, минимальный эффективный интервал — 30 секунд |
room_id | ID зоны / комнаты Home Assistant для устройства |
room_name | Понятное имя комнаты |
idle_disconnect_minutes | Отключить Bluetooth после указанного числа минут бездействия; 0 отключает |
enabled | При false устройство пропускается на старте |
Каждый эффективный listen_port должен быть уникальным для устройства. Если на одном хосте работает несколько bridge-экземпляров, задайте им разные диапазоны BASE_LISTEN_PORT или явные listen_port для каждого устройства.
Bluetooth-адаптеры
Заголовок раздела «Bluetooth-адаптеры»{ "BLUETOOTH_ADAPTERS": [ { "id": "hci0", "mac": "C0:FB:F9:62:D6:9D", "name": "Адаптер в гостиной" } ]}| Поле | Описание |
|---|---|
id | Имя интерфейса, например hci0 |
mac | MAC-адрес адаптера |
name | Понятная метка в UI |
Планирование портов и особенности HA Ingress
Заголовок раздела «Планирование портов и особенности HA Ingress»- HA Ingress использует динамически назначаемый Home Assistant Supervisor порт (
ingress_port: 0в манифесте аддона).WEB_PORT, заданный внутри аддона, не переопределяет ingress и не открывает параллельный прямой listener. - Multi-bridge setups вне HA addon mode должны использовать непересекающиеся диапазоны
WEB_PORTиBASE_LISTEN_PORT. Несколько вариантов аддона на одном HAOS-хосте уже получают разные дефолтыBASE_LISTEN_PORTпо каналам (8928 / 9028 / 9128) — listener’ы устройств не пересекаются автоматически. - Per-device overrides важнее:
listen_portиlisten_hostперекрывают top-level defaults. - Конфликт портов критичен для daemon: дублирующиеся
listen_portне дадут listener’у устройства забиндиться.
Переменные окружения
Заголовок раздела «Переменные окружения»Bridge читает переменные окружения при запуске. Они делятся на три группы: bootstrap-переменные, которые вы задаёте сами, контейнерные внутренности, устанавливаемые entrypoint.sh, и переменные аддона Home Assistant, внедряемые Supervisor.
Bootstrap-переменные
Заголовок раздела «Bootstrap-переменные»Наиболее часто используемые overrides. CONFIG_DIR всегда определяет, где находится config.json, а env-override для WEB_PORT / BASE_LISTEN_PORT разрешаются раньше сохранённых значений конфига.
| Переменная | По умолчанию | Описание |
|---|---|---|
CONFIG_DIR | /config | Путь к директории конфига |
WEB_PORT | 8080 (standalone) | Override прямого web UI порта для Docker / LXC / systemd. Игнорируется в HA addon mode — Supervisor назначает ingress-порт динамически, параллельного прямого listener’а bridge не открывает. |
BASE_LISTEN_PORT | 8928 (standalone) | Стартовый порт для auto-assigned player listeners. В HA addon mode per-channel дефолты: stable 8928, rc 9028, beta 9128 (чтобы варианты аддона не конфликтовали). |
TZ | из конфига | Override часового пояса, используемый при инициализации локального времени runtime |
BRIDGE_NAME | из конфига | Необязательный override имени bridge до появления сохранённого имени |
LOG_LEVEL | INFO | Уровень логирования: DEBUG, INFO, WARNING, ERROR. Также задаётся через конфиг или веб-интерфейс |
WEB_THREADS | 8 | Количество HTTP-потоков Waitress; увеличьте до 16 для 20+ устройств |
DEMO_MODE | (не задана) | Установите 1, true или yes для запуска в демо/эмуляционном режиме без реального Bluetooth-оборудования |
SENDSPIN_NAME | Sendspin-{hostname} | Override префикса имени плеера по умолчанию |
SENDSPIN_STATIC_DELAY_MS | 0 | Глобальный override статической задержки звука в миллисекундах (0–5 000). Значения вне диапазона клампятся; отрицательные значения в sendspin 7.0+ больше не принимаются. |
Контейнерные внутренности
Заголовок раздела «Контейнерные внутренности»Устанавливаются автоматически entrypoint.sh при запуске контейнера. Ручная настройка требуется редко.
| Переменная | По умолчанию | Описание |
|---|---|---|
PULSE_SERVER | (автоопределение) | Путь к сокету PulseAudio / PipeWire (например, unix:/run/audio/pulse.sock) |
PULSE_LATENCY_MSEC | из конфига (600) | Подсказка задержки PulseAudio в миллисекундах; берётся из ключа конфига PULSE_LATENCY_MSEC |
PULSE_SINK | (на подпроцесс) | PulseAudio-sink по умолчанию; задаётся отдельно для каждого подпроцесса устройства для маршрутизации звука на нужную колонку |
AUDIO_UID | 1000 | User ID для доступа к сокету PulseAudio |
AUDIO_GID | (из сокета) | Group ID для доступа к сокету PulseAudio |
DBUS_SYSTEM_BUS_ADDRESS | (автоопределение) | Путь к системному сокету D-Bus |
STARTUP_DEPENDENCY_WAIT_ATTEMPTS | 45 | Максимальное число попыток ожидания D-Bus, Bluetooth и аудио при старте |
STARTUP_DEPENDENCY_WAIT_DELAY_SECONDS | 1 | Задержка в секундах между проверками зависимостей при старте |
Переменные аддона Home Assistant
Заголовок раздела «Переменные аддона Home Assistant»Внедряются HA Supervisor; с точки зрения bridge — только для чтения.
| Переменная | По умолчанию | Описание |
|---|---|---|
SUPERVISOR_TOKEN | (только HA) | Токен API Home Assistant Supervisor; его наличие активирует addon-режим |
HA_CORE_URL | http://homeassistant:8123 | URL Home Assistant Core для auth-flow и API-вызовов |
HOSTNAME | (системный) | Hostname контейнера; используется для определения типа аддона |
SENDSPIN_HA_OPTIONS_FILE | /data/options.json | Путь к файлу опций аддона, записанному Supervisor |
SENDSPIN_HA_CONFIG_FILE | /data/config.json | Путь к транслированному конфигу, используемому в addon-режиме |