コード例 #1
0
    async def _getNearest(self, setup, rssiAtLeast, scanDuration,
                          returnFirstAcceptable, validated,
                          addressesToExclude) -> ScanData or None:
        addressesToExcludeSet = set()
        if addressesToExclude is not None:
            for data in addressesToExclude:
                if hasattr(data, 'address'):
                    addressesToExcludeSet.add(data.address.lower())
                elif isinstance(data, dict):
                    if "address" in data:
                        addressesToExcludeSet.add(data["address"].lower())
                    else:
                        raise CrownstoneException(
                            CrownstoneError.INVALID_ADDRESS,
                            "Addresses to Exclude is either an array of addresses (like 'f7:19:a4:ef:ea:f6') or an array of dicts with the field 'address'"
                        )
                else:
                    addressesToExcludeSet.add(data.lower())

        selector = NearestSelector(setup, rssiAtLeast, returnFirstAcceptable,
                                   addressesToExcludeSet)

        topic = BleTopics.advertisement
        if not validated:
            topic = BleTopics.rawAdvertisement

        subscriptionId = BleEventBus.subscribe(
            topic, lambda scanData: selector.handleAdvertisement(scanData))

        await self.ble.scan(duration=scanDuration)

        BleEventBus.unsubscribe(subscriptionId)

        return selector.getNearest()
コード例 #2
0
    async def waitForMode(self,
                          address,
                          requiredMode: CrownstoneOperationMode,
                          scanDuration=5):
        """
        This will wait until it has received an advertisement from the Crownstone with the specified address. Once it has received an advertisement, it knows the mode. We will
        scan for the scanDuration amount of seconds or until the Crownstone is in the required mode.

        It can throw the following CrownstoneBleException
        - BleError.NO_SCANS_RECEIVED
            We have not received any scans from this Crownstone, and can't say anything about it's state.
        - BleError.DIFFERENT_MODE_THAN_REQUIRED
            During the {scanDuration} seconds of scanning, the Crownstone was not in the required mode.
        """
        _LOGGER.debug(
            f"waitForMode address={address} requiredMode={requiredMode} scanDuration={scanDuration}"
        )
        checker = ModeChecker(address, requiredMode, True)
        subscriptionId = BleEventBus.subscribe(
            BleTopics.rawAdvertisement,
            lambda scanData: checker.handleAdvertisement(scanData))
        await self.ble.scan(duration=scanDuration)
        BleEventBus.unsubscribe(subscriptionId)
        result = checker.getResult()

        if result is None:
            raise CrownstoneBleException(
                BleError.NO_SCANS_RECEIVED,
                f'During the {scanDuration} seconds of scanning, no advertisement was received from this address.'
            )
        if result != requiredMode:
            raise CrownstoneBleException(
                BleError.DIFFERENT_MODE_THAN_REQUIRED,
                f'During the {scanDuration} seconds of scanning, the Crownstone was not in the required mode..'
            )
コード例 #3
0
    async def getMode(self,
                      address,
                      scanDuration=3) -> CrownstoneOperationMode:
        """
        This will wait until it has received an advertisement from the Crownstone with the specified address. Once it has received an advertisement, it knows the mode.

        We will return once we know.

        It can throw the following CrownstoneBleException
        - BleError.NO_SCANS_RECEIVED
            We have not received any scans from this Crownstone, and can't say anything about it's state.
        """
        _LOGGER.debug(f"getMode address={address} scanDuration={scanDuration}")
        checker = ModeChecker(address, None)
        subscriptionId = BleEventBus.subscribe(
            BleTopics.rawAdvertisement,
            lambda scanData: checker.handleAdvertisement(scanData))
        await self.ble.scan(duration=scanDuration)
        BleEventBus.unsubscribe(subscriptionId)
        result = checker.getResult()

        if result is None:
            raise CrownstoneBleException(
                BleError.NO_SCANS_RECEIVED,
                f'During the {scanDuration} seconds of scanning, no advertisement was received from this address.'
            )

        return result
コード例 #4
0
    async def isCrownstoneInSetupMode(self,
                                      address: str,
                                      scanDuration=3,
                                      waitUntilInSetupMode=False) -> bool:
        _LOGGER.warning(
            "isCrownstoneInSetupMode is deprecated. Will be removed in v3. Use either getMode or waitForMode instead."
        )
        """
        This will wait until it has received an advertisement from the Crownstone with the specified address. Once it has received an advertisement, it knows the mode.
        With default value for waitUntilInSetupMode (False), it will return True if the Crownstone is in setup mode, False if it isn't.

        You can use the boolean waitUntilInSetupMode to have it ignore advertisements from this Crownstone in other modes than setup mode.

        It can throw the following CrownstoneBleException
        - BleError.NO_SCANS_RECEIVED
            We have not received any scans from this Crownstone, and can't say anything about it's state.
        """
        _LOGGER.debug(
            f"isCrownstoneInSetupMode address={address} scanDuration={scanDuration} waitUntilInSetupMode={waitUntilInSetupMode}"
        )
        checker = ModeChecker(address, CrownstoneOperationMode.SETUP,
                              waitUntilInSetupMode)
        subscriptionId = BleEventBus.subscribe(BleTopics.advertisement,
                                               checker.handleAdvertisement)
        await self.ble.scan(duration=scanDuration)
        BleEventBus.unsubscribe(subscriptionId)
        result = checker.getResult()

        if result is None:
            raise CrownstoneBleException(
                BleError.NO_SCANS_RECEIVED,
                f'During the {scanDuration} seconds of scanning, no advertisement was received from this address.'
            )

        return result
コード例 #5
0
 async def getRssiAverage(self, address, scanDuration=3):
     checker = RssiChecker(address)
     subscriptionId = BleEventBus.subscribe(
         BleTopics.rawAdvertisement,
         lambda scanData: checker.handleAdvertisement(scanData))
     await self.ble.scan(duration=scanDuration)
     BleEventBus.unsubscribe(subscriptionId)
     return checker.getResult()
コード例 #6
0
 async def getCrownstonesByScanning(self, scanDuration=3):
     gatherer = Gatherer()
     subscriptionIdAll = BleEventBus.subscribe(
         BleTopics.rawAdvertisement,
         lambda scanData: gatherer.handleAdvertisement(scanData))
     await self.ble.scan(duration=scanDuration)
     BleEventBus.unsubscribe(subscriptionIdAll)
     return gatherer.getCollection()
コード例 #7
0
ファイル: BleHandler.py プロジェクト: crownstone/programmer
    async def waitForPeripheralToDisconnect(self, timeout: int = 10):
        if self.activeClient is not None:
            if await self.activeClient.isConnected():
                waiting = True

                def disconnectListener(data):
                    nonlocal waiting
                    waiting = False

                listenerId = BleEventBus.subscribe(
                    SystemBleTopics.forcedDisconnect, disconnectListener)

                timer = 0
                while waiting and timer < 10:
                    await asyncio.sleep(0.1)
                    timer += 0.1

                BleEventBus.unsubscribe(listenerId)

                self.activeClient = None
コード例 #8
0
 async def shutDown(self):
     for subscriptionId in self.subscriptionIds:
         BleEventBus.unsubscribe(subscriptionId)
     await self.disconnect()
     await self.stopScanning()