# Buggy code
async def discover(
    timeout: float = 5.0, loop: AbstractEventLoop = None, **kwargs
) -> List[BLEDevice]:
    """Perform a Bluetooth LE Scan using Windows.Devices.Bluetooth.Advertisement

    Args:
        timeout (float): Time to scan for.
        loop (Event Loop): The event loop to use.

    Keyword Args:
        string_output (bool): If set to false, ``discover`` returns .NET
            device objects instead.

    Returns:
        List of strings or objects found.

    """
    loop = loop if loop else asyncio.get_event_loop()

    watcher = BluetoothLEAdvertisementWatcher()

    devices = {}

    def _format_bdaddr(a):
        return ":".join("{:02X}".format(x) for x in a.to_bytes(6, byteorder="big"))

    def _format_event_args(e):
        try:
            return "{0}: {1}".format(
                _format_bdaddr(e.BluetoothAddress),
                e.Advertisement.LocalName or "Unknown",
            )
        except Exception:
            return e.BluetoothAddress

    def AdvertisementWatcher_Received(sender, e):
        if sender == watcher:
            logger.debug("Received {0}.".format(_format_event_args(e)))
            if e.BluetoothAddress not in devices:
                devices[e.BluetoothAddress] = e

    def AdvertisementWatcher_Stopped(sender, e):
        if sender == watcher:
            logger.debug(
                "{0} devices found. Watcher status: {1}.".format(
                    len(devices), watcher.Status
                )
            )

    watcher.Received += AdvertisementWatcher_Received
    watcher.Stopped += AdvertisementWatcher_Stopped

    # Watcher works outside of the Python process.
    watcher.Start()
    await asyncio.sleep(timeout, loop=loop)
    watcher.Stop()

    try:
        watcher.Received -= AdvertisementWatcher_Received
        watcher.Stopped -= AdvertisementWatcher_Stopped
    except Exception as e:
        logger.debug("Could not remove event handlers: {0}...".format(e))

    found = []
    for d in devices.values():
        bdaddr = _format_bdaddr(d.BluetoothAddress)
        uuids = []
        for u in d.Advertisement.ServiceUuids:
            uuids.append(u.ToString())
        data = {}
        for m in d.Advertisement.ManufacturerData:
            md = IBuffer(m.Data)
            b = Array.CreateInstance(Byte, md.Length)
            reader = DataReader.FromBuffer(md)
            reader.ReadBytes(b)
            data[m.CompanyId] = bytes(b)
        found.append(
            BLEDevice(
                bdaddr,
                d.Advertisement.LocalName,
                d,
                uuids=uuids,
                manufacturer_data=data,
            )
        )

    return found


# Traceback (bleak.exc.BleakError)
/Users/zaytsev/PycharmProjects/bluetooth/venv/bin/python /Users/zaytsev/PycharmProjects/bluetooth/bleak_demo.py
DEBUG:bleak.backends.corebluetooth.CentralManagerDelegate:Bluetooth powered on
DEBUG:bleak.backends.corebluetooth.CentralManagerDelegate:Discovered device A0E49DB2-B7F1-4A65-AB2E-D75121192329: Unknown @ RSSI: -79
A0E49DB2-B7F1-4A65-AB2E-D75121192329: HUAWEI Band 2-b6e
DEBUG:bleak.backends.corebluetooth.client:Connecting to BLE device @ A0E49DB2-B7F1-4A65-AB2E-D75121192329
DEBUG:bleak.backends.corebluetooth.CentralManagerDelegate:Successfully connected to device uuid A0E49DB2-B7F1-4A65-AB2E-D75121192329
WARNING:bleak.backends.corebluetooth.PeripheralDelegate:PeripheralDelegate is not compliant
DEBUG:bleak.backends.corebluetooth.client:Retrieving services...
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Services discovered
DEBUG:bleak.backends.corebluetooth.client:Retrieving characteristics for service 180F
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Characteristics discovered
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A19
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A19
DEBUG:bleak.backends.corebluetooth.client:Retrieving characteristics for service 180A
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Characteristics discovered
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A29
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A29
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A24
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A24
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A26
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A26
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A28
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A28
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A50
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A50
DEBUG:bleak.backends.corebluetooth.client:Retrieving characteristics for service 180D
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Characteristics discovered
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A37
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A37
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic 2A38
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered 2A38
DEBUG:bleak.backends.corebluetooth.client:Retrieving characteristics for service FE86
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Characteristics discovered
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic FE01
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered FE01
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic FE02
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered FE02
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic FE03
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered FE03
DEBUG:bleak.backends.corebluetooth.client:Retrieving descriptors for characteristic FE04
DEBUG:bleak.backends.corebluetooth.PeripheralDelegate:Descriptor discovered FE04
DEBUG:bleak.backends.corebluetooth.client:Retrieving services...
DEBUG:bleak.backends.corebluetooth.client:Retrieving characteristics for service 180F
DEBUG:bleak.backends.corebluetooth.CentralManagerDelegate:Peripheral Device disconnected!
Traceback (most recent call last):
File "/Users/zaytsev/PycharmProjects/bluetooth/bleak_demo.py", line 25, in <module>
loop.run_until_complete(ble_get_services(address, loop))
File "/usr/local/Cellar/python/3.7.4/Frameworks/Python.framework/Versions/3.7/lib/python3.7/asyncio/base_events.py", line 579, in run_until_complete
return future.result()
File "/Users/zaytsev/PycharmProjects/bluetooth/bleak_demo.py", line 18, in ble_get_services
svcs = await client.get_services()
File "/Users/zaytsev/PycharmProjects/bluetooth/venv/lib/python3.7/site-packages/bleak/backends/corebluetooth/client.py", line 118, in get_services
self.services.add_service(BleakGATTServiceCoreBluetooth(service))
File "/Users/zaytsev/PycharmProjects/bluetooth/venv/lib/python3.7/site-packages/bleak/backends/service.py", line 101, in add_service
"This service is already present in this BleakGATTServiceCollection!"
bleak.exc.BleakError: This service is already present in this BleakGATTServiceCollection!

