Skip to content

Body Composition

BLE Scale Sync calculates 10 body composition metrics from your scale's weight and impedance readings, combined with your user profile (height, age, gender).

Impedance is the electrical resistance measured when a small current passes through your body via the scale's electrodes (the metal pads you stand on). It's the key input for calculating body fat, muscle mass, water, and bone mass.

Exported Metrics

MetricUnitDescription
Weightkg / lbsRaw scale reading (configurable via weight_unit)
BMI(none)Body Mass Index
Body Fat%BIA-based (requires impedance) or Deurenberg fallback
Water%Total body water percentage
Bone Masskg / lbsEstimated bone mineral content
Muscle Masskg / lbsSkeletal muscle mass
Visceral Fat1-59Internal organ fat rating
BMRkcalBasal Metabolic Rate
Metabolic AgeyearsMetabolic age relative to BMR
Physique Rating1-9Body type classification based on fat % and muscle ratio

How It Works

Body fat (BIA)

When impedance is available, body fat is calculated using Bioelectrical Impedance Analysis:

LBM = c1 * (height² / impedance) + c2 * weight + c3 * age + c4
Body Fat % = (weight - LBM) / weight * 100

The coefficients vary by gender and athlete status:

c1c2c3c4
Male0.5030.165-0.15817.8
Male (athlete)0.6370.205-0.18012.5
Female0.4900.150-0.13011.5
Female (athlete)0.5500.180-0.1508.5

When an impedance is ignored

An impedance only drives the calculation when it looks like a body. Anything below 150 ohm or above 1200 ohm is refused, and the reading falls back to the Deurenberg estimate below.

The reason is that a wrong resistance is worse than none, and it fails convincingly rather than obviously. A value far too high pins the 60 % ceiling. A value far too low, which is what a missing or spurious factor of ten looks like, drives height² / impedance up until lean body mass exceeds body weight, and the result then pins the 4 % floor. Neither reads as an error; both silently move every derived metric.

The raw impedance is still exported either way, so you can compare it against whatever your vendor app reports. If your scale publishes an impedance and your body fat still looks like a BMI estimate, that number is why, and it is worth opening an issue with it.

Body fat fallback (Deurenberg)

When impedance is not available (e.g. the scale only measures weight), only weight, BMI, and body fat (estimated) are calculated. The remaining metrics (water, bone, muscle, visceral fat, physique rating) require impedance and will not be available.

Body fat without impedance is estimated from BMI:

Body Fat % = 1.2 * BMI + 0.23 * age - 10.8 * sex - 5.4

Where sex = 1 for male, 0 for female. For athletes, the result is multiplied by 0.85.

Other metrics

MetricFormula
BMIweight / height_m²
WaterLBM * 0.73 / weight * 100 (athlete: 0.74)
Bone MassLBM * 0.042
Muscle MassLBM * 0.54 (athlete: 0.60)
Visceral FatBody Fat % * 0.55 - 4 + age * 0.08
BMRMifflin-St Jeor: 10*W + 6.25*H - 5*A + s where s = +5 male / -161 female
Metabolic Ageage + (idealBMR - BMR) / 15

Athlete Mode

Setting is_athlete: true in a user's profile adjusts the formulas for people who exercise regularly. The setup wizard asks about this during user profile creation.

Effects:

  • Lean Body Mass: different BIA coefficients (see table above)
  • Water: higher hydration factor (74% vs 73% of LBM)
  • Muscle Mass: higher factor (60% vs 54% of LBM)
  • BMR: +5% boost
  • Metabolic Age: capped at actual age minus 5
  • Deurenberg: result multiplied by 0.85

Scale-Specific Algorithms

Xiaomi Mi Scale 2 (MIBCS / MIBFS / XMTZC05HM)

The Mi Scale 2 broadcasts raw impedance in its BLE advertisement (service data UUID 0x181B). BLE Scale Sync reads the impedance and computes body composition using the Mi Scale algorithm: the same formulas used by the official Mi Fit / Zepp Life app, originally reverse-engineered by the openScale project. Results match what the scale's own display shows.

The adapter uses passive BLE advertisement decoding, so no pairing or GATT connection is required. This works on all transports including the ESPHome proxy.

If impedance is not present in a frame (e.g. the user stepped off before the BIA measurement completed), weight is still reported and body fat is estimated using the Deurenberg BMI fallback. All other body composition metrics require impedance.

Xiaomi Body Composition Scale S400 (MJTZC01YM)

The S400 broadcasts weight plus its 50 kHz impedance (and a 250 kHz impedance and heart rate that are logged only). Body composition uses the same Xiaomi formulas as the Mi Scale 2 above. The S400's own app runs Yunmai's proprietary dual-frequency model, which no open implementation reproduces; on the same weigh-in the Xiaomi formulas land within about two points of body fat, 0.3 kg of bone mass and 2 kg of skeletal muscle of the app, while the generic BIA coefficients were more than five points of body fat away. Water and visceral fat differ by a few points either way. Expect small, consistent offsets from the app, not agreement to the decimal.

Yunmai

The Yunmai scale computes body composition on-device and transmits the pre-calculated fat, water, muscle, and bone values in its BLE notifications. BLE Scale Sync uses those values directly; the remaining metrics (BMI, BMR, metabolic age, visceral fat, physique rating) are calculated locally.

References

  • BIA: Lukaski H.C. et al. (1986), "Assessment of fat-free mass using bioelectrical impedance measurements of the human body", American Journal of Clinical Nutrition
  • Mifflin-St Jeor: Mifflin M.D., St Jeor S.T. et al. (1990), "A new predictive equation for resting energy expenditure in healthy individuals", American Journal of Clinical Nutrition
  • Deurenberg: Deurenberg P., Weststrate J.A., Seidell J.C. (1991), "Body mass index as a measure of body fatness: age- and sex-specific prediction formulas", British Journal of Nutrition

Released under the GPL-3.0 License.