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

Added even more debug logs, please try again with the latest dev version @godinperson.

godinperson commented 6 years ago

@erijo Pretty sure you got something here

openScale_2018-07-04_07-16.txt

erijo commented 6 years ago

Interesting. Could you, with the debug log on, go to settings, search for your scale and then click on it once found? That will fetch all services and log them.

godinperson commented 6 years ago

Here openScale_2018-07-04_07-52.txt

ulipo commented 6 years ago

@erijo I confirm that with the latest build, I get just one entry per measurement, it works!

erijo commented 6 years ago

@ulipo: :+1: @godinperson: it seems like the read of the extended info timed out. I've done something to hopefully avoid that. Could you please try again (what you did last) with the latest dev version?

godinperson commented 6 years ago

Here. I did fetch the information, then reconnected and tried it openScale_2018-07-04_19-03.txt

erijo commented 6 years ago

Hmm, this seems strange @godinperson. Could you capture a btsnoop log when using the original app? It looks like your scale differs from what we have support for.

@ulipo or @5thdev (or someone else with a scale that openScale can get the weight from): could you enable debug logging under settings -> about and then go search for your scale using the latest dev version? It would be interesting to compare that to what @godinperson got in the log.

godinperson commented 6 years ago

I'll need your help on that one. I was able to generate the log files but there is a lot of files and pretty big ones too. The main seems like 30Mb which contains many things

Found it btsnoop_hci.log

ulipo commented 6 years ago

openScale_2018-07-05_17-07.txt Here you go ;)

erijo commented 6 years ago

Thanks @godinperson and @ulipo!

It seems like your scale @godinperson differs from the one that @ulipo has. I tried to add some basic support for yours as well. Please try the latest dev version @godinperson and post the log here afterwards.

godinperson commented 6 years ago

@erijo Ok, we are getting somewhere. I don't get the lost connection anymore. Also, the bluetooth icon flashing on the scale stays light up (doesn't flash anymore) which is good sign. However, the application never gets the data. It stays empty.

Thanks

erijo commented 6 years ago

Please attach the log (also, please update again, I made a typo in the previous version).

godinperson commented 6 years ago

It works! Now the only thing is I only get Weight, BMR.

Body water, muscle, body fat are all 0% openScale_2018-07-06_07-00.txt

erijo commented 6 years ago

From the log it looks like you got some extra measurements @godinperson. I've made a fix for that. I hope it works :)

Regarding water, muscle, fat etc. that's the same problem as the others here in the issue. The scale doesn't send the values directly, but only the weight and some kind of impedance value. The app then does the conversion to water, etc. This formula is not (yet?) known.

godinperson commented 6 years ago

Tried but same data. How can we help you get those formula?

ulipo commented 6 years ago

I tried mailing 1byone and asking for the formula (was worth a try...), thi is their answer:

-- For your issue, we are sorry to tell you the calculation formula is set up by manufacturer and actually we don't have access to that.

godinperson commented 6 years ago

Would those formula fit? https://www.quora.com/How-do-bathroom-scales-that-calculate-body-fat-water-muscle-bone-kcal-actually-work-And-are-they-accurate Total body water TBW = (0.372 HeightCM HeightCM / Resistance) + (0.142 massKg) - (0.069 ageYears) + (3.05 * ifMale)

https://fitness.stackexchange.com/questions/15098/how-can-a-scale-measure-body-fat-and-water-percentages-muscle-and-bone-mass-bm A few of the common formula (see Wikipedia for the constants):

BMI = MassKg / (HeightM)^2

BMR (Basal Metabolic Rate) = a + (b MassKg) + (c HeightM) - (d * ageYears)

where: a, b, c, and d are constants that vary depending on your sex, and whose version of the equation you use.

LBM (Lean Body Mass) = ( x massKg ) + ( y HeightM) - z

where: x, y, and z are constants that vary depending on your sex, and whose variation of the equation you use.

BF (Body Fat) = ((massKg - LBM) / massKg) * 100

or = (e BMI) + (f ageYears) - g

where: e, f, and g are constants that vary depending on your sex, and whose variation of the equation you use.

shareimprove this answer

godinperson commented 6 years ago

I was able to decompile the APK using this website http://www.javadecompilers.com/apk

But I'm not a programmer so couldn't find the formula...

zanymuzik commented 6 years ago

thanks for working so diligently on this. i have the same scale and have been lurking on the thread to hear when i can use openscale.

how long does it take the changes to make to the prod version? or are these separate branches?

Dododappere commented 6 years ago

Found an interesting post on stackoverflow. Looks like someone already did the first steps to reverse engineer libBodyfat.so . This is the native library used by the 1byone app to calculate the body fat percentage.

