Python bluepy.btle.Scanner() Examples

The following are 28 code examples of bluepy.btle.Scanner(). You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may also want to check out all available functions/classes of the module bluepy.btle , or try the search function .
Example #1
Source File: manager.py    From BlueSTSDK_Python with BSD 3-Clause "New" or "Revised" License 8 votes vote down vote up
def __init__(self, show_warnings=False, *args, **kwargs):
        """Constructor.

        Args:
            show_warnings (bool, optional): If True shows warnings, if any, when
            discovering devices not respecting the BlueSTSDK's advertising
            data format, nothing otherwise.
        """
        try:
            super(_StoppableScanner, self).__init__(*args, **kwargs)
            self._stop_called = threading.Event()
            self._process_done = threading.Event()
            with lock(self):
                self._scanner = Scanner().withDelegate(_ScannerDelegate(show_warnings))
        except BTLEException as e:
            # Save details of the exception raised but don't re-raise, just
            # complete the function.
            import sys
            self._exc = sys.exc_info() 
Example #2
Source File: read_waveplus.py    From waveplus-reader with MIT License 7 votes vote down vote up
def connect(self):
        # Auto-discover device on first connection
        if (self.MacAddr is None):
            scanner     = Scanner().withDelegate(DefaultDelegate())
            searchCount = 0
            while self.MacAddr is None and searchCount < 50:
                devices      = scanner.scan(0.1) # 0.1 seconds scan period
                searchCount += 1
                for dev in devices:
                    ManuData = dev.getValueText(255)
                    SN = parseSerialNumber(ManuData)
                    if (SN == self.SN):
                        self.MacAddr = dev.addr # exits the while loop on next conditional check
                        break # exit for loop
            
            if (self.MacAddr is None):
                print "ERROR: Could not find device."
                print "GUIDE: (1) Please verify the serial number."
                print "       (2) Ensure that the device is advertising."
                print "       (3) Retry connection."
                sys.exit(1)
        
        # Connect to device
        if (self.periph is None):
            self.periph = Peripheral(self.MacAddr)
        if (self.curr_val_char is None):
            self.curr_val_char = self.periph.getCharacteristics(uuid=self.uuid)[0] 
Example #3
Source File: ble_connector.py    From thingsboard-gateway with Apache License 2.0 6 votes vote down vote up
def __init__(self, gateway, config, connector_type):
        super().__init__()
        self.__connector_type = connector_type
        self.__default_services = list(range(0x1800, 0x183A))
        self.statistics = {'MessagesReceived': 0,
                           'MessagesSent': 0}
        self.__gateway = gateway
        self.__config = config
        self.setName(self.__config.get("name",
                                       'BLE Connector ' + ''.join(choice(ascii_lowercase) for _ in range(5))))

        self._connected = False
        self.__stopped = False
        self.__previous_scan_time = time.time() - 10000
        self.__previous_read_time = time.time() - 10000
        self.__check_interval_seconds = self.__config['checkIntervalSeconds'] if self.__config.get(
            'checkIntervalSeconds') is not None else 10
        self.__rescan_time = self.__config['rescanIntervalSeconds'] if self.__config.get(
            'rescanIntervalSeconds') is not None else 10
        self.__scanner = Scanner().withDelegate(ScanDelegate(self))
        self.__devices_around = {}
        self.__available_converters = []
        self.__notify_delegators = {}
        self.__fill_interest_devices()
        self.daemon = True 
Example #4
Source File: ganglion.py    From pyOpenBCI with MIT License 6 votes vote down vote up
def _find_mac():
    """Finds and returns the mac address of the first Ganglion board
    found"""
    scanner = Scanner()
    devices = scanner.scan(5)

    if len(devices) < 1:
        raise OSError(
            'No nearby Devices found. Make sure your Bluetooth Connection '
            'is on.')

    else:
        gang_macs = []
        for dev in devices:
            for adtype, desc, value in dev.getScanData():
                if desc == 'Complete Local Name' and value.startswith(
                        'Ganglion'):
                    gang_macs.append(dev.addr)
                    print(value)

    if len(gang_macs) < 1:
        raise OSError('Cannot find OpenBCI Ganglion Mac address.')
    else:
        return gang_macs[0] 
