hertzg / metekcity Goto Github PK
View Code? Open in Web Editor NEWETEKCITY smart nutrition scale protocol reverse engneering
License: MIT License
ETEKCITY smart nutrition scale protocol reverse engneering
License: MIT License
So far the notes.txt
contains samples saved during research, this issue tries to collect the status of implementation of each packet type. Some of them might need their own issue but here they are represented all togeather.
SET_UNIT
(0xc0
) - c5736b4, - #2SET_TARE
(0xc1
) - #2SET_AUTO_OFF
(0xc4
) - 805a076, #2MEASUREMENT
(0xd0
) - bfcf5dfUNIT_STATE
(0xd1
) - #5TARE_STATE
(0xd3
) - bfcf5df, #3AUTO_OFF_STATE
(0xd5
) - #2ERROR_STATE
(0xe0
) - bfcf5df, #3ITEM_STATE
(0xe4
) - bfcf5df, #3SET_NUTRITION
(0xc2
)?PING
(0xc3
)???
(0xd2
)?PONG
(0xd4
)???
(0xe1
)???
(0xe2
)???
(0xe3
)Status | Type | Source(s) | Payload | Generic? | Notes |
---|---|---|---|---|---|
✅ | SET_UNIT |
COMMAND |
unit |
uint8Parselizer |
|
✅ | SET_TARE |
COMMAND |
shouldReset |
booleanParselizer |
|
✅ | SET_AUTO_OFF |
COMMAND |
timeout |
uint8Parselizer |
|
✅ | MEASUREMENT |
NOTIFY |
sign , value , unit |
uint8Parselizer |
|
✅ | TARE_STATE |
NOTIFY |
isOn |
booleanParselizer (inverted) |
|
✅ | AUTO_OFF_STATE |
NOTIFY |
timeout |
uint16Parselizer |
the value is the same as for command with the exception of extra 0 byte |
✅ | ERROR_STATE |
NOTIFY |
isOn |
booleanParselizer (inverted) |
|
✅ | ITEM_STATE |
NOTIFY |
isOn |
booleanParselizer (inverted) |
|
✅ | UNIT_STATE |
NOTIFY |
unit |
uint8Parselizer |
|
🛑 | SET_NUTRITION |
COMMAND |
(complex object) | need more samples to understad how data is encoded |
Marker | Category | Description |
---|---|---|
⌛ | Status | Waiting (todo) |
🛑 | Status | Blocked |
✅ | Status | Done |
COMMAND |
Source(s) | Command send to the Device |
NOTIFY |
Source(s) | Notification received from the Device |
I bought this scale on Amazon last week. The data on mine does not match up to the research here. I don't know if I'll open a PR here for some of the documentation, or just link to a new repo with my test data.
I've so far been doing the detection and parsing in Swift, so it wouldn't be a drop in replacement.
Of note: the services are different and the UInt8 data array has a different length and position of values than what I see in the packet package here.
Thanks for the inspiration in this repo! It really help bootstrap me and where to look in the array for the various values and to combine the two UInt8 values for a single UInt16 for the weight value.
some information on readme is out of date or incorrect, update readme with latest updates and findings
I do not have enough samples to understands this packet.
Having enough samples showing:
would (probably) help understand:
It would be great if someone can provide that information using an Android phone (I no longer have one).
This can be done using adb
and wireshark if anyone is willing to provide samples I can write up a guide how to do it.
I just bought one of these scales off of Amazon, and the data lines up perfectly.
I have never connected it to the app, so my theory is it cannot pull down new firmware.
I have written this code in Python to put nutrition info on the display, but nothing happens.
I am using Windows 10 and Bleak for Bluetooth, which is cross-platform. The check digit is also
correct, converted from TypeScript to Python. I am wondering what I did wrong to not get a result.
Here is my code
`import asyncio
from bleak import BleakClient # for bluetooh install with: pip install bleak
import struct
HEADER = bytearray(b"\xfe\xef\xc0\xa2") # Replace with your header bytes
def uint8(value):
return value & 0xff
def calculateChecksum(buffer, prevSum=0):
uint8_buffer = bytearray(buffer)
return sum(uint8_buffer, prevSum) & 0xff
def uint8ArrayBufferAppend(buffer, data, offset=0):
buffer[offset: offset + len(data)] = data
return offset + len(data)
def makePacket(header, type, payload, payloadLength=None, checksum=None):
# packet = header + type (1 byte) + length (1 byte) + payload + checksum (1 byte)
packetLength = len(header) + 3 + len(payload)
buffer = bytearray(packetLength)
cursor = 0
# header
cursor = uint8ArrayBufferAppend(buffer, header, cursor)
checksumOffset = cursor
# type (1 byte) + length (1 byte)
cursor = uint8ArrayBufferAppend(buffer, [uint8(type), uint8(payloadLength)] if payloadLength is not None else [uint8(type)], cursor)
# payload
cursor = uint8ArrayBufferAppend(buffer, payload, cursor)
checksumData = buffer[checksumOffset: cursor]
# checksum (1 byte)
uint8ArrayBufferAppend(buffer, [uint8(checksum)] if checksum is not None else [uint8(calculateChecksum(checksumData))], cursor)
return buffer
def create_set_nutrition_payload(calories, calories_from_fat, total_fat, saturated_fat, trans_fat,
cholesterol, sodium, potassium, total_carbs, dietary_fiber,
sugars, protein):
payload = bytearray(36)
# Set the nutrition data fields
fields = [calories, calories_from_fat, total_fat, saturated_fat, trans_fat,
cholesterol, sodium, potassium, total_carbs, dietary_fiber,
sugars, protein]
for i in range(len(fields)):
value = int(fields[i] * 10) # Multiply by 10 to match the scale's format
payload[i * 3: 3 + i * 3] = struct.pack('>H', value)
return payload
async def run():
# Replace "Device Name" and "Device Address" with the name and address of your Bluetooth device
async with BleakClient("xx:xx:xx:xx:xx:xx") as client: # Your device mac adrr
header = HEADER
packet_type = 0xc2
header = HEADER
packet_type = 0xc2
calories = 1500
calories_from_fat = 200
total_fat = 15
saturated_fat = 7
trans_fat = 0
cholesterol = 100
sodium = 2000
potassium = 300
total_carbs = 50
dietary_fiber = 10
sugars = 40
protein = 20
payload = create_set_nutrition_payload(calories, calories_from_fat, total_fat, saturated_fat, trans_fat,
cholesterol, sodium, potassium, total_carbs, dietary_fiber,
sugars, protein)
payload_length = len(payload)
packet = makePacket(header, int(packet_type), payload, payload_length)
print(packet)
await client.write_gatt_char("00002c11-0000-1000-8000-00805f9b34fb", packet, True)
exit()
while True:
await asyncio.sleep(1)
if name == "main":
asyncio.run(run())
`
Any help into what I am not doing correctly would be amazing.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.