https://reverseengineering.stackexchange.com/questions/18591/how-can-i-make-sense-of-an-android-ndk-library

He turned the body fat calculation into Javascript: https://gist.github.com/mamadcloud/95c8fe8f5816286f2ad62c81f937e6b6

Cleaning up that code and converting it to Java may do the trick...

oliexdev commented 6 years ago

@Dododappere thanks looks promising but I need more data for testing. So @all could you provide some test data which includes the following information. Please use the original app from 1byone for this.

To get the impedance value please weight yourself afterwards with openScale (with the exact condition like before) with the log enabled under settings->about. The impedance should be visible in the openScale log file.

Condorello commented 6 years ago

That's my data:

Debug BluetoothOneByone: weight: 63,50, impedance: 8169133

age 32 sex (1=male height (in cm) 172 weight (in kg) 63.5 body fat (in %) 12,1 muscle 53,1 water 60,3 visceral fat 5 bone 2,7

oliexdev commented 6 years ago

@Condorello thanks. Unfortunately, with your data I get a result of 15,6% body fat with the above formula. :disappointed:

Condorello commented 6 years ago

With 31 year it could change? Maybe it count the year exactly at the day of birth.. so currently i'm 31 for ne precise.

Il mar 14 ago 2018, 21:02 OliE notifications@github.com ha scritto:

@Condorello https://github.com/Condorello thanks. Unfortunately, with your data I get a result of 15,6% body fat with the above formula. 😞

— 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-412981198, or mute the thread https://github.com/notifications/unsubscribe-auth/AECss9Jlzk_SLzL984E_kZTGdFtnxQ8Eks5uQx7YgaJpZM4Rngi2 .

oliexdev commented 6 years ago

The value changed only slightly.

ulipo commented 6 years ago

openScale_2018-08-20_17-05.txt Here is my log, onebyone app reports this values: Age: 41 Sex: male Height: 170 Weight: 69.3 Body fat: 21,4 Muscle: 51,8 Water: 53,9 Visceral fat: 12 Bone: 2,7

oliexdev commented 6 years ago

@ulipo I get 21,16 % body fat :disappointed:

ulipo commented 6 years ago

Well, it's not too far from the value calculated by the official app... Try to see if it gets closer with 42 years, I'll turn 42 in December, maybe the app rounded up the age. Also remember that actually I measured two times consecutively, probably it's not exactly the same impedance value.

godinperson commented 6 years ago

openScale_2018-08-22_12-03.txt Age: 35 Sex: 1 Height: 178 cm Weight: 86.7 Body fat: 24.5% (New 1ByOne Health app: 27.3%) Muscle: 62.2 (New 1ByOne Health app: 59.9) Water: 51.8 (New 1ByOne Health app: 49.9) Visceral fat: 10.0 (New 1ByOne Health app: 12) Bone: 3.2 (New 1ByOne Health app: 3.1)

Condorello commented 6 years ago

I just did a new mesure with also the new heat app:

openscale impedance: 594974 openscale kg: 63.80

old onebyone kg 63.80 fat: 12% bone: 2.8kg bmi: 21.6 visceral: 5 bmr: 1653kcal muscle: 53.4kg

new onebyone healt kg 63.8 fat: 15.7% bone 2.6kg bmi: 21.6 visceral: 7 bmr: 1417 musce: 51.2

seems that the formula is the one used in the new app. Maybe more precise or not, for that i need to check with another balance. I can reach one in the days coming... i'll be back!

oliexdev commented 6 years ago

thx @all

I deeply looked into the disassembled code and I am really close! The status is as follows:

For the last two measurements I need your help again because all posted impedance values were wrong. My previous impedance calculation was faulty, so I need different btsnoop_hci.log files from different measurements with the original 1byone app.

With the log files, I need for each measurement the complete body measurement values with the entered age, sex, height and activity level which you have entered in the original app!

Sorry for the trouble but otherwise I can't find and test the impedance value.

Thanks in advance!

ulipo commented 6 years ago

Here is my data: age: 42 (birthdate in Dec 1975) sex: male height: 170 cm activity level: not found the setting in new app... weight: 70.5 Kg body fat: 22.1% bones: 2.7 Kg muscles: 52.2 Kg water: 53.4% BMI: 24.4

attached bt snoop log

btsnoop_hci.log

oliexdev commented 6 years ago

@ulipo thanks but unfortunately you didn't catch the data from the scale in the btsnoop_hci log file. Please make sure you enable the bluetooth log before you weight yourself and disable it after the weighting is finished (delete previous btsnoop_hci log file on your phone). Also could you make sure that you disable other Bluetooth devices or make sure they are far away. They are a lot of noises in the log file for example your Apple device.

ulipo commented 6 years ago

I'm sorry, I'm afraid I am not able to produce such file, probably the one I linked was an old one made who knows when and on which ROM was on my phone that time... I tried to generate a new one but the best I achieved is that my phone freezed and I had to force reset it :P

Do you think a snoop file generated from "adb shell dumpsys bluetooth_manager" could be of any use?

llewelin commented 6 years ago

My data

age: 40 (birthdate in Jan 1978) sex: male height: 178 cm activity level: intermediate weight: 94.4 Kg body fat: 27.4% bones: 3.4 Kg muscles: 65.1 Kg water: 49.8% BMI: 29.8

btsnoop_hci.log

And thanks for your work :)

