DEV Community πŸ‘©β€πŸ’»πŸ‘¨β€πŸ’»

George Hertz
George Hertz

Posted on

Hacking BLE Kitchen Scale

TL;DR: Result

GitHub logo hertzg / metekcity

ETEKCITY smart nutrition scale protocol reverse engneering

Backstory

Recently I have been gaining weight and blaming it all on the COV-19 (jira issue).
So I thought I have to manage my food intake and count calories therefore I did what I do best, procrastinate and try to do other stuff while still thinking about the task at hand.
All of this + Amazon and my interest in IoT somehow convinced me to buy Etekcity Smart Nutrition Food Calorie Kitchen Digital Scale.

Having hard time waking next day after late night impulse buying, I tried the device, played a bit with the (meh) app and realized that this is just an overpriced kitchen scale with app function whose sole reason is data mining. After installing in VeSync app and skipping as much of the registration as possible and playing enough with it, I decided to try and somehow gain control of the device without having to use the (meh) app.

Disclaimer

Before I go into technical details I would like to mention that I have never worked with BLE devices before. Being armed with 0 technical knowledge of Bluetooth Low energy I was (not) equipped with all the knowledge I need and (definitely not) ready to start hacking.

Step 1: Take it apart πŸ› 

Having dabbled in some other IoT devices (ESP) my first instinct was to disassemble the device and try to find how this thing worked. I was hoping I could find the microcontroller name and model or some debug ports exposed and labeled but I was disappointed to see this.

Photograph of PCB inside with blobbed microcontroller

PCB was labeled here and there but it was not too helpful as they were just "component ids" to pick and place. The communications device had some information for me.

Photograph of BLE communication module with IC

The communications module is for Bluetooth 4 which is something that I can start investigating.

Step 2: Maybe there's a lib for it? πŸ₯Ί

Next step was to try to somehow find how to communicate to this and maybe someone else has already done some hacking πŸ’” on this but I was not able to find information for this device πŸ’” . The one of the projects that was relatable to this was oliexdev/openScale

GitHub logo oliexdev / openScale

Open-source weight and body metrics tracker, with support for Bluetooth scales

Β  openScale logo Β openScale Build Status Translation status

Open-source weight and body metrics tracker, with support for Bluetooth scales

Get it on F-Droid Get it on Google Play

Install openScale-dev-build.apk to get the latest development build generated by Travis CI. Also be aware that this version may contain bugs and you don't get any automatic updates.

Summary πŸ“‹

Monitor and track your weight, BMI, body fat, body water, muscle and other body metrics in an open source app that:

  • has an easy to use user interface with graphs,
  • supports various Bluetooth scales,
  • doesn't require you to create an account,
  • can be configured to only show the metrics you care about, and
  • respects your privacy and lets you decide what to do with your data.

Supported Bluetooth scales πŸš€

openScale has built-in support for a number of Bluetooth (BLE or "smart") scales from many manufacturers, e.g. Beurer, Sanitas, Yunmai, Xiaomi, etc. (see model list below). Together with our users we constantly improve and extend the set…

But it was only targeted towards body weight scales πŸ’”.

I was also able to find a github issue asking about this particular device and model and it was rejected for obvious reason πŸ’”.

Add Support for the ETEKCITY Bluetooth Scale #509

Hi it's great app. it works like a charm for almost all devices. Thanks for this great creation. recently i bought new weight measurement scale of ETEKCITY and it is not supported by this app.

https://www.etekcity.com/product/100334

here the debug log file attached with your debug app

openScale_2019-10-17_12-57.txt

More debug Log, openScale_2019-10-17_16-04_new.txt

Scale information Screenshot_20191017-184936

Let me know if the above is sufficient or should I need to give more.

Thank you.

Step 3: Down the rabbit hole 🐰

I love JS and Node.JS and I felt confident (for some weird reason) in worst case scenario I could use some linux tools with child_process or even hack something in C to communicate using BLE (via USB). It was already getting late and I was getting delirious :D .

Now I'm here and I want to be able to at least get the measurements read. I quickly googled up a module for node which was a good start.

GitHub logo noble / noble

A Node.js BLE (Bluetooth Low Energy) central module

noble

Build Status Gitter OpenCollective OpenCollective

A Node.js BLE (Bluetooth Low Energy) central module.

Want to implement a peripheral? Checkout bleno

Note: macOS / Mac OS X, Linux, FreeBSD and Windows are currently the only supported OSes. Other platforms may be developed later on.

Prerequisites

OS X

Linux

  • Kernel version 3.6 or above
  • libbluetooth-dev

Ubuntu/Debian/Raspbian

sudo apt-get install bluetooth bluez libbluetooth-dev libudev-dev
Enter fullscreen mode Exit fullscreen mode

Make sure node is on your path, if it's not, some options:

Fedora / Other-RPM based

sudo yum install bluez bluez-libs bluez-libs-devel
Enter fullscreen mode Exit fullscreen mode

Intel Edison

See Configure Intel Edison for Bluetooth LE (Smart) Development

FreeBSD

Make sure you have GNU Make:

sudo pkg install gmake
Enter fullscreen mode Exit fullscreen mode

Disable automatic loading of the default Bluetooth stack by putting no-ubt.conf into /usr/local/etc/devd/no-ubt.conf and restarting devd (sudo service devd restart).

Unload ng_ubt kernel module if already loaded:

sudo kldunload ng_ubt
Enter fullscreen mode Exit fullscreen mode

…

And starting hacking away and logging output. With some luck and more luck I was able to guess the correct service, characteristic and ended up with some notes where I could start looking at the protocol.

And around 4 am in the morning finished writing the README and finally tired enough to just go to bed and rest.

GitHub logo hertzg / metekcity

ETEKCITY smart nutrition scale protocol reverse engneering

Build Status codecov

ETEKCITY Smart Nutrition Scale

⚠️ Very much work in progress ⚠️

This is a potential project that tries to reverse engineer the BLE protocol that ETEKCITY Smart Nutrition Scale (ESN00) uses.

ETEKCITY Smart Nutrition Scale (ESN00) (DE | US)

BLE Protocol

This section describes the protocol (what was researched so far)

Finding device

Device address is random so the way to find it is based on the advertisement name (tested) or manufacturer data (not tested) Device reports weight and status on service 1801 and characteristic 2c12.

Protocol

All packets have this structure

Data Packets

Data packet depends on the packet type values:

Name Value Length When What
Error E0 1 byte Error mode is triggered or reset 0x00 (error reset) / 0x01 (error triggered)
Tare D3 1 byte Tare is updated (set) or reset 0x00 (no tare) / 0x01 (tare mode)
Item E4 1 byte Item is
…

Next steps

I would like to write (at least half-) decent library to listen and possibly control the big display with nutritional information from outside the app. For now I need an Android device to sniff the packets and analyze the result.

I actually do not know which device to choose so maybe one late night I will pick a random cheap Android phone and invest more in my procrastination or maybe someone will tell me in comments which one to go for Β―\_(ツ)_/Β― .

The end goal would (probably) be to have it integrate with homebridge or home-assistant and have it comfortably enable the nutritional value display based on voice commands.

Top comments (11)

Collapse
wilsonsilva profile image
Wilson Silva

I have the exact same need as yours. The scale has a nice design, it is easy to clean and has a useful LCD display. But the app doesn't let me access MY data, search for food using a food database or use a barcode scanner.

At some point I thought that the only way to fulfil my needs was to make my own scale using a Raspberry PI or an Arduino. But reverse engineering seemed way easier.

Thanks for the amazing work!

Collapse
hertzg profile image
George Hertz Author

I'm glad you found this useful, I have ordered an android phone and dumped some more packets to progress futhter you can see the packets and a wireshark dissector code in the repository research folder. Next step for me would be to write a lib and a small cli tool right now :)

Collapse
madmod profile image
John Wells

