oliexdev / openScale

Open-source weight and body metrics tracker, with support for Bluetooth scales
GNU General Public License v3.0
1.7k stars 296 forks source link

Add support for 1byone scale #159

Closed dinki closed 6 years ago

dinki commented 6 years ago

I'm writing in hopes that you can add 1byone BT scale (https://www.amazon.com/1byone-Bluetooth-Wireless-Bathroom-Visceral/dp/B01FHELB56/) to your list of supported devices. I received this as a gift from my wife but it is tied to a proprietary app that leaves much to be desired.

While I am much more of a hacker than a programmer, I am pretty sure that this is possible as someone has written some software that pulls the information from the scale:

https://github.com/ec1oud/qt-ble-weightscale

Further, I was able to use BT Snoop to pull the log where the scale connects and passes the information on to the phone. You can see the same type of information listed at the above repo here:

https://github.com/ec1oud/qt-ble-weightscale/blob/master/doc/notes.txt

Here's what it looks like:

Frame 13693: 32 bytes on wire (256 bits), 32 bytes captured (256 bits)
Bluetooth
Bluetooth HCI H4
Bluetooth HCI Event - LE Meta
    Event Code: LE Meta (0x3e)
    Parameter Total Length: 29
    Sub Event: LE Advertising Report (0x02)
    Num Reports: 1
    Event Type: Connectable Undirected Advertising (0x00)
    Peer Address Type: Public Device Address (0x00)
    BD_ADDR: TexasIns_2a:8d:a6 (f0:c7:7f:2a:8d:a6)
    Data Length: 17
    Advertising Data
        Flags
            Length: 2
            Type: Flags (0x01)
            000. .... = Reserved: 0x0
            ...0 .... = Simultaneous LE and BR/EDR to Same Device Capable (Host): false (0x0)
            .... 0... = Simultaneous LE and BR/EDR to Same Device Capable (Controller): false (0x0)
            .... .1.. = BR/EDR Not Supported: true (0x1)
            .... ..0. = LE General Discoverable Mode: false (0x0)
            .... ...1 = LE Limited Discoverable Mode: true (0x1)
        16-bit Service Class UUIDs (incomplete)
            Length: 3
            Type: 16-bit Service Class UUIDs (incomplete) (0x02)
            UUID 16: Unknown (0xfff0)
        Manufacturer Specific
            Length: 9
            Type: Manufacturer Specific (0xff)
            Company ID: Ericsson Technology Licensing (0x0000)
            Data: f0c77f2a8da6
    RSSI (dB): -60

Frame 13694: 33 bytes on wire (264 bits), 33 bytes captured (264 bits)
Bluetooth
Bluetooth HCI H4
Bluetooth HCI Event - LE Meta
    Event Code: LE Meta (0x3e)
    Parameter Total Length: 30
    Sub Event: LE Advertising Report (0x02)
    Num Reports: 1
    Event Type: Scan Response (0x04)
    Peer Address Type: Public Device Address (0x00)
    BD_ADDR: TexasIns_2a:8d:a6 (f0:c7:7f:2a:8d:a6)
    Data Length: 18
    Advertising Data
        Device Name: Electronic Scale
            Length: 17
            Type: Device Name (0x09)
            Device Name: Electronic Scale
    RSSI (dB): -60

Frame 13721: 14 bytes on wire (112 bits), 14 bytes captured (112 bits)
Bluetooth
Bluetooth HCI H4
Bluetooth HCI ACL Packet
Bluetooth L2CAP Protocol
Bluetooth Attribute Protocol
    Opcode: Write Request (0x12)
        0... .... = Authentication Signature: False
        .0.. .... = Command: False
        ..01 0010 = Method: Write Request (0x12)
    Handle: 0x0015 (Unknown: Unknown: Client Characteristic Configuration)
        [Service UUID: Unknown (0xfff0)]
        [Characteristic UUID: Unknown (0xfff4)]
        [UUID: Client Characteristic Configuration (0x2902)]
    Characteristic Configuration Client: 0x0001, Notification
        0000 0000 0000 00.. = Reseved: 0x0000
        .... .... .... ..0. = Indication: False
        .... .... .... ...1 = Notification: True
    [Response in Frame: 13722]

Frame 13722: 10 bytes on wire (80 bits), 10 bytes captured (80 bits)
Bluetooth
Bluetooth HCI H4
Bluetooth HCI ACL Packet
Bluetooth L2CAP Protocol
Bluetooth Attribute Protocol
    Opcode: Write Response (0x13)
        0... .... = Authentication Signature: False
        .0.. .... = Command: False
        ..01 0011 = Method: Write Response (0x13)
    [Handle: 0x0015 (Unknown: Unknown: Client Characteristic Configuration)]
        [Service UUID: Unknown (0xfff0)]
        [Characteristic UUID: Unknown (0xfff4)]
        [UUID: Client Characteristic Configuration (0x2902)]
    [Request in Frame: 13721]

