1
0
mirror of https://github.com/oliexdev/openScale.git synced 2025-08-20 23:41:45 +02:00

Update calculations for OneByone scales (#747)

* Update calculations for OneByone scales

Previously, the value reported for muscle mass was lean body mass
less skeletal mass. This was not a correct report for muscle mass
since it included additional values, such as organs and skin mass.

In addition, the impedance value previously used was incorrect.
There were, in fact, two different calculations being performed
for impedance based on data fields that were not relevant to it,
therefore the value for impedance was entirely incorrect, jumpy,
and unpredictable. In fact, the correct bytes for impedance are
the second and third bytes in the data packet received from the
scale, which produces correct and reasonable impedance values.

This commit corrects the prior errors, provides a calculation for
lean body mass, and calculates muscle mass based on the Janssen
formula;

https://journals.physiology.org/doi/pdf/10.1152/jappl.2000.89.2.465

* Muscle mass should be percent of total body weight, not absolute kg
This commit is contained in:
Adam Serbinski
2021-10-10 05:05:35 -04:00
committed by GitHub
parent c9c6ca30bb
commit 4ec9b4bd0c
2 changed files with 18 additions and 32 deletions

View File

@@ -145,9 +145,8 @@ public class BluetoothOneByone extends BluetoothCommunication {
private void parseBytes(byte[] weightBytes) {
float weight = Converters.fromUnsignedInt16Le(weightBytes, 3) / 100.0f;
int impedanceCoeff = Converters.fromUnsignedInt24Le(weightBytes, 5);
int impedanceValue = weightBytes[5] + weightBytes[6] + weightBytes[7];
boolean impedancePresent = (weightBytes[9] != 1) && (impedanceCoeff != 0);
float impedanceValue = ((float)(((weightBytes[2] & 0xFF) << 8) + (weightBytes[1] & 0xFF))) * 0.1f;
boolean impedancePresent = (weightBytes[9] != 1) && (impedanceValue != 0);
boolean dateTimePresent = weightBytes.length >= 18;
if (!impedancePresent || (!dateTimePresent && historicMeasurement)) {
@@ -166,7 +165,7 @@ public class BluetoothOneByone extends BluetoothCommunication {
final ScaleUser scaleUser = OpenScale.getInstance().getSelectedScaleUser();
Timber.d("received bytes [%s]", byteInHex(weightBytes));
Timber.d("received decrypted bytes [weight: %.2f, impedanceCoeff: %d, impedanceValue: %d]", weight, impedanceCoeff, impedanceValue);
Timber.d("received decoded bytes [weight: %.2f, impedanceValue: %f]", weight, impedanceValue);
Timber.d("user [%s]", scaleUser);
int sex = 0, peopleType = 0;
@@ -203,11 +202,12 @@ public class BluetoothOneByone extends BluetoothCommunication {
dateTime.setLenient(false);
scaleBtData.setDateTime(dateTime.getTime());
scaleBtData.setFat(oneByoneLib.getBodyFat(weight, impedanceCoeff));
scaleBtData.setFat(oneByoneLib.getBodyFat(weight, impedanceValue));
scaleBtData.setWater(oneByoneLib.getWater(scaleBtData.getFat()));
scaleBtData.setBone(oneByoneLib.getBoneMass(weight, impedanceValue));
scaleBtData.setVisceralFat(oneByoneLib.getVisceralFat(weight));
scaleBtData.setMuscle(oneByoneLib.getMuscle(weight, scaleBtData.getFat(), scaleBtData.getBone()));
scaleBtData.setMuscle(oneByoneLib.getMuscle(weight, impedanceValue));
scaleBtData.setLbm(oneByoneLib.getLBM(weight, scaleBtData.getFat()));
Timber.d("scale measurement [%s]", scaleBtData);

View File

@@ -33,8 +33,12 @@ public class OneByoneLib {
return weight / (((height * height) / 100.0f) / 100.0f);
}
public float getMuscle(float weight, float bodyFat, float boneMass) {
return (weight - ((bodyFat / 100.0f) * weight)) - boneMass;
public float getLBM(float weight, float bodyFat) {
return weight - (bodyFat / 100.0f * weight);
}
public float getMuscle(float weight, float impedanceValue){
return (float)((height * height / impedanceValue * 0.401) + (sex * 3.825) - (age * 0.071) + 5.102) / weight * 100.0f;
}
public float getWater(float bodyFat) {
@@ -50,7 +54,7 @@ public class OneByoneLib {
return coeff * water;
}
public float getBoneMass(float weight, int impedanceValue) {
public float getBoneMass(float weight, float impedanceValue) {
float boneMass, sexConst , peopleCoeff = 0.0f;
switch (peopleType) {
@@ -173,30 +177,12 @@ public class OneByoneLib {
}
}
public float getBodyFat(float weight, int impedanceCoeff) {
float impedanceValue, bodyFatConst=0;
public float getBodyFat(float weight, float impedanceValue) {
float bodyFatConst=0;
if (impedanceCoeff == 0x0FFFFFF) {
return 1.0f;
}
impedanceValue = (float)(((impedanceCoeff & 0x0FF0000) >> 0x10) + (impedanceCoeff & 0x0F00) - ((impedanceCoeff & 0x0F000) >> 0xC) + (0 - (impedanceCoeff & 0xFF)) * 4) * 0.5f;
if (50.0f <= impedanceValue) {
if (impedanceValue > 3000.0f) {
bodyFatConst = 0.0068f;
} else {
if (200.0f > impedanceValue) {
bodyFatConst = 1.36f;
} else {
if (impedanceValue > 1200) {
bodyFatConst = 8.16f;
} else {
bodyFatConst = 0.0068f * impedanceValue;
}
}
}
}
if (impedanceValue >= 1200.0f) bodyFatConst = 8.16f;
else if (impedanceValue >= 200.0f) bodyFatConst = 0.0068f * impedanceValue;
else if (impedanceValue >= 50.0f) bodyFatConst = 1.36f;
float peopleTypeCoeff, bodyVar, bodyFat;