So I fixed the battery command, turns out my `make_packet` command was wrong. My packet was 15 chars long and I would copy the sub data bytearray to a slice that was one shorter than it, as long as there were at least 2 elements in the array. If it was empty, I ended up with a 15 byte packet that the ring just ignored. ```python def make_packet(command_key: int, sub_data: bytearray|None = None) -> bytearray: packet = bytearray(16) packet[0] = command_key if sub_data: assert len(sub_data) <= 14 for i in range(len(sub_data)): packet[i + 1] = sub_data[i] packet[-1] = crc(packet) return packet ``` This one works now and has an optional sub_data param! Trying to get steps now, so I'm reading through `StepDetailRepository` (someone knows some design patterns). There's a `ReadSportDataReq` called from `syncTodayStepDetail`. It sends a packet of `CMD_GET_STEP_SOMEDAY_DETAIL = 67`, which is promising and includes a "day offset", which must be less than 29 ```java public ReadDetailSportDataReq(int i, int i2, int i3) { super(Constants.CMD_GET_STEP_SOMEDAY_DETAIL); if (i > 29) { throw new IllegalArgumentException("dayOffset 最大只到29"); } if (i2 > i3 || i3 > 95) { throw new IllegalArgumentException("数据段索引值异常"); } this.data = new byte[]{(byte) i, 15, (byte) i2, (byte) i3, 1}; } ``` `最大只到29` translates to `Maximum is 29` and `数据段索引值异常` is `Abnormal data segment index value`. It seems like `i2` = 0 and `i3 = 95` in syncTodayStepDetail and syncDeviceStepDetail. It looks like first value is also `0` Sent `GET_TODAY_STEPS_PACKET = make_packet(CMD_GET_STEP_SOMEDAY, bytearray(b'\x00\x00\x5f'))` Got back `bytearray(b'C\xff\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00B')`` Seems like `\xff` is some kind of "reset" maybe to indicate an empty period or something?