A Flutter plugin to take measurements from Xiaomi weight scales.
What it does:
- Track measurements
- Weight
- Device weight unit (kg/lbs)
- Impedance
- Progress (e.g. Measuring -> Stabilized -> Measured)
- Scan for nearby Xiaomi scales
- Direct scale data
- Weight
- Device weight unit
- Device timestamp
- Impedance
- Flags
- Weight stabilized
- Weight removed
- Measurement completes
- Calculate* body data from impedance:
- Body fat
- Visceral Fat
- Bone Mass
- Water
- Muscle Mass
- BMI
- LBM Coefficient
* Note: These values are calculated through reverse engineered functions. While they should be similar to what the official app by Xiaomi reads, their accuracy is similarly not guaranteed and should be taken with a grain of salt.
What it does NOT do:
- Sync historical data stored on device
- Configure the device settings
Image | Name |
---|---|
Mi Body Composition Scale 2 |
I am still looking to support the Xiaomi Scale (v1) as well (The one without the 4 electrodes on top). I only have access to the v2 model, and therefore am not able to test. In case you have access to one and are willing to help out, please get in contact!
First of all I can recommend to just take a look at the example.
Min iOS Development Target => 11 This is because of flutter_reactive_ble
Add a description why you want to use the bluetooth peripherals in the info.plist iOS13 and higher
<key>NSBluetoothAlwaysUsageDescription</key>
<string>Connect to xiaomi scale to get weight</string>
iOS12 and lower
<key>NSBluetoothPeripheralUsageDescription</key>
<string>Connect to xiaomi scale to get weight</string>
No need to ask for runtime permission. This is already handled by flutter_reactive_ble Best practice: You should check if the permission is already given. if not show a message to the user. You can only request the permission once. After that you should check the status of the permission yourself. (this is not handled by this package or flutter_reactive_ble)
Min sdk Development Target => 24 This is because of flutter_reactive_ble
flutter_reactive_ble adds these permissions automaticly
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
At runtime you should still request the location permissions yourself. Otherwise the app won't work.
For the examples below, grab an instance of MiScale
first.
MiScale _mi = MiScale.instance;
You can keep track of measurements as follows:
StreamSubscription subscription =
_mi.takeMeasurements().listen((MiScaleMeasurement measurement) {
// Code for handing measurement
});
// Stop taking measurements
subscription.cancel();
Measurements must be cancelled before a new measurement can be started for the same device. Measurements are automatically cancelled when they reached the final MEASURED
stage.
In case you would like to cancel a measurement before the MEASURED
stage is reached, it is up to you to cancel the measurement manually.
_mi.cancelMeasurement(deviceId)
You can obtain the deviceId
either from a MiScaleMeasurement
or MiScaleDevice
instance.
Note: If a user steps off the scale before the STABILIZED
stage is reached, the measurement will remain incomplete. Hence, if you want to take a new measurement, you must also cancel the incomplete measurement first
The discoverDevices
stream will only output compatible devices that it finds.
StreamSubscription subscription = _mi.discoverDevices(
duration: Duration(seconds: 10), // Optional, default is 5 seconds
).listen(
(MiScaleDevice device) {
// Code for handling found device
},
);
// Stop discovering before given duration has expired
subscription?.cancel();
If you want to get the scale data directly without tracking measurements, you can do so as follows:
StreamSubscription subscription = _mi.readScaleData().listen(
(data) {
// Code to handle the scale data
},
);
// Stop reading data
subscription.cancel();
In case you are using ProGuard add the following snippet to your proguard-rules.pro file:
-keep class com.signify.hue.** { *; }