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

Январь – 1 марта: Истоки и взрыв функций v1

Январь 2026 — Архитектура v0: один файл, одна колонка

Заголовок раздела «Январь 2026 — Архитектура v0: один файл, одна колонка»

Состояние кода: единственный файл sendspin_client.py ≈ 400 строк.

Схема максимально простая:

MA Server ──(WebSocket/Sendspin)──► sendspin CLI ──(PulseAudio)──► bluetoothctl ──► BT Speaker

Bluetooth-менеджер опрашивает соединение раз в 10 секунд через bluetoothctl info <MAC>. Отключение обнаруживается с задержкой до 10 с. Веб-интерфейс показывает минимальный статус; ничего не настраивается.

Первые PR из родительского репозитория добавляют полноценный D-Bus мониторинг вместо таймерного опроса — статус BT обновляется мгновенно по системному событию.

Ключевое ограничение этой фазы: нет поддержки нескольких колонок. В PulseAudio — единственный PULSE_SINK, и куда sendspin отправляет аудио — туда оно и идёт. Две колонки = неоднозначность.


27 февраля – 1 марта 2026 — Взрыв функций (v1.0–1.7, ~130 коммитов за 3 дня)

Заголовок раздела «27 февраля – 1 марта 2026 — Взрыв функций (v1.0–1.7, ~130 коммитов за 3 дня)»

Самый быстрый период разработки. 73 коммита только 28 февраля.

Поддержка нескольких устройств и HA addon (28 февраля)

Заголовок раздела «Поддержка нескольких устройств и HA addon (28 февраля)»

Репозиторий переименован из sendspin-client в sendspin-bt-bridge — имя отражает новую роль: не клиент, а мост.

Ключевые дополнения за один день:

  • Multi-device: каждая запись в BLUETOOTH_DEVICES в конфиге запускает свою пару BluetoothManager + SendspinClient. В MA появляются несколько независимых плееров.
  • Home Assistant addon (ha-addon/): манифест, Dockerfile, run.sh. Мост интегрируется в панель HA Ingress; тема внедряется через postMessage API.
  • Proxmox LXC: proxmox-create.sh разворачивает нативный контейнер одной командой. Внутри — свой bluetoothd через D-Bus bridge, pulseaudio --system, avahi-daemon.
  • Полноценный веб-интерфейс: карточки устройств, BT-сканирование, управление громкостью, кнопки reconnect/re-pair, диагностика.
  • Управление BT-адаптерами: автодетекция, ручной выбор, привязка колонки к конкретному hci.

Основная цель — поддержка нескольких экземпляров моста, подключённых к одному MA-серверу. Когда два моста регистрируют плеер с одним именем — например "Living Room" — MA не может отличить их по имени: при появлении второго сбрасывалась очередь первого или они путались. player_id должен быть глобально уникальным и стабильным вне зависимости от имени плеера.

Решение: UUID5 из MAC-адреса (v1.3.0). UUID детерминирован (идентичен при каждом перезапуске), глобально уникален (MAC физически уникален) и не зависит от имени плеера. Два моста с разными колонками → два разных player_id → MA видит их как полностью независимых плееров, даже если имена совпадают.

Это также решило побочную, но не менее заметную проблему: раньше MA терял плеер при перезапуске или переименовании моста — очереди и группы сбрасывались. После v1.3.0 player_id никогда не меняется.

Параллельно — MPRIS D-Bus интеграция (v1.3.16): мост регистрирует себя как объект MediaPlayer2 на сессионной шине. MA может читать статус воспроизведения и управлять плеером через стандартный интерфейс. При остановке сервиса сначала отправляется MPRIS Pause — MA корректно останавливает группу до того, как плеер исчезнет из сети.

Идентификация плееров в MA-группах (v1.3.19): проблема в том, что MA строит syncgroup-ы по имени плеера. Была добавлена логика, обеспечивающая совпадение BRIDGE_NAME + суффикс + MPRIS Identity — чтобы имя плеера в MA соответствовало имени MPRIS-объекта; иначе группа не формируется.

Редизайн UI в стиле HA/MA с поддержкой тем (1 марта, v1.3.7)

Заголовок раздела «Редизайн UI в стиле HA/MA с поддержкой тем (1 марта, v1.3.7)»

До этой версии веб-интерфейс выглядел как типовой дашборд: фиолетовый градиент в хедере (#667eea), хардкод HSL-цветов, системный шрифт. При открытии через HA Ingress он визуально не вписывался в экосистему.

В v1.3.7 UI полностью переписан под визуальный язык Home Assistant и Music Assistant:

CSS custom properties вместо хардкода

/* before */
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: #28a745;
/* after */
background: var(--app-header-background-color, #03a9f4);
color: var(--success-color, #4CAF50);

Все цвета идут через HA design tokens (--primary-color, --error-color, --success-color, --warning-color, --ha-card-border-radius, --ha-card-box-shadow). Хедер оформлен как HA app-toolbar. Шрифт: Roboto (тот же, что использует HA).

Двойная схема тем: media query + Ingress postMessage

/* static theme — works everywhere */
@media (prefers-color-scheme: dark) {
:root { --primary-background-color: #111; ... }
}
// live theme injection from HA — Ingress only
window.addEventListener('message', (e) => {
if (e.data?.type === 'setTheme') applyTheme(e.data.theme);
});

Когда пользователь открывает UI через сайдбар HA, HA отправляет postMessage с текущей темой. Переключение темы в HA → мгновенно отражается в веб-интерфейсе без перезагрузки страницы. Если UI открыт напрямую (не через Ingress) — тема определяется системным prefers-color-scheme.

Результат: начиная с v1.3.7, веб-интерфейс визуально неотличим от нативных HA-панелей. Пользователи, добавляющие мост в сайдбар HA, видят согласованный дизайн.

Последующие итерации UI (v2.6.5, v2.6.6, v2.7.x) продолжили полировку: прогресс-бар трека, транспортные кнопки, обложка альбома, hover-действия, анимированное BT-сканирование, мобильная адаптация, UX-аудит с 20 улучшениями (v2.10.x).

Безопасность и надёжность (1–2 марта, v1.4–1.7)

Заголовок раздела «Безопасность и надёжность (1–2 марта, v1.4–1.7)»
  • Модуляризация (v1.4.0): монолитный sendspin_client.py разбит на config.py, mpris.py, bluetooth_manager.py.
  • Сайт документации (v1.4.2): Astro Starlight, двуязычный (EN/RU), деплой на GitHub Pages.
  • Аутентификация веб-интерфейса (v1.6.0): PBKDF2-SHA256 для standalone-режима; в HA addon — проксирование через HA Core login_flow с поддержкой 2FA/TOTP.
  • D-Bus BT-монитор (v1.7.0): переход от опроса к event-driven мониторингу Bluetooth — мост узнаёт об отключении в момент события, а не через 10 секунд.
  • Настраиваемый интервал BT-проверки и автоматическое отключение после N неудачных попыток переподключения.