OpenWonderLabs / python-host

The python code running on Raspberry Pi or other Linux based boards to control SwitchBot.
Apache License 2.0
376 stars 84 forks source link

Bluez executables are now deprecated #3

Closed blacklight closed 6 years ago

blacklight commented 6 years ago

Many of the executables in the old Bluez package have now been deprecated (see https://www.spinics.net/lists/linux-bluetooth/msg70489.html).

This includes the executables used to interact with the bluetooth stack in this script as well, such as hciconfig (replaced by btmgmt), gatttool (replaced by btgatt-client) and hcitool (replaced by direct DBus call) - see https://wiki.archlinux.org/index.php/bluetooth#Shell_command_is_missing_from_bluez-utils for more details about the mapping.

Although I strongly disagree with the decision of deprecating something before the new alternative can cover all the features provided by the old implementation (bgmgmt and bluetoothctl require some dirty piping to do the same things that were previously possible with a single hciconfig line, hcitool has been killed and replaced by a way less intuitive call to the DBus API), it's also good to keep in mind that if this script isn't updated to the new Bluez style then it'll soon stop working on most of the Linux devices.

The version of Bluez compiled on Raspbian still includes the deprecated executable for back-compatibility reason (and Raspbian is the only Linux distro I know where the script would run now), but when they decide to drop the deprecation support then the only way to run the script would be to compile an old version of Bluez on your system, which is quite far from ideal.

Two alternatives:

blacklight commented 6 years ago

See pull request https://github.com/OpenWonderLabs/python-host/pull/4

I have created a little script that allows interaction with the devices without relying on the old bluez utils.

SwitchBot commented 6 years ago

Hi BlackLight,

Thanks a lot for your contribution!

I have tested your script and it works great. Just some minor modifications I would like to discuss with you:

  1. The data writing handle will not send feedback in my side so it got timeout in read_by_handle. How about deleting data = self.req.read_by_handle(self.handle).
  2. Get the error below when do scanning.
    Traceback (most recent call last):
    File "newbot.py", line 130, in <module>
    main()
    File "newbot.py", line 102, in main
    devices = scanner.scan()
    File "newbot.py", line 42, in scan
    return sorted([addr for addr, device in devices.items()
    File "newbot.py", line 43, in <listcomp>
    if self.service_uuid in self._get_uuids(device)])
    File "newbot.py", line 22, in _get_uuids
    for id in device['uuids']:
    TypeError: string indices must be integers

    So I commented if self.service_uuid in self._get_uuids(device) then it works.

  3. How about changing the new script name to switchbot_py3.py?
  4. To install the dependencies in Ubuntu 16.4LTS I have run the commands below:
    sudo apt-get install python3-pip
    sudo pip3 install pybluez
    sudo apt-get install libboost-python-dev
    sudo apt-get install libboost-thread-dev
    sudo pip3 install gattlib

if the installation of gattlib fails, run:

pip3 download gattlib
tar xvzf ./gattlib-0.20150805.tar.gz
cd gattlib-0.20150805/
sed -ie 's/boost_python-py34/boost_python-py35/' setup.py
pip3 install .

I would also like to add this installation guide to the project description. Please let me know if anything left. Thanks.

blacklight commented 6 years ago

I've updated the pull requests with the commits to address your points.

The scan issue is indeed weird, I can replicate it as well now. It seems that DiscoveryService.discover() returns a dictionary with empty values, while the values are expected to contain the device info. Anyway, removing the UUID filtering logic fixes it, but also it will show all the available bluetooth devices, not only the Switchbots.