8b08c35f by huangyf2

蓝牙双重discover

1 parent 1fb31449
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
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!