Runstar R6: derive body composition from the reported impedance - #1535
Merged
oliexdev merged 1 commit intoSep 21, 2026
Merged
Conversation
The R6 reports whole-body impedance in its 0xA3 result frame, but the handler only stored the raw value, so openScale showed weight, BMI and heart rate and nothing else. Feed the impedance into StandardImpedanceLib to derive fat, water, skeletal muscle, bone mass, LBM and BMR, the same way VitafitVT701Handler and EtekcityESF551Handler do for their weight-plus-impedance-only scales. Readings outside 200-1200 Ohm, and users with no body height set, are skipped with a warning instead of being turned into fabricated numbers. The raw impedance is stored either way, so a later recompute stays possible. Two robustness gaps in the same frame handlers, for consistency with the rest of the package: - 0xA4 history timestamps came off the scale's own clock and were used unchecked, so an unset clock produced a measurement dated 1970. Guard them like AfuB1Handler and YunmaiHandler do, falling back to the current time. Rejecting the entry outright, as MiScaleHandler does, is wrong here: acking retires it on the scale, so a rejected reading is lost for good. - The 0xA3 status byte was documented but never read. Log a non-zero status instead of discarding the weigh-in, since its values have never been observed and guessing at them could drop valid measurements. The 0xA3 field extraction moves into a pure decodeFinalResult() in the companion object so it can be unit tested without a BLE stack, mirroring VitafitVT701Handler.parseStableWeightRaw. Also drops the write-only lastLockedWeightKg field. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Owner
|
Thanks for your PR 👍 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Runstar R6 reports whole-body impedance in its 0xA3 result frame, but
the handler added in #1432 only stored the raw value. Since the IMPEDANCE
measurement type is internal and disabled, and DerivedValuesCalculator
does not read it, users saw weight, BMI and heart rate and nothing else.
This feeds the impedance into StandardImpedanceLib to derive body fat,
water, skeletal muscle, bone mass, LBM and BMR, following the pattern
VitafitVT701Handler and EtekcityESF551Handler already use for their
weight-plus-impedance-only scales.
Measured impedance on a physical R6 is 533-605 Ohm across eight weigh-ins,
within the range StandardImpedanceLib documents its formulas for. Readings
outside 200-1200 Ohm, and users with no body height set, are skipped with
a warning rather than producing made-up values; the raw impedance is
stored regardless.
Also fixes two robustness gaps in the same handler:
produced measurements dated 1970. Now guarded like AfuB1Handler and
YunmaiHandler, falling back to the current time rather than dropping
the entry — acking retires it on the scale, so a rejected reading
cannot be recovered.
now logged rather than used to discard the weigh-in; its values have
never been observed in any capture.
Verification:
against hand-built frames, including malformed, wrong-type,
wrong-length and non-zero-status input.
(
F3 08 00 A3 00 01 03 2E 4B 02 45 ...-> 66.35 kg, 75 bpm, 581 Ohm).app after a weigh-in.
🤖 Generated with Claude Code