蓝牙双重discover
Showing
1 changed file
with
35 additions
and
12 deletions
| ... | @@ -127,6 +127,7 @@ class BLEClient: | ... | @@ -127,6 +127,7 @@ class BLEClient: |
| 127 | self.notification_records = defaultdict(lambda: (None, 0.0)) # 特征ID: (最后消息, 时间戳) | 127 | self.notification_records = defaultdict(lambda: (None, 0.0)) # 特征ID: (最后消息, 时间戳) |
| 128 | self._notification_callbacks = {} # 存储通知回调,用于清理 | 128 | self._notification_callbacks = {} # 存储通知回调,用于清理 |
| 129 | self._shutdown = False # 添加关闭标志 | 129 | self._shutdown = False # 添加关闭标志 |
| 130 | self._scanner = None # 当前扫描器实例 | ||
| 130 | 131 | ||
| 131 | def on_disconnect(self, client): | 132 | def on_disconnect(self, client): |
| 132 | print("BLE连接断开,关闭WebSocket") | 133 | print("BLE连接断开,关闭WebSocket") |
| ... | @@ -159,8 +160,22 @@ class BLEClient: | ... | @@ -159,8 +160,22 @@ class BLEClient: |
| 159 | print(f"制造商数据: {adv_data.manufacturer_data}") | 160 | print(f"制造商数据: {adv_data.manufacturer_data}") |
| 160 | print(f"服务数据: {adv_data.service_data}") | 161 | print(f"服务数据: {adv_data.service_data}") |
| 161 | print(f"本地名称: {adv_data.local_name}") | 162 | print(f"本地名称: {adv_data.local_name}") |
| 163 | # 发现设备后,尝试立即停止扫描 | ||
| 164 | try: | ||
| 165 | if self._scanner is not None: | ||
| 166 | # 在事件循环中停止扫描,避免阻塞回调 | ||
| 167 | asyncio.create_task(self._stop_scan_early()) | ||
| 168 | except Exception: | ||
| 169 | pass | ||
| 162 | return self.target_device | 170 | return self.target_device |
| 163 | 171 | ||
| 172 | async def _stop_scan_early(self): | ||
| 173 | try: | ||
| 174 | if self._scanner is not None: | ||
| 175 | await self._scanner.stop() | ||
| 176 | except Exception: | ||
| 177 | pass | ||
| 178 | |||
| 164 | async def handle_client(self, websocket, path): | 179 | async def handle_client(self, websocket, path): |
| 165 | self.websocket = websocket | 180 | self.websocket = websocket |
| 166 | if path != "/scratch/ble": | 181 | if path != "/scratch/ble": |
| ... | @@ -186,24 +201,32 @@ class BLEClient: | ... | @@ -186,24 +201,32 @@ class BLEClient: |
| 186 | self.services.extend(filt.get("services", [])) | 201 | self.services.extend(filt.get("services", [])) |
| 187 | self.optional_services = params.get("optionalServices", []) | 202 | self.optional_services = params.get("optionalServices", []) |
| 188 | 203 | ||
| 189 | scanner = BleakScanner(scanning_mode="active") | 204 | # 双重扫描:快速扫描后若未发现,再进行扩展扫描;发现即停 |
| 190 | scanner.register_detection_callback(self.detection_callback) | 205 | phases = [("active", 3.0), ("passive", 6.0)] |
| 191 | |||
| 192 | max_retries = 3 | ||
| 193 | found = False | 206 | found = False |
| 194 | for attempt in range(max_retries): | 207 | for phase_index, (scan_mode, duration) in enumerate(phases, start=1): |
| 195 | self.target_device = None | 208 | self.target_device = None |
| 196 | await scanner.start() | 209 | self._scanner = BleakScanner(scanning_mode=scan_mode) |
| 197 | await asyncio.sleep(5) | 210 | self._scanner.register_detection_callback(self.detection_callback) |
| 198 | await scanner.stop() | 211 | print(f"开始第{phase_index}阶段扫描(模式: {scan_mode}, 时长: {duration}s)...") |
| 212 | try: | ||
| 213 | await self._scanner.start() | ||
| 214 | # 轮询检查是否已找到,找到则提前停止 | ||
| 215 | start_ts = time.time() | ||
| 216 | while time.time() - start_ts < duration and not self.target_device: | ||
| 217 | await asyncio.sleep(0.1) | ||
| 218 | finally: | ||
| 219 | try: | ||
| 220 | await self._scanner.stop() | ||
| 221 | except Exception: | ||
| 222 | pass | ||
| 223 | self._scanner = None | ||
| 199 | 224 | ||
| 200 | if self.target_device: | 225 | if self.target_device: |
| 201 | found = True | 226 | found = True |
| 202 | break | 227 | break |
| 203 | 228 | else: | |
| 204 | if attempt < max_retries - 1: | 229 | print(f"第{phase_index}阶段未找到设备") |
| 205 | print(f"未找到设备,第{attempt+1}次重试...") | ||
| 206 | await asyncio.sleep(3) | ||
| 207 | 230 | ||
| 208 | if found: | 231 | if found: |
| 209 | device, adv_data = self.target_device | 232 | device, adv_data = self.target_device | ... | ... |
-
Please register or sign in to post a comment