From cd9c1bd1d2bc607dadf5e62519452fb157208dd8 Mon Sep 17 00:00:00 2001 From: Riedel-David <48388362+Riedel-David@users.noreply.github.com> Date: Wed, 21 Oct 2026 23:59:54 +0300 Subject: [PATCH 1/2] Mi scales: read the 7-byte history count the XMTZC05HM sends The Mi Body Composition Scale 2 answers a history request with 01 , 7 bytes. miScaleHistoryCount only accepted 3, so the count read as null and the stored records were never requested. Captured from a real XMTZC05HM. --- lib/src/miscale.dart | 8 ++++++-- test/thermometer_scale_test.dart | 3 +++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/lib/src/miscale.dart b/lib/src/miscale.dart index ab2e47a..3bbbccd 100644 --- a/lib/src/miscale.dart +++ b/lib/src/miscale.dart @@ -144,9 +144,13 @@ List miScaleHistoryRequest(int userId) => [ (userId >> 24) & 0xff, ]; -/// The record count in the scale's `01 ` answer, or null. +/// The record count in the scale's `01 ` answer, or null. The +/// Mi Body Composition Scale 2 (XMTZC05HM) answers with 7 bytes: the same +/// three, then the requested user id (u32 LE) echoed back. int? miScaleHistoryCount(List b) => - b.length == 3 && b[0] == 0x01 ? b[1] | (b[2] << 8) : null; + (b.length == 3 || b.length == 7) && b[0] == 0x01 + ? b[1] | (b[2] << 8) + : null; const List kMiScaleHistorySend = [0x02]; diff --git a/test/thermometer_scale_test.dart b/test/thermometer_scale_test.dart index b90ea3d..a9b9304 100644 --- a/test/thermometer_scale_test.dart +++ b/test/thermometer_scale_test.dart @@ -141,6 +141,9 @@ void main() { expect(miScaleHistoryRequest(0x01020304), [1, 4, 3, 2, 1]); expect(miScaleHistoryCount([0x01, 0x02, 0x01]), 258); expect(miScaleHistoryCount([0x01, 0x02]), isNull); + // Captured from a real XMTZC05HM: count 2, user id 1 echoed. + expect(miScaleHistoryCount([1, 2, 0, 1, 0, 0, 0]), 2); + expect(miScaleHistoryCount([1, 2, 0, 1, 0]), isNull); expect(miScaleHistoryDone([0x03]), isTrue); expect(miScaleHistoryDone([]), isTrue); expect(miScaleHistoryDone([0x03, 0]), isFalse); From f5d1a9d3548b6f99eda243cff9e6906f110ec5a4 Mon Sep 17 00:00:00 2001 From: Riedel-David <48388362+Riedel-David@users.noreply.github.com> Date: Thu, 22 Oct 2026 00:08:55 +0300 Subject: [PATCH 2/2] Mi scales: document the 7-byte count reply, test more counts The four bytes after the count were seen as 01 00 00 00 after a request for user 1. That they are the user id is not established, so say so instead of validating them. Add the 3 and 4 counts captured from the scale, and describe the variant in the stored-history overview. --- lib/src/miscale.dart | 7 +++++-- test/thermometer_scale_test.dart | 4 +++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/src/miscale.dart b/lib/src/miscale.dart index 3bbbccd..696633d 100644 --- a/lib/src/miscale.dart +++ b/lib/src/miscale.dart @@ -25,7 +25,9 @@ // // STORED HISTORY (both scales) — on [kMiScaleHistoryChar], notify + write: // host `01 ` how many records for this user -// scale `01 ` +// scale `01 ` (the XMTZC05HM appends four more bytes, +// seen as `01 00 00 00` after a request for +// user 1; their meaning is not established) // host `02` send them (skipped when count is 0) // scale records: 10-byte Scale 2 records, or 13-byte frames laid out as // 0x2A9C on the composition scale; a notification of one byte or @@ -146,7 +148,8 @@ List miScaleHistoryRequest(int userId) => [ /// The record count in the scale's `01 ` answer, or null. The /// Mi Body Composition Scale 2 (XMTZC05HM) answers with 7 bytes: the same -/// three, then the requested user id (u32 LE) echoed back. +/// three, then four more (seen as `01 00 00 00` after a request for user 1; +/// whether that is the user id is not established, so it is not validated). int? miScaleHistoryCount(List b) => (b.length == 3 || b.length == 7) && b[0] == 0x01 ? b[1] | (b[2] << 8) diff --git a/test/thermometer_scale_test.dart b/test/thermometer_scale_test.dart index a9b9304..86904f4 100644 --- a/test/thermometer_scale_test.dart +++ b/test/thermometer_scale_test.dart @@ -141,8 +141,10 @@ void main() { expect(miScaleHistoryRequest(0x01020304), [1, 4, 3, 2, 1]); expect(miScaleHistoryCount([0x01, 0x02, 0x01]), 258); expect(miScaleHistoryCount([0x01, 0x02]), isNull); - // Captured from a real XMTZC05HM: count 2, user id 1 echoed. + // Captured from a real XMTZC05HM: counts 2, 3 and 4 (tail 01 00 00 00). expect(miScaleHistoryCount([1, 2, 0, 1, 0, 0, 0]), 2); + expect(miScaleHistoryCount([1, 3, 0, 1, 0, 0, 0]), 3); + expect(miScaleHistoryCount([1, 4, 0, 1, 0, 0, 0]), 4); expect(miScaleHistoryCount([1, 2, 0, 1, 0]), isNull); expect(miScaleHistoryDone([0x03]), isTrue); expect(miScaleHistoryDone([]), isTrue);