Skip to content

Added impedance support for Huawei AH/CH 100 - #1497

Open
D-Voi wants to merge 5 commits into
oliexdev:masterfrom
D-Voi:master
Open

Added impedance support for Huawei AH/CH 100#1497
D-Voi wants to merge 5 commits into
oliexdev:masterfrom
D-Voi:master

Conversation

@D-Voi

@D-Voi D-Voi commented Aug 28, 2026

Copy link
Copy Markdown

Enabled the impedance reading in the handler and added all the fields that derive from the impedance. Tested the changes in my phone with HUAWEI AH100 and they work. Please let me know if these changes make it into the play store app by emailing me in: voikiaetsi@gmail.com

Enabled the impedance reading in the handler and added all the fields that derive from the impedance. Tested the changes in my phone with HUAWEI AH100 and they work. Please let me know if these changes make it into the play store app by emailing me in: voikiaetsi@gmail.com
Copilot AI lite review requested due to automatic review settings August 28, 2026 20:12

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new impedance-derived calculations need additional input validation/guarding (e.g., unset/invalid user height/age and sane impedance range) to avoid publishing nonsensical derived values.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR enables impedance handling for Huawei AH/CH 100 measurements and derives additional body-composition fields from impedance using the shared StandardImpedanceLib, integrating those computed values into published ScaleMeasurements.

Changes:

  • Passes ScaleUser through the decode/publish pipeline so impedance-derived metrics can be calculated with user profile data.
  • When impedance is present, computes and populates water, muscle, bone, bmr, and lbm via StandardImpedanceLib.
File summaries
File Description
android_app/app/src/main/java/com/health/openscale/core/bluetooth/scales/HuaweiAhCh100Handler.kt Wires impedance into measurement publishing and derives additional metrics from impedance using StandardImpedanceLib.
Review details

Suppressed comments (1)

android_app/app/src/main/java/com/health/openscale/core/bluetooth/scales/HuaweiAhCh100Handler.kt:346

  • This change introduces new impedance-derived fields (water/muscle/bone/bmr/lbm) in the Huawei handler, but the existing HuaweiAhCh100HandlerTest suite only exercises the wire-protocol primitives and doesn't cover the derived body-composition mapping. Adding a small unit test for the new mapping/guards would help prevent regressions (e.g., invalid height/age or out-of-range impedance producing implausible values).
                val lib = StandardImpedanceLib(
                    gender = user.gender,
                    age = user.age,
                    weightKg = m.weightKg.toDouble(),
                    heightM = user.bodyHeight / 100.0,
                    impedance = m.impedanceOhm.toDouble(),
                )
                this.water = lib.totalBodyWaterPercentage.toFloat()
                this.muscle = lib.skeletalMusclePercentage.toFloat()
                this.bone = lib.boneMassKg.toFloat()
                this.bmr = lib.basalMetabolicRate.toFloat()
                this.lbm = lib.fatFreeMassKg.toFloat()
  • Files reviewed: 1/1 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new impedance-derived calculation path should guard against zero/invalid weight to avoid producing Infinity/NaN values (and there’s also a small lint-risk whitespace-only line).

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment on lines 331 to 333
this.fat = m.fatPct
// The scale reports impedance but the v2.5.4 reference doesn't
// derive water/muscle/bone from it; openScale's existing
// StandardImpedanceLib can be wired in later for that.

if (m.impedanceOhm in 1..3999) {
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

A published measurement’s userId is still set from the scale’s on-wire slot ID instead of the app user ID, which can misattribute data to the wrong user.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 1/1 changed files
  • Comments generated: 2
  • Review effort level: Lite

Comment on lines +345 to +349
this.water = lib.totalBodyWaterPercentage.toFloat()
this.muscle = lib.skeletalMusclePercentage.toFloat()
this.bone = lib.boneMassKg.toFloat()
this.bmr = lib.basalMetabolicRate.toFloat()
this.lbm = lib.fatFreeMassKg.toFloat()

val sm = ScaleMeasurement().apply {
this.userId = m.userId
this.dateTime = m.dateTime ?: Date()
@oliexdev

Copy link
Copy Markdown
Owner

Thanks for wiring StandardImpedanceLib into the AH/CH100 handler.

Before we look at the code: do the derived values match reality on your device?

StandardImpedanceLib's doc comment says the formulas only hold for whole-body impedance around 500 ± 100 Ω, and warns against using the class for scales reporting e.g. 250 or
800 Ω. Your 1..3999 window suggests we don't yet know what the AH100 really sends.

From two or three weigh-ins, could you post:

  • the raw impedance from the log line (impedance=… Ω)
  • what Huawei Health shows for fat, water, muscle and bone
  • what openScale shows with this patch

If it's close, this is good to go. If it's far off, better to store nothing than wrong values — people track these over months.

Two things for a later round:

  • The last commit reverted the heightM > 0.0 && user.age > 0 && m.weightKg > 0f guard from commits 2 and 3. That should come back — ScaleUser.bodyHeight defaults to -1f.
  • fat stays the scale's value while lbm comes from the library, so the two contradict each other. See PicoocHandler.kt:341-352 for how to mix them.

On your question from the first commit message: releases go to both F-Droid and Play Store, so this lands there once merged — GitHub will notify you, no email needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants