OpenPrepPad
Smart electronics and IoT (Internet of Things) are all the rage these days. You have a lot of companies sprout up trying to make the next big thing, which also leads to a lot of failures big and small. Pebble, the maker of my smartwatch, got bought out by Fitbit recently. This left watch owners without any official support, but thankfully, community members stepped up to continue maintaining it.
Another casualty of the IoT boom was the Orange Chef Prep Pad. It’s a bluetooth connected weighing scale to make it easy to track your calories and carb/fat/protein intake. My dad bought it last year only to find out that the app was incredibly buggy. The search function doesn’t work which makes the whole thing practically useless. I also found out later that you can’t even download the app to use the scale anymore.
Note I just found out as I was writing this post that it may get supported by another company.
So the app is useless, but at least you can use it as a scale, right?
Nope. The device has no display whatsoever. The only controls on it are the on/off button and a green LED that isn’t even that useful at telling you whether it’s on or not. At this point, it’s just a giant paperweight.
Reverse Engineering
Since I essentially had nothing to lose, I tried poking at the thing to figure
out how it works. I didn’t really have experience with bluetooth besides trying
to get my bluetooth mouse connected on Linux. The main thing I used then was
bluetoothctl
which is essentially a CLI for managing bluetooth devices so I
started there.
I started up bluetoothctl
and turned on the Prep Pad. And it showed up!
[bluetooth]# power on
[CHG] Controller ... Class: 0x00010c
Changing power on succeeded
[CHG] Controller ... Powered: yes
[bluetooth]# scan on
Discovery started
[CHG] Device 1C:BA:8C:21:7C:BB RSSI: -51
[CHG] Device 1C:BA:8C:21:7C:BB Name: CHSLEEV_00
[CHG] Device 1C:BA:8C:21:7C:BB Alias: CHSLEEV_00
I then connected to it, which was surprisingly easy.
[bluetooth]# connect 1C:BA:8C:21:7C:BB
Attempting to connect to 1C:BA:8C:21:7C:BB
[CHG] Device 1C:BA:8C:21:7C:BB Connected: yes
[CHG] Device 1C:BA:8C:21:7C:BB Name: CH BTScale_00
[CHG] Device 1C:BA:8C:21:7C:BB Alias: CH BTScale_00
Now normally, when you turn the device on, the green light flashes occasionally. Once I connected to it, the green light stayed on permanently. Clearly, I was making progress. A lot of services were also discovered but I had no idea what those things were at that point.
After a lot of poking around, I could check the general device information. You could get the hardware, software and firmware version. There’s also the device serial number which was nowhere on the actual physical device.
[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
[CH BTScale_00:/service0010/char0017]# attribute-info
Characteristic - Firmware Revision String
UUID: 00002a26-0000-1000-8000-00805f9b34fb
Service: /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010
Value: 0x31
Value: 0x2e
Value: 0x31
Value: 0x33
Value: 0x41
Value: 0x00
Flags: read
[CH BTScale_00:/service0010/char0017]# read
Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x2e
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x31
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x33
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x41
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0010/char0017 Value: 0x00
31 2e 31 33 41 00 1.13A.
[CH BTScale_00:/service0010/char0017]#
There was also a service which contained Accel Enable, Accel Range, Accel X-Coordinate, Accel Y-Coordinate, and Accel Z-Coordinate. I guess it stands for accelerometer, which is probably what it uses to weigh things.
[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
[CH BTScale_00:/service0023/char0024/desc0026]# read
Attempting to read /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x41
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x63
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x20
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x45
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6e
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x61
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x62
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x6c
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024/desc0026 Value: 0x65
41 63 63 65 6c 20 45 6e 61 62 6c 65 Accel Enable
I couldn’t read from any of the Accel Coordinates. It kept saying permission denied. I could however, notify on them. But that didn’t yield anything as well. What I could read was Accel Enable, which was set to 00. I guess that means it was off. After writing 01 to Accel Enable, I found I could get values out of Accel X-Coordinate! Also, the green LED which was permanently on turned off.
[CHSLEEV_00]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
[CH BTScale_00:/service0023/char0024]# write 01
Attempting to write /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char0024
[CH BTScale_00:/service0023/char0024]# select-attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a
[CH BTScale_00:/service0023/char002a]# notify on
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Notifying: yes
Notify started
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x5b
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x55
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x59
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0xa3
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x02
[CHG] Attribute /org/bluez/hci0/dev_1C_BA_8C_21_7C_BB/service0023/char002a Value: 0x00
I tried pressing the scale down a few times, and the values changed accordingly.
Now, I just had to figure out how to convert the values into grams. It looked
like the values were 32-bit integers sent as 4 bytes. In the above example it
would be 0x0002a35b
, 0x0002a355
, 0x0002a359
or 172891, 172855, 172899. The
values also decrease as you exert more effort on the scale. So assuming you take
the initial value as tare, you simply subtract any succeeding value from that
tare and you get the “weight”.
The values I got didn’t seem to be in grams though. After weighing some things on an actual scale and comparing the values I got, I found I can just divide the values by 14 and get something in grams. That 14 is entirely a magic number though and I have no idea whether other Prep Pad’s would have the same constant.
OpenPrepPad
With all that figured out, I went ahead and made a simple CLI application to interface with the Prep Pad. Ironically, node was the simplest thing I found that had nice bluetooth library support so that’s what I wrote it in. I also added most of the technical details in the README for that as well.
While this is all well and cool, I doubt the intersection of Linux users and people who got ripped off bought the Prep Pad is anyone besides me. In light of that, I’m in the process of making a React Native version of the app, but that’s still a work in progress. Who knows, if the new owners of Prep Pad are good, I might not even need to finish it.