Get list of discovered Bluetooth devices Args: refresh: Whether to refresh device information Returns: Dictionary of devices keyed by MAC address
(self, refresh: bool = True)
| 473 | return False, f"Error stopping scan: {str(e)}" |
| 474 | |
| 475 | def get_discovered_devices(self, refresh: bool = True) -> Dict[str, Dict[str, Any]]: |
| 476 | """ |
| 477 | Get list of discovered Bluetooth devices |
| 478 | Args: |
| 479 | refresh: Whether to refresh device information |
| 480 | Returns: Dictionary of devices keyed by MAC address |
| 481 | """ |
| 482 | devices = {} |
| 483 | |
| 484 | try: |
| 485 | if self._is_windows(): |
| 486 | # Windows-specific device discovery using PowerShell |
| 487 | devices = self._get_windows_bluetooth_devices() |
| 488 | self.logger.info(f"Windows Bluetooth scan found {len(devices)} devices") |
| 489 | else: |
| 490 | # Linux method |
| 491 | # If scanning is active, use scan results method which captures real-time discoveries |
| 492 | if self.scan_active or self._check_scan_status(): |
| 493 | self.logger.info("Scanning is active, getting scan results...") |
| 494 | scan_devices = self._get_scan_results() |
| 495 | if scan_devices: |
| 496 | # Enrich device names with detailed info from bluetoothctl |
| 497 | self.logger.info(f"Enriching {len(scan_devices)} discovered devices with detailed info...") |
| 498 | scan_devices = self._enrich_device_names(scan_devices) |
| 499 | devices.update(scan_devices) |
| 500 | self.logger.info(f"Found {len(scan_devices)} devices from active scan") |
| 501 | |
| 502 | # Also check for cached/paired devices from bluetoothctl devices |
| 503 | result = subprocess.run(['bluetoothctl', 'devices'], |
| 504 | capture_output=True, text=True, timeout=10) |
| 505 | |
| 506 | self.logger.info(f"bluetoothctl devices returned: returncode={result.returncode}, stdout='{result.stdout.strip()}', stderr='{result.stderr.strip()}'") |
| 507 | |
| 508 | if result.returncode == 0: |
| 509 | for line in result.stdout.strip().split('\n'): |
| 510 | line = line.strip() |
| 511 | self.logger.debug(f"Processing device line: '{line}'") |
| 512 | if line and line.startswith('Device '): |
| 513 | parts = line.split(None, 2) |
| 514 | if len(parts) >= 2: |
| 515 | address = parts[1] |
| 516 | name = parts[2] if len(parts) > 2 else 'Unknown Device' |
| 517 | |
| 518 | # Only add if not already in devices (scan results take priority) |
| 519 | if address not in devices: |
| 520 | self.logger.info(f"Found cached device: {address} - {name}") |
| 521 | |
| 522 | device_info = { |
| 523 | 'address': address, |
| 524 | 'name': name, |
| 525 | 'rssi': None, |
| 526 | 'device_class': None, |
| 527 | 'device_type': 'Cached', |
| 528 | 'services': [], |
| 529 | 'paired': False, |
| 530 | 'connected': False, |
| 531 | 'trusted': False, |
| 532 | 'last_seen': time.time() |
no test coverage detected