Skip to content

Commit 62f16d3

Browse files
committed
fix BLE scan and connect to work with latest bleak
1 parent e6a88e0 commit 62f16d3

3 files changed

Lines changed: 37 additions & 25 deletions

File tree

.vscode/launch.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,14 @@
7676
"justMyCode": true,
7777
"args": ["--debug", "--info"]
7878
},
79+
{
80+
"name": "meshtastic debug BLE",
81+
"type": "python",
82+
"request": "launch",
83+
"module": "meshtastic",
84+
"justMyCode": true,
85+
"args": ["--debug", "--ble", "--info"]
86+
},
7987
{
8088
"name": "meshtastic debug set region",
8189
"type": "python",

meshtastic/__main__.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ def common():
10501050
meshtastic.util.our_exit("BLE scan finished", 0)
10511051
return
10521052
elif args.ble:
1053-
client = BLEInterface(args.ble, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes)
1053+
client = BLEInterface(args.ble_dest, debugOut=logfile, noProto=args.noproto, noNodes=args.no_nodes)
10541054
elif args.host:
10551055
try:
10561056
client = meshtastic.tcp_interface.TCPInterface(
@@ -1119,6 +1119,12 @@ def addConnectionArgs(parser: argparse.ArgumentParser) -> argparse.ArgumentParse
11191119
group.add_argument(
11201120
"--ble",
11211121
help="The BLE device address or name to connect to",
1122+
action="store_true",
1123+
)
1124+
1125+
group.add_argument(
1126+
"--ble-dest",
1127+
help="The BLE device address or name to connect to",
11221128
default=None,
11231129
)
11241130

meshtastic/ble_interface.py

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
from threading import Thread, Event
88
from typing import Optional
99

10-
from bleak import BleakScanner, BleakClient
10+
from bleak import BleakScanner, BleakClient, BLEDevice
1111

1212
from meshtastic.mesh_interface import MeshInterface
1313
from 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

Comments
 (0)