Git Product home page Git Product logo

miband-js's Introduction

SWUbanner

NPM version NPM download GitHub issues GitHub license

Mi Band 2 JS library

A clean implementation of Mi Band 2 library for Browsers and Node.js, using WebBluetooth API. demo

Setting up

It's best to unbind your Mi Band 2 from MiFit App first.
You should be able to bind it back again, but no guaranee here ;)

Browser

LIVE DEMO

You need a browser with WebBluetooth support. Tested with:

  • Chrome on OS X (Yosemite or later)
  • Chrome on Android (6.0 Marshmallow or later)
  • Chrome on Linux (the chrome://flags/#enable-experimental-web-platform-features flag must be enabled)

Node.js

npm install miband -g
miband-test

This should work on Windows, Linux and OSX.
On Linux, you need to grant Bluetooth access for Node.js:

sudo setcap cap_net_raw+eip $(eval readlink -f `which node`)

Features

  • Authentication
  • Device info: time, battery status, hw/sw versions, etc.
  • Button tap event
  • Notifications: message, phone, vibrate
  • Heart Rate Monitor
  • Realtime data (soon)

API usage example

const MiBand = require('miband');

const device = await bluetooth.requestDevice({
  filters: [
    { services: [ MiBand.advertisementService ] }
  ],
  optionalServices: MiBand.optionalServices
});

const server = await device.gatt.connect();

let miband = new MiBand(server);
await miband.init();

log('Notifications demo...')
await miband.showNotification('message');

Here you can find more API examples


Contributing

Please check out DEVELOPMENT.md

miband-js's People

Contributors

dnbard avatar vshymanskyy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

miband-js's Issues

Read Data

Did you able to read the data from mi band? Do you need any help to do it?

ReferenceError: TextDecoder is not defined

I'm trying to use this library to read data from a Xiaomi 2 Band with Node. I got a Bluetooth dongle and did several changes on the example code (since I cannot access Web Bluetooth from plain Node.js and the webbluetooth package doesn't seem to work at the moment). I can detect the device and presumably connect to it but I've stumbled upon this problem. When I try to create a new Miband object I get an exception from this line of miband.js (line 78).

this.textDec = new TextDecoder();

SO: Windows 10 x64
Node version: v10.15.0
Npm: 6.4.1

How do download the past day's data (HR and step) from the band?

Any pointers where I'd look to implement the ability to download the HR and steps data the band 3 has stored on it, along with timestamps? i.e. the same operation that a phone app might use when it 'syncs' data from the band?

I can set the band to collect HR data every X minutes using Gadgetbridge or Notify & Fitness, but I'm trying to make an easy way to download this data into a CSV.

Running miband-test on Windows 10 fails with error message that adapter state is poweredOff

The demo web app runs just fine and successfully connects to my Mi Band 2. But when I run miband-test on my Windows 10 system locally (I installed WinUSB using Zadig for my CSR8510 A10 device) it fails with:

Argh! requestDevice error: adapter not enabled

I removed the check for "this.state === true" in miband/node_modules/webbluetooth/lib/adapter.js so that it at least tries to call noble.startScanning(), which gives a more accurate error message. What I get then is:

Argh! Error: Could not start scanning, state is poweredOff (not poweredOn)

Any idea how I can get my adapter set to poweredOn? Running miband/node_modules/noble/examples/advertisement-discovery.js lists my MiBand as you would expect, so noble itself can access the Bluetooth device without issues.

Setting constant 'key' in MiBand class constructor