@hertzg I'm trying to use this scale to prototype an automated ingredient mixer. Could you please share your code to connect to the scale? I tried making a simple discover script with @abandonware/noble but wasn't able to find it. (Maybe that just doesn't work on M1 macs?)

Collapse
hertzg profile image
George Hertz Author

Hey! Glad you found this interesting, I've just recently refactored and pushed demo code to run it directly in your browser. You might need to enable some flags in chrome but should work without it. You can always create a pr or issue on github to further address certain topics :)

Collapse
shaunhurley profile image
Shaun Hurley

Looks like a great start, am interested in how this develops. Found myself in a similar situation, have one of these scales, but it (the app) doesn't address a key need - I make the same (or similar) foods regularly - my lunch salad, for example - but it varies a little day to day depending on what is in the fridge. I don't want to store static, once-and-done recipes, I want to save the recipe as a 'template' and then queue up the ingredients each time I make it, based on the stored template, then step though each ingredient (as in, accepting a weight with a tap/click automatically jumps to the next ingredient/line) grabbing the current weights, and have the current nutrition pop out at the end (with bonus points for submitting to through the Fitbit API :). And, of course, their food database sucks :)

Was looking at playing with some Arduino based stuff, but it's wired USB based (until/unless I figure out adding in a BLE module) and then I came across your writeup :)

I know you said you are getting an Android device for some planned wok, but would you mind sharing the hardware stack you are / have been using to date? As in, Windows / OSX / Linux, etc?

Collapse
hertzg profile image
George Hertz Author

Glad you found this (somewhat) useful 😊 , so far I managed to borrow an the Android device from a friend and managed to take dumps of data that was being sent over the network. As well as tried to disassemble the Android .apk to get a glimpse of the packing/compression algorithm.

The current status is that the project is on-hold because I've exhausted the samples of data I have and I no longer have access to an Android device to make more snapshots/samples.

In terms of the hardware stack, for development I was mainly using Linux (Ubuntu) on my personal laptop. To take the samples I (had to) use Windows (due to drivers of the specific phone model) and adb + wireshark to snoop on the bluetooth traffic between the phone and the scale.
For testing the written code I used linux and noble npm package to communicate with the BLE scale while utilising the library I wrote to pack and unpack packets.

For the final use case I got a raspberry pi with bluetooth + bluez to manage BLE GATT protocol. Placed the whole thing in the kitchen (where the scale is) and it constantly scans for the scales MAC and GATT ID's, once it finds it, tries to connect and sends the measurements to my local MQTT broker from where I deal with the data.

So far the whole setup is kind of "listen only" mode because I never got time to take snapshots of the "SET_NUTRITION" packets to understand how they are packed.

Collapse
mike_hatfield_bf922d43339 profile image
Mike hatfield

Wow! Nice work. I’m looking to add this device to my homebridge running on rpi to so it can warm up my kettle in the morning. Need it to follow my espresso machine on/off schedule with a slight delay so it doesn’t draw too many amps from same outlet and trip my breaker.

Eventually would like to read temp of scale and use it to stop my espresso shot at designated weight. I already installed a Shelly switch in espresso machine so that is hooked up to homebridge and apple HomeKit.

Any luck sending commands to turn it on/off?

Collapse
hertzg profile image
George Hertz Author

Connecting to its BLE (GATT) service causes it to turn on, have you tried doing that? Not sure how that would affect the initial calibration weighting though

Collapse
dbirkhead profile image
dbirkhead • Edited on

Have a headache myself with a client who commissioned an app and wants to add a scale for users to weigh things for the app to read. It seems we can’t just use any Bluetooth scale for that?

Has anyone ID’d any β€œoff the shelf” kitchen scales that may be fit for this purpose as of yet?

Watching closely as I have a real and urgent need for this.

Collapse
niklampe profile image
Nik • Edited on

Hey George, impressive work so far.

Last night I had a similar idea. I wanted to write my own App to read the scale values of a renpho kitchen scale as the app is.. well, not good. :D

But the advertised services and their characteristics unfortunately didn't lead to anything. Found something, but there seem to be no values transmitted.

You wrote, that "With some luck and more luck I was able to guess the correct service, characteristic and ended up with some notes where I could start looking at the protocol."

How did you start the guessing? Were the services and characteristics you found not advertised by the peripheral?

Collapse
hertzg profile image
George Hertz Author

The easiest way would be to use the official app and somehow sniff the data. In one of the comments I've described how I've done this. Easiest way would be to use an Android device, adb and wireshark to sniff the bluetooth traffic. Next step would be to disassemble the apk which might give you more hints, like strings and constants and maybe a glimpse of how it serializes/marshals the data. Hope this helps a bit.

🌚 Friends don't let friends browse without dark mode.

Sorry, it's true.