My Mi-Band is finally here and I totally love it.

Official App now available for Android and iOS.

To allow third-party developers access to this device I will post details here.



Based on me:

Used BLE chip: Dialog DA14580

Default name MI

Connectable yes (approx. 30sec timeout)

Does advertise yes

What features does it have (accessible by BLE):

3 LED (color adjustable), capacitive touch sensor, Vibrator (can be stopped actively), Timer (starts to Vibrate), Battery stats, stores full user profile (gender, age, weight, ...), live step notifications, save step notifications, sleep detection

After a firmware update Mi Band no longer has user-descriptions for their Chars & Services. Either they don't want us to reverse engineer or they simply forgot it ...

BLE Actions





The protocol is not up to date, I am no longer updating it.





Extracted from com.xiaomi.hm.bleservice.profile.MiLiProfile.java





Pair

Note: Once the Miband is actively paired with a device, other devices won't discover it





Write 2 to Characteristic 0xFF0F (PAIR). Maybe you have to confirm by putting your finger on the aluminium part of the Mi Band.

Mi Band will respond with 2 on the same characteristic if the pairing was successful.

Mi Band will respond with 0xfff on the same characteristic if the device is not paired.

Self Test

Note: This will remove bonding information on the Mi Band, which might confused iOS (and probably Android, too). So before you connect next time remove your Mi Band via Settings > Bluetooth.





Write

to Characteristic

(TEST). Your Mi Band will do crazy things (LED flashing, vibrate)

Realtime Step Notification





Enable Notifications:

Write

to Characteristic

(CONTROL_POINT).

Disable Notifications:

Write

to Characteristic

(CONTROL_POINT).





I assume that you will be notified from 0xFF03 but I haven't verified yet.

Sensor Data Notification





Enable Notifications:

Write

to Characteristic

(CONTROL_POINT).

Disable Notifications:

Write 18,

to Characteristic

(CONTROL_POINT).





I assume that you will be notified from 0xFF03 but I haven't verified yet.

Get Battery Info





Read or let notify from Characteristic

(BATTERY).

Interpret the received byte array, skip if received not exactly 10 bytes:





Battery Info:

Level in%: byte[0]

Charges: 0xffff & (0xff & byte[7] | (0xff & byte[8]) << 8

Status: byte[9]

where 1 = Battery low

2 = Battery charging

3 = Battery full (charging)

4 = Not charging





Last charged Date Information (Gregorian Calendar):

Year: byte[1] + 2000

Month: byte[2]

Day / date: byte[3]





Hour (0-24): byte[4]

Minute: byte[5]

Second: byte[6]





Example response: 33 0E 09 1B 08 03 2E 06 00 04

=> 51 % charged

=> Not charging

=> Last charged 2014\09\27 08:03:46

=> 6 Cycles (seems like someone charged it before me 5 times ...)





Get Date Time

Get Device / Bluetooth Name



Read from Characteristic 0xFF02 (DEVICE_NAME). The received bytes are to be interpreted as UTF8 String.

Get Device Info



Read from Characteristic 0xFF01 (DEVICE_INFO). Interpret the received byte array.



UUID: formate byte[0-7] as "%02X%02X%02X%02X%02X%02X%02X%02X"



You can extract features, appearance (probably the color) and hardwareRevision form UUID.

There other bytes inside the array are profileVersion and firmwareVersion. Calculation will be posted later.

Get LE Params



Read from Characteristic 0xFF09 (LE_PARAMS). Interpret the received byte array, skip if received not exactly 12 bytes:



connIntMin: 0xffff & (0xff & byte[0] | (0xff & byte[1]) << 8)

connIntMax: 0xffff & (0xff & byte[2] | (0xff & byte[3]) << 8)

latency: 0xffff & (0xff & byte[4] | (0xff & byte[5]) << 8)

timeout: 0xffff & (0xff & byte[6] | (0xff & byte[7]) << 8)

connInt: 0xffff & (0xff & byte[8] | (0xff & byte[9]) << 8)

advInt: 0xffff & (0xff & byte[10] | (0xff & byte[11]) << 8)



How to interpret this raw timing data:



connIntMin * 1.25 milliseconds

connIntMax * 1.25 milliseconds

latency milliseconds

timeout * 10 milliseconds

connInt * 1.25 milliseconds

advInt * 0.625 milliseconds





Get Usage

Get User Info

Get Realtime Steps



Read from Characteristic 0xFF06 (REALTIME_STEPS). The 2 received bytes are the steps. Interpret them as integer.



Example response: 12 16

=> 4630 steps

Factory Reset

Note: This will remove bonding information on the Mi Band, which might confused iOS (and probably Android, too). So before you connect next time remove your Mi Band via Settings > Bluetooth.





Write

to Characteristic

(

CONTROL_POINT

).

Reboot



Write 12 to Characteristic 0xFF05 (CONTROL_POINT).

Remind (seems to be Beta testing)

Remote Disconnect

Note: This will remove bonding information on the Mi Band, which might confused iOS (and probably Android, too). So before you connect next time remove your Mi Band via Settings > Bluetooth.



Write 1 to Characteristic 0xFF0D (TEST).

Start Vibration



Write 8, 2 to Characteristic 0xFF05 (CONTROL_POINT).

Stop Motor Vibration



Write 19 to Characteristic 0xFF05 (CONTROL_POINT).

Sync



Write 11 to Characteristic 0xFF05 (CONTROL_POINT).

Write MD5 (???)

Send Firmware

Send Firmware Info

Set Color Theme



Write 14, R , G , B , D to Characteristic 0xFF05 (CONTROL_POINT). Where R, G, B, is a byte representing red, green blue value and D is 0 (don't flash) or 1 (quickly flash Color).



Default colors from the app:



blue: 1542 (Note: yes, this is a int)

green: 0x40500

red: 0x60102

orange: 0x60200





Set Goal (in steps)

Set Device / Bluetooth Name



Write an UTF8 String (as byte array) to Characteristic 0xFF02 (DEVICE_NAME).

Set Realtime Steps

Set Timer

Set User Info

Set Wear Location (Left Hand, Right Hand, Neck)

Authenticate





















I will update more details and post the protocol soon (step by step).