oliexdev / openScale

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

Renpho Scale Not Supported (model ES-CS20M-B) #291

Open jphendrix opened 6 years ago

jphendrix commented 6 years ago

I will update issue with bluetooth/wireshark logs soon.

erijo commented 6 years ago

Looks like there might be a library involved in this scale as well (https://github.com/YolandaQingniu/qn-ble-sdk-android). We'll see what the logs say...

Please provide the openScale debug log (settings -> about) after scanning for your device as well.

jphendrix commented 6 years ago

This is the debug log I was able to capture from the other day.

2018-06-11 22:25:22.463 Debug AboutPreferences: Debug log enabled, openScale v1.8.1 (28), SDK 24, samsung SM-G930V
2018-06-11 22:26:02.953 Debug BluetoothPreferences: Start discovery
2018-06-11 22:26:03.090 Debug BluetoothPreferences: Discovery: android.bluetooth.adapter.action.DISCOVERY_STARTED
2018-06-11 22:26:03.985 Debug BluetoothPreferences: Discovery: android.bluetooth.device.action.FOUND
2018-06-11 22:26:04.019 Debug BluetoothPreferences: Found unsupported device QN-Scale [A4:C1:38:4C:58:CE] (type: 2)
2018-06-11 22:26:07.227 Debug OpenScale: Trying to connect to bluetooth device [A4:C1:38:4C:58:CE] in debug mode
2018-06-11 22:26:07.230 Info BluetoothCommunication: Connecting to [A4:C1:38:4C:58:CE] (driver: Debug)
2018-06-11 22:26:07.243 Debug BluetoothCommunication: Starting LE scan
2018-06-11 22:26:07.625 Debug BluetoothPreferences: Discovery: android.bluetooth.adapter.action.DISCOVERY_FINISHED
2018-06-11 22:26:07.629 Debug BluetoothPreferences: Start LE scan
2018-06-11 22:26:08.156 Debug BluetoothPreferences: Found unsupported device Mirkwood Forest speaker [E4:F0:42:15:35:B9] (type: 3)
2018-06-11 22:26:08.249 Debug BluetoothCommunication$GattCallback: onConnectionStateChange: status=0, newState=2
2018-06-11 22:26:08.773 Debug BluetoothCommunication$GattCallback: onServicesDiscovered: status=0
2018-06-11 22:26:09.233 Debug OpenScale: Disconnecting from bluetooth device
2018-06-11 22:26:09.234 Info BluetoothCommunication: Disconnecting (with cleanup)
2018-06-11 22:26:09.779 Debug BluetoothCommunication: INIT STATE: 0
2018-06-11 22:26:09.782 Debug BluetoothCommunication: CMD STATE: 0
2018-06-11 22:26:16.063 Debug BluetoothPreferences: Found unsupported device Charge 2 [C2:BC:8A:AE:A7:19] (type: 2)
2018-06-11 22:26:17.660 Debug BluetoothPreferences: Stop discovery
2018-06-11 22:26:17.683 Debug BluetoothPreferences: Stop LE scan
2018-06-11 22:26:28.788 Debug AboutPreferences: Debug log disabled
erijo commented 6 years ago

I would have expected that the debug log would contain a list of GATT services from the scale. Please try the dev version and attach the log from that version.

jphendrix commented 6 years ago

This is the log from the dev version. Am I missing something?

2018-06-20 17:33:23.796 Debug AboutPreferences: Debug log enabled, openScale (dev) v1.8.1-dev_cb885d16 (1528314896), SDK 26, samsung SM-G930V
2018-06-20 17:34:11.235 Debug BluetoothPreferences: Start discovery
2018-06-20 17:34:11.317 Debug BluetoothPreferences: Discovery: android.bluetooth.adapter.action.DISCOVERY_STARTED
2018-06-20 17:34:17.695 Debug BluetoothPreferences: Discovery: android.bluetooth.device.action.FOUND
2018-06-20 17:34:17.734 Debug BluetoothPreferences: Found unsupported device QN-Scale [A4:C1:38:4C:58:CE] (type: 2)
2018-06-20 17:34:24.376 Debug BluetoothPreferences: Discovery: android.bluetooth.adapter.action.DISCOVERY_FINISHED
2018-06-20 17:34:24.385 Debug BluetoothPreferences: Start LE scan
2018-06-20 17:34:24.790 Debug BluetoothPreferences: Found unsupported device Mirkwood Forest speaker [E4:F0:42:15:35:B9] (type: 2)
2018-06-20 17:34:31.534 Debug OpenScale: Trying to connect to bluetooth device [A4:C1:38:4C:58:CE] in debug mode
2018-06-20 17:34:31.537 Info BluetoothCommunication: Connecting to [A4:C1:38:4C:58:CE] (driver: Debug)
2018-06-20 17:34:31.548 Debug BluetoothCommunication: BT is enabled, state=12, scan mode=21, is not discovering
2018-06-20 17:34:31.562 Debug BluetoothCommunication: Starting LE scan
2018-06-20 17:34:31.697 Debug BluetoothCommunication: Found LE device QN-Scale [A4:C1:38:4C:58:CE]
2018-06-20 17:34:31.704 Debug BluetoothCommunication: Found LE device null [4C:47:02:12:EF:53]
2018-06-20 17:34:31.748 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:32.961 Debug BluetoothCommunication: Found LE device null [4C:47:02:12:EF:53]
2018-06-20 17:34:32.977 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:33.009 Debug BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-06-20 17:34:33.055 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:33.177 Debug BluetoothCommunication: Found LE device null [6D:6A:09:A9:C0:D9]
2018-06-20 17:34:33.205 Debug BluetoothCommunication: Found LE device null [4C:47:02:12:EF:53]
2018-06-20 17:34:33.278 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:33.298 Debug BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-06-20 17:34:33.441 Debug BluetoothCommunication: Found LE device null [6D:6A:09:A9:C0:D9]
2018-06-20 17:34:33.477 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:33.565 Debug BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-06-20 17:34:33.584 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:33.696 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:33.727 Debug BluetoothCommunication: Found LE device null [4C:47:02:12:EF:53]
2018-06-20 17:34:33.788 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:33.806 Debug BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-06-20 17:34:33.909 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:33.944 Debug BluetoothCommunication: Found LE device null [6D:6A:09:A9:C0:D9]
2018-06-20 17:34:33.968 Debug BluetoothCommunication: Found LE device null [4C:47:02:12:EF:53]
2018-06-20 17:34:33.992 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:34.035 Debug BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-06-20 17:34:34.141 Debug OpenScale: Disconnecting from bluetooth device
2018-06-20 17:34:34.158 Info BluetoothCommunication: Disconnecting (with cleanup)
2018-06-20 17:34:34.383 Debug BluetoothPreferences: Stop discovery
2018-06-20 17:34:34.394 Debug BluetoothPreferences: Stop LE scan
2018-06-20 17:34:35.820 Debug OpenScale: Trying to connect to bluetooth device [A4:C1:38:4C:58:CE] in debug mode
2018-06-20 17:34:35.824 Info BluetoothCommunication: Connecting to [A4:C1:38:4C:58:CE] (driver: Debug)
2018-06-20 17:34:35.846 Debug BluetoothCommunication: BT is enabled, state=12, scan mode=21, is not discovering
2018-06-20 17:34:35.874 Debug BluetoothCommunication: Starting LE scan
2018-06-20 17:34:36.009 Debug BluetoothCommunication: Found LE device null [6D:6A:09:A9:C0:D9]
2018-06-20 17:34:36.014 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:36.030 Debug BluetoothCommunication: Found LE device null [4C:47:02:12:EF:53]
2018-06-20 17:34:36.086 Debug BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-06-20 17:34:36.127 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:36.244 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:36.259 Debug BluetoothCommunication: Found LE device null [6D:6A:09:A9:C0:D9]
2018-06-20 17:34:36.294 Debug BluetoothCommunication: Found LE device null [4C:47:02:12:EF:53]
2018-06-20 17:34:36.343 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:36.358 Debug BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-06-20 17:34:36.521 Debug BluetoothCommunication: Found LE device null [6D:6A:09:A9:C0:D9]
2018-06-20 17:34:36.556 Debug BluetoothCommunication: Found LE device null [4C:47:02:12:EF:53]
2018-06-20 17:34:36.621 Debug BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-06-20 17:34:36.659 Debug BluetoothCommunication: Found LE device null [2D:01:D8:F8:FA:EA]
2018-06-20 17:34:36.660 Debug BluetoothCommunication$GattCallback: onConnectionStateChange: status=133, newState=0
2018-06-20 17:34:36.675 Info BluetoothCommunication: Disconnecting
2018-06-20 17:34:36.693 Debug OpenScale: Disconnecting from bluetooth device
erijo commented 6 years ago

Please try with the latest dev version.

jphendrix commented 6 years ago

Logs from the dev version downloaded today. Hopefully this will be more helpful! Thanks for your support!

2018-07-07 11:02:41.593 Debug [2] AboutPreferences: Debug log enabled, openScale (dev) v1.8.1-dev_b92e143e_2018-07-06 (1530911762), SDK 26, samsung SM-G930V
2018-07-07 11:04:49.218 Debug [2] BluetoothPreferences: Start discovery
2018-07-07 11:04:49.272 Debug [2] BluetoothPreferences: Discovery: android.bluetooth.adapter.action.DISCOVERY_STARTED
2018-07-07 11:04:51.252 Debug [2] BluetoothPreferences: Discovery: android.bluetooth.device.action.FOUND
2018-07-07 11:04:51.279 Debug [2] BluetoothPreferences: Found unsupported device QN-Scale [A4:C1:38:4C:58:CE] (type: 2)
2018-07-07 11:04:54.130 Debug [2] BluetoothPreferences: Stop discovery
2018-07-07 11:04:54.189 Debug [2] OpenScale: Trying to connect to bluetooth device [A4:C1:38:4C:58:CE] in debug mode
2018-07-07 11:04:54.210 Debug [2] BluetoothCommunication: BT is enabled, state=12, scan mode=21, is not discovering
2018-07-07 11:04:54.232 Debug [2] BluetoothCommunication: Starting LE scan for device [A4:C1:38:4C:58:CE]
2018-07-07 11:04:54.397 Debug [2] BluetoothCommunication: Found LE device null [17:42:C1:5F:2E:F2]
2018-07-07 11:04:54.451 Debug [2] BluetoothCommunication: Found LE device null [67:EA:2C:B8:15:AC]
2018-07-07 11:04:54.458 Debug [2] BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-07-07 11:04:54.723 Debug [2] BluetoothCommunication: Found LE device QN-Scale [A4:C1:38:4C:58:CE]
2018-07-07 11:04:54.730 Debug [2] BluetoothCommunication: Stopping LE scan
2018-07-07 11:04:54.754 Info [2] BluetoothCommunication: Connecting to [A4:C1:38:4C:58:CE] (driver: Debug)
2018-07-07 11:04:54.776 Debug [2] BluetoothCommunication: Found LE device null [67:EA:2C:B8:15:AC]
2018-07-07 11:04:54.783 Debug [2] BluetoothCommunication: Found LE device null [17:42:C1:5F:2E:F2]
2018-07-07 11:04:54.791 Debug [2] BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-07-07 11:04:56.547 Debug [37539] BluetoothCommunication$GattCallback: onConnectionStateChange: status=0, newState=2
2018-07-07 11:04:57.599 Debug [37539] BluetoothCommunication$GattCallback: onServicesDiscovered: status=0 (4 services)
2018-07-07 11:04:58.605 Debug [37539] BluetoothCommunication: INIT STATE: 0
2018-07-07 11:04:58.607 Debug [37539] BluetoothCommunication: Read characteristic 00002a00-0000-1000-8000-00805f9b34fb
2018-07-07 11:04:58.692 Debug [37539] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a00-0000-1000-8000-00805f9b34fb (status=0): 51 4E 2D 53 63 61 6C 65 00 00 00 00 00 00 00 00 00 00 00
2018-07-07 11:04:58.762 Debug [2] BluetoothCommunication: INIT STATE: 1
2018-07-07 11:04:58.775 Debug [2] BluetoothCommunication: Read characteristic 00002a01-0000-1000-8000-00805f9b34fb
2018-07-07 11:04:58.892 Debug [37539] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a01-0000-1000-8000-00805f9b34fb (status=0): 00 00
2018-07-07 11:04:58.963 Debug [2] BluetoothCommunication: INIT STATE: 2
2018-07-07 11:04:58.977 Debug [2] BluetoothCommunication: Read characteristic 00002a04-0000-1000-8000-00805f9b34fb
2018-07-07 11:04:59.089 Debug [37539] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a04-0000-1000-8000-00805f9b34fb (status=0): 14 00 28 00 00 00 E8 03
2018-07-07 11:04:59.162 Debug [2] BluetoothCommunication: INIT STATE: 3
2018-07-07 11:04:59.175 Debug [2] BluetoothCommunication: Read characteristic 00002a50-0000-1000-8000-00805f9b34fb
2018-07-07 11:04:59.330 Debug [37539] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a50-0000-1000-8000-00805f9b34fb (status=0): 02 8A 24 66 82 01 00
2018-07-07 11:04:59.403 Debug [2] BluetoothCommunication: INIT STATE: 4
2018-07-07 11:04:59.418 Debug [2] BluetoothCommunication: Read characteristic 00002a29-0000-1000-8000-00805f9b34fb
2018-07-07 11:04:59.520 Debug [37539] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a29-0000-1000-8000-00805f9b34fb (status=0): 51 69 6E 67 20 4E 69 75 20 54 65 63 68 6E 6F 6C 6F 67 79
2018-07-07 11:04:59.589 Debug [2] BluetoothCommunication: INIT STATE: 5
2018-07-07 11:04:59.604 Debug [2] BluetoothCommunication: Read characteristic 00002a26-0000-1000-8000-00805f9b34fb
2018-07-07 11:04:59.718 Debug [37539] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a26-0000-1000-8000-00805f9b34fb (status=0): 56 35 36 2E 30
2018-07-07 11:04:59.790 Debug [2] BluetoothCommunication: INIT STATE: 6
2018-07-07 11:04:59.808 Debug [2] BluetoothCommunication: Read characteristic 00002a23-0000-1000-8000-00805f9b34fb
2018-07-07 11:04:59.915 Debug [37539] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a23-0000-1000-8000-00805f9b34fb (status=0): CE 58 4C 00 00 38 C1 A4
2018-07-07 11:04:59.989 Debug [2] BluetoothCommunication: INIT STATE: 7
2018-07-07 11:05:00.004 Debug [2] BluetoothCommunication: Read descriptor 00002902-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:00.154 Debug [37539] BluetoothCommunication$GattCallback: onDescriptorRead 00002902-0000-1000-8000-00805f9b34fb (status=0): 00 00
2018-07-07 11:05:00.227 Debug [2] BluetoothCommunication: INIT STATE: 8
2018-07-07 11:05:00.243 Debug [2] BluetoothCommunication: Read descriptor 00002902-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:00.401 Debug [37539] BluetoothCommunication$GattCallback: onDescriptorRead 00002902-0000-1000-8000-00805f9b34fb (status=0): 00 00
2018-07-07 11:05:00.471 Debug [2] BluetoothCommunication: INIT STATE: 9
2018-07-07 11:05:00.484 Debug [2] BluetoothCommunication: Read characteristic 00002a19-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:00.645 Debug [37539] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a19-0000-1000-8000-00805f9b34fb (status=0): 00
2018-07-07 11:05:00.717 Debug [2] BluetoothCommunication: INIT STATE: 10
2018-07-07 11:05:00.730 Debug [2] BluetoothCommunication: CMD STATE: 0
2018-07-07 11:05:00.737 Debug [2] BluetoothDebug: Service 00001800-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:00.745 Debug [2] BluetoothDebug: |- characteristic 00002a00-0000-1000-8000-00805f9b34fb (instance 3): READ (permissions=0x0)
2018-07-07 11:05:00.754 Debug [2] BluetoothDebug: |--> value: 51 4E 2D 53 63 61 6C 65 00 00 00 00 00 00 00 00 00 00 00 (QN-Scale???????????)
2018-07-07 11:05:00.758 Debug [2] BluetoothDebug: |- characteristic 00002a01-0000-1000-8000-00805f9b34fb (instance 5): READ (permissions=0x0)
2018-07-07 11:05:00.763 Debug [2] BluetoothDebug: |--> value: 00 00 (??)
2018-07-07 11:05:00.767 Debug [2] BluetoothDebug: |- characteristic 00002a04-0000-1000-8000-00805f9b34fb (instance 7): READ (permissions=0x0)
2018-07-07 11:05:00.772 Debug [2] BluetoothDebug: |--> value: 14 00 28 00 00 00 E8 03 (??(???�?)
2018-07-07 11:05:00.775 Debug [2] BluetoothDebug: Service 0000180a-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:00.779 Debug [2] BluetoothDebug: |- characteristic 00002a50-0000-1000-8000-00805f9b34fb (instance 10): READ (permissions=0x0)
2018-07-07 11:05:00.785 Debug [2] BluetoothDebug: |--> value: 02 8A 24 66 82 01 00 (?�$f�??)
2018-07-07 11:05:00.791 Debug [2] BluetoothDebug: |- characteristic 00002a29-0000-1000-8000-00805f9b34fb (instance 12): READ (permissions=0x0)
2018-07-07 11:05:00.796 Debug [2] BluetoothDebug: |--> value: 51 69 6E 67 20 4E 69 75 20 54 65 63 68 6E 6F 6C 6F 67 79 (Qing Niu Technology)
2018-07-07 11:05:00.799 Debug [2] BluetoothDebug: |- characteristic 00002a26-0000-1000-8000-00805f9b34fb (instance 14): READ (permissions=0x0)
2018-07-07 11:05:00.803 Debug [2] BluetoothDebug: |--> value: 56 35 36 2E 30 (V56.0)
2018-07-07 11:05:00.805 Debug [2] BluetoothDebug: |- characteristic 00002a23-0000-1000-8000-00805f9b34fb (instance 16): READ (permissions=0x0)
2018-07-07 11:05:00.809 Debug [2] BluetoothDebug: |--> value: CE 58 4C 00 00 38 C1 A4 (�XL??8d)
2018-07-07 11:05:00.811 Debug [2] BluetoothDebug: Service 0000ffe0-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:00.813 Debug [2] BluetoothDebug: |- characteristic 0000ffe1-0000-1000-8000-00805f9b34fb (instance 19): NOTIFY (permissions=0x0)
2018-07-07 11:05:00.814 Debug [2] BluetoothDebug: |--- descriptor 00002902-0000-1000-8000-00805f9b34fb (permissions=0x0)
2018-07-07 11:05:00.816 Debug [2] BluetoothDebug: |-----> value: 00 00
2018-07-07 11:05:00.819 Debug [2] BluetoothDebug: |- characteristic 0000ffe2-0000-1000-8000-00805f9b34fb (instance 22): INDICATE (permissions=0x0)
2018-07-07 11:05:00.821 Debug [2] BluetoothDebug: |--- descriptor 00002902-0000-1000-8000-00805f9b34fb (permissions=0x0)
2018-07-07 11:05:00.823 Debug [2] BluetoothDebug: |-----> value: 00 00
2018-07-07 11:05:00.826 Debug [2] BluetoothDebug: |- characteristic 0000ffe3-0000-1000-8000-00805f9b34fb (instance 25): WRITE_NO_RESPONSE, WRITE (permissions=0x0)
2018-07-07 11:05:00.830 Debug [2] BluetoothDebug: |- characteristic 0000ffe4-0000-1000-8000-00805f9b34fb (instance 27): WRITE_NO_RESPONSE, WRITE (permissions=0x0)
2018-07-07 11:05:00.832 Debug [2] BluetoothDebug: |- characteristic 0000ffe5-0000-1000-8000-00805f9b34fb (instance 29): WRITE_NO_RESPONSE, WRITE (permissions=0x0)
2018-07-07 11:05:00.834 Debug [2] BluetoothDebug: Service 0000180f-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:00.836 Debug [2] BluetoothDebug: |- characteristic 00002a19-0000-1000-8000-00805f9b34fb (instance 32): READ (permissions=0x0)
2018-07-07 11:05:00.840 Debug [2] BluetoothDebug: |--> value: 00 (?)
2018-07-07 11:05:00.843 Info [2] BluetoothCommunication: Disconnecting
2018-07-07 11:05:00.852 Debug [2] OpenScale: Disconnecting from bluetooth device
2018-07-07 11:05:08.003 Debug [2] OpenScale: Trying to connect to bluetooth device [A4:C1:38:4C:58:CE] in debug mode
2018-07-07 11:05:08.021 Debug [2] BluetoothCommunication: BT is enabled, state=12, scan mode=21, is not discovering
2018-07-07 11:05:08.037 Debug [2] BluetoothCommunication: Starting LE scan for device [A4:C1:38:4C:58:CE]
2018-07-07 11:05:08.177 Debug [2] BluetoothCommunication: Found LE device null [67:EA:2C:B8:15:AC]
2018-07-07 11:05:08.183 Debug [2] BluetoothCommunication: Found LE device Mirkwood Forest speaker [E4:F0:42:15:35:B9]
2018-07-07 11:05:08.204 Debug [2] BluetoothCommunication: Found LE device QN-Scale [A4:C1:38:4C:58:CE]
2018-07-07 11:05:08.205 Debug [2] BluetoothCommunication: Stopping LE scan
2018-07-07 11:05:08.214 Info [2] BluetoothCommunication: Connecting to [A4:C1:38:4C:58:CE] (driver: Debug)
2018-07-07 11:05:08.223 Debug [2] BluetoothCommunication: Found LE device QN-Scale [A4:C1:38:4C:58:CE]
2018-07-07 11:05:08.225 Info [2] BluetoothCommunication: Connecting to [A4:C1:38:4C:58:CE] (driver: Debug)
2018-07-07 11:05:08.237 Debug [2] BluetoothCommunication: Found LE device null [17:42:C1:5F:2E:F2]
2018-07-07 11:05:08.242 Debug [2] BluetoothCommunication: Found LE device QN-Scale [A4:C1:38:4C:58:CE]
2018-07-07 11:05:08.243 Info [2] BluetoothCommunication: Connecting to [A4:C1:38:4C:58:CE] (driver: Debug)
2018-07-07 11:05:09.160 Debug [37539] BluetoothCommunication$GattCallback: onConnectionStateChange: status=0, newState=2
2018-07-07 11:05:09.165 Debug [37537] BluetoothCommunication$GattCallback: onConnectionStateChange: status=0, newState=2
2018-07-07 11:05:09.168 Debug [37528] BluetoothCommunication$GattCallback: onConnectionStateChange: status=0, newState=2
2018-07-07 11:05:10.192 Debug [37539] BluetoothCommunication$GattCallback: onServicesDiscovered: status=0 (4 services)
2018-07-07 11:05:10.193 Debug [37537] BluetoothCommunication$GattCallback: onServicesDiscovered: status=0 (4 services)
2018-07-07 11:05:10.198 Debug [37528] BluetoothCommunication$GattCallback: onServicesDiscovered: status=0 (4 services)
2018-07-07 11:05:11.196 Debug [37539] BluetoothCommunication: INIT STATE: 0
2018-07-07 11:05:11.199 Debug [37539] BluetoothCommunication: Read characteristic 00002a00-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:11.208 Debug [37537] BluetoothCommunication: INIT STATE: 1
2018-07-07 11:05:11.212 Debug [37537] BluetoothCommunication: Read characteristic 00002a01-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:11.216 Debug [37528] BluetoothCommunication: INIT STATE: 2
2018-07-07 11:05:11.219 Debug [37528] BluetoothCommunication: Read characteristic 00002a04-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:11.269 Debug [37528] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a00-0000-1000-8000-00805f9b34fb (status=0): 51 4E 2D 53 63 61 6C 65 00 00 00 00 00 00 00 00 00 00 00
2018-07-07 11:05:11.334 Debug [2] BluetoothCommunication: INIT STATE: 3
2018-07-07 11:05:11.343 Debug [2] BluetoothCommunication: Read characteristic 00002a50-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:11.425 Debug [37528] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a50-0000-1000-8000-00805f9b34fb (status=0): 02 8A 24 66 82 01 00
2018-07-07 11:05:11.496 Debug [2] BluetoothCommunication: INIT STATE: 4
2018-07-07 11:05:11.511 Debug [2] BluetoothCommunication: Read characteristic 00002a29-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:11.623 Debug [37528] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a29-0000-1000-8000-00805f9b34fb (status=0): 51 69 6E 67 20 4E 69 75 20 54 65 63 68 6E 6F 6C 6F 67 79
2018-07-07 11:05:11.693 Debug [2] BluetoothCommunication: INIT STATE: 5
2018-07-07 11:05:11.705 Debug [2] BluetoothCommunication: Read characteristic 00002a26-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:11.815 Debug [37528] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a26-0000-1000-8000-00805f9b34fb (status=0): 56 35 36 2E 30
2018-07-07 11:05:11.886 Debug [2] BluetoothCommunication: INIT STATE: 6
2018-07-07 11:05:11.899 Debug [2] BluetoothCommunication: Read characteristic 00002a23-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:12.006 Debug [37528] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a23-0000-1000-8000-00805f9b34fb (status=0): CE 58 4C 00 00 38 C1 A4
2018-07-07 11:05:12.074 Debug [2] BluetoothCommunication: INIT STATE: 7
2018-07-07 11:05:12.087 Debug [2] BluetoothCommunication: Read descriptor 00002902-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:12.198 Debug [37528] BluetoothCommunication$GattCallback: onDescriptorRead 00002902-0000-1000-8000-00805f9b34fb (status=0): 00 00
2018-07-07 11:05:12.268 Debug [2] BluetoothCommunication: INIT STATE: 8
2018-07-07 11:05:12.276 Debug [2] BluetoothCommunication: Read descriptor 00002902-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:12.342 Debug [37528] BluetoothCommunication$GattCallback: onDescriptorRead 00002902-0000-1000-8000-00805f9b34fb (status=0): 00 00
2018-07-07 11:05:12.410 Debug [2] BluetoothCommunication: INIT STATE: 9
2018-07-07 11:05:12.422 Debug [2] BluetoothCommunication: Read characteristic 00002a19-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:12.545 Debug [37528] BluetoothCommunication$GattCallback: onCharacteristicRead 00002a19-0000-1000-8000-00805f9b34fb (status=0): 00
2018-07-07 11:05:12.617 Debug [2] BluetoothCommunication: INIT STATE: 10
2018-07-07 11:05:12.630 Debug [2] BluetoothCommunication: CMD STATE: 0
2018-07-07 11:05:12.637 Debug [2] BluetoothDebug: Service 00001800-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:12.645 Debug [2] BluetoothDebug: |- characteristic 00002a00-0000-1000-8000-00805f9b34fb (instance 3): READ (permissions=0x0)
2018-07-07 11:05:12.654 Debug [2] BluetoothDebug: |--> value: 51 4E 2D 53 63 61 6C 65 00 00 00 00 00 00 00 00 00 00 00 (QN-Scale???????????)
2018-07-07 11:05:12.657 Debug [2] BluetoothDebug: |- characteristic 00002a01-0000-1000-8000-00805f9b34fb (instance 5): READ (permissions=0x0)
2018-07-07 11:05:12.662 Debug [2] BluetoothDebug: |- characteristic 00002a04-0000-1000-8000-00805f9b34fb (instance 7): READ (permissions=0x0)
2018-07-07 11:05:12.665 Debug [2] BluetoothDebug: Service 0000180a-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:12.668 Debug [2] BluetoothDebug: |- characteristic 00002a50-0000-1000-8000-00805f9b34fb (instance 10): READ (permissions=0x0)
2018-07-07 11:05:12.673 Debug [2] BluetoothDebug: |--> value: 02 8A 24 66 82 01 00 (?�$f�??)
2018-07-07 11:05:12.676 Debug [2] BluetoothDebug: |- characteristic 00002a29-0000-1000-8000-00805f9b34fb (instance 12): READ (permissions=0x0)
2018-07-07 11:05:12.680 Debug [2] BluetoothDebug: |--> value: 51 69 6E 67 20 4E 69 75 20 54 65 63 68 6E 6F 6C 6F 67 79 (Qing Niu Technology)
2018-07-07 11:05:12.684 Debug [2] BluetoothDebug: |- characteristic 00002a26-0000-1000-8000-00805f9b34fb (instance 14): READ (permissions=0x0)
2018-07-07 11:05:12.687 Debug [2] BluetoothDebug: |--> value: 56 35 36 2E 30 (V56.0)
2018-07-07 11:05:12.690 Debug [2] BluetoothDebug: |- characteristic 00002a23-0000-1000-8000-00805f9b34fb (instance 16): READ (permissions=0x0)
2018-07-07 11:05:12.692 Debug [2] BluetoothDebug: |--> value: CE 58 4C 00 00 38 C1 A4 (�XL??8d)
2018-07-07 11:05:12.694 Debug [2] BluetoothDebug: Service 0000ffe0-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:12.695 Debug [2] BluetoothDebug: |- characteristic 0000ffe1-0000-1000-8000-00805f9b34fb (instance 19): NOTIFY (permissions=0x0)
2018-07-07 11:05:12.697 Debug [2] BluetoothDebug: |--- descriptor 00002902-0000-1000-8000-00805f9b34fb (permissions=0x0)
2018-07-07 11:05:12.699 Debug [2] BluetoothDebug: |-----> value: 00 00
2018-07-07 11:05:12.701 Debug [2] BluetoothDebug: |- characteristic 0000ffe2-0000-1000-8000-00805f9b34fb (instance 22): INDICATE (permissions=0x0)
2018-07-07 11:05:12.703 Debug [2] BluetoothDebug: |--- descriptor 00002902-0000-1000-8000-00805f9b34fb (permissions=0x0)
2018-07-07 11:05:12.705 Debug [2] BluetoothDebug: |-----> value: 00 00
2018-07-07 11:05:12.707 Debug [2] BluetoothDebug: |- characteristic 0000ffe3-0000-1000-8000-00805f9b34fb (instance 25): WRITE_NO_RESPONSE, WRITE (permissions=0x0)
2018-07-07 11:05:12.709 Debug [2] BluetoothDebug: |- characteristic 0000ffe4-0000-1000-8000-00805f9b34fb (instance 27): WRITE_NO_RESPONSE, WRITE (permissions=0x0)
2018-07-07 11:05:12.710 Debug [2] BluetoothDebug: |- characteristic 0000ffe5-0000-1000-8000-00805f9b34fb (instance 29): WRITE_NO_RESPONSE, WRITE (permissions=0x0)
2018-07-07 11:05:12.712 Debug [2] BluetoothDebug: Service 0000180f-0000-1000-8000-00805f9b34fb
2018-07-07 11:05:12.714 Debug [2] BluetoothDebug: |- characteristic 00002a19-0000-1000-8000-00805f9b34fb (instance 32): READ (permissions=0x0)
2018-07-07 11:05:12.716 Debug [2] BluetoothDebug: |--> value: 00 (?)
2018-07-07 11:05:12.717 Info [2] BluetoothCommunication: Disconnecting
2018-07-07 11:05:12.725 Debug [2] OpenScale: Disconnecting from bluetooth device
2018-07-07 11:05:17.092 Debug [37528] BluetoothCommunication$GattCallback: onConnectionStateChange: status=14, newState=0
2018-07-07 11:05:17.114 Debug [37537] BluetoothCommunication$GattCallback: onConnectionStateChange: status=14, newState=0
erijo commented 6 years ago

Thanks! Can you please attach it as a file?

Also, we need the btsnoop logs.

jphendrix commented 6 years ago

openScale_2018-07-07_11-02.txt File attached. I will read up on how to generate btsnoop logs.

jphendrix commented 6 years ago

I was able to enable developer mode and turn on bluetooth logging but I was not able to find the log file. I have installed ADB and was able to pull my bt_stack.conf which does not show the setting for BtSnoopLogOutput nor does it have a setting for BtSnoopFileName. My phone is not rooted and I am not an android dev. I will do some research before going any further.

erijo commented 6 years ago

Try this: https://stackoverflow.com/a/46674486/9242132

ZHAJOR commented 6 years ago

I have a Renpho too and I start to work on it. I am filtering on this using wireshark: btatt.uuid16 == 0xffe1

I went 3 times on the scale:

1/ 10:0b:15:22:fb:01:01:fc:01:f8:44 Weight 89.55kg Body fat 20.1% Body water 57.4 Fat Free Body 71.5 kg Muscle Mass 68kg Bone Mass 3.6 kg BMI 26.7

2/ 10:0b:15:23:46:01:01:fc:01:ed:85 Weight 90.3kg Body fat 20.5% Body water 57.4% Fat Free Body 71.8 kg Muscle Mass 68.2kg Bone Mass 3.6 kg BMI 27

3/ 10:0b:15:23:b9:01:02:02:01:f9:0b Weight 91.45kg Body fat 21% Body water 57% Fat Free Body 72.2 kg Muscle Mass 68.6kg Bone Mass 3.6 kg BMI 27.3

Analysis: 10:0b:15 was always the same Then we have the weight 23:b9 => 9145 Then we have something not changing much 01:02:02:01 and 01:01:fc:01

I tried to understand the data but didn't get anything from it (INT16 and INT32 Big Endian), do you have an hint?

oliexdev commented 6 years ago

could be the impedance value since it seems a so. library is used to calculate the body measurements like for the 1byone scale in issue #159 or yunmai scale in issue #71

ghost commented 6 years ago

Is there anyone can understand value like this from renpho scale ? 10:0b:15:22:fb:01:01:fc:01:f8:44 I just need Body Fat value.

ZHAJOR commented 6 years ago

22 fb is your weight 01 FC is the impedance You can use the formula from oliexdev to get your body fat from this

oliexdev commented 6 years ago

@ZHAJOR do you have an implementation for openScale? If yes could you send a PR?

ZHAJOR commented 6 years ago

@oliexdev I didn't have time to work on it since August so I don't have an implementation yet. I will do it late October if everything is going well on my side, I will not forget the PR!

oliexdev commented 6 years ago

@ZHAJOR thanks in advance :+1:

ghost commented 6 years ago

@ZHAJOR Thanks for your help I really appreciated. for this example I could not get the true result with oliexdev formulas ; scale results ; weight : 81.95 height : 176 sex :male age:28 bmı 26.5 body-fat:16.3 % (I try oliexdev formulas and I get the result around 22 ) body-water 60.4 %

srwareham commented 6 years ago

Happy to open another issue, but I just picked up a FITINDEX ES-26M scale and it seems it's a clone of the RENPHO here (they both use the QN-Scale device name/library).

I mention this so others can see this issue and also to offer assistance with debugging or contributions to the reverse engineering effort (although might need a bit of hand-holding).

Here's the btsnoop_hci.log file taken on a Nexus 5x by taking the following steps:

  1. Install FITINDEX app, configure per in-app instructions
  2. Enable Developer options
  3. Enable Bluetooth
  4. Developer options -> Enable Bluetooth HCI snoop log
  5. Disable Bluetooth
  6. Enable Bluetooth
  7. Reboot
  8. Step on scale and record in-app weight/BMI/etc. measurements
  9. Developer options -> Take bug report -> Full report
  10. Tap on bug report notification (takes ~2 minutes to show up) and "share" to a file explorer app (I used X-plore) to save it to a known on-device location
  11. Use file explorer app to SCP the bugreport zip file to computer with wireshark (emailing the file would work too)
  12. On computer, unzip the bugreport zip file
  13. The final btsnoop_hci.log file is located at FS/data/misc/bluetooth/logs/btsnoop_hci.log

The associated scale measurements from the app for this log were:

Weight (kg) BMI Body Fat (%) Fat-free Body Weight (kg) Body Water (%) Skeletal Muscle (%) Muscle Mass (kg) Bone Mass (kg) Protein (%) BMR (kcal) Metabolic Age
67.60 23.7 15.7 57.1 60.9 54.5 54.2 2.9 19.2 1602 21
66.66 23.3 15.1 56.5 61.3 54.8 53.7 2.8 19.4 1590 21
74.8 26.2 19.5 60.2 58.1 52 56.2 3.0 18.4 1670 25

The openscale v1.8.1 (28) debug file, taken an hour or so later, is here openScale_2018-09-27_21-20.txt

Supporting the theory these two scales use the same protocol, I've included below a wireshark excerpt for weights of 66.6kg and 74.8kg (the values follow the same pattern as those for RENPHO):

No. Time Value Source Source BD_ADDR Destination CID Length Info
526 532.897881 100b151a0400000000004e TelinkSe_c2:ac:3d (QN-Scale) a4:c1:38:c2:ac:3d LgElectr_f0:f7:af (Nexus 5X) Attribute Protocol 23 Rcvd Handle Value Notification, Handle: 0x0013 (Unknown: Unknown)
1769 801.73624 100b151d380101fa01ef71 TelinkSe_c2:ac:3d (QN-Scale) a4:c1:38:c2:ac:3d LgElectr_f0:f7:af (Nexus 5X) Attribute Protocol 23 Rcvd Handle Value Notification, Handle: 0x0013 (Unknown: Unknown)

Thanks for all the great work everyone!

srwareham commented 6 years ago

As an update, I think I've figured out a good chunk of the protocol to at least get weight data. Forgive me in advance if I use any incorrect terminology:

  1. Phone receives LE advertising report from Service 0xffe0 (LE Meta event code)

  2. Phone sends LE Create Connection message (HCI_CMD event code)

  3. Phone and scale exchange GATT traffic to learn there are 5 characteristics for the custom service with weight measurements (skipping some details here, as I think they aren't needed)

  4. Phone sends write request to characteristic at 0xffe1 to subscribe to notifications (this is where weight data comes from). Best I can tell, this is represented in the openScale library by code like:

    setNotificationOn(
    UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb"),  UUID.fromString("0000ffe1-0000-1000-8000-00805f9b34fb"), UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
  5. Phone sends write request to characteristic 0xffe2 to subscribe to indications. I haven't yet discerned what comes from here.

setIndicationOn(
UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb"),  UUID.fromString("0000ffe2-0000-1000-8000-00805f9b34fb"), UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));
  1. Phone receives a value notification from 0xffe1. This always contains the magic number 0x120f153dacc238c1a43801380000ef as the value. Edit 1: it looks like one other value can occur here as well, "0x120f153dacc238c1a43801380104f4" My suspicion is that this has something to do with the existence (or not) of historical/saved data. Haven't figured this out yet.
  2. Phone sends a write command with a magicnumber value 0x130915011000000042 to characteristic 0xffe3
    writeBytes(
    UUID.fromString("0000ffe0-0000-1000-8000-00805f9b34fb"), 
    UUID.fromString("0000ffe3-0000-1000-8000-00805f9b34fb"), 
    new byte[] {(byte)0x13, (byte)0x09, (byte)0x15, (byte)0x01, (byte)0x10, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x42});
  3. Phone receives value notification from characteristic 0xffe1, always with the magicnumber 0x140b150000010000000035 as the value
  4. Phone sends a write command with the date prefaced by a magic number to characteristic 0xffe3. The packet will contain a value like "20081568df4023e7" The first 6 hex are the magic number and the following 8 hex contain the date. The date is encoded in little endian with an epoch of 2000-01-01 00:00:00 (utc) for some reason. The example I've provided here subsequently decodes to 2018-09-29 17:47.
  5. Phone receives a handle value indication from 0xffe2. The value is always 210515013c. The phone then sends the expected value confirmation to the same characteristic
  6. The scale sends any number of notifications from characteristic 0xffe1. Example: "100b151a3b000000000085" Each message containing a weight begins with 0x100b15 and there can be many (for instance if you stand on the scale and purposely change weight while it reports to the app). For these messages, as mentioned above in this thread, the weight is the 4 hex after the aforementioned constant, and can be directly translated to decimal and divided by 100 for weight in kg. The previously mentioned message subsequently has a weight of 67.15.
  7. Sometimes, at the end of a series of weight messages, there will be a more dense message, like "100b151a450101fd01f180" (generally the weight is followed by eight 0s, then by what appears to be a checksum--I'm calling these more common messages "sparse" for comparison).
  8. The phone sends a write command to characteristic 0xffe3. The value is always 0x1f05151049 and it is quickly followed by a "Rcvd Disconnect Complete" HCI_EVT

I've put together a strawman implementation in my own repository, but it's highly unlikely I've understood what's required by the lib. How can I help get a PR together (whether by someone helping me understand the lib or by my providing information on the protocol to someone more familiar with the lib).

Thanks!

Edit 1: Analyzing a bit more traffic, it seems historical data is received on the 0xffe2 characteristic, with messages prefaced with "0x231415" As an example, the below values came in consecutive indications from one connection with the scale:

"2314150401c7da44231a0401fa01f9000000006c"
"2314150402e7da44231be4020101f30000000070"
"231415040301db44231a5401fe01f600000000fa" 
"2314150404b10645231c0201fb01f1000000007f"

Edit 2:

I've more or less confirmed the above 0x23145 message type does contain stored/historical records. The date for the record appears to be in hex codes 10-20, with some other structured data before it. Haven't yet figured out the data after it, which I'd think would somehow contain the weight and impedance. I've made a table breaking down this message type below with what I've inferred (date is certainly right, the rest could be off).

Value/Message Payload Magic#/Header total # of messages for this sequence # message in sequence Timestamp (LE 2000-01-01 epoch) TBD Empty+Checksum
2314150401c7da44231a0401fa01f9000000006c 231415 04 01 c7da44231a 0401fa01 000000006c
2314150402e7da44231be4020101f30000000070 231415 04 02 e7da44231b e4020101 0000000070
231415040301db44231a5401fe01f600000000fa 231415 04 03 01db44231a 5401fe01 00000000fa
2314150404b10645231c0201fb01f1000000007f 231415 04 04 b10645231c 0201fb01 000000007f
oliexdev commented 6 years ago

@srwareham you have to disassembly and reverse engineering the libyolanda_calc.so Use for example IDA free, JEB or radare2. To get the .so files just download the apk and unzip it. You see a folder named lib. Use for example x86 so file.

srwareham commented 6 years ago

@oliexdev Is that to say that you're recommending decompiling the scale's android app as a necessary step for adding support to openScale? Is there anything that needs to be learned that can't be discerned by packet capture/inspection? When I was saying "lib" above, I was intending to refer to openScale itself. Apologies if that was unclear!

oliexdev commented 5 years ago

@srwareham yes as I wrote you have to disassembly and understand the libyolanda_calc.so as there are the body metrics are calculated.

@YilmazTasdelen just read two post above yours https://github.com/oliexdev/openScale/issues/291#issuecomment-425615095

srwareham commented 5 years ago

@oliexdev I'm not yet approaching the problem of capturing and decoding impedance values; for now, I'd just like to be able to properly add support to openScale to capture the scale's weight data.

I have a somewhat-working proof of concept here https://github.com/srwareham/openScale/blob/feature_qn_scale/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothQNScale.java, but don't quite have grip on what needs to be implemented for basic functionality to work smoothly (for instance, my current version requires bluetooth to be toggled in-app in order to pair openScale with my scale, the app only receives the chronologically first measurement--instead of a stable one, and the scale force disconnects after transmitting the weight payload).

Do you have a sense of the general workflow that's required across all scales (e.g., handshake, request historical records, receive historical records, request current weight, receive current weight, confirm receipt, disconnect)? It seems like the various scales supported by the project vary a decent amount, but it would be helpful to understand what' needs to be done (at least almost all of the time).

Thanks!

oliexdev commented 5 years ago

for instance, my current version requires bluetooth to be toggled in-app in order to pair openScale with my scale

that is a normal behavior, there is no auto connection. You have always click on the Bluetooth icon in openScale to connect to the scale.

the app only receives the chronologically first measurement--instead of a stable one

Do you mean the behavior which you have describe at nr 11 in post https://github.com/oliexdev/openScale/issues/291#issuecomment-425610365 ? Most scales sends the current weight constantly to the app via an advertisement message to the app. I think that is the same here. But these messages we can ignore. We only want the last message which have always some indication (most time you see a change in the first bytes) in the transmitted value, so this is then a stable weight.

and the scale force disconnects after transmitting the weight payload

Well most scales doesn't send any command to disconnect. They just let the timeout of the Bluetooth connection happened. You can do it too. It is not very clean but you don't have to actively disconnect from the scale. If the scales goes offline the app will close the Bluetooth connection after a while.

The general workflow of most scales are as following:

  1. Initialize the scale with a user or set the time, unit or so on (depends on the scale)
  2. set the Bluetooth scales notification / indication flags on
  3. send a special command to receive weight history (if the scale supports it)
  4. read and decode incoming values from the scales via GATT changes
  5. send an ack command that you have received the weight history (some scales needs that) or optional cleanup the connection

If you scale doesn't support history data then you only have to interpret the incoming weight data if they are stable or not. For the mi scale v1 I wrote in the wiki a little bit how the communication of this scale works.

srwareham commented 5 years ago

@oliexdev Thank you!! That is very helpful!

puddly commented 5 years ago

@srwareham Thank you for reverse engineering most of the protocol. I'm working on a different project but with the same scale and your description saved me quite a bit of time. I'm not sure if you'll find it useful, but here are some of my observations about the protocol:

oliexdev commented 5 years ago

@puddly Is your source-code published? Could your working code snippet here?

puddly commented 5 years ago

@oliexdev of course, but it's pretty messy and written in asyncio-littered Python. It requires Python 3.7+ and the bluepy library (pip install bluepy). You'll probably have to run the script with superuser privileges.

I tried to reverse engineer the libyolanda_calc.so library to figure out how it uses the two magic "resistance" values sent with the final weight measurement but didn't get very far. It's a function of the user's height, age, sex, weight, and the two "resistance" (impedance?) values (in that order, if you're trying to directly use the function at 0x13f0 in x86_64 library).

import logging
import asyncio

from bluepy import btle
from datetime import datetime
from collections import defaultdict

logging.getLogger().setLevel(logging.DEBUG)

SCALE_ADDRESS = 'XX:XX:XX:XX:XX:XX'
SCALE_UNITS = 'lb'

class MainDelegate(btle.DefaultDelegate):
    def __init__(self, peripheral):
        super().__init__()

        self.loop = asyncio.get_event_loop()
        self.peripheral = peripheral
        self.responses = defaultdict(lambda: asyncio.Queue(loop=self.loop))

        self.weight_service = None
        self.characteristic = None

    async def connect(self, address):
        for i in range(50):
            try:
                await self.loop.run_in_executor(None, lambda: self.peripheral.connect(address))
                break
            except btle.BTLEException:
                logging.warning('Failed to connect! Retrying...')
                await asyncio.sleep(1)
                continue

        self.weight_service = await self.loop.run_in_executor(None, lambda: self.peripheral.getServiceByUUID('0000ffe0-0000-1000-8000-00805f9b34fb'))
        self.characteristic = await self.loop.run_in_executor(None, lambda: self.weight_service.getCharacteristics('0000ffe3-0000-1000-8000-00805f9b34fb')[0])

        # Subscribe to notifications
        await self.loop.run_in_executor(None, lambda: self.peripheral.writeCharacteristic(0x0014, b'\x01\x00'))
        await self.loop.run_in_executor(None, lambda: self.peripheral.writeCharacteristic(0x0017, b'\x01\x00'))

        asyncio.create_task(self.notification_loop())

    def handleNotification(self, handle, data):
        logging.debug('<<< %s', ' '.join(f'{c:02X}' for c in data))

        if data[-1] != self.message_checksum(data[:-1]):
            raise ValueError(f'Checksum invalid for {data!r}')

        response_id = data[0]
        unknown = data[1]
        payload = data[3:-1]

        self.responses[response_id].put_nowait(payload)

    @staticmethod
    def message_checksum(message):
        return sum(message) & 0xff

    async def notification_loop(self):
        while True:
            try:
                await self.loop.run_in_executor(None, lambda: self.peripheral.waitForNotifications(60))
            except btle.BTLEException:
                break

    async def receive(self, response_id):
        return await self.responses[response_id].get()

    async def send(self, request_id, unknown, payload, *, wait_for_response=True):
        message = bytearray([request_id, unknown, 0x15]) + payload
        message += bytes([self.message_checksum(message)])

        # Empty the response queue since the protocol has no transaction IDs
        if not self.responses[request_id + 1].empty():
            logging.warning('Response queue for request %d is not empty. Clearing anyways!', request_id)

        del self.responses[request_id + 1]

        logging.debug('>>> %s', ' '.join(f'{c:02X}' for c in message))

        await self.loop.run_in_executor(None, lambda: self.characteristic.write(message))

        if wait_for_response:
            # Response id is always request id + 1
            return await self.receive(request_id + 1)

async def main():
    peripheral = btle.Peripheral()
    delegate = MainDelegate(peripheral)
    peripheral.setDelegate(delegate)

    logging.debug('Connecting to scale')
    await delegate.connect(SCALE_ADDRESS)

    unit_code = {
        'kg': 1,
        'lb': 2,
        'jin': 3
    }[SCALE_UNITS]

    logging.debug('Sending handshake')
    await delegate.send(0x13, 0x09, unit_code.to_bytes(1, 'big') + (0x10).to_bytes(4, 'little'))

    # My scale doesn't send a response back?
    logging.debug('Syncing clock')
    timestamp = int((datetime.now() - datetime(2000, 1, 1)).total_seconds())
    await delegate.send(0x20, 0x08, timestamp.to_bytes(4, 'little'), wait_for_response=False)

    logging.debug('Reading weight data')

    while True:
        payload = await delegate.receive(0x10)

        weight_kg = int.from_bytes(payload[0:2], 'big') / 100
        is_stable = (payload[2] == 0x01)
        magic1 = int.from_bytes(payload[3:5], 'big')
        magic2 = int.from_bytes(payload[5:7], 'big')

        logging.debug('Received a weight measurement (stable=%r): %dkg %d? %d?', is_stable, weight_kg, magic1, magic2)

        if is_stable:
            break

    logging.debug('Disconnecting gracefully')
    await delegate.send(0x1f, 0x05, (0x10).to_bytes(4, 'little'), wait_for_response=False)

if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(main())
Perpetucake commented 5 years ago

The EPLIANS scale also uses the QN library/QN-Scale device name, paired with a copy-pasted app and I'd assume the multitude of Amazon listings with screenshots of the same app do too FWIW.

dockerss commented 5 years ago

@oliexdev have found another repo that has the code to get the weight - https://github.com/JackChan1999/boohee_v5.6/blob/master/src/main/java/com/kitnew/ble/QNDecoder.java. Basic experiments show that the weight returned is same using both codes. However other metrics are in a .so file as seen here https://github.com/JackChan1999/boohee_v5.6/blob/221f7ea237f491e2153039a42941a515493ba52c/src/main/java/com/kitnew/ble/QNCalc.java#L47 and also as seen in the decompiled fitindex app code. https://play.google.com/store/apps/details?id=com.qingniu.fitindex&hl=en_US Also the code supports all these devices - https://github.com/JackChan1999/boohee_v5.6/blob/221f7ea237f491e2153039a42941a515493ba52c/src/main/java/com/kitnew/ble/BleScanImpl.java#L27

dockerss commented 5 years ago

Yolanda The SDK code is available here with examples - https://github.com/YolandaQingniu/qn-ble-sdk-android/blob/master/README_en.md. @oliexdev is there a way to incorporate this SDK into OpenScale? Also found that bytes 6,7 and 8,9 return the resistances as per https://github.com/JackChan1999/boohee_v5.6/blob/221f7ea237f491e2153039a42941a515493ba52c/src/main/java/com/kitnew/ble/QNDecoder.java#L62

private void parseCustom1Data(byte[] data){ switch (data[0]) { case (byte) 16: { if (data[5] == (byte) 1) { float weight = decodeWeight(data[3], data[4]); System.out.println("Weight "+weight); if (weight > 0.0f) { int resistance1 = decodeIntegerValue (data[6], data[7]); int resistance2 = decodeIntegerValue(data[8], data[9]); System.out.println("resistance 1: "+ resistance1); System.out.println("resistance 2: "+ resistance2); } } default: return; } }

public static int decodeIntegerValue(byte a, byte b) {
    return ((a & 255) << 8) + (b & 255);
}

float decodeWeight(byte a, byte b) { return ((float) (((a & 255) << 8) + (b & 255))) / 100; }

This when used with https://github.com/oliexdev/openScale/blob/26159c296608311456a275bb21ce9d43c626fcf5/android_app/app/src/main/java/com/health/openscale/core/bluetooth/lib/TrisaBodyAnalyzeLib.java#L102 gives similar reading for bodyfat.

dockerss commented 5 years ago

Decompiled libyolanda_calc.so: https://onlinedisassembler.com/odaweb/VvkLVabS/0

dockerss commented 5 years ago

Quick and dirty translation and build of https://github.com/YolandaQingniu/sdk-android-demo at https://github.com/dockerss/sdk-android-demo and the APK is now at - https://github.com/dockerss/sdk-android-demo/blob/master/QNScaleDemo-1.0.apk

oliexdev commented 5 years ago

@dockerss please read https://www.gnu.org/licenses/gpl-faq.html#FSWithNFLibs https://www.gnu.org/licenses/gpl-faq.html#GPLIncompatibleLibs and https://f-droid.org/en/docs/Inclusion_Policy/

Jeyaseelan2528 commented 4 years ago

Hello All,

Does anyone know the formula's for all those measurements so that I can test by myself to be aware of the calculations...

tomfitzhenry commented 3 years ago

Another Bluetooth MAC address for an ES-CM20M: ED:67:38:5C:D2:94

huxley101 commented 3 years ago

The IOS sdk that contains a linkable library: https://github.com/YolandaQingniu/sdk-ios-demo/blob/master/QNSDK/SDK/libQNDeviceSDK.a is an ar archive which can be extracted and contains a file algorithm.o which might be useful to look at.

miyoyo commented 1 year ago

Sorry to dig this up, but I think I may have a bit more info about all of this

I've been disassembling the firmware of my Renpho R-A003 (PCB: COM202C1X) in order to decipher the wifi algorithm, which, while it does not use HTTPS, is encrypted (... with a key being renphorenpho6666 obviously.)

If anyone is curious, the format of that is: 2 Bytes to indicate the process 6 Bytes of the device's mac address Remaining bytes are encrypted AES ECB (no pad) with the mentionned key

While this was for wifi (not sure if this project supports that) I'll probably give a look to Bluetooth too

UserID?               : 01
Smth 2->8             : E6 07 0C 1A 0D 00 2B
Pad                   : 00 00 00 00 00 00 00
Smth 1->0      weight?: 1C C0
Pad                   : 00
Smth 10->9 resistnce1?: 01 F6
Pad                   : 00
Smth C->B  resistnce2?: 01 F4
Pad                   : 00
SmEl 4  16b           : 09 7E
Pad                   : 00 
SmEl 8  16b           : 08 DE
Pad                   : 00 
SmEl 38 16b           : 00 0A
Pad                   : 00 
SmEl 24 16b           : 16 3A
Pad                   : 00 
SmEl C  16b           : 07 EE
Pad                   : 00 
SmEl 10 16b           : 02 BC
Pad                   : 00 
SmEl 14 16b           : 15 CC
Pad                   : 00 
SmEl 1C 16b           : 13 7E
Pad                   : 00 
SmEl 2C 16b           : 15 22
Pad                   : 00 
SmEl 20 16b           : 01 18
Pad                   : 00 
SmEl 28 16b           : 06 E0
Pad                   : 00 
SmEl 18 16b           : 06 3F
Pad                   : 00 
SmEl 34 16b           : 08 98
Pad                   : 00 00 00 00 00 00 00
SmEl 30 16b           : 21 D4
Pad                   : 00 
Smth D  16b           : 00 00
Pad                   : 00 
0x3FFC9231            : 00 00
Pad                   : 00 
Pad                   : 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Pad                   : 00
UserID ?              : 03

I haven't decoded most of it, but this seems to be the data breakdown after looking at the assembly.

Here is how they are stored in the scale's memory for history purposes:

  Entry 9
  Bitmap State : Written
    Written Entry 9
      NS Index : 2
          NS : NVS_Record
      Type : BLOB_DATA
      Span : 14
      ChunkIndex : 0
      Key : RecordUser 9
      Blob Data :
        Size : 400 
        Data :
00000000: F7 1C E6 07 0C 1A 0C 10  1E F2 01 FB 01 00 9E 90  ................
00000010: A9 63 00 00 00 00 00 00  00 00 00 00 00 00 00 00  .c..............
00000020: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000030: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000040: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000050: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000060: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000070: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000080: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000090: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000000A0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000000B0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000000C0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000000D0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000000E0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
000000F0: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000100: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000110: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000120: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000130: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000140: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000150: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000160: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000170: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................
00000180: 00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  ................

These don't match up, as I recorded the URL part after dumping the rom, however the "E6 07" seems to be the same.

Aside from that, my scale sends modern standard bluetooth packets to my phone after sniffing, so it's possible modern (My firmware is from november 2021) devices don't require custom bullshit.