Integrating Xiaomi Mi Scale

what version of the scale do you have? Does it have 4 silver pads on it?

Yes, it is the one with 4 silver pads.

I believe @Syssi is working on updating his script to take into account pounds. If you need pounds, replace above line with
if measunit == "03": unit = 'lbs'

That should work

Thanks for your help. I did the change and will check when I get back to home.

1 Like

If you select your country as Mainland China, you can also select jin.

Thanks will try tonight…

You can select the units under the Units of Body Composition Scale where jin doesn’t appear and also in Settings of your profile where you can select jin as well.

BTW, you could check this: https://github.com/oliexdev/openScale/issues/71

Thanks will have a look, though format is different. For starters there is a lot more data in that scale than in the Xiaomi one, but maybe I can find some pointers…

Think I might have made some progress. I need to validate (maybe someone can help with this too) but I believe data might broken down as follows:

Item Formula Value
Device Type data[0:4] 1b18
Unit data[4:6] 02
User? data[6:8] 166
year int((data[10:12] + data[8:10]), 16) 2018
month data[12:14] 5
day data[14:16] 20
Hour? data[16:18] 0
Min? data[18:20] 27
Weight int((data[28:26] + data[26:28]), 16) * 0.01 80.4

The year, month date just looks too much of a coincidence to be just that.
This makes me think the hours and minutes are a logical following.
This leaves me with 3 sets of HEX numbers. From the link provided by @cihanulusoy, it would appear the scale doesn’t send all the data, and possibly only sends the body resistance, the app doing the calculations.
If true, again from the formula, my body resistance would be 291.9342357

This is what I need to “retrieve”:
Weight: 80.4 Kg
Body fat: 25.8%
Muscle Mass 56.5Kg
Water: 50.8%

Good job. There are several different approaches in literature for calculation of total body water and fat free mass through biomedical impedance analysis. You can refer to the article at https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4118362 to see some of these and have a look at http://kennisbank.hva.nl/document/220141 for a comprehensive list.

Oh that’s a LOT of reading :slight_smile: I’ll see if I can spend some time on this over the next few days and see if I find any correlation with the data from the scale…

Corrected :slight_smile:

What about L51? The original code is:
if data.startswith(‘1d18’) and sdid == 22:
Your data starts with 1b18, did you change it as well?

Yes I had to change this line to if data.startswith(‘1b18’) :
Admittedly, I’ve not tried with the and sdid == 22 bit

I believe it’s like that:

String: 1b1802a6e20705150a251df401443e

Item Formula HEX Decimal
Device Type data[0:4] 1b18
Unit data[4:6] 02
User? data[6:8] a6 166
year int((data[10:12] + data[8:10]), 16) 07e2 2018
month data[12:14] 05 5
day data[14:16] 15 21
Hour? data[16:18] 0a 10
Min? data[18:20] 25 37
Sec data[20:22] 1d 29
Impedance int((data[24:26] + data[22:24]), 16) 01f4 500
Weight int((data[28:30] + data[26:28]), 16) * 0.01 / 2 3e44 79.7

Does this help? https://unix.stackexchange.com/questions/96106/bluetooth-le-scan-as-non-root

small typo for sec, should be data[20:22].
The formulas were not correct either for most

String: 1b1802a6e20705150a251df401443e
Item Formula Value Value
Device Type data[0:4] 1b18
Unit int(data[4:6],16) 02 2
? int(data[6:8],16) a6 166
year int((data[10:12] + data[8:10]), 16) 07e2 2018
month int(data[12:14],16) 05 5
day int(data[14:16],16) 15 21
Hour int(data[16:18],16) 0a 10
Min int(data[18:20],16) 25 37
Sec int(data[20:22],16) 1d 29
Impedance? int((data[24:26] + data[22:24]), 16) 01f4 500
Weight int((data[28:26] + data[26:28]), 16) * 0.01 /2 3e44 79.7

I can confirm above readings to be correct / as expected

Actual readings from the app:
Weight: 79.7 Kg
Body fat: 25.7%
Muscle 56.1Kg
water: 50.9%

my height: 175cm
my age: 39

Here’s another reading from this morning:

String: 1b1802a6e20705180c0d04d701943e
Item Formula Value Value
Device Type data[0:4] 1b18
Unit int(data[4:6],16) 02 2
User? int(data[6:8],16) a6 166
year int((data[10:12] + data[8:10]), 16) 07e2 2018
month int(data[12:14],16) 05 5
day int(data[14:16],16) 18 24
Hour int(data[16:18],16) 0c 12
Min int(data[18:20],16) 0d 13
Sec int(data[20:22],16) 04 4
Impedance int((data[24:26] + data[22:24]), 16) 01d7 471
Weight int((data[28:26] + data[26:28]), 16) * 0.01 /2 3e94 80.1

Actual readings from the app:
Weight: 80.1 Kg
Body fat: 25.7%
Muscle 56.4Kg
water: 50.9%

my height: 175cm
my age: 39

I’ve tried various formulas to try and calculate Total Body Water (TBW) Fat Mass (FM) and Fat Free Mass (FFM) from the links that @cihanulusoy provided, but I can’t find anything that gives me the same values as what’s in the app.
I’ve emailed Xiaomi asking if they can provide the formulas they use, you never know

For the purpose of reading from the Xiaomi scale, I guess the above is enough, the calculations will need to be made in HA / in the script anyway as extra data will be required, such as height, age and male/female…

@syssi I can’t find a way for the scale to send the data in jin, I only have lbs and kgs options for the scale. The app offers different units, but changing these has no incidence on the data the scale itself sends…

I’ve amended thes scrip to cater for both versions. Can people try and feedback please?
https://hastebin.com/mibikorepo.py

Thanks for the warning. I’ve corrected. Actually, 2 jins = 1 kg, therefore the weight data that the scale sends is in jin, we divide it by two to get the wieght in kg.

I know that 2 jins = 1 kg (the other way round :wink: ) I just don’t know if the scale can send measures in that unit (so as to try and catch the unit from the stream and handle correctly)
If anyone has a V2 scale that sends in jin, please provide the data so I can update the code…