oliexdev / openScale

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

Scale support: Weight Gurus appSync non-bluetooth (bar code via camera) #584

Open ethana2 opened 4 years ago

ethana2 commented 4 years ago

WeightGURUS appSync https://weightgurus.com/ https://play.google.com/store/apps/details?id=com.dmdbrands.gurus.weight&hl=en_US

This would expand the scope of openScale beyond bluetooth and require the creation of a new camera fragment or activity with logic to pull scale information from the bar code via the camera, as the proprietary weightGURUS app currently does. I don't expect anyone would implement this for me. What I need to know is, if I invested the time and effort to write this and submitted a pull request, would it be possible for it to be merged?

oliexdev commented 4 years ago

what does the bar code contain? Why not support the weight gurus scales via Bluetooth?

ethana2 commented 4 years ago

The bar code contains, at the least, body fat, muscle, weight, and water weight. I haven't reverse-engineered it yet but since the scale supports bone weight it may include that as well.

This product line does not include bluetooth hardware, just the LCD.

ethana2 commented 4 years ago

Is it cool if I write the new code in Kotlin so long as I don't change the Kotlin standard library version from the version used by AppIntro?

oliexdev commented 4 years ago

ok strange never seen that before that the results are displayed as a barcode but on the homepage they write they supports 3 way connections and one of them is Bluetooth? Which product line do you have?

I would prefer to have the source-code in Java only because I am not familiar with Kotlin and don't want to mix the source-code between the two languages but if you only program in Kotlin that's ok.

ethana2 commented 4 years ago

I have the one in this product manual: https://www.3gorillas.com/images/email/AppSYNC_Manual.pdf There may be others with multiple sync methods but mine is barcode-only.

I'll get to work on this! Thanks!

oliexdev commented 4 years ago

ok that's really exotic.

ethana2 commented 4 years ago

So here's one I've got where I think I see the encoding of the weight at the top as 11010110011 / 1715 Lb x 10^-1 But none of the other fields make sense. I'm beginning to feel like these are ciphered as some kind of scheme for obfuscation and/or parity. I think the cipher bits are in the bottom row and the reason I'm able to read the weight from this image is that they're very low entropy for this payload. https://ibin.co/5PowlSTpFnbJ.jpg

The other reason I suspect a cipher or parity scheme is because I should be able to flip these bits individually and I find most of the time I do, it makes the code invalid instead of flipping a bit in synced data.

Full payload contents: 171.5 Lb weight 23.9% Body fat 36.4% Muscle mass 50.5% Water weight 24 BMI

These should show up in the payload respectively as: 11010110011 (I do see this one at the top) 11101111 101101100 111111001 11000

The hardware is limited in such a way that I'm prevented from isolating the most- or least- significant bits of any of the fields. I'm going to write a program to generate arbitrary barcode images, because GIMP is not an efficient way to do this-- I've generated 11 valid codes so far.

oliexdev commented 4 years ago

hmm this will be not easy. Did you verify you observation regarding the top line? Do you can decode other weight values from other images? I assume too that there are some kind of parity checks because if I flip a bit in the image the correct value is still shown but if I flip two then another value shows up. For example in your image I set the first two 1 to 0 and I get 199,7 lbs as a weight.

Could be https://en.wikipedia.org/wiki/Hamming_code ?

ethana2 commented 4 years ago

Oh, yeah, it has parity that can detect any two bit flips and correct almost any one bit flip. The entire payload is one parity domain but there are some bits which, when flipped, invalidate the code. This whole thing seems to be a heavily obfuscated, poorly implemented mess and I'm having to build a suite of tools for reverse-engineering it.

I've built a barcode generator in GTK+ Cairo that reliably generates valid codes from Array\<Boolean>(68). Next I'm working on making a barcode reader for Android that generates hexadecimal from the barcode and I'm going to manually copy those hex codes over into a local MySQL database and build kind of a payload "zoo" and make a tool that can scan payloads for values that are obfuscated with known obfuscation methods. So far I've observed it reversing the order of bits for fields, flipping segments of bits within fields, and that's probably only the beginning of what they're up to. This is going to take me a bit.

ethana2 commented 3 years ago

Sorry for the delay, my mental health has been a dumpster fire due in part to the pandemic. I did a bunch of reverse-engineering work and the resulting Kotlin code is here: https://github.com/ethana2/WeightGurus_appSYNC_GTK I hope to circle back around to get it ported to Android, hooked up to CameraX, and committed properly after I get a job.

Also, yes, it was Hamming 7,4

Screenshot from 2021-03-08 16-50-30

ilopez commented 1 year ago

I have this scale, and I'm going to check out what it would take for this to work. I'll ping here in about a month on my progress.

ethana2 commented 1 year ago

That's wonderful news! I also bought a second, similar model of scale to try to bring up support for the entire hardware family, but I have no idea when or if I'll actually get to that. Let me know if you'd like me to send it to you. If and when you get this working, I will be showing off your work to everyone I know as an effort I helped along, and I'd be open to taking you out for drinks if you're ever in the area!