Frame 1965: 28 bytes on wire (224 bits), 28 bytes captured (224 bits)
Bluetooth
    [Source: TexasIns_2a:8d:a6 (f0:c7:7f:2a:8d:a6)]
    [Destination: AsustekC_7e:22:04 (50:46:5d:7e:22:04)]
Bluetooth HCI H4
Bluetooth HCI ACL Packet
Bluetooth L2CAP Protocol
Bluetooth Attribute Protocol
    Opcode: Handle Value Notification (0x1b)
    Handle: 0x0014 (Unknown: Unknown)
    Value: cf01adaa0404015b1e026c1301cd0599

cf01adaa 0414 015e 1c02 7013 01ca059c
104.4 kg, fat 35%, water 45.8%, muscle 62.4kg, bone 2.8kg

cf01adaa 0406 015b 1e 026d 13 01cd 0599
103.0 kg, fat 34.7%, water 46.1%, muscle 62.1kg, bone 3.0kg, BMR 1433 kcal

0x0406: 1030  kg
0x015b: 347 fat
0x1e: 30 bone
0x026d: 621 muscle
0x13: 19 visceral fat
0x01cd: 461  water
0x0599: 1433  BMR

I am certainly willing to do testing on this if someone can decrypt the handshake and add the functionality to openScale.

Let me know what you think!

Thanks

erijo commented 6 years ago

You can now take the latest openScale dev version, go to settings, about and enable debug log. Then connect to the scale with openScale and weight yourself. Write down the numbers seen on the scale and provide them together with the log from openScale in this issue.