I am trying to port this code to Flutter(dart) so people can use it in their mobile devices to communicate with MiBand 3, However I am stuck in authentication. I am not familiar with js too much unfortunately :(

In the code, author shared the comment below.

// TODO: this is constant for now, but should random and managed per-device
this.key = new Buffer('30313233343536373839404142434445', 'hex');

Is this a problem? Why does it need to be managed per device?
I always thought the key was related to a value hardcoded in the MiBand(like a serial number or so)

Back to my Authorization problem. Can anybody please summarize the authentication process for MiBand3? Seems like auth differs for all the different MiBands (1,2,3,4) and the resources on the internet confuses me. I am interested in MiBand3. This repos web app works perfectly so this code is working with my MiBand3

await this.startNotificationsFor('auth')

await this.authenticate()

// Notifications should be enabled after auth
for (let char of ['hrm_data', 'event', 'raw_data']) {
   await this.startNotificationsFor(char)
}

What did I understand wrong?
1-We run startNotifications on "auth" characteristic which is;
00000009-0000-3512-2118-0009af100700

async startNotificationsFor(c) {
    let char = this.char[c]
    await char.startNotifications()
    char.addEventListener('characteristicvaluechanged', this._handleNotify.bind(this));
}

This allows auth event changes to be listened by _handleNotify() function

2-We run authenticate():

async authenticate() {
   await this.authReqRandomKey()
   return new Promise((resolve, reject) => {
      setTimeout(() => reject('Timeout'), 10000);
      this.once('authenticated', resolve);
   });
}

which runs await this.authReqRandomKey() and requests the MiBand for a Random Key. However, aren't we supposed to run authSendNewKey(key) before requesting the random key? I am very confused here.
I am thinking maybe sending authReqRandomKey before authSendNewKey throws an error inside of _handleNotify which is;

else if (cmd === '100304') {
     debug('Encryption Key Auth Fail, sending new key...')
     this.authSendNewKey(this.key)
}

which fires the authSendNewKey for the first time. Inside of this we prepend 0108 to the constant Key I talked about in the beginning: this.char.auth.writeValue(AB([0x01, 0x08], key))

3-MiBand takes this constant Key and sends us a 100101 inside _handleNotify:

if (cmd === '100101') {         // Set New Key OK
     this.authReqRandomKey()
}

4-MiBand gets our request and sends us the random number:

else if (cmd === '100201') {  // Req Random Number OK
     let rdn = value.slice(3)
     let cipher = crypto.createCipheriv('aes-128-ecb', this.key, '').setAutoPadding(false)
     let encrypted = Buffer.concat([cipher.update(rdn), cipher.final()])
     this.authSendEncKey(encrypted)
}

And we use this random number and do the AES stuff to get the encrypted key

5-We send the encrypted key to MiBand by:
this.char.auth.writeValue(AB([0x03, 0x08], encrypted))

6-_handleNotify is triggered for the last time with a value of 100301:

else if (cmd === '100301') {
     debug('Authenticated')
     this.emit('authenticated')
}

I don't understand what does this.once('authenticated', resolve); inside of the Authenticate Promise have to do any thing with the this.emit('authenticated') inside of the _handleNotify.

7- Now we are authenticated and ready to do the heart rate stuff.

Lastly, @creotiv in his how-i-hacked-xiaomi-miband-2-to-control-it-from-linux article

A1-Setting on auth notifications (to get a response) by sending 2 bytes request \x01\x00 to the Des.
A2-Send 16 bytes encryption key to the Char with a command and appending to it 2 bytes \x01\x00 + KEY.
A3-Requesting random key from the device with a command by sending 2 bytes \x02\x00 to the Char.
A4-Getting random key from the device response (last 16 bytes).
A5-Encrypting this random number with our 16 bytes key using the AES/ECB/NoPadding encryption algorithm (from Crypto.Cipher import AES) and send it back to the Char (\x03\x00 + encoded data)

In A1 he talks about sending x01x00 to initiate the auth process. However I did not see something like that in this code. Was it specific to MiBand 2 and not MiBand3?

@dj0001 I am sure you can help me:) I have seen some of your very helpful comments in the issues. Can you please clarify this authorization process

Sleep Activity

Is there also a possibility to add the reading of the activities? The amount of steps? The sleep activity?

Allow device selection when using in Node.js

Currently filter should be specified to select some bluetooth peripheral device.
Is there a way to select a certain device out of discovered ones when using this lib in node.js? It is important when I don't know beforehand which device should be connected and user interaction is needed.
For example I want to connect Mi Band 2 and there are several Mi Band 2 devices nearby but I don't know exactly which one should be connected.

show Notification

showNotification('message') only shows ???
can we add text (title or body)

Backwards Compatibility with Mi Band 1A and 1S

Hey!

Really love the work. I'd like to help out by introducing backwards compatibility for the Mi Band 1A and 1S. Any tips as to how I should go about doing this, as I've grappled with the code but couldn't get the authentication working correctly. Any tips? I have the necessary UUIDs, however I can't get the GATT service to activate.

Thanks!

Rhys

local install timeout error

When I follow the instructions to install from NPM and run the miband-test in terminal (OSX), it says it can connect to the device. But after that a timeout occurs:

Requesting Bluetooth Device...
Connecting to the device...
Connected
Argh! Timeout
Device disconnected

Support for MiBand 2: HRX Edition

The hrx edition of the MiBand 2 does not support heart rate measurement and thus cannot be used with this library. Introducing simple if statements to check if the band supports HR can add compatibility with this edition as well.

Installation issue (no xpc-connection dep)

Screenshot 2019-04-27 at 14 29 28

                         ^
../src/XpcConnection.cpp:143:89: error: too few arguments to function call, expected 2, have 1
      Local<Value> propertyValue = object->GetRealNamedProperty(propertyName->ToString());
                                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~                         ^

...

