This release is a pre-release and may not be stable for production use.
Scratch Link Bleak
Unofficial, experimental Scratch Link BLE bridge for Linux using Bleak (BlueZ/D-Bus) rather than bluepy. No installation of pyscrlink or reuse of its files is needed.
Verified setup: LEGO WeDo 2.0 (LPF2 Smart Hub), Ubuntu 24.04.5 LTS, Chrome and the official Scratch editor. A one-hour hardware session was successful. The standalone installation was separately verified in a fresh Python environment without pyscrlink/bluepy: new TLS certificate and Chrome trust, motor and sensors, disconnect and reconnect. Other hardware and distributions remain untested.
Why?
On one Ubuntu machine, the WeDo 2.0 repeatedly disconnected via pyscrlink 0.2.8 with BTLEException: Error from bluepy-helper (badstate) during a GATT write. Equivalent GATT operations via Bleak succeeded, so this experimental bridge retains the Scratch Link WebSocket protocol while replacing the Bluetooth implementation.
Requirements
- Linux desktop with BlueZ and a working BLE adapter, Python >= 3.10.
- Chrome (or compatible Chromium) and the official Scratch editor.
- OpenSSL is optional for inspecting the public certificate.
libnss3-toolsto import the public certificate into Chrome's NSS store.- No
pyscrlink,bluepy, orbluepy-helperinstallation required.
Standalone installation
sudo apt install python3-venv libnss3-tools
git clone https://github.com/rril/scratch-link-bleak.git
cd scratch-link-bleak
python3 -m venv .venv
source .venv/bin/activate
python -m pip install .
scratch-link-bleak --setup
--setup generates:
~/.local/share/scratch-link-bleak/server.crt: public, self-signed TLS server certificate with SANdevice-manager.scratch.mit.edu.~/.local/share/scratch-link-bleak/server.key: private key (mode 0600). Never publish this file.
The tool refuses to replace existing certificate/key files. It does not automatically alter browser trust, your hosts file, or the system certificate store.
Configure local hostname
Check the current mapping:
getent ahostsv4 device-manager.scratch.mit.edu
For local Scratch Link operation, ensure device-manager.scratch.mit.edu resolves to 127.0.0.1. If it does not, use sudoedit /etc/hosts to add this line (preserve existing entries):
127.0.0.1 device-manager.scratch.mit.edu
Only do this on the machine running the bridge, not on a remote server.
Trust the NEW public certificate in Chrome (Linux NSS)
Chromium's Linux certificate management documentation specifies P,, for a trusted self-signed TLS server peer. Import only the generated public server.crt; do not import the private key.
Newer Chromium (M146+) defaults to ~/.local/share/pki/nssdb, but continues to use ~/.pki/nssdb if the latter already exists. Choose one directory according to the Chrome profile in use:
if [ -d "$HOME/.pki/nssdb" ]; then
NSSDB="$HOME/.pki/nssdb"
else
NSSDB="$HOME/.local/share/pki/nssdb"
fi
mkdir -p "$NSSDB"
# Only initialize a *missing* database, never reset an existing one:
if [ ! -f "$NSSDB/cert9.db" ]; then
certutil -d "sql:$NSSDB" -N --empty-password
fi
certutil -d "sql:$NSSDB" -A -t "P,," \
-n "Scratch Link Bleak Local Server" \
-i "$HOME/.local/share/scratch-link-bleak/server.crt"
certutil -d "sql:$NSSDB" -L -n "Scratch Link Bleak Local Server"
If your NSS database is password protected, use certutil -N without --empty-password for initialization and unlock it as prompted. A Chrome installed through Flatpak/Snap may use a different certificate store; the examples here target standard Chrome on Ubuntu.
Fully close Chrome and reopen it after importing the certificate.
Start
Ensure the original Scratch Link (if installed) is not running on TCP port 20110:
ss -ltnp | grep ':20110' || true
scratch-link-bleak
The process binds only to 127.0.0.1:20110, serves wss://device-manager.scratch.mit.edu:20110/scratch/ble, and uses the generated TLS certificate.
Open Scratch editor in Chrome, enable LEGO WeDo 2.0, and connect to LPF2 Smart Hub. Test motor, sensor, power off, and reconnect. Run as a regular desktop user, not root.
Optional flags: --debug, --scan-seconds 15.
Proving independence from pyscrlink
python -m pip show scratch-link-bleak bleak websockets cryptographyshould show installed dependencies.python -m pip show pyscrlink bluepyshould say the packages are absent in the new virtual environment.- The bridge reads only
~/.local/share/scratch-link-bleak/{server.crt,server.key}. - If you have an old
~/.local/share/pyscrlink, rename it temporarily, rather than deleting it, while testing this installation. A previously installed Chrome trust entry for the old certificate may remain, but will not validate the newly generated, distinct server certificate.
Troubleshooting
- Certificate error in Chrome: check correct NSS database, peer trust
P,,, fully restart Chrome, verify the public certificate has the expected SAN; never bypass certificate checks globally. - Connection refused: check port 20110, that the bridge is running, and the hostname mapping.
- No WeDo discovered: close other BLE connections, power-cycle the hub and retry.
Limitations and roadmap
- Discovery, connect, read, write and notifications over Bleak for LEGO WeDo 2.0.
- Suppress traceback flood for queued operations after BLE disconnect.
- Independent TLS certificate generator and documented manual Chrome trust setup (verified on Ubuntu 24.04.5 LTS + Chrome).
- WebSocket/reconnect regression suite and better installer UX.
- Additional hardware support, optional systemd user service.
- BSD 3-Clause license, retaining the original pyscrlink copyright notice.
- Test on additional Linux distributions and hardware before claiming broader support.
License and adoption
BSD 3-Clause. Commercial use, modification, proprietary redistribution and integration into an official product are permitted under the license conditions, including retaining the applicable notices and not implying endorsement.
LEGO, the Scratch Foundation, and others are welcome to adopt or contribute to this project. This invitation does not imply affiliation or endorsement, or grant any trademark rights.
Acknowledgements
Thanks to pyscrlink for its Linux Scratch Link contribution and compatibility context. This independent community project is not affiliated with or endorsed by Scratch, LEGO, or pyscrlink.
Please report reproducible logs in Issues. Never post private keys.
Metadata
Release files for scratch-link-bleak 0.2.0b1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| scratch_link_bleak-0.2.0b1.tar.gz | 11.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| scratch_link_bleak-0.2.0b1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.7 kB
Release files / scratch_link_bleak-0.2.0b1.tar.gz
| Download URL | scratch_link_bleak-0.2.0b1.tar.gz |
|---|---|
| Size | 11.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f5e3172e4087d7e47ebb3e0a5f382c351493b85e19799e130bb83fb8c62a88f8
|
|
BLAKE2b-256 checksum How to use checksums |
6bdb2b0e5e9558446052b32f578d12f19df1f8484c4e6feada04de887719f3d3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency logRelease files / scratch_link_bleak-0.2.0b1-py3-none-any.whl
| Download URL | scratch_link_bleak-0.2.0b1-py3-none-any.whl |
|---|---|
| Size | 12.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
31198faab85994f6a699a8065ae80796716a43a2c2e026854d3a2ceff96a3a65
|
|
BLAKE2b-256 checksum How to use checksums |
7f27f200fe2404d6d13aaa60360fcce963c0634d6b87a61a3f3a98d16fa96836
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.
Transparency log