Might be easier than getting Bluetooth snoop logs from the original app (even if we'll still need them later to reverse engineer the data sent to the scale).

dinki commented 6 years ago

@erijo This certainly does seem easier. My scale only shows the weight on it's display. Don't you need to know body fat/bone density/etc? How will I get those? Do I do the debug in OpenScale then weigh again and grab the numbers from the scale's app?

erijo commented 6 years ago

Yes, that can work. The numbers shouldn't differ too much between measurements.

erijo commented 6 years ago

I have some bad news @dinki. Unfortunately it seems like the scale doesn't provide us with fat, water, etc., but only with weight and an impedance reading. This is then converted by the app to fat, water, etc. and reverse engineer that will be a challenge as it's done by a native (i.e. not java) library in the app.

oliexdev commented 6 years ago

@erijo I am a bit confused do we talk about two different scale devices? I thought @ec1coud have been already done the reverse engineer part for the other measurements like described in his notes?

erijo commented 6 years ago

@oliexdev It looks like @dinki has a scale with the device name "Health Scale" and @itsmegb, @simon6162 and I guess @ec1oud has one with the device name "Electronic Scale".

The former seems to only send the impedance value which is then converted to body fat etc. by a library from holtek.com (libBodyfat). Which by the way seems to be the same library as is used in the Mi app. The latter on the other hand seems to send all values.

@dinki: it would be good if you could download the latest dev version, start it and go to settings -> about and enable debug log. Then go to settings -> bluetooth and search for your device and click on it once found. Then do a measurement in openScale. Directly afterwards do the measurement in the original app and post all the values here together with the log from openScale. I'm interesting in seeing how the impedance values map to body fat etc.

@simon6162: if you could do the same that would be great.

simon6162 commented 6 years ago

Will do. Btw the label on the bottom of my scales has no fcc number or model number

On Wed, 25 Apr 2018, 19:50 Erik Johansson, notifications@github.com wrote:

@oliexdev https://github.com/oliexdev It looks like @dinki https://github.com/dinki has a scale with the device name "Health Scale" and @itsmegb https://github.com/itsmegb, @simon6162 https://github.com/simon6162 and I guess @ec1oud https://github.com/ec1oud has one with the device name "Electronic Scale".

The former seems to only send the impedance value which is then converted to body fat etc. by a library from holtek.com (libBodyfat). Which by the way seems to be the same library as is used in the Mi app. The latter on the other hand seems to send all values.

@dinki https://github.com/dinki: it would be good if you could download the latest dev version https://github.com/oliexdev/openScale/releases/tag/travis-dev-build, start it and go to settings -> about and enable debug log. Then go to settings -> bluetooth and search for your device and click on it once found. Then do a measurement in openScale. Directly afterwards do the measurement in the original app and post all the values here together with the log from openScale. I'm interesting in seeing how the impedance values map to body fat etc.

@simon6162 https://github.com/simon6162: if you could do the same that would be great.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/oliexdev/openScale/issues/159#issuecomment-384394910, or mute the thread https://github.com/notifications/unsubscribe-auth/AdUB7VvTs3Mlzgr1FTDlAM1f3L0HefYdks5tsMVhgaJpZM4Rngi2 .

dinki commented 6 years ago

@erijo Here's the info:

https://www.dropbox.com/s/n0r4eorhmy0lwti/openScale_2018-04-25_20-36.txt?dl=0 https://photos.app.goo.gl/3a0w73WaXoboMCtn1

Thanks for looking at this.

erijo commented 6 years ago

@dinki: can you also post your age, sex, height and activity level (as entered in the app)? They are all used in the calculations.

dinki commented 6 years ago

@erijo 46, male, 5'8", ordinary (lowest activity level)

dinki commented 6 years ago

@erijo was that the information you needed? Thanks

erijo commented 6 years ago

Yes it was.

I've been trying to reverse engineer the calculations done by the app, but the problem is that they are done by a native library (libBodyfat.so) and my assembler reading skills are not as good as they would need to be to decompile the formula.

I have a small native C++ program that can call the functions in the library and get e.g. the fat measurement. Perhaps the way forward would be to get an existing formula for fat calculation and try to compare the result for different input?

Is there any good formula available?

oliexdev commented 6 years ago

Is there any good formula available?

For general formula see https://www.biodyncorp.com/tools/450/calculations.html

Condorello commented 6 years ago

Hi, i've the same scale with the infamous oem app.... i'm happy to post my data for help the reverse engineering. I'll be back ASAP.

Condorello commented 6 years ago

Here my log + screen of official app. Thanks!

https://www.dropbox.com/s/h12txt9n07jmc78/test_openscale.zip?dl=0

erijo commented 6 years ago

@Condorello: can you also post your age, sex, height and activity level (as entered in the app) if they aren't included in the log already? They are all used in the calculations.

Condorello commented 6 years ago

31, Male, 172cm, activity Amateur

Thanks again!

erijo commented 6 years ago

For reference, here are the values from @dinki (with impedance adjusted to get correct results):

  // User
  const double height = 172; // 5'8""
  const int age = 46;
  const int sex = 1; // 0 = female, 1 = male
  const int peopleType = 0; // 0 = ordinary, 1 = amatuer, 2 = professional

  // From measurement using original app
  const double weight = 69.4; // ~153.0 lb
  const double bodyWater = 53.9; // %
  const double bodyFat = 21.4; // %
  const double boneMass = 2.7; // ~6.0 lb
  const double bmi = 23.5;
  const double visceralFat = 12;
  const double bmr = 1375;
  const double muscle = 51.8; // ~114.4 lb

  // From measurement using openScale (weight = 69.40)
  const int impedance = 11839149 + 2;

And from @Condorello (had to change your age to 32 to get the same result as from the app, I assume your birthday is later this year and that the app isn't too smart when calculating the age):

  // User
  const double height = 172;
  const int age = 32;
  const int sex = 1; // 0 = female, 1 = male
  const int peopleType = 1; // 0 = ordinary, 1 = amatuer, 2 = professional

  // From measurement using original app
  const double weight = 63.1;
  const double bodyWater = 60.1; // %
  const double bodyFat = 12.4; // %
  const double boneMass = 2.7;
  const double bmi = 21.3;
  const double visceralFat = 5;
  const double bmr = 1641;
  const double muscle = 52.6;

  // From measurement using openScale (weight = 63.10)
  const int impedance = 472377 - 4;
Condorello commented 6 years ago

Yep, 32 at the end of the year! I can add also a girl in the weekend so we can add a female data.

Condorello commented 6 years ago

https://www.brianmac.co.uk/mobile//fatbia.htm

Here a formula for body fat from the resistance values... Maybe could be that One?

erijo commented 6 years ago

This is the BMR formula used by the app:

double bmr(int peopleType, int sex, double weight, double height, int age)
{
  double typeFactor;
  if (peopleType == 0) {
    typeFactor = 1.32;
  }
  else if (peopleType == 1) {
    typeFactor = 1.54;
  }
  else {
    typeFactor = 1.98;
  }

  if (sex == 1) { // Male
    return typeFactor * (11.3 * weight + 665 - 0.55 * height - 6.8 * age);
  }
  else {
    return typeFactor * (7.73 * weight + 655 - 0.298 * height - 4.7 * age);
  }
}
Condorello commented 6 years ago

Hi, here a female data. 29, female, 164, Activity ordinary

https://www.dropbox.com/s/92dbubr70ol3geg/1by1.zip?dl=0

godinperson commented 6 years ago

I have that scale, will be happy to help since I don't like the vendor app

llewelin commented 6 years ago

Same here. If you need some data just ask.

ulipo commented 6 years ago

My scale shows up as "health scale", I'm happy to help if needed.

jimbolaya commented 6 years ago

I have some logs and a screenshot for a 1byone scale described in this thread. https://klaashome.org/index.php/s/A7ob4pBJUc0gkSR

ulipo commented 6 years ago

I can get measurements from my scale, but every measure I take it makes two or three entries in the app...

godinperson commented 6 years ago

I can't connect to it. It says connected and then: lost connection

erijo commented 6 years ago

Please try the dev version and see if that works better @ulipo and @godinperson

godinperson commented 6 years ago

Yep, it's the one I'm using

erijo commented 6 years ago

Ok. Please go to settings, about and enable debug log. Then try to connect to the scale and attach the log here afterwards.

ulipo commented 6 years ago

@erijo I am also using the dev build, here I attached a log from one "double" measure, even if I don't see any relevant content...

[code] 2018-06-23 12:23:15.780 Debug AboutPreferences: Debug log enabled, openScale v1.8.1-dev_39737b52 (1529683770), SDK 25, OnePlus A0001 2018-06-23 12:23:23.936 Debug OpenScale: Disconnecting from bluetooth device [/code]

erijo commented 6 years ago

That looks really weird @ulipo. Could you try again, perhaps saving the log to a different location?

ulipo commented 6 years ago

I tried several times to get a more detailed log, but probably I am doing it wrong... here is how I do:

  1. launch the app on my smartphone
  2. step on the scale and let it connect to the app
  3. after the measurement, go to settings and enable debug log, save to a file

Every time I get the same as reported in my previous post (except for the timestamps)

erijo commented 6 years ago

You need to swap step 2 and 3, ie enable debug log first.

ulipo commented 6 years ago

You're (obviously) right! Here is the log! Also I got so lucky this time that the app got four measurements instead of one! openScale_2018-06-25_08-22.txt

tomvitale commented 6 years ago

I've also received this scale as a gift and I can help to test. There something that you need again like showed in the wiki or I simply try a beta-dev build? (play store beta program?)

dinki commented 6 years ago

Any progress on adding the other readings besides weight or is that a loss cause?

georges-da-costa commented 6 years ago

A measurement : Debug BluetoothCommunication$GattCallback: onCharacteristicChanged 00002a9c-0000-1000-8000-00805f9b34fb: 03 06 D0 07 02 04 0B 03 14 D4 0D 0C 26 00 00 46 43 E0 00 DE weight: 97,40, impedance: 14697286

On the official appli:

97.4 kg BMI 30.7 water 49% fat 28.6% bones 3.4kg visceral fat 11kg BMR 2147 kcal Muscles 66.1kg

If you need something else, please ask :)

godinperson commented 6 years ago

Here is my log. My issue is it is connecting but it disconnect before getting the data openScale_2018-06-26_15-30 (1).txt

erijo commented 6 years ago

@godinperson: please try with the latest dev version.

@dinki: no real progress to report. I've been focusing on some other stuff lately.

@5thdev: what we need most is someone fluent in arm or x86 assembly ;)

