Your wheelchair, your rules.
Python toolkit for the Alber e-motion M25 power-assist wheels. Because paying €595 for a Bluetooth remote that does less than a Python script is absurd.
Presented at 39C3 Hamburg: "Pwn2Roll: Who Needs a 595€ Remote When You Have wheelchair.py?"
- Decrypt the "encrypted" Bluetooth protocol: AES-128-CBC, nothing fancy
- Replace the €595 ECS remote: Same features, zero cost, more control
- Bypass all of the in-app purchases: All the "premium" features, free
- Currently we support out-of-the-box: ECS remote, speed increase to 8.5km/h, parking mode. Cruise mode and the push counter are possible in theory, but not tested yet. Stay tuned, this will be tested soonish (it's also the ground work for replacing the knob-style remote).
- Access dealer-only parameters: Your wheels, your data
- Warranty and Gewährleistung: Using unofficial tools may void them. The manufacturer or reseller will likely not be thrilled if you mention wheelchair.py during a service appointment.
- The Speedenings: 8.5 km/h is faster than 6 km/h. Physics applies. In Germany, electric wheelchairs above 6 km/h require registration when using in the public. This is also the case when one's using the paid feature in the official app. But if you want to break the law, you can do it with our tools, for free.
- Ownership: If your Krankenkasse paid for the device, they technically own it. You're poking at insurance property. They might have opinions, or they might never notice. We don't judge here.
- Safety: These wheels move a human. Cats have nine lives and always land on their feet, you might not have those features. Misconfigured parameters do things.
| Feature | Official ECS Remote | wheelchair.py |
|---|---|---|
| Price | €595 | Free |
| Read battery | Yes | Yes |
| Change assist level | Yes | Yes |
| Toggle hill hold | Yes | Yes |
| Read raw sensor data | No | Yes |
| Adjust drive parameters | No | Yes |
| Works on Linux | No | Obviously |
Easiest Way (All Platforms):
# Windows: Double-click start.bat
# Linux/Mac: ./start.sh
# Or:
python launch.pyThe GUI includes optional core architecture support with safety features, plus an optional (but cautioned) deadman disable mode for controlled testing.
See QUICKSTART.md for more options and details.
Traditional Setup:
# Setup (Ubuntu/Debian)
sudo apt install python3.12-venv python3-bluez
python3 -m venv .venv --system-site-packages
.venv/bin/pip install -e .
source .venv/bin/activate
# Get your AES keys (scan the QR codes on your wheel hubs)
python m25_qr_to_key.py "YourQRCodeHere"
# Talk to your wheels
python m25_ecs.py --left-addr AA:BB:CC:DD:EE:FF --right-addr 11:22:33:44:55:66 \
--left-key HEXKEY --right-key HEXKEY- Download and install Python 3.12 from python.org
- Enable “Add Python to PATH” during setup
- Verify:
py -3.12 --version
cd C:\path\to\your\m5squared
py -3.12 -m venv .venvSet-ExecutionPolicy -Scope Process -ExecutionPolicy BypassOptional, persistent for your user:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned.\.venv\Scripts\Activate.ps1python -m pip install --upgrade pippip install -e .| Script | What it does |
|---|---|
m25_qr_to_key.py |
QR code → AES key (their encoding is... creative) |
m25_ecs.py |
The main event: read status, change settings |
m25_gui.py |
GUI interface for Windows/Linux (NEW) |
m25_decrypt.py |
Decrypt captured Bluetooth packets |
m25_encrypt.py |
Encrypt packets for transmission |
m25_analyzer.py |
Make sense of the packet soup |
m25_parking.py |
Remote movement control (use responsibly) |
m25_bluetooth.py |
Scan, connect, send/receive (Linux) |
m25_bluetooth_windows.py |
Windows Bluetooth support via Bleak |
Each wheel has a QR code sticker. That's your key to the kingdom.
- Scan the QR code (22 characters of proprietary encoding)
- Run:
python m25_qr_to_key.py "ABCD1234..." - Get a 16-byte hex key
- Use it with
--left-key/--right-key
Both wheels have different keys. Yes, you need both.
Once you've saved your keys, consider taping over the QR codes. They're the keys to your wheels.
Bluetooth SPP on channel 6. Packets look like:
[0xEF] [length:2] [IV encrypted with ECB:16] [payload encrypted with CBC:n] [CRC:2]
Why encrypt the IV with ECB first? Nobody knows. But it works.
- Python 3.8+
pycryptodome- For the cryptopython-dotenv- For .env file support- Linux:
bluez/python3-bluez- For Bluetooth - Windows:
bleak- For Bluetooth (installed automatically)
Create a .env file from the template to store your credentials securely:
cp .env.example .envEdit .env and fill in:
M25_LEFT_MAC- Left wheel MAC addressM25_LEFT_KEY- Left wheel encryption key (from QR code)M25_RIGHT_MAC- Right wheel MAC addressM25_RIGHT_KEY- Right wheel encryption key
The .env file is gitignored and won't be committed.
This is for your own wheels. Don't be creepy.
- Research and education: Yes
- Your own devices: Yes
- Other people's wheelchairs: Absolutely not
- Protocol docs:
doc/directory - Supplementary resources (media, manuals, talk materials and other non-codey stuff: m5squared-resource repo
- 39C3 Talk: "Pwn2Roll: Who Needs a 595€ Remote When You Have wheelchair.py?"
- [DE] Warum eine Multiple-Sklerose-Erkrankte ihren Rollstuhl hackte
- [DE] Wie eine Multiple-Sklerose-Erkrankte die Paywall ihres Rollstuhls knackte
- [DE] 39C3: Rollstuhl-Security – Wenn ein QR-Code alle Schutzmechanismen aushebelt
- [EN] Louis Rossmann: Wheelchairs have paywalls and digital locks now (YouTube video)
This is non-profit research code. No exploits, no vulnerabilities. It's just documentation and tools for interoperability with a protocol that already exists.
The security model here is identical to what the official apps use: if you don't have the QR code, you don't get access. We're not bypassing anything, just using the same protocol with our own code. Your wheels, your keys, your choice of software.
That said, this only applies to your own equipment. Using these tools on someone else's wheelchair without explicit consent isn't just unethical, it might cause serious safety issues. Also: creepy.
The author(s) take responsible disclosure seriously. These are mobility devices that people depend on every day, and that should come before making a point.