oliexdev / openScale

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

Support for "Crenot GoFit S2" #1061

Open sroemer opened 3 months ago

sroemer commented 3 months ago

I am looking into getting openScale to work with a "Crenot GoFit S2" scale, which I recently bought on Lazada in Vietnam. The Crenot website currently only shows an older version of the S2 scale, which has a simpler display. The scale uses the Fitdays app.

Here pictures of my scale and its packaging: crenot_gofit_s2 crenot_gofit_s2_box

Today I gathered some initial information with BLE Scanner and looked if I find any scale sharing similarities, but so far didn't see one (I am totally new to bluetooth stuff and might have missed that, so if anybody sees similarities or has additional helpful input I am very happy to hear about it). After the weekend I will set up my development environment for this and also gather Bluetooth HCI logs and OpenScale logs.

Here my BLE Scanner screenshots (not on the screenshots, but please note that the manufacturer of the scale is "ICOMON" and the model number is "FG2210LB" - maybe that can be useful for supporting similar scales with different branding?):

crenot_gofit_s2_ble_device_information crenot_gofit_s2_ble_generic_access crenot_gofit_s2_ble_generic_attribute crenot_gofit_s2_ble_custom_service_1 crenot_gofit_s2_ble_custom_service_2

sroemer commented 3 months ago

bti snoop log # 1

The log was imported in wireshark, then filtered for 'bluetooth.addr==scale address' and exported again.

sex male
height 172cm

date 2024-08-26
time 14:59

Weight 95.55kg
BMI 32.3
Body Fat 33.4%
Fat mass 31.9kg
Fat-free Body Weight 63.6kg
Muscle mass 59.6kg
Muscle rate 62.4%
Skeletal muscle 45.8%
Bone Mass 3.3kg
Protein mass 15.2kg
Protein 15.9%
Water weight 45.1kg
Body Water 47.2%
Subcutaneous fat 21.8%
Visceral Fat 15.5
BMR 1830kcal
Body age 47
Ideal body weigh 65.1kg
Obesity level Obesity level I
Body type Overweight

btsnoop_hci_crenot_gofit_s2_2024-08-26_14-59_w9555_bmi323_fat334.log

On a quick look yesterday I didn't find the weight, but didn't have much time to dig deeper yet.

sroemer commented 2 months ago

Additional note: When Searching for "FG2210LB" I found some identical scales sold with different branding. For example "Runstar FG2210". Therefore - if possible - detecting the scale by its model number "FG2210LB" and manufacturer "ICOMON" instead of "Crenot GoFit S2" seems to be beneficial and might cover a bunch of other scales as well.

The chipset used in this scale is one from Chipsea

sroemer commented 2 months ago

I just sent an email to ICOMON (email from PlayStore) and asked for specifications or other input. I do not really expect that they provide something, but its worth a try anyway. Let's see what happens ...

sroemer commented 2 months ago

No reply from ICOMON - that was expected, but therefore I got some progress on other sides:

Python client:

I did implement a small client myself in Python by using bleak (it is not yet up to date, but I will push everything to my scale-communication repo). With it I already managed to receive notifications from the scale and from those I was able to identify the bits containing the weight value.

Weight in the transferred data:

Due to the results from my Python client I was able to find the weight in above btsnoop log:

This log contains the before mentioned notifications with the data a20700a2020069753e0000000000000000000000 (example from packet number 183). From this data bytes 6, 7 and 8 contain the weight value with only 2 bits used of byte 6. So the value is 0x69753e from which the last 18bits are the weight value. 0x69753e = 011010010111010100111110. Therefore the last 18bits are '010111010100111110 = 95550' - the expected weight of 95.55kg :-)

I am pretty happy now with getting that to work quite quickly, but need to spend some more time to implement that cleanly in Python first and find out about other values (body fat, etc.) before moving on to openScale again.

sroemer commented 2 months ago

My python client in my scale-communication now is quite clean regarding its communication and gets the weight reliably.

For this I enable FFB2 notifications, which are sent very frequently and contain the weight in bytes 6-8 as described before. Additionally (based on byte 4 of the message) I can detect when the weight gets 'stable'.

Additionally FFB3 indications are enabled. I don't know the exact purpose of those yet, but one indication is sent instantly (with some unknown data) and one seems to be sent after the scale switches to showing the BIA results. In the HCI snoop I also see another kind of FFB3 indications which I cannot reproduce with my client yet.

When I realized a message is sent correlating with the time BIA seems to end, I expected results to be in it too but sadly it only contains the weight value which with FFB2 was shown as stable already (but now shifted one byte to the left in bytes 5-7).

So currently my client implements the following communication (see Releases):

  1. Discover BLE devices
  2. Connect to scale with the name "Crenot Gofit S2"
  3. Enable FFB2 and FFB3 notification / indication
  4. Based on FFB2 notifications wait for the weight to become stable
  5. Based on FFB3 indication wait for 'the end of BIA'
  6. Verify that the stable weight from 4.) and the weight from the message received in 5.) match.
  7. Print result

How the BIA results are transferred currently is a mystery to me. I do not see any additional data to be transferred - not even a single RAW value. Not in the HCI snoop and not with my client. I didn't give up yet, but due to being out of ideas for the moment I started implementing a Bluetooth class for openScale already. Baaah, Java ;)