Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection problem: bluetooth rejects frames with the same rssi ? #494

Closed
pawelm87 opened this issue Mar 26, 2021 · 6 comments
Closed

Connection problem: bluetooth rejects frames with the same rssi ? #494

pawelm87 opened this issue Mar 26, 2021 · 6 comments
Assignees
Labels
Backend: BlueZ Issues and PRs relating to the BlueZ backend

Comments

@pawelm87
Copy link

pawelm87 commented Mar 26, 2021

  • bleak version: 0.11.0
  • Python version: 3.7.4
  • Operating System: Windows 10
  • BlueZ version (bluetoothctl -v) in case of Linux:

Description

I have a device that broadcasts every 1 second, when I try to use the example "detection_callback.py", my device shows only 3-4 times in the console, not 10. The scan is set to 10 (sleep time between start and stop). When I change the ble advertising time in the device to 6 seconds, the scan usually catches 1 or 2 frames.

Then I want to connect to the device which is broadcasting every 6 seconds and I set the timeout to 30 seconds so I can hardly ever connect to it.

I noticed that when I shake the device and thus the RSSI changes, at adv = 1s I catch many more frames. If there is any filter such as RSSI does not change, then discard these broadcast frames. That would explain the problems with connecting devices. To connect to the device, you must have at least 2 frames, as duplicates after RSSI are deleted (RSSI has not changed), you cannot connect :(

Why am I having such problems?

What I Did

short example

import asyncio
from bleak import BleakScanner
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData
import logging
from bleak import BleakClient, BleakScanner
import time

logging.basicConfig()
x = None

async def run():
    
    def simple_callback(device: BLEDevice, advertisement_data: AdvertisementData):
        print(device.name, device.address, "RSSI:", device.rssi, advertisement_data)
        if "LN" in device.name:
            print(device.name, device.address, "RSSI:", device.rssi, advertisement_data)
            global x 
            x = device.address

    scanner = BleakScanner()
    scanner.register_detection_callback(simple_callback)

    for i in range(1):
        await scanner.start()
        await asyncio.sleep(10)
        await scanner.stop()     


async def print_services(ble_address: str):
    async with BleakClient(ble_address, timeout=30) as client:
        svcs = await client.get_services()
        print("Services:")
        for service in svcs:
            print(service)    


print(x)
print(time.time())
loop = asyncio.get_event_loop()
loop.run_until_complete(run())
print(x)
print(time.time())
loop.run_until_complete(print_services(x.address))
print(time.time())
@hbldh
Copy link
Owner

hbldh commented Mar 29, 2021

This seems to be another instance of the problem described in #235 and #394. The property RSSI needs to change in order to be sent to Bleak as a PropertyChanged callback.

You can also set x = device in your callback and the do a loop.run_until_complete(print_services(x)) instead. This way you get rid of scanning for the device once again in the async with BleakClient(ble_address, timeout=30) as client: call.

Example, with a event for breaking the scanning instead:

import asyncio
import time

from bleak import BleakClient, BleakScanner
from bleak.backends.device import BLEDevice
from bleak.backends.scanner import AdvertisementData

x = None


async def run():
    def simple_callback(device: BLEDevice, advertisement_data: AdvertisementData):
        print(device.name, device.address, "RSSI:", device.rssi, advertisement_data)
        if "LN" in device.name:
            print(device.name, device.address, "RSSI:", device.rssi, advertisement_data)
            global x
            x = device
            asyncio.get_event_loop().call_soon_threadsafe(stop_scanning_event.set)

    scanner = BleakScanner()
    scanner.register_detection_callback(simple_callback)
    stop_scanning_event = asyncio.Event()

    await scanner.start()
    await asyncio.wait_for(stop_scanning_event.wait(), 10.0)
    await scanner.stop()


async def print_services(ble_address: str):
    async with BleakClient(ble_address, timeout=30) as client:
        svcs = await client.get_services()
        print("Services:")
        for service in svcs:
            print(service)


print(x)
print(time.time())
asyncio.run(run())
print(x)
print(time.time())
asyncio.run(print_services(x))
print(time.time())

@hbldh hbldh self-assigned this Mar 29, 2021
@hbldh hbldh added the Backend: BlueZ Issues and PRs relating to the BlueZ backend label Mar 29, 2021
@dlech
Copy link
Collaborator

dlech commented Mar 29, 2021

This seems to be another instance of the problem described in #235 and #394.

Except this issue is for Windows 10, correct?

@hbldh
Copy link
Owner

hbldh commented Mar 29, 2021

Ah, somehow I missed that. It is not related to those issues then...

@pawelm87
Copy link
Author

so this problem occurs on linux?

I have the impression that it is similar on Windows ...

@hbldh
Copy link
Owner

hbldh commented Apr 20, 2021

The scan intervals seem to be locked on Windows 10, if one does not do more low level changes like this SO post is proposing.

I am not sure Bleak can do what you want it to do right now. But the program I posted above should work if you just get at least one detection of the device while scanning. For connecting to the device it should be enough. If you want to read every advertisement package, it will not work though.

@pawelm87 pawelm87 closed this as completed Jul 2, 2021
@pawelm87
Copy link
Author

pawelm87 commented Jul 2, 2021

Thank you for your help

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Backend: BlueZ Issues and PRs relating to the BlueZ backend
Projects
None yet
Development

No branches or pull requests

3 participants