Reading Xiaomi Mi Scale data with Web Bluetooth Scanning API
Tags: webdev, javascript, bluetooth, iot
Published: 2020-05-10 13:32:54

---
title: Reading Xiaomi Mi Scale data with Web Bluetooth Scanning API
published: true
description: Learn how I retrieve the weight data from my Xiaomi Mi Body Composition Scale using the Web Bluetooth Scanning API.
tags: webdev, javascript, bluetooth, iot
cover_image: https://i.imgur.com/xNhY5A6.png
---

The Web Bluetooth API provides the ability to connect and interact with Bluetooth Low Energy (BLE) peripherals. It was introduced in Chrome 56 on macOS back in January 2017.

## Reading the weight data

> **Note:** This demo only works on the first generation of Mi Body Composition Scale which was released in 2017 (Model Number: XMTZC02HM).

To capture the BLE advertising packets from the Xiaomi Mi Scale, we will need to use the [Web Bluetooth Scanning API](https://googlechrome.github.io/samples/web-bluetooth/scan.html). 

However, the Web Bluetooth Scanning API is still under development. You need to use Chrome 79+ with the `chrome://flags/#enable-experimental-web-platform-features` flag enabled to use the API.

{% gist https://gist.github.com/limhenry/cfb66dac0c2f92fc736b2572554704b4 %}

`navigator.bluetooth.requestLEScan()` will start scanning for the advertising packets. Right before that, the permission prompt will popup asking the user for permission to access Bluetooth.

![](https://i.imgur.com/ZWaabw6.png)

After the user has granted permission, we can listen to the advertising packets by using the `advertisementreceived` event:

{% gist https://gist.github.com/limhenry/618386777bd7aa57a083dece2198aa1a %}

The `advertisementreceived` event will return information like Device Local Name, Device ID, Received Signal Strength Indicator (RSSI), Transmit power (TX Power), Service UUIDs, Manufacturer Data, and Service Data.

To retrieve the payload data from Xiaomi Mi Scale, we need to get the data from `serviceData`.

{% gist https://gist.github.com/limhenry/501818dcca1310a8e7a077f1d2b14141 %}

![](https://i.imgur.com/FBfv966.png)
<figcaption>The output result of "valueDataView.buffer"</figcaption>

![](https://i.imgur.com/eBjMKTl.png)
<figcaption>The payload format for the Mi Scale</figcaption>

Next, to get the weight data, we need to  get the value of bytes 11 and 12 (which are [little-endian](https://hacks.mozilla.org/2017/01/typedarray-or-dataview-understanding-byte-order/)) then divide the value by 200.

{% gist https://gist.github.com/limhenry/999e0ea08de7c3fffc98832eb4bff5ca %}

With that, we have successfully retrieved the weight data from Xiaomi Mi Scale using the Web Bluetooth Scanning API.

## Extra: Reading the Impedance Data
The Xiaomi Mi Scale is also able to measure information like muscle mass, bone mass, body fat, and more through [Bioelectrical Impedance Analysis](https://en.wikipedia.org/wiki/Bioelectrical_impedance_analysis) (BIA). 

We can get the impedance data from bytes 9 and 10:

{% gist https://gist.github.com/limhenry/30524ec85514dedd2a80e795c25030a7 %}

Next, we can convert the impedance value using [this algorithm](https://github.com/wiecosystem/Bluetooth/blob/master/sandbox/huami.health.scale2/body_metrics.py). The output should look something like this:

![](https://i.imgur.com/roEyamC.png)

---

## Try It Out

![](https://i.imgur.com/mt5aWNY.gif)
<figcaption>Note: There's no way to get the impedance data if you are wearing socks, but I don't want to show my ugly feet… (And yes, that's a T-Rex socks)</figcaption>


Demo: [https://scale.limhenry.xyz](https://scale.limhenry.xyz)
GitHub (Source Code): [github.com/limhenry/web-bluetooth-mi-scale](https://github.com/limhenry/web-bluetooth-mi-scale)


---

## References

1. Web Bluetooth Documentation: [Link](https://webbluetoothcg.github.io/web-bluetooth/)
2. Web Bluetooth Scanning API  Sample: [Link](https://googlechrome.github.io/samples/web-bluetooth/scan.html)
3. Xiaomi Mi Scale BLE (Unofficial) Documentation: [Link](https://github.com/wiecosystem/Bluetooth/blob/master/doc/devices/huami.health.scale2.md)
4. TypedArray or DataView: Understanding byte order: [Link](https://hacks.mozilla.org/2017/01/typedarray-or-dataview-understanding-byte-order/)