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:
@@ -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);
|
||||
|
||||
|
@@ -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;
|
||||
|
||||
|
Reference in New Issue
Block a user