oliexdev commented 6 years ago

@ulipo I don't know what your adb command do?! Do we get the btsnoop_hci.log file? @llewelin thanks I found the impedance value. For your data the impedance value is 340!

For the body fat (the most complex one) I need to find some impedance coefficients or I have a bug in the code. I need to analyse it more but I will be on holiday for the next weeks, so it can take time. ;)

In the mean time it would be great if somebody could post a btsnoop_hci.log file as a female (just change in the original app to female and post the output).

darkcheater commented 6 years ago

btsnoop_hci.log hopefully the file is ok. Needed to capture it using old Galaxy S3 because S7 didn't want to create the snoop file...

Data: age: 25 (01.01.1993) height: 185 cm sex: female activity level: setting not found in app (https://play.google.com/store/apps/details?id=com.quhwa.health) weight: 71.5 kg body fat: 28.1 % bone mass: 2.9 kg muscle mass: 48.5 kg visceral fat: 3 body water: 49.3 % BMR: 1366 BMI: 20.9 photo5210968475051338064

oliexdev commented 6 years ago

@ulipo

I get all results for your measurement. Could you provide a measurement as a female and another male measurement with different values?

@darkcheater

with your measurement I get for the body fat and bones mass wrong values... Can you post a measurement with again with a female and another with male?

ulipo commented 6 years ago

Female, 42 years: weight 69.1 Kg BMI 23.9 visceral fat 7 Kg water 46.9% bones: 2.6 Kg BMR 1236 female-openScale_2018-09-03_19-17.txt

Male, 42 years: weight 58.4 Kg BMI 20.2 visceral fat 6 Kg water 58.0% bones 2.5 Kg BMR 1239 male-openScale_2018-09-03_19-19.txt

Condorello commented 6 years ago

btsnoop_hci.log

Here my log

Male, 32 Weight 63,9 BMI 21,6 Visceral 5 Water 60% Fat 12,6% Bone 2,7 Bmr 1655 Activity amateur Height 172cm

darkcheater commented 6 years ago

I think we are still using different apps, could this be? Because some are posting activity level and some are not! In the app @oliexdev suggested, there is no activity level!

Condorello commented 6 years ago

ok i was using the older app. I'll do a new log with the latest app.

Condorello commented 6 years ago

screenshot_1byone_health_20180905-151455 btsnoop_hci.log

New app log, Hope it's fine!

oliexdev commented 6 years ago

I am back from my holidays. :)

@ulipo unfortunately, without the corresponding hci log files your measurements are useless. I can't verify it. @Condorello thanks with your last data (weight 64.1kg) I get correct results beside for the bone mass.

@all I added in the last dev build more debug information in the log file, so we hopefully don't need any hci log files anymore because now I print in the log file the correct impedance and other useful information as well.

But I still need more log file with different settings for testing purposes (especially as a female and different activity levels and heights)

So please post some the true values from the 1byone app and the openScale debug file. Both has to be the same measurement configuration!

Condorello commented 6 years ago

Latest dev build crash immeditely in my phone :(

oliexdev commented 6 years ago

@Condorello strange on my phone it works. Could you provide a crash report? You could also try to complete remove openScale and install it again.

Condorello commented 6 years ago

openScale_2018-09-19_08-27.txt I reset something and now it start, but i cannot sync with the scale. Here the log, but probably is related to my phone. In few hours i can try with another phone and come back to report

oliexdev commented 6 years ago

thanks can you do it again with the latest dev build. I did a comparison wrong. I also need the true values from the original app with the same configuration as you weighted yourself in openScale.

oliexdev commented 6 years ago

I commited the reverse engineering version for all body measurements with commit https://github.com/oliexdev/openScale/commit/50284e05167462607c7538f7599a31560f80fae0

But still needs more testing especially for women and different ages, heights. As I don't own this scale, some calculations could still be wrong.