Shin'ichiro Kawasaki 39ca1904b7 ble: implement BLEDBusSession class
Current implementation of BLESession class depends on the library bluepy
to communicate with BLE devices. This implementation has two major
issues. The first issue is no maintenance of bluepy library. It's last
commit was made in May 2021. It is no longer active and it is not likely
that its issues get resolved. The second issue is lack of asyncio
interface. pyscrlink uses websockets which uses asyncio. Dirty glue code
and locks are required to connect websockets and bluepy.

This commit avoids the issue by moving away from bluepy. Instead, use
BlueZ D-Bus API. Bluepy communicates with BlueZ kernel module via bluepy
unique user space program. Instead, pyscrlink communicate with well
maintained Blue-Z user space program, or bluetoothd, through D-Bus
protocol. To handle D-Bus protocol, use python-sdbus library [2]. It has
sub-library python-sdbus-bluez to cover BlueZ D-Bus API [3].

Using these libraries, implement a new class named BLEDBusSession. It
replaces BLESession which uses bluepy. These two classes share same
base class named Session. To allow async I/O, add a new function
async_handle_request to the Session class. Until this new implementation
get proved stable enough, keep the old BLESession. Introduce a new
command line option '-b' of scratch_link. When this option is specified,
the new class is used.

To improve code readability, implement BLEDBusSession in a new file
'ble.py'. To share scan_seconds between scratch_link.py and ble.py,
change scan_seconds from global variable to an argument of Session class
constructor. Also to share logger between scratch_link.py and ble.py,
modify the logging.getLogger() argument from __name__ to scratch_link
module name.

[1] http://www.bluez.org/bluez-5-api-introduction-and-porting-guide/
[2] https://github.com/python-sdbus/python-sdbus
[3] https://github.com/python-sdbus/python-sdbus-bluez

Signed-off-by: Shin'ichiro Kawasaki <kawasaki@juno.dti.ne.jp>
2023-09-18 18:34:51 +09:00
2020-08-08 12:04:20 +09:00
2020-01-06 15:57:49 +09:00
2023-08-05 17:08:21 -07:00
2023-07-02 21:52:08 +09:00

pyscrlink

Pyscrlink is a Scratch-link for Linux. Scratch-link is a software module which connects Scratch to Bluetooth devices such as micro:bit. However, as of October 2020, it only works on Windows and MacOS, and Linux operating systems can not connect Scratch and micro:bit.

Pyscrlink allows you to connect Scratch and bluetooth devices with the Linux OSes. It uses the Linux Bluetooth protocol stack Bluez and bluepy to handle Bluetooth Low Energy (BLE) connections. It has been reported that pyscrlink connects Scratch 3.0 with micro:bit, LEGO WeDo, LEGO Boost and toio.

Until version v0.2.5, pyscrlink supported Bluetooth Classic protocol using pybluez. Unfortunately, pybluez is not well maintained and caused technical troubles. Then Bluetooth Classic protocol support is dropped from pyscrlink. This means that LEGO Mindstorm EV3 can not be connected with pyscrlink. Bluetooth Classic support is the improvement opportunity of pyscrlink.

To use websockets, pyscrlink requires python version 3.6 or later. If your system has python older than version 3.6, install newer version. If your system has python 3 explicit command names python3 and pip3, use them in the steps below.

Pyscrlink was launched in 2019 as "bluepy-scratch-link". This was a small task dedicated to micro:bit and bluepy for BLE connection. After many contributions, it expanded coverage to pybluez with other devices for Bluetooth connectivity. It was misleading that the name "bluepy-scratch-link" indicates that it depends only on bluepy. As of October 2020, name of the project has been changed from "bluepy-scratch-link" to "pyscrlink" to avoid confusion.

Confirmed Environments

The instructions below was confirmed with following devices and distros. Trial with other distros and feed-backs will be appreciated.

Pyscrlink was confirmed with following devices, Linux distros and browsers.

Devices:

  • micro:bit

Linux distros:

  • Arch Linux

Browsers:

  • Firefox
  • Chromium

It was reported that pyscrlink (former bluepy-scratch-link) working with following devices and Linux distros.

Devices:

  • LEGO WeDo by @zhaowe, @KingBBQ
  • LEGO Boost and compatible devices by @laurentchar, @miguev, @jacquesdt, @n3storm
  • toio by @shimodash

Linux distros:

  • Raspbian by @chrisglencross
  • Ubuntu 16.04 @jacquesdt
  • Ubuntu Studio 20.04 @miguev
  • Debian 11 @n3storm

