diff -r df2ff78bbc01 -r 0122ae72618d src/eric7/MicroPython/Devices/CircuitPythonDevices.py --- a/src/eric7/MicroPython/Devices/CircuitPythonDevices.py Tue Mar 07 16:23:03 2023 +0100 +++ b/src/eric7/MicroPython/Devices/CircuitPythonDevices.py Wed Mar 08 14:25:24 2023 +0100 @@ -1153,6 +1153,7 @@ @return flag indicating the availability of Bluetooth @rtype bool + @exception OSError raised to indicate an issue with the device """ command = """ def has_bt(): @@ -1182,6 +1183,7 @@ @return list of tuples containing the translated status data label and the associated value @rtype list of tuples of (str, str) + @exception OSError raised to indicate an issue with the device """ command = """ def ble_status(): @@ -1235,6 +1237,7 @@ @return flag indicating the new state of the Bluetooth interface @rtype bool + @exception OSError raised to indicate an issue with the device """ command = """ def activate_ble(): @@ -1260,6 +1263,7 @@ @return flag indicating the new state of the Bluetooth interface @rtype bool + @exception OSError raised to indicate an issue with the device """ command = """ def deactivate_ble(): @@ -1279,6 +1283,83 @@ return out.strip() == b"True" + def getDeviceScan(self, timeout=10): + """ + Public method to perform a Bluetooth device scan. + + @param timeout duration of the device scan in seconds (defaults + to 10) + @type int (optional) + @return tuple containing a dictionary with the scan results and + an error string + @rtype tuple of (dict, str) + """ + from ..BluetoothDialogs.BluetoothAdvertisement import ( + ADV_IND, + ADV_SCAN_IND, + SCAN_RSP, + BluetoothAdvertisement, + ) + + command = """ +def ble_scan(): + import _bleio + import binascii + import time + + a = _bleio.adapter + + ble_enabled = a.enabled + if not ble_enabled: + a.enabled = True + + scanResults = a.start_scan( + buffer_size=1024, extended=True, timeout={0}, minimum_rssi=-100, active=True + ) + time.sleep(10) + a.stop_scan() + + for res in scanResults: + print({{ + 'address': binascii.hexlify( + bytes(reversed(res.address.address_bytes)), ':' + ).decode(), + 'advertisement': res.advertisement_bytes, + 'connectable': res.connectable, + 'rssi': res.rssi, + 'scan_response': res.scan_response, + }}) + + if not ble_enabled: + a.enabled = False + +ble_scan() +del ble_scan +""".format( + timeout + ) + out, err = self._interface.execute( + command, mode=self._submitMode, timeout=(timeout + 5) * 1000 + ) + if err: + return {}, err + + scanResults = {} + for line in out.decode("utf-8").splitlines(): + res = ast.literal_eval(line) + address = res["address"] + if address not in scanResults: + scanResults[address] = BluetoothAdvertisement(address) + if res["scan_response"]: + advType = SCAN_RSP + elif res["connectable"]: + advType = ADV_IND + else: + advType = ADV_SCAN_IND + scanResults[address].update(advType, res["rssi"], res["advertisement"]) + + return scanResults, "" + def createDevice(microPythonWidget, deviceType, vid, pid, boardName, serialNumber): """