IanHarvey / bluepy

Python interface to Bluetooth LE on Linux
Other
1.58k stars 490 forks source link

Peripheral connect not taking in timeout parameter #456

Open danlee-lils opened 2 years ago

danlee-lils commented 2 years ago

The document has timeout as optional but whenever I pass in iface and timeout, I get this error...

connect() takes from 2 to 4 positional arguments but 5 were given

What is the default timeout??

danlee-lils commented 2 years ago

I also want to add that when I do this below:

self.peripheral = Peripheral(macAddress, btle.ADDR_TYPE_RANDOM, 0, 5.0)

I get following error message:

Exception ignored in: <function Peripheral.__del__ at 0xb64f2df8> Traceback (most recent call last): File "/home/pi/.local/share/virtualenvs/lil-ble-pi-fId0qiJ4/lib/python3.7/site-packages/bluepy/btle.py", line 630, in __del__ self.disconnect() File "/home/pi/.local/share/virtualenvs/lil-ble-pi-fId0qiJ4/lib/python3.7/site-packages/bluepy/btle.py", line 448, in disconnect if self._helper is None: AttributeError: 'Peripheral' object has no attribute '_helper' Connection failed. Retry attempt 1/2 Exception ignored in: <function Peripheral.__del__ at 0xb64f2df8> Traceback (most recent call last): File "/home/pi/.local/share/virtualenvs/lil-ble-pi-fId0qiJ4/lib/python3.7/site-packages/bluepy/btle.py", line 630, in __del__ self.disconnect() File "/home/pi/.local/share/virtualenvs/lil-ble-pi-fId0qiJ4/lib/python3.7/site-packages/bluepy/btle.py", line 448, in disconnect if self._helper is None: AttributeError: 'Peripheral' object has no attribute '_helper' Connection failed. Retry attempt 2/2 Exception ignored in: <function Peripheral.__del__ at 0xb64f2df8> Traceback (most recent call last): File "/home/pi/.local/share/virtualenvs/lil-ble-pi-fId0qiJ4/lib/python3.7/site-packages/bluepy/btle.py", line 630, in __del__ self.disconnect() File "/home/pi/.local/share/virtualenvs/lil-ble-pi-fId0qiJ4/lib/python3.7/site-packages/bluepy/btle.py", line 448, in disconnect if self._helper is None: AttributeError: 'Peripheral' object has no attribute '_helper' Total retries: 2 -> Time: 0.02 seconds Device status updated -> __init__() takes from 1 to 4 positional arguments but 5 were given -> c9:93:75:58:17:37

danlee-lils commented 2 years ago

So... I just looked at the btle.py that is in my Pi and noticed that it does not have the timeout parameter... I see that the Master branch has the timeout parameter...

danlee-lils commented 2 years ago

Found the issue and fixed.

But the question still remains that if you use pip to install bluepy, the btle.py does not have timeout parameter. Any thoughts on this? I had to build from source and it was there.

danlee-lils commented 2 years ago

Essentially the core problem is that the version in PIP is outdated...

https://github.com/IanHarvey/bluepy/issues/458

RenierM26 commented 2 years ago

Hi @danlee-lils ,

Why not just inherit the Peripheral class, and override the _connect method? This example will need some changes but gives the general idea.

class SwitchbotDevice(bluepy.btle.Peripheral):
      def __init__(self, deviceAddr, interface)
        bluepy.btle.Peripheral.__init__(self,deviceAddr=None,addrType=bluepy.btle.ADDR_TYPE_RANDOM,iface=interface)

      def _connect(self, timeout: int = None) -> None:
        _LOGGER.debug("Connecting to Switchbot")
        self._startHelper(self._interface)
        self._writeCmd("conn %s %s\n" % (self._mac, bluepy.btle.ADDR_TYPE_RANDOM))
        rsp = self._getResp("stat", timeout)
        if rsp is None:
            self._stopHelper()
            raise bluepy.btle.BTLEDisconnectError(
                "Timed out while trying to connect to peripheral %s" % self._mac,
                rsp,
            )
        while rsp and rsp["state"][0] in [
            "tryconn",
            "scan",
        ]:  # Wait for scan to finish.
            rsp = self._getResp("stat", timeout)

        # If operation in progress, disc is returned.
        # Bluepy helper can't handle state. Execute stop, wait and retry.
        if rsp["state"][0] == "disc":
            _LOGGER.warning("Bluepy busy, waiting before retry")
            self._stopHelper()
            time.sleep(self._scan_timeout)
            return self._connect(timeout)

        if rsp["state"][0] != "conn":
            _LOGGER.warning("Bluehelper returned unable to connect state: %s", rsp)
            self._stopHelper()
            raise bluepy.btle.BTLEDisconnectError(
                "Failed to connect to peripheral %s, rsp: %s" % (self._mac, rsp)
            )