Installation

  1. Prepare Bluetooth/BLE controller.

    Confirm that your Linux PC has a Bluetooth controller with BLE support. Bluetooth 4.0 controller supports BLE. If your PC does not have it, need to plug USB Bluetooth 4.0 adapter.

    Note: BLED112 USB dongle with Bluegiga BGAPI is not supported.

  2. Install required packages.

    Ubuntu
    $ sudo apt install bluez libbluetooth-dev libnss3-tools libcap2-bin libglib2.0-dev
    Arch
    $ sudo pacman -S bluez bluez-utils nss libcap
    
  3. Install python modules.

    $ pip install pyscrlink
    Or if your system has python3 command,
    $ pip3 install pyscrlink
    
  4. Set bluepy-helper capability.

    $ bluepy_helper_cap
    Set capacbility 'cap_net_raw,cap_net_admin' to /usr/lib/python3.8/site-packages/bluepy-1.3.0-py3.8.egg/bluepy/bluepy-helper
    

    The command above requires super user privilege. It may request to input super user password.

  5. For micro:bit, install Scratch-link hex on your device.

    • Download and unzip the micro:bit Scratch Hex file.
    • Flash the micro:bit over USB with the Scratch Hex File, you will see the five character name of the micro:bit scroll across the screen such as 'zo9ev'.

Usage

  1. Start scratch-link python script.

    $ scratch_link
    

    If your device is toio, add "-s 1" option to the scratch_link command. It allows the toio Do Visual Programming to connect to toio automatically.

  2. Connect scratch to the target device such as micro:bit:

    • Open FireFox or Chrome. (Make sure to run as the same user for scratch-link python script.)
    • Access Scratch 3.0 and create your project.
    • Select the "Add Extension" button.
    • Select the extension for your device (e.g., micro:bit) and follow the prompts to connect.
    • Build your project with the extension blocks.

In Case You Fail to Connect

  1. If Scratch says "Make sure you have Scratch Link installed" but you are sure that scratch-link python script is running, check that Firefox or Chrome allows local server certificate.

    • Open Firefox or Chrome and access https://device-manager.scratch.mit.edu:20110/. You will see a security risk warning.
    • In Firefox: Click "Advanced" and click "Accept Risk and Continue".
    • In Chrome: type the special bypass keyword thisisunsafe.
    • Immediately, you will see "Failed to open a WebSocket connection". This is expected.
  2. If device scan fails, check systemd bluetooth service status.

    systemctl status bluetooth.service
    
    • If the service is not working, refer guide of your distro to set it up.
    • If the service is working, also check that /etc/bluetooth/main.conf sets AutoEnable=true.
  3. If device scan still fails, use -r option to retry device scan. The command line below does device scan twice. Each scan takes 10 seconds.

    $ scratch_link -r 2
    

    It would be good to use -s option together to reduce each scan duration. The command line below does 3 seconds device scan twice.

    $ scratch_link -r 2 -s 3
    
  4. If scratch_link.py says "failed to connect to BT device: [Errno 13] Permission denied", make sure to pair the bluetooth device to your PC before connecting to Scratch.

  5. To connect to multiple devices at the same time, make all the target devices ready for scan at the first device scan. This is important for toio. The toio allows a single project to connect to two toio devices.

    • When the second device was prepared after the first device was connected, device scan can not find the second device.
    • To scan and find the second device, disconnect connections for the first device beforehand.

Issus Reporting

Please file issues to GitHub issue tracker.

Releases

Release 0.2.8

  • Supported Microbit More v2

Release 0.2.7

  • Supported Snap Firefox and Chromium
  • Added -r option to retry BLE scan

Release 0.2.6

  • Removed Bluetooth Classic and LEGO Mindstorm EV3 support

Release 0.2.5

  • Fixed handling of multiple UUIDs for LEGO Boost

Release 0.2.4

  • Added -s option to specify BLE scan duration
  • Improved README.md

Release 0.2.3

  • Fixed eternal loop caused by hostname resolve failure

Release 0.2.2

  • Supported multiple device connections for toio
  • Improved session closure handling

Release 0.2.1

  • Added libglib to required package list in README.md
  • Improved setcap and getcap tool finding

Release 0.2.0

  • Latency issue fix for BLE devices' write characteristics

Release 0.1.0

  • Initial release
Languages
Python 98.7%
Shell 1.3%