use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class OpenScale method getSmartUserAssignment.
private int getSmartUserAssignment(float weight, float range) {
List<ScaleUser> scaleUsers = getScaleUserList();
Map<Float, Integer> inRangeWeights = new TreeMap<>();
for (int i = 0; i < scaleUsers.size(); i++) {
List<ScaleMeasurement> scaleUserData = measurementDAO.getAll(scaleUsers.get(i).getId());
float lastWeight;
if (scaleUserData.size() > 0) {
lastWeight = scaleUserData.get(0).getWeight();
} else {
lastWeight = scaleUsers.get(i).getInitialWeight();
}
if ((lastWeight - range) <= weight && (lastWeight + range) >= weight) {
inRangeWeights.put(Math.abs(lastWeight - weight), scaleUsers.get(i).getId());
}
}
if (inRangeWeights.size() > 0) {
// return the user id which is nearest to the weight (first element of the tree map)
int userId = inRangeWeights.entrySet().iterator().next().getValue();
Timber.d("assign measurement to the nearest measurement with the user " + getScaleUser(userId).getUserName() + " (smartUserAssignment=on)");
return userId;
}
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
// if ignore out of range preference is true don't add this data
if (prefs.getBoolean("ignoreOutOfRange", false)) {
Timber.d("to be added measurement is thrown away because measurement is out of range (smartUserAssignment=on;ignoreOutOfRange=on)");
return -1;
}
// return selected scale user id if not out of range preference is checked and weight is out of range of any user
Timber.d("assign measurement to the selected user (smartUserAssignment=on;ignoreOutOfRange=off)");
return getSelectedScaleUser().getId();
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothInlife method processMeasurementData.
void processMeasurementData(byte[] data) {
float weight = Converters.fromUnsignedInt16Be(data, 2) / 10.0f;
float lbm = Converters.fromUnsignedInt24Be(data, 4) / 1000.0f;
float visceralFactor = Converters.fromUnsignedInt16Be(data, 7) / 10.0f;
float bmr = Converters.fromUnsignedInt16Be(data, 9) / 10.0f;
if (lbm == 0xffffff / 1000.0f) {
Timber.e("Measurement failed; feet not correctly placed on scale?");
return;
}
Timber.d("weight=%.1f, LBM=%.3f, visceral factor=%.1f, BMR=%.1f", weight, lbm, visceralFactor, bmr);
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
switch(getAthleteLevel(selectedUser)) {
case 0:
break;
case 1:
lbm *= 1.0427f;
break;
case 2:
lbm *= 1.0958f;
break;
}
final float fatKg = weight - lbm;
final double fat = (fatKg / weight) * 100.0;
final double water = (0.73f * (weight - fatKg) / weight) * 100.0;
final double muscle = (0.548 * lbm / weight) * 100.0;
final double bone = 0.05158 * lbm;
final float height = selectedUser.getBodyHeight();
double visceral = visceralFactor - 50;
if (selectedUser.getGender().isMale()) {
if (height >= 1.6 * weight + 63) {
visceral += (0.765 - 0.002 * height) * weight;
} else {
visceral += 380 * weight / (((0.0826 * height * height) - 0.4 * height) + 48);
}
} else {
if (weight <= height / 2 - 13) {
visceral += (0.691 - 0.0024 * height) * weight;
} else {
visceral += 500 * weight / (((0.1158 * height * height) + 1.45 * height) - 120);
}
}
if (getAthleteLevel(selectedUser) != 0) {
if (visceral >= 21) {
visceral *= 0.85;
}
if (visceral >= 10) {
visceral *= 0.8;
}
visceral -= getAthleteLevel(selectedUser) * 2;
}
ScaleMeasurement measurement = new ScaleMeasurement();
measurement.setWeight(weight);
measurement.setFat(clamp(fat, 5, 80));
measurement.setWater(clamp(water, 5, 80));
measurement.setMuscle(clamp(muscle, 5, 80));
measurement.setBone(clamp(bone, 0.5, 8));
measurement.setLbm(lbm);
measurement.setVisceralFat(clamp(visceral, 1, 50));
addScaleMeasurement(measurement);
sendCommand(0xd4);
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothInlife method onNextStep.
@Override
protected boolean onNextStep(int stepNr) {
switch(stepNr) {
case 0:
setNotificationOn(WEIGHT_SERVICE, WEIGHT_MEASUREMENT_CHARACTERISTIC);
break;
case 1:
ScaleUser scaleUser = OpenScale.getInstance().getSelectedScaleUser();
byte level = (byte) (getAthleteLevel(scaleUser) + 1);
byte sex = (byte) scaleUser.getGender().toInt();
byte userId = (byte) scaleUser.getId();
byte age = (byte) scaleUser.getAge();
byte height = (byte) scaleUser.getBodyHeight();
sendCommand(0xd2, level, sex, userId, age, height);
break;
case 2:
sendMessage(R.string.info_step_on_scale, 0);
break;
default:
return false;
}
return true;
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothMiScale2 method parseBytes.
private void parseBytes(byte[] data) {
try {
final byte ctrlByte0 = data[0];
final byte ctrlByte1 = data[1];
final boolean isWeightRemoved = isBitSet(ctrlByte1, 7);
final boolean isDateInvalid = isBitSet(ctrlByte1, 6);
final boolean isStabilized = isBitSet(ctrlByte1, 5);
final boolean isLBSUnit = isBitSet(ctrlByte0, 0);
final boolean isCattyUnit = isBitSet(ctrlByte1, 6);
final boolean isImpedance = isBitSet(ctrlByte1, 1);
if (isStabilized && !isWeightRemoved && !isDateInvalid) {
final int year = ((data[3] & 0xFF) << 8) | (data[2] & 0xFF);
final int month = (int) data[4];
final int day = (int) data[5];
final int hours = (int) data[6];
final int min = (int) data[7];
final int sec = (int) data[8];
float weight;
float impedance = 0.0f;
if (isLBSUnit || isCattyUnit) {
weight = (float) (((data[12] & 0xFF) << 8) | (data[11] & 0xFF)) / 100.0f;
} else {
weight = (float) (((data[12] & 0xFF) << 8) | (data[11] & 0xFF)) / 200.0f;
}
if (isImpedance) {
impedance = ((data[10] & 0xFF) << 8) | (data[9] & 0xFF);
Timber.d("impedance value is " + impedance);
}
String date_string = year + "/" + month + "/" + day + "/" + hours + "/" + min;
Date date_time = new SimpleDateFormat("yyyy/MM/dd/HH/mm").parse(date_string);
// Is the year plausible? Check if the year is in the range of 20 years...
if (validateDate(date_time, 20)) {
final ScaleUser scaleUser = OpenScale.getInstance().getSelectedScaleUser();
ScaleMeasurement scaleBtData = new ScaleMeasurement();
scaleBtData.setWeight(Converters.toKilogram(weight, scaleUser.getScaleUnit()));
scaleBtData.setDateTime(date_time);
int sex;
if (scaleUser.getGender() == Converters.Gender.MALE) {
sex = 1;
} else {
sex = 0;
}
if (impedance != 0.0f) {
MiScaleLib miScaleLib = new MiScaleLib(sex, scaleUser.getAge(), scaleUser.getBodyHeight());
scaleBtData.setWater(miScaleLib.getWater(weight, impedance));
scaleBtData.setVisceralFat(miScaleLib.getVisceralFat(weight));
scaleBtData.setFat(miScaleLib.getBodyFat(weight, impedance));
// convert muscle in kg to percent
scaleBtData.setMuscle((100.0f / scaleBtData.getWeight()) * miScaleLib.getMuscle(weight, impedance));
scaleBtData.setBone(miScaleLib.getBoneMass(weight, impedance));
} else {
Timber.d("Impedance value is zero");
}
addScaleMeasurement(scaleBtData);
} else {
Timber.e("Invalid Mi scale weight year %d", year);
}
}
} catch (ParseException e) {
setBluetoothStatus(UNEXPECTED_ERROR, "Error while decoding bluetooth date string (" + e.getMessage() + ")");
}
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothMiScale2 method onNextStep.
@Override
protected boolean onNextStep(int stepNr) {
switch(stepNr) {
case 0:
// set scale units
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
byte[] setUnitCmd = new byte[] { (byte) 0x06, (byte) 0x04, (byte) 0x00, (byte) selectedUser.getScaleUnit().toInt() };
writeBytes(WEIGHT_CUSTOM_SERVICE, WEIGHT_CUSTOM_CONFIG, setUnitCmd);
break;
case 1:
// set current time
Calendar currentDateTime = Calendar.getInstance();
int year = currentDateTime.get(Calendar.YEAR);
byte month = (byte) (currentDateTime.get(Calendar.MONTH) + 1);
byte day = (byte) currentDateTime.get(Calendar.DAY_OF_MONTH);
byte hour = (byte) currentDateTime.get(Calendar.HOUR_OF_DAY);
byte min = (byte) currentDateTime.get(Calendar.MINUTE);
byte sec = (byte) currentDateTime.get(Calendar.SECOND);
byte[] dateTimeByte = { (byte) (year), (byte) (year >> 8), month, day, hour, min, sec, 0x03, 0x00, 0x00 };
writeBytes(BluetoothGattUuid.SERVICE_BODY_COMPOSITION, BluetoothGattUuid.CHARACTERISTIC_CURRENT_TIME, dateTimeByte);
break;
case 2:
// set notification on for weight measurement history
setNotificationOn(BluetoothGattUuid.SERVICE_BODY_COMPOSITION, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC);
break;
case 3:
// configure scale to get only last measurements
int uniqueNumber = getUniqueNumber();
byte[] userIdentifier = new byte[] { (byte) 0x01, (byte) 0xFF, (byte) 0xFF, (byte) ((uniqueNumber & 0xFF00) >> 8), (byte) ((uniqueNumber & 0xFF) >> 0) };
writeBytes(BluetoothGattUuid.SERVICE_BODY_COMPOSITION, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, userIdentifier);
break;
case 4:
// invoke receiving history data
writeBytes(BluetoothGattUuid.SERVICE_BODY_COMPOSITION, WEIGHT_MEASUREMENT_HISTORY_CHARACTERISTIC, new byte[] { 0x02 });
stopMachineState();
break;
default:
return false;
}
return true;
}
Aggregations