hertzg / metekcity

ETEKCITY smart nutrition scale protocol reverse engneering
MIT License
15 stars 8 forks source link

Trouble Understading Nutrition Info Packet #255

Closed CmdOffical closed 1 year ago

CmdOffical commented 1 year ago

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.

hertzg commented 1 year ago

Does this comment help?

https://github.com/hertzg/metekcity/issues/33#issuecomment-1042559311