Disconnected callbacks firing multiple times when multiple connections are made in a session
See original GitHub issue- bleak version: 0.8.0
- Python version: 3.8.5
- Operating System: Windows 10 2004, build 19041.508
Description
When connecting to a BLE device, I am creating a new client and setting a disconnected callback using client.set_disconnected_callback()
, then storing the client in self.connected_devices { }
with a reference against the MAC address.
This all works great including the firing off the callback when the device is connected (either by client.disconnect()
or wandering out of range, powered off, etc). The disconnect callback discards the client by deleting it from self.connected_devices
when fired.
However after reconnecting to the same device in the same session (and again creating a new client, assigning the disconnected callback and stuffing it in the dict of connected devices), on disconnect the callback with run twice. And on the third time, three times, and so on.
I have determined as a workaround, I could try separately tracking all MAC addresses (a self.client_history
dict, perhaps) and then avoid setting disconnection callbacks on any MAC addresses I find in there, but I wonder if this is going about things the wrong way? Is there some way the client instance is surviving having been discarded? It’s as if there is a stale reference to previously-connected devices somewhere.
What I Did
async def __connect_device(self, mac):
# connect to a device based on a mac address
print("Connecting to mac: {0}".format(mac),flush=True)
client = BleakClient(mac)
try:
await client.connect()
except BleakError as err:
print(err)
else:
client.set_disconnected_callback(self.__disconnect_callback)
await client.get_services()
self.connected_devices[mac] = client
async def __disconnect_device(self, mac):
# connect to a device based on a mac address
print("Disconnecting mac: {0}".format(mac),flush=True)
if mac in self.connected_devices:
await self.connected_devices[mac].disconnect()
def __disconnect_callback(self, device_client):
# fires when a device is disconnected
print("Disconnected from {0}".format(device_client.address))
mac = device_client.address
# remove from self.connected_devices
if mac in self.connected_devices:
del self.connected_devices[mac]
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (2 by maintainers)
Top GitHub Comments
I ran into the same problem and this workaround does work quite nicely.
Amazing… that is similar to how I do it in the
feature/winrt
branch. I have never seen that method in thepythonnet
world; But it is a method on the EventBinding, right? I must have notdir
:ed them enough.I prefer keeping solutions outside of the BleakBridge and if all event handler handling can be done with
add
andremove
methods instead I am all for it!