godinperson commented 6 years ago

Pretty sure I used the latest one, installed May 22nd, 1.8.1-dev_0444b9da (1527003541)

erijo commented 6 years ago

That version is a month old. Please download the latest from https://github.com/oliexdev/openScale/releases/tag/travis-dev-build

godinperson commented 6 years ago

For the record, because I might not be the only one doing this mistake. On your link, it says: oliexdev released this on May 19. But we really need to look at the bottom where it says: Automatic openScale development build of master (c790ee6) built by Travis CI on 2018-06-24 20:11:58 UTC.

Thanks

godinperson commented 6 years ago

Same issue with latest version openScale_2018-06-26_17-28.txt

In the newest version, if I go into bluetooth and select my scale, it fetches for information for a very long time.

tomvitale commented 6 years ago

OpenScale v1.8.1 (28) records two measurements instead of one, I tried several times with the same result. Here the bluetooth log: openScale_2018-06-28_19-13.txt

godinperson commented 6 years ago

@erijo Same issue with newer version, here is the log openScale_2018-07-03_17-40.txt

erijo commented 6 years ago

That's strange @godinperson. I've added some more debug logs. Please try again with the latest dev version and attach the log.

erijo commented 6 years ago

Please try the latest dev version @5thdev, it should be fixed now.

godinperson commented 6 years ago

@erijo Here! Thanks for your time! I really appreciate openScale_2018-07-03_19-24.txt