6 warnings and 1 error generated.
make: *** [Release/obj.target/binding/src/XpcConnection.o] Error 1
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! stack     at ChildProcess.onExit (/usr/local/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:262:23)
gyp ERR! stack     at ChildProcess.emit (events.js:197:13)
gyp ERR! stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:254:12)
gyp ERR! System Darwin 18.5.0
gyp ERR! command "/Users/mxtnr/n/bin/node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /Users/mxtnr/xp/xiaomi-mi-band-2-heart-rate/miband-js-app/node_modules/xpc-connection
gyp ERR! node -v v11.12.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok 
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN [email protected] No description
npm WARN [email protected] No repository field.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/bluetooth-hci-socket):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for [email protected]: wanted {"os":"linux,android,win32","arch":"any"} (current: {"os":"darwin","arch":"x64"})
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] (node_modules/xpc-connection):
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: [email protected] install: `node-gyp rebuild`
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: Exit status 1

+ [email protected]
added 17 packages from 12 contributors and audited 143 packages in 4.045s
found 2 low severity vulnerabilities
  run `npm audit fix` to fix them, or `npm audit` for details

xp/xiaomi-mi-band-2-heart-rate/miband-js-app took 5s ❯ miband-test        
internal/modules/cjs/loader.js:651
    throw err;
    ^

Error: Cannot find module 'xpc-connection'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:649:15)
    at Function.Module._load (internal/modules/cjs/loader.js:575:25)
    at Module.require (internal/modules/cjs/loader.js:705:19)
    at require (internal/modules/cjs/helpers.js:14:16)
    at Object.<anonymous> (/Users/mxtnr/xp/xiaomi-mi-band-2-heart-rate/miband-js-app/node_modules/noble/lib/mac/highsierra.js:7:21)
    at Module._compile (internal/modules/cjs/loader.js:799:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:810:10)
    at Module.load (internal/modules/cjs/loader.js:666:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:606:12)
    at Function.Module._load (internal/modules/cjs/loader.js:598:3)

Deprecated dependencies

Most of the dependencies required upon by this repo have been deprecated. Additionally, Buffer() is also deprecated in most browsers and node. Also, in node, crypto makes more sense than browserify-aes.

Error: No compatible USB Bluetooth 4.0 device found!

When I tried to run this repo with my miband 3 it shows the below error.
throw new Error('No compatible USB Bluetooth 4.0 device found!');
^

Error: No compatible USB Bluetooth 4.0 device found!
at BluetoothHciSocket.bindUser (C:\Users\Sukanya Bharati\AppData\Roaming\npm\node_modules\miband\node_modules@abandonware\bluetooth-hci-socket\lib\usb.js:91:11)
at BluetoothHciSocket.bindRaw (C:\Users\Sukanya Bharati\AppData\Roaming\npm\node_modules\miband\node_modules@abandonware\bluetooth-hci-socket\lib\usb.js:47:8)
at Hci.init (C:\Users\Sukanya Bharati\AppData\Roaming\npm\node_modules\miband\node_modules@abandonware\noble\lib\hci-socket\hci.js:101:35)
at NobleBindings.init (C:\Users\Sukanya Bharati\AppData\Roaming\npm\node_modules\miband\node_modules@abandonware\noble\lib\hci-socket\bindings.js:82:13)
at Noble.get (C:\Users\Sukanya Bharati\AppData\Roaming\npm\node_modules\miband\node_modules@abandonware\noble\lib\noble.js:69:26)
at E.get state [as state] (C:\Users\Sukanya Bharati\AppData\Roaming\npm\node_modules\miband\node_modules\webbluetooth\dist\webbluetooth.umd.js:1:17819)
at new E (C:\Users\Sukanya Bharati\AppData\Roaming\npm\node_modules\miband\node_modules\webbluetooth\dist\webbluetooth.umd.js:1:17660)
at C:\Users\Sukanya Bharati\AppData\Roaming\npm\node_modules\miband\node_modules\webbluetooth\dist\webbluetooth.umd.js:1:23049
at C:\Users\Sukanya Bharati\AppData\Roaming\npm\node_modules\miband\node_modules\webbluetooth\dist\webbluetooth.umd.js:1:69
at Object. (C:\Users\Sukanya Bharati\AppData\Roaming\npm\node_modules\miband\node_modules\webbluetooth\dist\webbluetooth.umd.js:1:230)

authentication protocol

Hello,
I would like to thank you for this cool project, I am trying to connect to a Mi Band 6 from a raspberry pi using python (or any other programming language) in order to be able to sync the time and maybe send some notifications, because the band will not be used with a phone.
I am trying to figure out the authentication protocol but I would like to ask for a diagram or something documented on this regard.
I do have gathered the authentication key for the band.

Thank you and best regards

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.