Compare commits
3 Commits
2ac979e207
...
3f4c49ccf2
| Author | SHA1 | Date | |
|---|---|---|---|
| 3f4c49ccf2 | |||
| 126e27e29f | |||
| 9ae9e7873a |
2
app.py
2
app.py
@ -34,6 +34,8 @@ def _apply_startup_sound_defaults():
|
|||||||
settings.setValue("sound/premute_volume", premute_volume)
|
settings.setValue("sound/premute_volume", premute_volume)
|
||||||
if not settings.contains("sound/ducking_volume"):
|
if not settings.contains("sound/ducking_volume"):
|
||||||
settings.setValue("sound/ducking_volume", ducking_volume)
|
settings.setValue("sound/ducking_volume", ducking_volume)
|
||||||
|
if not settings.contains("bluetooth/music_mac"):
|
||||||
|
settings.setValue("bluetooth/music_mac", "")
|
||||||
|
|
||||||
applied_volume = settings.value("sound/base_volume", base_volume)
|
applied_volume = settings.value("sound/base_volume", base_volume)
|
||||||
try:
|
try:
|
||||||
|
|||||||
@ -4,7 +4,7 @@ from abc import ABC, abstractmethod
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from PySide6.QtCore import QObject, Signal
|
from PySide6.QtCore import QObject, Signal, QSettings
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -74,6 +74,18 @@ class BluetoothController(MediaSourceController):
|
|||||||
|
|
||||||
def __init__(self, bt_service: Any):
|
def __init__(self, bt_service: Any):
|
||||||
self._bt_service = bt_service
|
self._bt_service = bt_service
|
||||||
|
self._music_mac: str | None = None
|
||||||
|
|
||||||
|
def set_music_mac(self, mac: str | None) -> None:
|
||||||
|
"""Установить приоритетный MAC для музыки."""
|
||||||
|
self._music_mac = mac
|
||||||
|
# Синхронизируем с сервисом
|
||||||
|
if self._bt_service:
|
||||||
|
self._bt_service.set_music_mac(mac)
|
||||||
|
|
||||||
|
def get_music_mac(self) -> str | None:
|
||||||
|
"""Получить приоритетный MAC для музыки."""
|
||||||
|
return self._music_mac
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def name(self) -> str:
|
||||||
@ -184,6 +196,7 @@ class MediaController(QObject):
|
|||||||
def __init__(self, bt_service: Any = None, parent: QObject = None):
|
def __init__(self, bt_service: Any = None, parent: QObject = None):
|
||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._bt_service = bt_service
|
self._bt_service = bt_service
|
||||||
|
self._settings = QSettings("car_ui", "ui")
|
||||||
self._controllers: dict[str, MediaSourceController] = {}
|
self._controllers: dict[str, MediaSourceController] = {}
|
||||||
self._current_mode: str = "bluetooth"
|
self._current_mode: str = "bluetooth"
|
||||||
|
|
||||||
@ -192,7 +205,12 @@ class MediaController(QObject):
|
|||||||
|
|
||||||
def _register_controllers(self) -> None:
|
def _register_controllers(self) -> None:
|
||||||
"""Зарегистрировать все доступные контроллеры."""
|
"""Зарегистрировать все доступные контроллеры."""
|
||||||
self._controllers["bluetooth"] = BluetoothController(self._bt_service)
|
bt_controller = BluetoothController(self._bt_service)
|
||||||
|
# Читаем приоритетный MAC из настроек
|
||||||
|
music_mac = self._settings.value("bluetooth/music_mac", "")
|
||||||
|
if music_mac:
|
||||||
|
bt_controller.set_music_mac(music_mac)
|
||||||
|
self._controllers["bluetooth"] = bt_controller
|
||||||
self._controllers["carplay"] = CarPlayController()
|
self._controllers["carplay"] = CarPlayController()
|
||||||
# В будущем можно добавить:
|
# В будущем можно добавить:
|
||||||
# self._controllers["aux"] = AuxController()
|
# self._controllers["aux"] = AuxController()
|
||||||
@ -203,8 +221,15 @@ class MediaController(QObject):
|
|||||||
# Если переключаемся с Bluetooth на CarPlay - ставим паузу
|
# Если переключаемся с Bluetooth на CarPlay - ставим паузу
|
||||||
if self._current_mode == "bluetooth" and mode == "carplay":
|
if self._current_mode == "bluetooth" and mode == "carplay":
|
||||||
self._controllers["bluetooth"].pause()
|
self._controllers["bluetooth"].pause()
|
||||||
elif self._current_mode == "carplay" and mode == "bluetooth":
|
|
||||||
self._controllers["bluetooth"].play()
|
# Если переключаемся на Bluetooth - подключаем приоритетное устройство
|
||||||
|
elif mode == "bluetooth":
|
||||||
|
bt_controller = self._controllers["bluetooth"]
|
||||||
|
music_mac = bt_controller.get_music_mac()
|
||||||
|
if music_mac:
|
||||||
|
# Пытаемся подключить приоритетное устройство
|
||||||
|
bt_controller.connect_device(music_mac)
|
||||||
|
|
||||||
self._current_mode = mode
|
self._current_mode = mode
|
||||||
# Сигнал о смене режима для обновления UI
|
# Сигнал о смене режима для обновления UI
|
||||||
self.metadata_changed.emit(self.get_metadata())
|
self.metadata_changed.emit(self.get_metadata())
|
||||||
|
|||||||
@ -47,6 +47,7 @@ class BluetoothService(QObject):
|
|||||||
super().__init__(parent)
|
super().__init__(parent)
|
||||||
self._log_path = Path("~/.cache/car_ui/bluetooth.log").expanduser()
|
self._log_path = Path("~/.cache/car_ui/bluetooth.log").expanduser()
|
||||||
self._last_error = ""
|
self._last_error = ""
|
||||||
|
self._settings = QSettings("car_ui", "ui")
|
||||||
|
|
||||||
# === Public API ===
|
# === Public API ===
|
||||||
|
|
||||||
@ -95,32 +96,57 @@ class BluetoothService(QObject):
|
|||||||
return info.get("Connected", "no") == "yes"
|
return info.get("Connected", "no") == "yes"
|
||||||
|
|
||||||
def connect_device(self, mac: str) -> bool:
|
def connect_device(self, mac: str) -> bool:
|
||||||
"""Подключиться к устройству."""
|
"""Подключиться к устройству.
|
||||||
|
|
||||||
|
При успешном подключении обновляет bluetooth/music_mac.
|
||||||
|
"""
|
||||||
self._last_error = ""
|
self._last_error = ""
|
||||||
self._run_cmd(["bluetoothctl", "trust", mac])
|
self._run_cmd(["bluetoothctl", "trust", mac])
|
||||||
result = self._run_cmd(["bluetoothctl", "connect", mac])
|
result = self._run_cmd(["bluetoothctl", "connect", mac])
|
||||||
success = not self._last_error
|
success = not self._last_error
|
||||||
|
if success:
|
||||||
|
# Обновляем приоритетный MAC
|
||||||
|
self._settings.setValue("bluetooth/music_mac", mac)
|
||||||
self.connected_changed.emit(mac, success)
|
self.connected_changed.emit(mac, success)
|
||||||
return success
|
return success
|
||||||
|
|
||||||
def disconnect_device(self, mac: str) -> bool:
|
def disconnect_device(self, mac: str) -> bool:
|
||||||
"""Отключить устройство."""
|
"""Отключить устройство.
|
||||||
|
|
||||||
|
Если это устройство было в bluetooth/music_mac, обнуляем настройку.
|
||||||
|
"""
|
||||||
self._last_error = ""
|
self._last_error = ""
|
||||||
result = self._run_cmd(["bluetoothctl", "disconnect", mac])
|
result = self._run_cmd(["bluetoothctl", "disconnect", mac])
|
||||||
success = not self._last_error
|
success = not self._last_error
|
||||||
|
# Если отключаем приоритетное устройство, обнуляем настройку
|
||||||
|
if success and self._settings.value("bluetooth/music_mac") == mac:
|
||||||
|
self._settings.setValue("bluetooth/music_mac", "")
|
||||||
self.connected_changed.emit(mac, False)
|
self.connected_changed.emit(mac, False)
|
||||||
return success
|
return success
|
||||||
|
|
||||||
def remove_device(self, mac: str) -> bool:
|
def remove_device(self, mac: str) -> bool:
|
||||||
"""Удалить устройство из списка сопряженных."""
|
"""Удалить устройство из списка сопряженных.
|
||||||
|
|
||||||
|
Если это устройство было в bluetooth/music_mac, обнуляем настройку.
|
||||||
|
"""
|
||||||
self._last_error = ""
|
self._last_error = ""
|
||||||
# Сначала отключаем, если подключено
|
# Сначала отключаем, если подключено
|
||||||
if self.is_connected(mac):
|
if self.is_connected(mac):
|
||||||
self._run_cmd(["bluetoothctl", "disconnect", mac])
|
self._run_cmd(["bluetoothctl", "disconnect", mac])
|
||||||
result = self._run_cmd(["bluetoothctl", "remove", mac])
|
result = self._run_cmd(["bluetoothctl", "remove", mac])
|
||||||
success = not self._last_error
|
success = not self._last_error
|
||||||
|
# Если удаляем приоритетное устройство, обнуляем настройку
|
||||||
|
if success and self._settings.value("bluetooth/music_mac") == mac:
|
||||||
|
self._settings.setValue("bluetooth/music_mac", "")
|
||||||
return success
|
return success
|
||||||
|
|
||||||
|
def set_music_mac(self, mac: str | None) -> None:
|
||||||
|
"""Установить приоритетный MAC для музыки."""
|
||||||
|
if mac:
|
||||||
|
self._settings.setValue("bluetooth/music_mac", mac)
|
||||||
|
else:
|
||||||
|
self._settings.setValue("bluetooth/music_mac", "")
|
||||||
|
|
||||||
def make_discoverable(self, timeout_sec: int = 10) -> bool:
|
def make_discoverable(self, timeout_sec: int = 10) -> bool:
|
||||||
"""Сделать устройство видимым для сопряжения.
|
"""Сделать устройство видимым для сопряжения.
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user