From 29de0e2de28fdaa427c0ec424c159ebeacefb915 Mon Sep 17 00:00:00 2001 From: Sunguk Lee Date: Tue, 10 Dec 2019 04:42:24 +0900 Subject: [PATCH] Support activity level in Yunmai scales (#524) * Support activity level in Yunmai scales and clean up YunmaiLib --- .../bluetooth/BluetoothYunmaiSE_Mini.java | 5 +- .../core/bluetooth/lib/YunmaiLib.java | 112 ++++++++++++------ 2 files changed, 81 insertions(+), 36 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiSE_Mini.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiSE_Mini.java index 343ad5cd..d371406b 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiSE_Mini.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothYunmaiSE_Mini.java @@ -60,12 +60,13 @@ public class BluetoothYunmaiSE_Mini extends BluetoothCommunication { final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser(); byte sex = selectedUser.getGender().isMale() ? (byte)0x01 : (byte)0x02; byte display_unit = selectedUser.getScaleUnit() == Converters.WeightUnit.KG ? (byte) 0x01 : (byte) 0x02; + byte body_type = (byte) YunmaiLib.toYunmaiActivityLevel(selectedUser.getActivityLevel()); byte[] user_add_or_query = new byte[]{ (byte) 0x0d, (byte) 0x12, (byte) 0x10, (byte) 0x01, (byte) 0x00, (byte) 0x00, userId[0], userId[1], (byte) selectedUser.getBodyHeight(), sex, (byte) selectedUser.getAge(), (byte) 0x55, (byte) 0x5a, (byte) 0x00, - (byte)0x00, display_unit, (byte) 0x03, (byte) 0x00}; + (byte)0x00, display_unit, body_type, (byte) 0x00}; user_add_or_query[user_add_or_query.length - 1] = xorChecksum(user_add_or_query, 1, user_add_or_query.length - 1); writeBytes(WEIGHT_CMD_SERVICE, WEIGHT_CMD_CHARACTERISTIC, user_add_or_query); @@ -129,7 +130,7 @@ public class BluetoothYunmaiSE_Mini extends BluetoothCommunication { sex = 0; } - YunmaiLib yunmaiLib = new YunmaiLib(sex, scaleUser.getBodyHeight()); + YunmaiLib yunmaiLib = new YunmaiLib(sex, scaleUser.getBodyHeight(), scaleUser.getActivityLevel()); float bodyFat; int resistance = Converters.fromUnsignedInt16Be(weightBytes, 15); if (weightBytes[1] >= (byte)0x1E) { diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/lib/YunmaiLib.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/lib/YunmaiLib.java index c21eb99c..353b327e 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/lib/YunmaiLib.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/lib/YunmaiLib.java @@ -16,13 +16,27 @@ package com.health.openscale.core.bluetooth.lib; +import com.health.openscale.core.utils.Converters.ActivityLevel; + public class YunmaiLib { private int sex; // male = 1; female = 0 private float height; + private boolean fitnessBodyType; - public YunmaiLib(int sex, float height) { + static public int toYunmaiActivityLevel(ActivityLevel activityLevel) { + switch (activityLevel) { + case HEAVY: + case EXTREME: + return 1; + default: + return 0; + } + } + + public YunmaiLib(int sex, float height, ActivityLevel activityLevel) { this.sex = sex; this.height = height; + this.fitnessBodyType = YunmaiLib.toYunmaiActivityLevel(activityLevel) == 1; } public float getWater(float bodyFat) { @@ -40,14 +54,17 @@ public class YunmaiLib { r = (float)Math.sqrt(r); } + fat = (weight * 1.5f / h / h) + (age * 0.08f); if (this.sex == 1) { - fat = (weight * 1.5f / h / h) + (age * 0.08f) - 10.8f; - } else { - fat = (weight * 1.5f / h / h) + (age * 0.08f); + fat -= 10.8f; } fat = (fat - 7.4f) + r; + if (fat < 5.0f || fat > 75.0f) { + fat = 0.0f; + } + return fat; } @@ -55,7 +72,7 @@ public class YunmaiLib { float muscle; muscle = (100.0f - bodyFat) * 0.67f; - if (sex == 1) { + if (this.fitnessBodyType) { muscle = (100.0f - bodyFat) * 0.7f; } @@ -64,6 +81,20 @@ public class YunmaiLib { return muscle; } + public float getSkeletalMuscle(float bodyFat) { + float muscle; + + muscle = (100.0f - bodyFat) * 0.53f; + if (this.fitnessBodyType) { + muscle = (100.0f - bodyFat) * 0.6f; + } + + muscle = ((muscle * 100.0f) + 0.5f) / 100.0f; + + return muscle; + } + + public float getBoneMass(float muscle, float weight) { float boneMass; @@ -81,46 +112,59 @@ public class YunmaiLib { } public float getLeanBodyMass(float weight, float bodyFat) { - if (bodyFat < 5.0f || bodyFat > 75.0f) { - return 0.0f; - } return weight * (100.0f - bodyFat) / 100.0f; } public float getVisceralFat(float bodyFat, int age) { - float f = (bodyFat < 5.0f || bodyFat > 75.0f) ? 0.0f : bodyFat; + float f = bodyFat; int a = (age < 18 || age > 120) ? 18 : age; - if (sex == 1) { - if (a < 40) { - f -= 21.0f; - } else if (a < 60) { - f -= 22.0f; + float vf; + if (!fitnessBodyType) { + if (sex == 1) { + if (a < 40) { + f -= 21.0f; + } else if (a < 60) { + f -= 22.0f; + } else { + f -= 24.0f; + } } else { - f -= 24.0f; + if (a < 40) { + f -= 34.0f; + } else if (a < 60) { + f -= 35.0f; + } else { + f -= 36.0f; + } } + + float d = sex == 1 ? 1.4f : 1.8f; + if (f > 0.0f) { + d = 1.1f; + } + + vf = (f / d) + 9.5f; + if (vf < 1.0f) { + return 1.0f; + } + if (vf > 30.0f) { + return 30.0f; + } + return vf; } else { - if (a < 40) { - f -= 34.0f; - } else if (a < 60) { - f -= 35.0f; + if (bodyFat > 15.0f) { + vf = (bodyFat - 15.0f) / 1.1f + 12.0f; } else { - f -= 36.0f; + vf = -1 * (15.0f - bodyFat) / 1.4f + 12.0f; } + if (vf < 1.0f) { + return 1.0f; + } + if (vf > 9.0f) { + return 9.0f; + } + return vf; } - - float d = sex == 1 ? 1.4f : 1.8f; - if (f > 0.0f) { - d = 1.1f; - } - - float vf = (f / d) + 9.5f; - if (vf < 1.0f) { - return 1.0f; - } - if (vf > 30.0f) { - return 30.0f; - } - return vf; } }