xiaomi_scale 1.0.1

  • Readme
  • Changelog
  • Example
  • Installing
  • 29

xiaomi_scale #

A Flutter plugin to take measurements from Xiaomi weight scales.

App Screenshots

What it does:

  • Track measurements
    • Weight
    • Device weight unit (kg/lbs)
    • Progress (e.g. Measuring -> Stabilized -> Measured)
  • Scan for nearby Xiaomi scales
  • Direct scale data
    • Weight
    • Device weight unit
    • Device timestamp
    • Flags
      • Weight stabilized
      • Weight removed
      • Measurement completes

What it does NOT do:

  • Sync historical data stored on device
  • Configure the device settings

Supported devices #

ImageName
Mi Body Composition Scale 2Mi 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!

How to use #

First of all I can recommend to just take a look at the example.

Note: Make sure before using any functionality of this library, that permission has been given to scan for bluetooth devices. On Android, this is the ACCESS_COARSE_LOCATION permission.

For the examples below, grab an instance of MiScale first.

MiScale _mi = MiScale.instance;

Tracking measurements #

You can keep track of measurements as follows:

StreamSubscription subscription =
    _mi.takeMeasurements().listen((MiScaleMeasurement measurement) {
  // Code for handing measurement
});

// Stop taking measurements
subscription.cancel();

Cancelling measurements

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

Scanning for devices #

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();

Getting all scale data #

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();

0.0.1 #

Initial release of plugin

0.0.2 #

Formatting fixes

0.0.3 #

Updated readme

1.0.0 #

First major release

1.0.1 #

Dismiss repeat measurement events that are identical.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:xiaomi_scale_example/measurement-pane.dart';
import 'package:xiaomi_scale_example/raw-data-pane.dart';
import 'package:xiaomi_scale_example/scanning-pane.dart';

void main() {
  runApp(ScaleApp());
}

class ScaleApp extends StatefulWidget {
  @override
  _ScaleAppState createState() => _ScaleAppState();
}

class _ScaleAppState extends State<ScaleApp> {
  int bottomSelectedIndex = 0;

  PageController pageController = PageController(
    initialPage: 0,
    keepPage: true,
  );

  List<BottomNavigationBarItem> buildBottomNavBarItems() {
    return [
      BottomNavigationBarItem(
        icon: new Icon(Icons.timeline),
        title: new Text('Measurements'),
      ),
      BottomNavigationBarItem(
        icon: new Icon(Icons.search),
        title: new Text('Scanning'),
      ),
      BottomNavigationBarItem(
          icon: Icon(Icons.description), title: Text('Raw Data'))
    ];
  }

  void pageChanged(int index) {
    setState(() {
      bottomSelectedIndex = index;
    });
  }

  void bottomTapped(int index) {
    setState(() {
      bottomSelectedIndex = index;
      pageController.animateToPage(index,
          duration: Duration(milliseconds: 500), curve: Curves.ease);
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Scale Example App')),
        body: PageView(
          controller: pageController,
          onPageChanged: (index) {
            pageChanged(index);
          },
          children: <Widget>[
            MeasurementPane(),
            ScanningPane(),
            RawDataPane(),
          ],
        ),
        bottomNavigationBar: BottomNavigationBar(
          currentIndex: bottomSelectedIndex,
          onTap: (index) {
            bottomTapped(index);
          },
          items: buildBottomNavBarItems(),
        ),
      ),
    );
  }
}

Use this package as a library

1. Depend on it

Add this to your package's pubspec.yaml file:


dependencies:
  xiaomi_scale: ^1.0.1

2. Install it

You can install packages from the command line:

with Flutter:


$ flutter pub get

Alternatively, your editor might support flutter pub get. Check the docs for your editor to learn more.

3. Import it

Now in your Dart code, you can use:


import 'package:xiaomi_scale/xiaomi_scale.dart';
  
Popularity:
Describes how popular the package is relative to other packages. [more]
25
Health:
Code health derived from static analysis. [more]
0
Maintenance:
Reflects how tidy and up-to-date the package is. [more]
80
Overall:
Weighted score of the above. [more]
29
Learn more about scoring.

We analyzed this package on Jul 11, 2020, and provided a score, details, and suggestions below. Analysis was completed with status completed using:

  • Dart: 2.8.4
  • pana: 0.13.15
  • Flutter: 1.17.5

Analysis issues and suggestions

Make sure flutter format successfully runs on your package's source files.

Running flutter format failed with the following output:

Hit a bug in the formatter when formatting src/mi-scale.dart.
The formatter produced unexpected output. Input was:
import 'dart:async';

import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';

import 'mi-scale-data.dart';
import 'mi-scale-device.dart';
import 'mi-scale-measurement.dart';

Package does not support Flutter platform Linux

Because:

  • package:xiaomi_scale/xiaomi_scale.dart that declares support for platforms: Android, iOS

Package does not support Flutter platform Web

Because:

  • package:xiaomi_scale/xiaomi_scale.dart that declares support for platforms: Android, iOS

Package does not support Flutter platform Windows

Because:

  • package:xiaomi_scale/xiaomi_scale.dart that declares support for platforms: Android, iOS

Package does not support Flutter platform macOS

Because:

  • package:xiaomi_scale/xiaomi_scale.dart that declares support for platforms: Android, iOS

Package not compatible with SDK dart

Because:

  • xiaomi_scale that is a package requiring null.

Maintenance issues and suggestions

Support latest dependencies. (-10 points)

The version constraint in pubspec.yaml does not support the latest published versions for 1 dependency (rxdart).

Homepage URL isn't helpful. (-10 points)

Update the homepage field from pubspec.yaml: link to a website about the package or use the source repository URL.

Dependencies

Package Constraint Resolved Available
Direct dependencies
Dart SDK >=2.5.0 <3.0.0
flutter 0.0.0
flutter_reactive_ble ^2.0.0 2.3.0
rxdart ^0.23.1 0.23.1 0.24.1
uuid ^2.0.4 2.2.0
Transitive dependencies
charcode 1.1.3
collection 1.14.12 1.14.13
convert 2.1.1
crypto 2.1.5
fixnum 0.10.11
functional_data 0.3.0
meta 1.1.8 1.2.2
pedantic 1.9.0 1.9.2
plain_optional 0.1.3
protobuf 1.0.1
sky_engine 0.0.99
typed_data 1.1.6 1.2.0
vector_math 2.0.8 2.1.0-nullsafety
Dev dependencies
flutter_test