From ffd846069b52e876be541b80b6e5115e462bd1ca Mon Sep 17 00:00:00 2001 From: David Riedel <48388362+Riedel-David@users.noreply.github.com> Date: Thu, 22 Oct 2026 00:20:36 +0300 Subject: [PATCH] Mi Body Composition Scale 2: pin the real 7-byte history count reply The XMTZC05HM answers the history request with 7 bytes, not 3. The composition history test now sends that reply, so it fails on a protocol that cannot read it. Mark the composition scale as verified on hardware; the Mi Smart Scale 2 stays experimental. Needs the openstrap_protocol pin bumped to a commit containing OpenStrap/protocol#81. --- lib/ble/adapters/_registry.dart | 4 ++-- lib/ble/adapters/miscale.dart | 4 +++- test/adapters/miscale_test.dart | 4 +++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/lib/ble/adapters/_registry.dart b/lib/ble/adapters/_registry.dart index beeef00f0..b7f7c3e29 100644 --- a/lib/ble/adapters/_registry.dart +++ b/lib/ble/adapters/_registry.dart @@ -979,8 +979,8 @@ bool _looksLikeThermometer(String lowercaseName) => /// OS-level service filter does not match, so it is also named there /// ([BandEntry.scanServiceData]). /// -/// EXPERIMENTAL (ASSUMPTIONS R6). Weight becomes a `weight` observation and -/// impedance a vendor observation. With its developer flag on (default off) +/// Verified on a physical Mi Body Composition Scale 2 (XMTZC05HM). Weight +/// becomes a `weight` observation and impedance a vendor observation. With its developer flag on (default off) /// the newest weight within 10% of the profile's becomes it /// (`newestWeighing`); impedance /// stays a measurement only. diff --git a/lib/ble/adapters/miscale.dart b/lib/ble/adapters/miscale.dart index 74e19e1fa..201475457 100644 --- a/lib/ble/adapters/miscale.dart +++ b/lib/ble/adapters/miscale.dart @@ -23,7 +23,9 @@ // impedance are shown attributed; with the scale's flag on, a weighing near // the profile's weight becomes it (`measurement_inputs.dart`). // -// EXPERIMENTAL (ASSUMPTIONS R6): nobody on this project owns one. +// The Mi Body Composition Scale 2 (XMTZC05HM) is verified on a physical unit: +// pairing, stored history and live weight with impedance. The Mi Smart Scale 2 +// is still EXPERIMENTAL (ASSUMPTIONS R6): nobody on this project owns one. import 'dart:async'; import 'dart:typed_data'; diff --git a/test/adapters/miscale_test.dart b/test/adapters/miscale_test.dart index 9ef504b39..1df7cab6a 100644 --- a/test/adapters/miscale_test.dart +++ b/test/adapters/miscale_test.dart @@ -151,7 +151,9 @@ void main() { final (rows, link) = await _drive( kMiScaleComposition, reply: (u, v) => switch ((u == kMiScaleHistoryChar, v.first)) { - (true, 0x01) => [(kMiScaleHistoryChar, [0x01, 2, 0])], + // The XMTZC05HM's real count reply is 7 bytes (captured on hardware); + // weights and stamps below are made up. + (true, 0x01) => [(kMiScaleHistoryChar, [0x01, 2, 0, 1, 0, 0, 0])], (true, 0x02) => [ (kMiScaleHistoryChar, [ ..._bc(0x22, 480, 14000, DateTime.utc(2026, 10, 2, 7)),