Example #5
Source File: lib_blescan.py    From rpieasy with GNU General Public License v3.0 6 votes vote down vote up
def scan(self):
    result = False
    devices = []
    try:
     self.scanner = Scanner(self.bledev)
     devices = self.scanner.scan(self.timeout)
     result = True
     self.lastscan = time.time()
    except Exception as e:
     print("BLE error: ",e)
     self.devices = []
     self.devrssi = []
    tempdev = []
    temprssi = []
    for dev in devices:
      try:
       if self.bledev == int(dev.iface):
        temprssi.append(dev.rssi)
        tempdev.append(str(dev.addr).lower().strip())
      except:
        pass
    self.devices = tempdev
    self.devrrsi = temprssi
    return result 
Example #6
Source File: findMinidrone.py    From pyparrot with MIT License 6 votes vote down vote up
def main():
    scanner = Scanner().withDelegate(ScanDelegate())
    devices = scanner.scan(10.0)

    for dev in devices:
        #print "Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi)
        for (adtype, desc, value) in dev.getScanData():
            #print "  %s = %s" % (desc, value)
            if (desc == "Complete Local Name"):
                if ("Mambo" in value):
                    print("FOUND A MAMBO!")
                    print("Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi))
                    print("  %s = %s" % (desc, value))

                elif ("Swing" in value):
                    print("FOUND A SWING!")
                    print("Device %s (%s), RSSI=%d dB" % (dev.addr, dev.addrType, dev.rssi))
                    print("  %s = %s" % (desc, value)) 
Example #7
Source File: pr_rileylink.py    From omnipy with MIT License 6 votes vote down vote up
def _findRileyLink(self):
        global g_rl_address
        scanner = Scanner()
        g_rl_address = None
        self.logger.debug("Scanning for RileyLink")
        retries = 10
        while g_rl_address is None and retries > 0:
            retries -= 1
            for result in scanner.scan(1.0):
                if result.getValueText(7) == RILEYLINK_SERVICE_UUID:
                    self.logger.debug("Found RileyLink")
                    g_rl_address = result.addr

        if g_rl_address is None:
            raise PacketRadioError("Could not find RileyLink")

        return g_rl_address 
Example #8
Source File: blescanmulti.py    From bt-mqtt-gateway with MIT License 6 votes vote down vote up
def __init__(self, command_timeout, global_topic_prefix, **kwargs):
        from bluepy.btle import Scanner, DefaultDelegate

        class ScanDelegate(DefaultDelegate):
            def __init__(self):
                DefaultDelegate.__init__(self)

            def handleDiscovery(self, dev, isNewDev, isNewData):
                if isNewDev:
                    _LOGGER.debug("Discovered new device: %s" % dev.addr)

        super(BlescanmultiWorker, self).__init__(
            command_timeout, global_topic_prefix, **kwargs
        )
        self.scanner = Scanner().withDelegate(ScanDelegate())
        self.last_status = [
            BleDeviceStatus(self, mac, name) for name, mac in self.devices.items()
        ]
        _LOGGER.info("Adding %d %s devices", len(self.devices), repr(self)) 
Example #9
Source File: miscale.py    From bt-mqtt-gateway with MIT License 6 votes vote down vote up
def _get_data(self):
        from bluepy import btle

        scan_processor = ScanProcessor(self.mac)
        scanner = btle.Scanner().withDelegate(scan_processor)
        scanner.scan(self.SCAN_TIMEOUT, passive=True)

        with timeout(
            self.SCAN_TIMEOUT,
            exception=DeviceTimeoutError(
                "Retrieving data from {} device {} timed out after {} seconds".format(
                    repr(self), self.mac, self.SCAN_TIMEOUT
                )
            ),
        ):
            while not scan_processor.ready:
                time.sleep(1)
            return scan_processor.results

        return scan_processor.results 
Example #10
Source File: cbluepy.py    From pylgbst with MIT License 6 votes vote down vote up
def connect(self, hub_mac=None, hub_name=None):
        log.debug("Trying to connect client to MoveHub with MAC: %s", hub_mac)
        scanner = btle.Scanner()

        while not self._peripheral:
            log.info("Discovering devices...")
            scanner.scan(1)
            devices = scanner.getDevices()

            for dev in devices:
                address = dev.addr
                address_type = dev.addrType
                name = dev.getValueText(COMPLETE_LOCAL_NAME_ADTYPE)

                if self._is_device_matched(address, name, hub_mac, hub_name):
                    self._peripheral = BluepyThreadedPeripheral(address, address_type, self._controller)
                    break

        return self 
Example #11
Source File: luksmnt.py    From circo with MIT License 6 votes vote down vote up
def btle():
    findkey = False
    scanner = Scanner()
    devices = scanner.scan(10.0)
    for dev in devices:
        for (adtype, desc, value) in dev.getScanData():
            if findkey:
                if 'Complete 128b Services' in desc:
                    subprocess.call('umount /home/pi-enc 2>/dev/null', shell=True)
                    subprocess.call('cryptsetup close /dev/mapper/pi.enc 2>/dev/null', shell=True)
                    subprocess.call('losetup -D', shell=True)
                    subprocess.call('losetup /dev/loop0 /home/pi.enc 2>/dev/null', shell=True)
                    subprocess.call('echo ' + value +  ' | cryptsetup --batch-mode luksOpen /dev/loop0 pi.enc', shell=True)
                    subprocess.call('mount /dev/mapper/pi.enc /home/pi-enc', shell=True)
                    break
            if 'Complete Local Name' in desc:
                if btlename in value:
                    findkey = True 
Example #12
Source File: bluepy.py    From btlewrap with MIT License 6 votes vote down vote up
def scan_for_devices(timeout: float, adapter='hci0') -> List[Tuple[str, str]]:
        """Scan for bluetooth low energy devices.

        Note this must be run as root!"""
        from bluepy.btle import Scanner

        match_result = re.search(r'hci([\d]+)', adapter)
        if match_result is None:
            raise BluetoothBackendException(
                'Invalid pattern "{}" for BLuetooth adpater. '
                'Expetected something like "hci0".'.format(adapter))
        iface = int(match_result.group(1))

        scanner = Scanner(iface=iface)
        result = []
        for device in scanner.scan(timeout):
            result.append((device.addr, device.getValueText(9)))
        return result 
Example #13
Source File: switchbot.py    From python-host with Apache License 2.0 5 votes vote down vote up
def __init__( self ):
        DefaultDelegate.__init__(self)
        #print("Scanner inited") 
Example #14
Source File: switchbot_meter_py3.py    From python-host with Apache License 2.0 5 votes vote down vote up
def __init__( self ):
        DefaultDelegate.__init__(self)
        #print("Scanner inited") 
Example #15
Source File: switchbot_meter.py    From python-host with Apache License 2.0 5 votes vote down vote up
def __init__( self ):
        DefaultDelegate.__init__(self)
        #print("Scanner inited") 
Example #16
Source File: open_myo.py    From Open-Myo with GNU General Public License v3.0 5 votes vote down vote up
def get_myo(mac=None):
    if mac is not None:
        while True:
            for i in btle.Scanner(0).scan(1):
                if i.addr == mac:
                    return str(mac).upper()

    while True:
        for i in btle.Scanner(0).scan(1):
            for j in i.getScanData():
                if j[0] == 6 and j[2] == '4248124a7f2c4847b9de04a9010006d5':
                    return str(i.addr).upper() 
Example #17
Source File: Calima.py    From pycalima with Apache License 2.0 5 votes vote down vote up
def FindCalimas():
    scanner = ble.Scanner()
    devices = scanner.scan()
    calimas = filter(lambda dev: dev.addr[0:8] == "58:2b:db", devices)
    return tuple(map(lambda dev: dev.addr, calimas)) 
Example #18
Source File: manager.py    From BlueSTSDK_Python with BSD 3-Clause "New" or "Revised" License 5 votes vote down vote up
def handleDiscovery(self, scan_entry, is_new_device, is_new_data):
        """Discovery handling callback.

        Called when an advertising data is received from a BLE device while a
        Scanner object is active.

        Args:
            scan_entry (ScanEntry): BLE device. It contains device information
            and advertising data. Refer to
            `ScanEntry <https://ianharvey.github.io/bluepy-doc/scanentry.html>`_
            for more information.
            is_new_device (bool): True if the device (as identified by its MAC
            address) has not been seen before by the scanner, False
            otherwise.
            is_new_data (bool): True if new or updated advertising data is
            available.

        Raises:
            :exc:`blue_st_sdk.utils.blue_st_exceptions.BlueSTInvalidAdvertisingDataException`
            if an advertising data has a format not recognized by the
            BlueSTSDK.
        """
        # Getting a Manager's instance.
        manager = Manager.instance()

        try:
            # If the node has already been added skip adding it again, otherwise
            # update it.
            nodes = manager.get_nodes()[:]
            for node in nodes:
                if node.get_tag() == scan_entry.addr:
                    node.is_alive(scan_entry.rssi)
                    node.update_advertising_data(scan_entry.getScanData())
                    return

            # Creating new node.
            node = Node(scan_entry)
            manager._add_node(node)
        except (BlueSTInvalidAdvertisingDataException, BTLEException) as e:
            if self._show_warnings:
                self._logger.warning(str(e)) 
Example #19
Source File: ble_tools.py    From peniot with MIT License 5 votes vote down vote up
def scan(interface, timeout):
        scanner = btle.Scanner(interface)
        entries = scanner.scan(timeout)
        return entries 
Example #20
Source File: ble.py    From HomePWN with GNU General Public License v3.0 5 votes vote down vote up
def scan_devices(self, delegate=DefaultDelegate, timeout=5):
        devices = Scanner(self.iface).withDelegate(delegate()).scan(timeout=timeout) 
        return self._package_data_devices(devices) 
Example #21
Source File: bluetoothScanner.py    From sensorReporter with Apache License 2.0 5 votes vote down vote up
def getTag(self):
        """Scans for BT LE devices and returns the choosen keywords"""
        self.count = 0
        scanner = Scanner().withDelegate(DefaultDelegate())
        devices = scanner.scan(self.scanTimeout)
        for dev in devices:
            if dev.addr == self.address.lower():
                self.count = 1
			
        if self.count > 0:
            self.count = 0
            return self.found
        else:
            return self.missing 
Example #22
Source File: read_wave2.py    From wave-reader with MIT License 5 votes vote down vote up
def discover(self):
        scan_interval = 0.1
        timeout = 3
        scanner = btle.Scanner()
        for _count in range(int(timeout / scan_interval)):
            advertisements = scanner.scan(scan_interval)
            for adv in advertisements:
                if self.serial_number == _parse_serial_number(adv.getValue(btle.ScanEntry.MANUFACTURER)):
                    return adv.addr
        return None 
Example #23
Source File: read_wave.py    From wave-reader with MIT License 5 votes vote down vote up
def discover(self):
        scan_interval = 0.1
        timeout = 3
        scanner = btle.Scanner()
        for _count in range(int(timeout / scan_interval)):
            advertisements = scanner.scan(scan_interval)
            for adv in advertisements:
                if self.serial_number == _parse_serial_number(adv.getValue(btle.ScanEntry.MANUFACTURER)):
                    return adv.addr
        return None 
Example #24
Source File: Xiaomi_Scale.py    From xiaomi_mi_scale with MIT License 5 votes vote down vote up
def main():
    if MQTT_DISCOVERY:
        discovery()
    BluetoothFailCounter = 0
    while True:
        try:
            scanner = btle.Scanner(HCI_DEV).withDelegate(ScanProcessor())
            scanner.scan(5) # Adding passive=True to try and fix issues on RPi devices
        except BTLEDisconnectError as error:
            sys.stderr.write(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - btle disconnected: {error}\n")
            pass
        except BTLEManagementError as error:
            sys.stderr.write(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - Bluetooth connection error: {error}\n")
            if BluetoothFailCounter >= 4:
                sys.stderr.write(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - 5+ Bluetooth connection errors. Resetting Bluetooth...\n")
                cmd = 'hciconfig hci0 reset'
                ps = subprocess.Popen(cmd, shell=True)
                time.sleep(30)
                BluetoothFailCounter = 0
            else:
                BluetoothFailCounter+=1
            pass
        except Exception as error:
            sys.stderr.write(f"{datetime.now().strftime('%Y-%m-%d %H:%M:%S')} - Error while running the script: {error}\n")
            pass
        else:
            BluetoothFailCounter = 0
        time.sleep(TIME_INTERVAL) 
Example #25
Source File: manager.py    From BlueSTSDK_Python with BSD 3-Clause "New" or "Revised" License 4 votes vote down vote up
def discover(self, timeout_s=SCANNING_TIME_DEFAULT_s, asynchronous=False,
        show_warnings=False):
        """Perform the discovery process.

        This method can be run in synchronous (blocking) or asynchronous
        (non-blocking) way. Default is synchronous.

        The discovery process will last *timeout_s* seconds if provided, a
        default timeout otherwise.

        Please note that when running a discovery process, the already connected
        devices get disconnected (limitation intrinsic to the bluepy library).

        Args:
            timeout_s (int, optional): Time in seconds to wait before stopping
            the discovery process.
            asynchronous (bool, optional): If True the method is run in
            asynchronous way, thus non-blocking the execution of the thread,
            the opposite otherwise.
            show_warnings (bool, optional): If True shows warnings, if any, when
            discovering devices not respecting the BlueSTSDK's advertising
            data format, nothing otherwise.

        Returns:
            bool: True if the synchronous discovery has finished or if the
            asynchronous discovery has started, False if a discovery is already
            running.

        Raises:
            :exc:`blue_st_sdk.utils.blue_st_exceptions.BlueSTInvalidOperationException`
            is raised if this method is not run as root.
        """
        try:
            if not asynchronous:
                # Synchronous version.
                if self.is_discovering():
                    return False
                self._discovered_nodes = []
                self._notify_discovery_change(True)
                with lock(self):
                    self._scanner = \
                        Scanner().withDelegate(_ScannerDelegate(show_warnings))
                    self._scanner.scan(timeout_s)
                self._notify_discovery_change(False)
                return True
            else:
                # Asynchronous version.
                if not self.start_discovery(show_warnings):
                    return False
                threading.Timer(timeout_s, self.stop_discovery).start()
                return True
        except BTLEException as e:
            msg = '\nBluetooth scanning requires root privileges, ' \
                  'so please run the application with \"sudo\".'
            raise BlueSTInvalidOperationException(msg) 
Example #26
Source File: webserver.py    From rpieasy with GNU General Public License v3.0 4 votes vote down vote up
def handle_blescanner(self):
 global TXBuffer, navMenuIndex
 TXBuffer=""
 navMenuIndex=3
 if (rpieGlobals.wifiSetup):
  return self.redirect('/setup')
 if (not isLoggedIn(self.get,self.cookie)):
  return self.redirect('/login')
 sendHeadandTail("TmplStd",_HEAD)

 blesupported = True
 try: 
  from bluepy.btle import Scanner
 except:
  blesupported = False
 if blesupported:
    if OS.check_permission()==False:
     TXBuffer += "Scanning does not work properly without root permission!<p>"
    blesuccess = True
    try:
     scanner = Scanner()
     devices = scanner.scan(5.0)
    except Exception as e:
     TXBuffer += "BLE scanning failed "+str(e)+"<p>"
     TXBuffer += "Try to run:<br>sudo systemctl stop bluetooth<br>sudo hciconfig hci0 up<p>"
     blesuccess = False
    if blesuccess:
     TXBuffer += "<table class='multirow'><TR><TH>Interface<TH>Address<TH>Address type<TH>RSSI<TH>Connectable<TH>Name<TH>Appearance</TH><TH>Actions</TH></TR>"
     cc = 0
     for dev in devices:
      cc += 1
      TXBuffer += "<TR><TD>"+str(dev.iface)+"<TD><div id='mac"+str(cc)+"_1' name='mac"+str(cc)+"_1'>"+str(dev.addr)+"</div><TD>"+str(dev.addrType)+"<TD>"+str(dev.rssi)+" dBm<TD>"+str(dev.connectable)
      dname = ""
      shortdname = ""
      appear = ""
      for (adtype, desc, value) in dev.getScanData():
        if desc.lower() == "complete local name":
         dname = str(value)
        if desc.lower() == "shortened local name":
         shortdname = str(value)
        if desc.lower() == "appearance":
         appear = str(value)
      if dname.strip()=="":
        dname = shortdname
      TXBuffer += "<TD>"+str(dname)+"<TD>"+str(appear)+"<TD>"
      addCopyButton("mac"+str(cc),"","Copy MAC to clipboard",str(cc))
      TXBuffer += "</TR>"
     TXBuffer += "</table>"
 else:
    TXBuffer += "BLE supporting library not found! Please install <a href='plugins?installmodule=bluepy'>bluepy</a>"

 sendHeadandTail("TmplStd",_TAIL);
 return TXBuffer 
Example #27
Source File: switchbot.py    From python-host with Apache License 2.0 4 votes vote down vote up
def scan_loop(self):
        service_uuid = '1bc5d5a50200b89fe6114d22000da2cb'
        menufacturer_id = '5900f46d2c8a5f31'
        dev_list =[]
        bot_list =[]
        enc_list =[]
        link_list =[]
        self.con = pexpect.spawn('hciconfig')
        pnum = self.con.expect(["hci0",pexpect.EOF,pexpect.TIMEOUT])
        if pnum==0:
            self.con = pexpect.spawn('hcitool lescan')
            #self.con.expect('LE Scan ...', timeout=5)
            scanner = Scanner().withDelegate(DevScanner())
            devices = scanner.scan(5.0)
            print "Start scanning..."
        else:
            raise Error("no bluetooth error")

        for dev in devices:
            mac = 0
            for (adtype, desc, value) in dev.getScanData():
                #print adtype,desc,value
                if desc == '16b Service Data' :
                    model = binascii.a2b_hex(value[4:6])
                    mode  = binascii.a2b_hex(value[6:8])
                if desc == 'Local name' and value == "WoHand":
                    mac   = dev.addr
                    model = 'H'
                    mode  = 0
                elif desc == 'Complete 128b Services' and value == service_uuid :
                    mac = dev.addr

            if mac != 0 :
                #print binascii.b2a_hex(model),binascii.b2a_hex(mode)
                dev_list.append([mac,model,mode])

        #print dev_list
        for (mac, dev_type,mode) in dev_list:
            #print mac  ,dev_type
            if dev_type == 'L':
                link_list.append(mac)
            if dev_type == 'H'  or ord(dev_type) == ord('L') + 128:
                #print int(binascii.b2a_hex(mode),16)
                if int(binascii.b2a_hex(mode),16) > 127 :
                    bot_list.append([mac,"Turn On"])
                    bot_list.append([mac,"Turn Off"])
                    bot_list.append([mac,"Up"])
                    bot_list.append([mac,"Down"])
                else :
                    bot_list.append([mac,"Press"])
            if ord(dev_type) == ord('L') + 128:
                enc_list.append([mac,"Press"])
        #print bot_list
        print "scan timeout"
        return bot_list
        pass 
Example #28
Source File: ganglion.py    From OpenBCI_Python with MIT License 4 votes vote down vote up
def find_port(self):
        """Detects Ganglion board MAC address
        If more than 1 around, will select first. Needs root privilege.
        """

        print("Try to detect Ganglion MAC address. "
              "NB: Turn on bluetooth and run as root for this to work!"
              "Might not work with every BLE dongles.")
        scan_time = 5
        print("Scanning for 5 seconds nearby devices...")

        #   From bluepy example
        class ScanDelegate(DefaultDelegate):
            def __init__(self):
                DefaultDelegate.__init__(self)

            def handleDiscovery(self, dev, isNewDev, isNewData):
                if isNewDev:
                    print("Discovered device: " + dev.addr)
                elif isNewData:
                    print("Received new data from: " + dev.addr)

        scanner = Scanner().withDelegate(ScanDelegate())
        devices = scanner.scan(scan_time)

        nb_devices = len(devices)
        if nb_devices < 1:
            print("No BLE devices found. Check connectivity.")
            return ""
        else:
            print("Found " + str(nb_devices) + ", detecting Ganglion")
            list_mac = []
            list_id = []

            for dev in devices:
                # "Ganglion" should appear inside the "value" associated
                # to "Complete Local Name", e.g. "Ganglion-b2a6"
                for (adtype, desc, value) in dev.getScanData():
                    if desc == "Complete Local Name" and value.startswith("Ganglion"):
                        list_mac.append(dev.addr)
                        list_id.append(value)
                        print("Got Ganglion: " + value +
                              ", with MAC: " + dev.addr)
                        break
        nb_ganglions = len(list_mac)

        if nb_ganglions < 1:
            print("No Ganglion found ;(")
            raise OSError('Cannot find OpenBCI Ganglion MAC address')

        if nb_ganglions > 1:
            print("Found " + str(nb_ganglions) + ", selecting first")

        print("Selecting MAC address " + list_mac[0] + " for " + list_id[0])
        return list_mac[0]