77from threading import Thread , Event
88from typing import Optional
99
10- from bleak import BleakScanner , BleakClient
10+ from bleak import BleakScanner , BleakClient , BLEDevice
1111
1212from meshtastic .mesh_interface import MeshInterface
1313from meshtastic .util import our_exit
@@ -35,9 +35,6 @@ class BLEState(): # pylint: disable=C0115
3535 def __init__ (self , address : Optional [str ], noProto : bool = False , debugOut = None , noNodes : bool = False ):
3636 self .state = BLEInterface .BLEState ()
3737
38- if not address :
39- return
40-
4138 self .should_read = False
4239
4340 logging .debug ("Threads starting" )
@@ -54,10 +51,9 @@ def __init__(self, address: Optional[str], noProto: bool = False, debugOut = Non
5451 self .client = self .connect (address )
5552 self .state .BLE = True
5653 logging .debug ("BLE connected" )
57- except BLEInterface .BLEError as e :
54+ # except BLEInterface.BLEError as e:
55+ finally :
5856 self .close ()
59- our_exit (e .message , 1 )
60- return
6157
6258 logging .debug ("Mesh init starting" )
6359 MeshInterface .__init__ (self , debugOut = debugOut , noProto = noProto , noNodes = noNodes )
@@ -78,33 +74,35 @@ async def from_num_handler(self, _, b): # pylint: disable=C0116
7874 self .should_read = True
7975
8076
81- def scan (self ):
82- "Scan for available BLE devices"
77+ def scan (self ) -> list [ BLEDevice ] :
78+ """ Scan for available BLE devices."" "
8379 with BLEClient () as client :
84- return [
85- (x [0 ], x [1 ]) for x in (client .discover (
80+ response = client .discover (
8681 return_adv = True ,
87- service_uuids = [ SERVICE_UUID ]
88- )).values ()
89- ]
82+ service_uuids = [SERVICE_UUID ]
83+ )
9084
85+ devices = response .values ()
9186
92- def find_device (self , address ):
93- "Find a device by address"
94- meshtastic_devices = self .scan ()
87+ # bleak sometimes returns devices we didn't ask for, so filter the response
88+ # to only return true meshtastic devices
89+ # d[0] is the device. d[1] is the advertisement data
90+ devices = list (filter (lambda d : SERVICE_UUID in d [1 ].service_uuids , devices ))
91+ return list (map (lambda d : d [0 ], devices ))
9592
96- addressed_devices = list (filter (lambda x : address in (x [1 ].local_name , x [0 ].name ), meshtastic_devices ))
97- # If nothing is found try on the address
98- if len (addressed_devices ) == 0 :
99- addressed_devices = list (filter (
100- lambda x : BLEInterface ._sanitize_address (address ) == BLEInterface ._sanitize_address (x [0 ].address ),
101- meshtastic_devices ))
93+
94+ def find_device (self , address : Optional [str ]) -> BLEDevice :
95+ """Find a device by address"""
96+ addressed_devices = self .scan ()
97+
98+ if address :
99+ addressed_devices = list (filter (lambda x : address == x .name or address == x .address , addressed_devices ))
102100
103101 if len (addressed_devices ) == 0 :
104102 raise BLEInterface .BLEError (f"No Meshtastic BLE peripheral with identifier or address '{ address } ' found. Try --ble-scan to find it." )
105103 if len (addressed_devices ) > 1 :
106104 raise BLEInterface .BLEError (f"More than one Meshtastic BLE peripheral with identifier or address '{ address } ' found." )
107- return addressed_devices [0 ][ 0 ]
105+ return addressed_devices [0 ]
108106
109107 def _sanitize_address (address ): # pylint: disable=E0213
110108 "Standardize BLE address by removing extraneous characters and lowercasing"
0 commit comments