# Fixed code
async def discover(
    timeout: float = 5.0, loop: AbstractEventLoop = None, **kwargs
) -> List[BLEDevice]:
    """Perform a Bluetooth LE Scan using Windows.Devices.Bluetooth.Advertisement

    Args:
        timeout (float): Time to scan for.
        loop (Event Loop): The event loop to use.

    Keyword Args:
        string_output (bool): If set to false, ``discover`` returns .NET
            device objects instead.

    Returns:
        List of strings or objects found.

    """
    loop = loop if loop else asyncio.get_event_loop()

    watcher = BluetoothLEAdvertisementWatcher()

    devices = {}
    scan_responses = {}

    def _format_bdaddr(a):
        return ":".join("{:02X}".format(x) for x in a.to_bytes(6, byteorder="big"))

    def _format_event_args(e):
        try:
            return "{0}: {1}".format(
                _format_bdaddr(e.BluetoothAddress),
                e.Advertisement.LocalName or "Unknown",
            )
        except Exception:
            return e.BluetoothAddress

    def AdvertisementWatcher_Received(sender, e):
        if sender == watcher:
            logger.debug("Received {0}.".format(_format_event_args(e)))
            if e.AdvertisementType == BluetoothLEAdvertisementType.ScanResponse:
                if e.BluetoothAddress not in scan_responses:
                    scan_responses[e.BluetoothAddress] = e
            else:
                if e.BluetoothAddress not in devices:
                    devices[e.BluetoothAddress] = e

    def AdvertisementWatcher_Stopped(sender, e):
        if sender == watcher:
            logger.debug(
                "{0} devices found. Watcher status: {1}.".format(
                    len(devices), watcher.Status
                )
            )

    watcher.Received += AdvertisementWatcher_Received
    watcher.Stopped += AdvertisementWatcher_Stopped

    watcher.ScanningMode = BluetoothLEScanningMode.Active

    # Watcher works outside of the Python process.
    watcher.Start()
    await asyncio.sleep(timeout, loop=loop)
    watcher.Stop()

    try:
        watcher.Received -= AdvertisementWatcher_Received
        watcher.Stopped -= AdvertisementWatcher_Stopped
    except Exception as e:
        logger.debug("Could not remove event handlers: {0}...".format(e))

    found = []
    for d in devices.values():
        bdaddr = _format_bdaddr(d.BluetoothAddress)
        uuids = []
        for u in d.Advertisement.ServiceUuids:
            uuids.append(u.ToString())
        data = {}
        for m in d.Advertisement.ManufacturerData:
            md = IBuffer(m.Data)
            b = Array.CreateInstance(Byte, md.Length)
            reader = DataReader.FromBuffer(md)
            reader.ReadBytes(b)
            data[m.CompanyId] = bytes(b)
        local_name = d.Advertisement.LocalName
        if not local_name and d.BluetoothAddress in scan_responses:
            local_name = scan_responses[d.BluetoothAddress].Advertisement.LocalName
        found.append(
            BLEDevice(
                bdaddr,
                local_name,
                d,
                uuids=uuids,
                manufacturer_data=data,
            )
        )

    return found