Comprehensive Bluetooth management class for Ragnar Supports both Classic Bluetooth and BLE operations Works on both Linux (bluetoothctl) and Windows (PowerShell)
| 21 | b_parent = None |
| 22 | |
| 23 | class BluetoothManager: |
| 24 | """ |
| 25 | Comprehensive Bluetooth management class for Ragnar |
| 26 | Supports both Classic Bluetooth and BLE operations |
| 27 | Works on both Linux (bluetoothctl) and Windows (PowerShell) |
| 28 | """ |
| 29 | |
| 30 | def __init__(self, logger=None): |
| 31 | self.logger = logger or logging.getLogger(__name__) |
| 32 | self.scan_active = False |
| 33 | self.scan_start_time = 0.0 |
| 34 | self.discovered_devices = {} |
| 35 | self.paired_devices = {} |
| 36 | self.os_type = platform.system() # 'Linux', 'Windows', 'Darwin' |
| 37 | self.logger.info(f"BluetoothManager initialized for {self.os_type}") |
| 38 | |
| 39 | def _is_windows(self) -> bool: |
| 40 | """Check if running on Windows""" |
| 41 | return self.os_type == 'Windows' |
| 42 | |
| 43 | def _is_linux(self) -> bool: |
| 44 | """Check if running on Linux""" |
| 45 | return self.os_type == 'Linux' |
| 46 | |
| 47 | def check_bluetooth_availability(self) -> Tuple[bool, str]: |
| 48 | """ |
| 49 | Check if Bluetooth is available on the system |
| 50 | Returns: (available, message) |
| 51 | """ |
| 52 | try: |
| 53 | if self._is_windows(): |
| 54 | # Check Windows Bluetooth availability using PowerShell |
| 55 | ps_script = """ |
| 56 | $adapters = Get-PnpDevice -Class Bluetooth -Status OK |
| 57 | if ($adapters) { Write-Output "Available" } else { Write-Output "NotFound" } |
| 58 | """ |
| 59 | result = subprocess.run(['powershell', '-Command', ps_script], |
| 60 | capture_output=True, text=True, timeout=10) |
| 61 | |
| 62 | if result.returncode == 0 and 'Available' in result.stdout: |
| 63 | return True, "Bluetooth available on Windows" |
| 64 | else: |
| 65 | return False, "No Bluetooth adapters found on Windows" |
| 66 | else: |
| 67 | # Linux/Unix method |
| 68 | result = subprocess.run(['bluetoothctl', '--version'], |
| 69 | capture_output=True, text=True, timeout=5) |
| 70 | if result.returncode == 0: |
| 71 | return True, "Bluetooth available" |
| 72 | else: |
| 73 | return False, "bluetoothctl not found or not working" |
| 74 | except FileNotFoundError: |
| 75 | if self._is_windows(): |
| 76 | return False, "PowerShell not found" |
| 77 | else: |
| 78 | return False, "bluetoothctl command not found" |
| 79 | except subprocess.TimeoutExpired: |
| 80 | return False, "Bluetooth check command timed out" |
no outgoing calls
no test coverage detected