Command Reference
Commands are sent as register read/write operations within encrypted frames. Each command targets a specific board (module) and register address.
Command types
| Value |
Constant |
Direction |
Response? |
0x01 |
CMD_READ |
App → Device |
Yes — read request |
0x02 |
CMD_WRITE |
App → Device |
Yes — write with ACK |
0x03 |
CMD_WRITE_NR |
App → Device |
No — write, no response |
0x04 |
CMD_READ_RESP |
Device → App |
Read response |
0x05 |
CMD_WRITE_RESP |
Device → App |
Write acknowledgment |
0x06 |
CMD_WR_BIT |
App → Device |
Bitfield write |
Read operation
Request (cmd = 0x01):
INDEX = register_address
LENGTH = bytes_to_read
DATA = [LENGTH] (length byte in data field)
Response (cmd = 0x04):
INDEX = register_address
DATA = [requested_bytes...]
Write operation
Request (cmd = 0x02 or 0x03):
INDEX = register_address
DATA = [bytes_to_write...]
Write ACK (cmd = 0x05):
INDEX = register_address
DATA[0] = echoed index (for verification)
CMD_WRITE_NR (0x03) does not expect a response.
Special command IDs
These commands use a dedicated command byte instead of the standard read/write types:
| Cmd |
Hex |
Purpose |
| 87 |
0x57 |
Vehicle activation |
| 91 |
0x5B |
PRE_COMM (handshake phase 1) |
| 92 |
0x5C |
SET_PWD (handshake phase 2) |
| 93 |
0x5D |
AUTH (handshake phase 3) |
| 99 |
0x63 |
Vehicle unlock |
| 100 |
0x64 |
Trunk/ACC open (requires auth) |
| 102 |
0x66 |
Set password |
| 104 |
0x68 |
NFC operations |
| 110 |
0x6E |
HID bond management |
| 111 |
0x6F |
BLE config (connect mode, RSSI) |
| 113 |
0x71 |
Navigation data (to TFT) |
| 118-120 |
0x76-78 |
File transfer (info/write/CRC) |
| 129 |
0x81 |
TFT theme/gear name |
| 171 |
0xAB |
Handlebar calibration |
| 175 |
0xAF |
Set password (newer) |
Speed & drive
Speed limit
| Command |
Board |
Index |
Cmd |
Data |
Effect |
| Read limit |
DIS (0x01) |
147 (0x93) |
READ |
2 bytes |
Current speed limit (0.1 km/h units) |
| Set limit |
DIS (0x01) |
147 (0x93) |
WRITE_NR |
uint16 LE |
Set to value (0.1 km/h units) |
| Disable limit |
DIS (0x01) |
147 (0x93) |
WRITE_NR |
00 00 |
No limit |
| 25 km/h |
DIS (0x01) |
147 (0x93) |
WRITE_NR |
FA 00 |
250 = 25.0 km/h |
| 35 km/h |
DIS (0x01) |
147 (0x93) |
WRITE_NR |
5E 01 |
350 = 35.0 km/h |
| 45 km/h |
DIS (0x01) |
147 (0x93) |
WRITE_NR |
C2 01 |
450 = 45.0 km/h |
| 60 km/h |
DIS (0x01) |
147 (0x93) |
WRITE_NR |
58 02 |
600 = 60.0 km/h |
Data format: unsigned 16-bit little-endian ([lo_byte, hi_byte]), in 0.1 km/h units.
Speed readings
| Command |
Board |
Index |
Size |
Description |
| Current speed |
DIS (0x01) |
38 (0x26) |
2B |
Speed in 0.1 km/h units |
| Rated max speed |
DIS (0x01) |
72 (0x48) |
2B |
Factory max speed (0.1 km/h units) |
| Trip max speed |
DIS (0x01) |
36 (0x24) |
2B |
Trip maximum (x0.1 km/h) |
| Average speed |
DIS (0x01) |
39 (0x27) |
2B |
Trip average (x0.1 km/h) |
Riding mode
| Command |
Board |
Index |
Data |
Purpose |
| Read mode |
DIS (0x01) |
116 (0x74) |
2B read |
Current riding mode |
| Set mode |
DIS (0x01) |
116 (0x74) |
write |
Set riding mode |
Gear profiles (MCU board)
| Command |
Board |
Index |
Data |
Purpose |
| Read gear 1 |
MCU (0x02) |
34 |
32B |
Gear profile 1 |
| Write gear 1 |
MCU (0x02) |
34 |
write |
Write gear profile 1 |
| Gear top speed |
MCU (0x02) |
49 |
write |
Set gear top speed |
| Gear acceleration |
MCU (0x02) |
45 |
write |
Set acceleration rate |
| Gear TCS |
MCU (0x02) |
47 |
write |
Set traction control |
| Gear nitro |
MCU (0x02) |
48 |
write |
Set nitro speed |
| Read gear 2 |
MCU (0x02) |
58 |
32B |
Gear profile 2 |
| Gear 2 top speed |
MCU (0x02) |
73 |
write |
Set gear 2 top speed |
| MCU max speed |
MCU (0x02) |
9 |
2B read |
MCU max speed |
| Speed safe lock |
MCU (0x02) |
83 |
2B |
Speed safety lock |
Battery & power
Battery status
| Command |
Board |
Index |
Size |
Description |
| Battery % |
DIS (0x01) |
181 (0xB5) |
2B |
Battery percentage |
| Main power |
ECU (0x09) |
3 |
2B |
Power status (mask 4 = battery online) |
| Current power |
DIS (0x01) |
189 |
2B |
Current power draw |
| Max power |
DIS (0x01) |
73 |
2B |
Maximum power |
| Charge power |
DIS (0x01) |
145 |
2B |
Charge power setting (read/write) |
| Battery type |
DIS (0x01) |
146 |
2B |
Battery type identifier |
| VRLA voltage |
DIS (0x01) |
177 |
2B |
12V lead-acid voltage |
Mileage
| Command |
Board |
Index |
Size |
Description |
| Total mileage |
DIS (0x01) |
183 (0xB7) |
4B |
Odometer (0.001 km units, i.e. 1 metre precision) |
| Trip mileage |
DIS (0x01) |
185 (0xB9) |
4B |
Trip distance (0.001 km units) |
| Remaining range |
DIS (0x01) |
37 (0x25) |
2B |
Estimated range (0.1 km units) |
| Precise range |
DIS (0x01) |
175 (0xAF) |
2B |
Precise range (0.1 km units) |
| Trip time |
DIS (0x01) |
186 |
2B |
Current trip duration |
Per-battery detail
Each battery module has its own board ID. For E-series mopeds: BMS1 = 0x07, BMS2 = 0x06, BMS3 = 0x05.
| Register |
Index |
Size |
Description |
| Voltage |
26 |
2B |
Battery voltage |
| Status flags |
2 |
4B |
Detailed status |
| Remaining capacity |
38 |
2B |
Capacity remaining |
| Manufacture date |
32 |
2B |
Production date |
| Energy throughput |
39 |
4B |
Total energy (Wh) |
| Capacity throughput |
42 |
4B |
Total capacity (Ah) |
| Cycle count |
27 |
2B |
Charge cycles |
| Deep discharge count |
122 |
2B |
Deep discharges |
| State of charge |
50 |
2B |
SoC percentage |
Security & auth
Vehicle actions (cmd 0x64 / 100)
Vehicle control commands (power on/off, open seat/trunk) use a special command byte and require an $ident authentication token as the payload. The target board differs by device generation:
| Generation |
Target board |
Cmd byte |
Notes |
| Gen2 (E-series mopeds) |
VCU (0x09) |
0x64 (100) |
E125S, E150S, E250S, E300SE |
| Gen3 (kick scooters) |
BLE (0x04) |
0x03 (WRITE_NR) |
Max G2, GT-series, P-series |
Target board matters
Sending vehicle actions to the wrong board (e.g., BLE 0x04 on an E-series moped) silently fails — the device does not respond or act. The E-series requires target VCU (0x09).
Action registers
| Action |
Index |
Hex |
Description |
| Open ACC |
78 |
0x4E |
Power on the vehicle (turn on ignition) |
| Close ACC |
70 |
0x46 |
Power off the vehicle |
| Open trunk |
115 |
0x73 |
Open seat/trunk compartment |
$ident payload
The $ident token is a 16-byte authorization secret issued by the Segway cloud during first-time device pairing. It is sent as the data payload of the command frame. The device verifies this token before executing the action.
Frame (Gen2, open ACC):
Target: VCU (0x09)
Cmd: 0x64
Index: 0x4E
Data: 16 bytes of hex-decoded ident
Silent failure on wrong ident
Frames with a mismatched ident still decrypt cleanly and pass MAC verification — the device just ignores them. There is no error response. This is the failure mode for an app that has the correct handshake password but the wrong (or missing) ident: handshake succeeds, reads work, but no vehicle action ever fires.
Wire format. The value is stored on-device as a 32-character lowercase hex string and decoded to 16 binary bytes before being placed on the wire:
Stored (UserDefaults): "00112233445566778899aabbccddeeff" (example)
On-wire payload: 00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
Provenance. In the official Segway/Ninebot app (cn.ninebot.device.motor.MotorDevice), the value arrives once via an authenticated cloud API response, is cached in HttpCacheClient under the key "ident", and is written to persistent storage so the app continues to work offline:
| Platform |
Storage |
| iOS |
Library/Preferences/com.ninebot.segway.plist → UserDefaults key {serialNumber}_ident |
| Android |
SharedPreferences (analogous) |
Not to be confused with the "airlock" proximity-unlock feature (iBeacon → auto-unlock while holding the start button near the scooter). The backup keys nb_airlock_ident_{sn} and nb_airlock_beacon_{sn} belong to that feature; they incidentally hold the same 16-byte value in the reference app, but the code paths are independent.
Third-party apps that cannot talk to the Segway cloud must obtain the ident out-of-band — the typical path is to extract it from an iOS backup the user already has. See Credential QR setup for the QR/paste flow used by the open-source Flutter client in this repository.
Other security commands
| Command |
Board |
Index |
Cmd |
Purpose |
| Unlock |
ECU (0x09) |
1 |
99 (0x63) |
Unlock vehicle |
| Activate |
DIS (0x01) |
0 |
87 (0x57) |
Activate vehicle |
| Set NFC pwd |
DIS (0x01) |
0 |
102 (0x66) |
Set NFC password |
NFC operations (DIS board, cmd 104)
| Command |
Index |
Timeout |
Purpose |
| Enter write mode |
5 |
60s |
Enable NFC card writing |
| Delete card |
6 |
10s |
Remove NFC card |
| Exit NFC mode |
10 |
default |
Exit NFC operation mode |
Feature flags
Boolean registers control vehicle features. Each register is a bitmask where individual bits enable/disable features.
rFunBool (DIS, index 125 / 0x7D)
| Bit |
Mask |
Feature |
| 1 |
0x0002 |
Push assist mode |
| 2 |
0x0004 |
Auto security / auto guard |
| 7 |
0x0080 |
Extended range mode |
| 8 |
0x0100 |
Parking mode |
| 9 |
0x0200 |
Sitting detection |
| 10 |
0x0400 |
Tail light |
| 11 |
0x0800 |
Auto turn signal light |
| 13 |
0x2000 |
Reverse mode |
| 14 |
0x4000 |
Range display mode |
rCTLBool2 (DIS, index 124 / 0x7C)
| Bit |
Mask |
Feature |
| 1 |
0x0002 |
Metric/Imperial units |
| 3 |
0x0008 |
Turn signal sound (inverted logic) |
| 7 |
0x0080 |
Auto park |
| 10 |
0x0400 |
Electric brake |
| 13 |
0x2000 |
TCS (traction control) |
rFunAppBool (DIS, index 138 / 0x8A)
This register gates UI feature visibility in the app:
| Bit |
Mask |
Features gated |
| 4 |
0x0010 |
Speed safety lock, electric brake, auto park, handlebar calibrate |
| 10 |
0x0400 |
Precise mileage support |
rFunAppBool2 (DIS, index 140 / 0x8C)
| Bit |
Mask |
Feature |
| 1 |
0x0002 |
TCS support |
| 2 |
0x0004 |
Sitting detection (alternate) |
Other boolean registers
| Register |
Index |
Purpose |
| rCTLBool |
132 (0x84) |
Control flags group 2 |
| rFunAppBool3 |
169 (0xA9) |
App feature flags 3 |
| rFunAppBool4 |
156 (0x9C) |
App feature flags 4 |
| rBool |
178 (0xB2) |
General boolean register |
| rBool2 |
170 (0xAA) |
Boolean register 2 |
| rInfoBool2 |
55 (0x37) |
Info boolean register |
Lights & sound
Sound (DIS board)
| Command |
Index |
Description |
| Volume |
117 (0x75) |
Mask 0x00FF: volume 0-100% |
| Sound effect |
117 (0x75) |
Mask 0xFF00: 0=E1, 256=E2, 512=E3 |
| Alarm volume |
118 |
Alarm volume level |
| Alarm sensitivity |
119 |
Sensitivity 1-4 (4 = highest) |
| Play sound |
— |
cmd 17: trigger sound effect |
Headlights (DIS board)
| Command |
Index |
Description |
| Brightness |
123 |
Headlight brightness level |
| Delay off |
129 |
Delay before lights turn off |
| Handle light mode |
141 |
Handlebar light mode |
| Handle RGB 1 |
142 |
4-byte RGB color 1 |
| Handle RGB 2 |
157 |
4-byte RGB color 2 |
HEP lights (HEP board, 0x11)
| Command |
Index |
Size |
Purpose |
| Mode (power on) |
0 |
8B |
Light mode when powered on |
| Mode (power off) |
4 |
8B |
Light mode when powered off |
| Current mode |
8 |
8B |
Active light mode |
| Park mode |
12 |
8B |
Parking light mode |
| Play animation |
1 |
cmd 17 |
Trigger light animation |
| Command |
Board |
Index |
Size |
Description |
| Serial number |
DIS (0x01) |
16 |
14B |
ASCII serial number |
| CPU ID |
DIS (0x01) |
218 |
12B |
CPU identifier |
| Dashboard FW |
DIS (0x01) |
26 |
2B |
Dashboard firmware version |
| MCU FW |
DIS (0x01) |
40 |
2B |
MCU firmware version |
| BMS1 FW |
DIS (0x01) |
48 |
2B |
Battery 1 firmware |
| BMS2 FW |
DIS (0x01) |
49 |
2B |
Battery 2 firmware |
| BMS3 FW |
DIS (0x01) |
50 |
2B |
Battery 3 firmware |
| ECU FW |
DIS (0x01) |
76 |
2B |
ECU firmware version |
| BLE FW |
BLE (0x04) |
104 |
2B |
BLE module firmware |
| ABS FW |
DIS (0x01) |
208 |
2B |
ABS firmware version |
| Charger FW |
DIS (0x01) |
93 |
2B |
Charger firmware |
| DIS part number |
DIS (0x01) |
80 |
14B |
Dashboard part number |
| ECU part number |
ECU (0x09) |
40 |
14B |
ECU part number |
| MCU part number |
MCU (0x02) |
16 |
14B |
MCU part number |
| Timezone |
DIS (0x01) |
134 |
2B |
Timezone setting (read/write) |
Polling schedule
The app polls different registers at different intervals depending on the active screen:
| Period |
Register types |
| Once (0) |
Static info (serial, firmware versions) |
| 500 ms |
Fast-changing: speed, power |
| 1,000 ms |
Medium: running time, trip max speed |
| 2,000 ms |
Slow: range, battery level, mileage |
| 3,000 ms |
Very slow: tire pressure, temperature |