Start Bluetooth device discovery scan Args: duration: Optional scan duration in seconds Returns: (success, message)
(self, duration: Optional[int] = None)
| 299 | return False, f"Error setting discoverable mode: {str(e)}" |
| 300 | |
| 301 | def start_scan(self, duration: Optional[int] = None) -> Tuple[bool, str]: |
| 302 | """ |
| 303 | Start Bluetooth device discovery scan |
| 304 | Args: |
| 305 | duration: Optional scan duration in seconds |
| 306 | Returns: (success, message) |
| 307 | """ |
| 308 | try: |
| 309 | self.logger.info("Starting Bluetooth device scan...") |
| 310 | |
| 311 | if self._is_windows(): |
| 312 | # On Windows, scanning is done via get_discovered_devices |
| 313 | # Just mark scanning as active |
| 314 | self.scan_active = True |
| 315 | self.scan_start_time = time.time() |
| 316 | |
| 317 | message = "Bluetooth device scan started (Windows mode)" |
| 318 | if duration: |
| 319 | message += f" (will run for {duration} seconds)" |
| 320 | message += ". Scanning for nearby Bluetooth devices..." |
| 321 | |
| 322 | self.logger.info("Windows Bluetooth scan initiated - devices will be discovered on demand") |
| 323 | return True, message |
| 324 | |
| 325 | # Linux-specific scanning code |
| 326 | # Ensure Bluetooth is powered on first |
| 327 | status = self.get_status() |
| 328 | if not status['enabled']: |
| 329 | power_success, power_msg = self.power_on() |
| 330 | if not power_success: |
| 331 | return False, f"Cannot start scan: {power_msg}" |
| 332 | |
| 333 | # Try multiple methods to start scanning |
| 334 | methods_tried = [] |
| 335 | scan_started = False |
| 336 | |
| 337 | # Method 1: Standard bluetoothctl scan on |
| 338 | try: |
| 339 | result = subprocess.run( |
| 340 | ['bluetoothctl', 'scan', 'on'], |
| 341 | capture_output=True, |
| 342 | text=True, |
| 343 | timeout=10, |
| 344 | ) |
| 345 | methods_tried.append(f"bluetoothctl scan on: rc={result.returncode}") |
| 346 | self.logger.info( |
| 347 | f"Method 1 - bluetoothctl scan on: returncode={result.returncode}, " |
| 348 | f"stdout='{result.stdout.strip()}', stderr='{result.stderr.strip()}'" |
| 349 | ) |
| 350 | |
| 351 | if result.returncode == 0: |
| 352 | # Treat a successful command as good enough; some stacks |
| 353 | # don't immediately report Discovering: yes via bluetoothctl show. |
| 354 | scan_started = True |
| 355 | methods_tried.append("scan command succeeded (no discovering check)") |
| 356 | |
| 357 | # Still try to read discovering state for diagnostics only. |
| 358 | try: |
no test coverage detected