Open, community-reverse-engineered BLE register / tuning maps for e-scooters, as a small JSON database. Independent of any paid app dataset.
Files · Schema · Tuning safely · Sources
Note
This is structured documentation of an open protocol standard. It powers the E-Tune app but is useful on its own for any client.
- Is: the openly published reverse-engineering knowledge (ScooterHacking
community,
CamiAlfa/M365-BLE-PROTOCOL,ub4raf/Ninebot-PROTOCOL,nootnooot/segway-ninebot-ble,py-mi-scooter). This is the same protocol knowledge a tuning app uses — it's the open standard for talking to the scooter. - Isn't: XiaoDash's (or any paid app's) proprietary backend dataset. That lives behind Firebase Auth + a paywall + client-side encryption and is not included or fetched here. You don't need it: the open protocol below is enough to read and tune the scooter yourself.
| File | Brand | Models | Coverage |
|---|---|---|---|
xiaomi_m365.json |
Xiaomi | M365, M365 Pro, 1S, Pro 2, Essential, Mi 3 | telemetry + KERS/cruise/light tuning |
ninebot.json |
Segway-Ninebot | ES1/2/4, G30 (Max), F20-40, E22/25/45 | telemetry + speed-limit/mode tuning |
kukirin.json |
Kukirin (Kugoo) | G2/G2 Max/Pro/Master, G3/Pro, G4/Max, V3, A1 | dashboard P-menu + brake/power derestrict combo (no BLE map) |
neoline.json |
Neoline (E-Ride) | generic TI CC254x platform | full plaintext BLE protocol: telemetry + speed-curve tuning + OAD firmware |
apps.json |
— | analyzed source apps (XiaoDash, Neoline E-Ride) + open sources | provenance of all data |
firmware_manifest.json |
Xiaomi M365 | stock firmware download index | versions + byte size + sha256 per image |
index.json |
— | catalog + schema + not-covered list | — |
This repo does not redistribute firmware binaries — those are Xiaomi's proprietary
copyrighted works. firmware_manifest.json is a download & checksum index for the
stock Xiaomi M365 firmware (gen A, plaintext/unsigned): per image it lists component,
version, byte size and sha256, plus the public download_base
(files.scooterhacking.org/firmware/m365/). Download each image yourself and verify it
against the sha256 before flashing.
esc/DRV*.bin— controller firmware (DRV143 = ESC v1.4.3)ble/BLE*.bin— bluetooth chip firmware (BLE129 = v1.2.9)bms/BMS*.bin— battery firmware (BMS126 = v1.2.6)
These are flashed to the scooter over BLE OTA — you can't read the current image out of the device. Match the component to the chip and verify the running version first; a wrong flash can brick a part. Newer (1S/Pro 2/Essential/Mi 3) firmware is signed and is deliberately out of scope. For custom firmware (derestrict, Pmax/KERS tuning) use the open builder at https://mi.cfw.sh/.
Dualtron/Kaabo/Inokim/Zero/Apollo/NIU use closed controllers (Minimotors EY3, LingBo, VESC variants). Telemetry is partially known; tuning is firmware/app-locked. Adding them would mean reverse-engineering each yourself, not copying a dataset.
- Read before you write. Register addresses and scales shift between firmware versions — verify the current value first.
- M365 stock firmware has no single speed-limit register; real delimiting is
done via custom firmware (CFW) flashed over BLE (e.g.
mi.cfw.sh), not a write. - Ninebot exposes a real
speed_limit(0x93) andriding_mode(0x74). - Over-current / brake / BMS changes can damage hardware (fire risk on BMS disable) and removing speed limits can be illegal for street use. Your scooter, your call.
- ScooterHacking Wiki — Mi guide: https://wiki.scooterhacking.org/doku.php?id=guide-mi
- CamiAlfa/M365-BLE-PROTOCOL: https://github.com/CamiAlfa/M365-BLE-PROTOCOL
- camcamfresh/Xiaomi-M365-BLE-Controller-Replacement: https://github.com/camcamfresh/Xiaomi-M365-BLE-Controller-Replacement
- nootnooot segway-ninebot-ble: https://nootnooot.codeberg.page/segway-ninebot-ble/
- ub4raf/Ninebot-PROTOCOL: https://github.com/ub4raf/Ninebot-PROTOCOL
- Ninebot ES protocol doc: https://cloud.scooterhacking.org/release/nbdoc.pdf
{ "reg": "0x7B", // hex register; M365 byte offset in bank = 2 x reg "name": "kers_regen_level", "access": "R/W", // R or R/W "type": "uint8", "units": "0=weak 1=medium 2=strong", "tuning": true, // changes ride behaviour "confidence": "high" // high = confirmed in multiple open sources }