[General Accessories] Osid:
I'll share my findings.

Sorry for my bad English.

Mi band sends ActivityData to app. Each ActivityData is 1 minute long and are 3 bytes.

(category, intensity, steps)

steps is the most obvious.

You'll find those bytes in data blob of date_data table or, if you have miband_log.txt on /sdcard in JSON sended to server (data property, base64 encoded).

App "rewrites" them in SportData class.

SportData is

(timeIndex, activity, mode, runs, step)

timeIndex = minute of day (1-1440)

step = steps in a minute

the others are calculated as follows (pseudo Java code):

category, intensity, steps

if (category == 0x7f) {

mode = category;

} else {

mode = category & 0xf;

if (step > 0) {

runs = category >> 4;

}

activity = intensity

step = steps

Now, some formula which Mi fit uses to calculate distance and calories burned every minute

d = height_in_cm * 3 / 100

iDistance = (step <= 90) ? (step*d*0.9) : (step^2*d)/(step > 120 ? 125 : 100)

runDistance = (((runs * 2) + 3) * iDistance) / 15;

For calories it uses a lookup table of doubles:

calList = {40.233d, 0.95d}, {53.645d, 1.19d}, {67.056d, 1.41d}, {80.467d, 1.57d}, {93.878d, 1.78d}, {107.29d, 2.36d}, {120.7d, 2.97d}, {134.11d, 3.79d}, {160.94d, 4.67d}, {187.76d, 5.24d}, {214.58d, 5.62d}, {241.4d, 6.1d}, {268.23d, 6.91d}, {295.05d, 7.62d}, {321.87d, 9.05d}, {348.69d, 9.43d}, {375.52d, 10.95d}};

calList index is the max of calList 1st value less than iDistance.

cals = (weight_in_kg * 2.2046 * calList i-th tuple[1] * iDistance) / (60 * calList i-th tuple[0])

runCalories = (cals * ((runs * 2) + 3) / 15);

Some examples taken for logcat:

03-13 23:05:54.220 5092-5140/com.xiaomi.hm.health D/dataProcess? DataAnalysis i=2274:steps=67

03-13 23:05:54.220 5092-5140/com.xiaomi.hm.health D/dataProcess? DataAnalysis iDistance=42.547680,p=1,cals=119.911552

03-13 23:05:54.220 5092-5140/com.xiaomi.hm.health D/dataProcess? DataAnalysis i=2275:steps=100

03-13 23:05:54.220 5092-5140/com.xiaomi.hm.health D/dataProcess? DataAnalysis iDistance=70.560000,p=3,cals=123.047801

03-13 23:05:54.220 5092-5140/com.xiaomi.hm.health D/dataProcess? DataAnalysis i=2276:steps=97

03-13 23:05:54.220 5092-5140/com.xiaomi.hm.health D/dataProcess? DataAnalysis iDistance=66.389904,p=2,cals=126.227996

BTW: I'm 168cm and 62kg :D

After that algorithm finds intervals. How?

for (Iterating over all sportDatas, i used as index [minute]) }

startMode = sportData.mode;

if (spordData.mode != sportData[i-1].mode) {

if ((sportmode[i - 1] == 0 && sportmode - startmode >= 10) || !(sportmode[i - 1] == 1 || sportmode[i - 1] == 2 || sportmode[i - 1] == 0)) {

this is an interval startMode -> i-1

}

} else {

i++;

}

}

Intervals are discarded.

The remaining gaps are filtered (I have't still reverse engineered Java method filterData) and under some conditions it finds sections which are the real sections showed in graphs on Mi Fit app.

I haven't see SleepAnalysis.

I've developed, for internal use, an Xposed module which hooks into MiLiProfile class of Mi Fit and through intents is able to control vibration, LEDs, realtime steps, sensors, etc.

Maybe, in the future, I'll release it with Tasker integration and/or as a standalone app (without Xposed) if there's some interest.

Hope to help you ;)