use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothOneByone method parseBytes.
private void parseBytes(byte[] weightBytes) {
float weight = Converters.fromUnsignedInt16Le(weightBytes, 3) / 100.0f;
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)) {
// unwanted, no impedance or historic measurement w/o time-stamp
return;
}
Calendar dateTime = Calendar.getInstance();
if (dateTimePresent) {
// 18-byte or longer measurements contain date and time, used in history
dateTime.set(Converters.fromUnsignedInt16Be(weightBytes, 11), weightBytes[13] - 1, weightBytes[14], weightBytes[15], weightBytes[16], weightBytes[17]);
}
final ScaleUser scaleUser = OpenScale.getInstance().getSelectedScaleUser();
Timber.d("received bytes [%s]", byteInHex(weightBytes));
Timber.d("received decoded bytes [weight: %.2f, impedanceValue: %f]", weight, impedanceValue);
Timber.d("user [%s]", scaleUser);
int sex = 0, peopleType = 0;
if (scaleUser.getGender() == Converters.Gender.MALE) {
sex = 1;
} else {
sex = 0;
}
switch(scaleUser.getActivityLevel()) {
case SEDENTARY:
peopleType = 0;
break;
case MILD:
peopleType = 0;
break;
case MODERATE:
peopleType = 1;
break;
case HEAVY:
peopleType = 2;
break;
case EXTREME:
peopleType = 2;
break;
}
OneByoneLib oneByoneLib = new OneByoneLib(sex, scaleUser.getAge(), scaleUser.getBodyHeight(), peopleType);
ScaleMeasurement scaleBtData = new ScaleMeasurement();
scaleBtData.setWeight(weight);
try {
dateTime.setLenient(false);
scaleBtData.setDateTime(dateTime.getTime());
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, impedanceValue));
scaleBtData.setLbm(oneByoneLib.getLBM(weight, scaleBtData.getFat()));
Timber.d("scale measurement [%s]", scaleBtData);
if (dateTime.getTimeInMillis() - lastDateTime.getTimeInMillis() < DATE_TIME_THRESHOLD) {
// don't save measurements too close to each other
return;
}
lastDateTime = dateTime;
addScaleMeasurement(scaleBtData);
} catch (IllegalArgumentException e) {
if (historicMeasurement) {
Timber.d("invalid time-stamp: year %d, month %d, day %d, hour %d, minute %d, second %d", Converters.fromUnsignedInt16Be(weightBytes, 11), weightBytes[13], weightBytes[14], weightBytes[15], weightBytes[16], weightBytes[17]);
// discard historic measurement with invalid time-stamp
return;
}
}
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothOneByone method onNextStep.
@Override
protected boolean onNextStep(int stepNr) {
switch(stepNr) {
case 0:
setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_CHARACTERISTIC_BODY_COMPOSITION);
break;
case 1:
ScaleUser currentUser = OpenScale.getInstance().getSelectedScaleUser();
// kg
byte unit = 0x00;
switch(currentUser.getScaleUnit()) {
case LB:
unit = 0x01;
break;
case ST:
unit = 0x02;
break;
}
byte group = 0x01;
byte[] magicBytes = { (byte) 0xfd, (byte) 0x37, unit, group, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
magicBytes[magicBytes.length - 1] = xorChecksum(magicBytes, 0, magicBytes.length - 1);
writeBytes(WEIGHT_MEASUREMENT_SERVICE, CMD_MEASUREMENT_CHARACTERISTIC, magicBytes);
break;
case 2:
Calendar dt = Calendar.getInstance();
final byte[] setClockCmd = { (byte) 0xf1, (byte) (dt.get(Calendar.YEAR) >> 8), (byte) (dt.get(Calendar.YEAR) & 255), (byte) (dt.get(Calendar.MONTH) + 1), (byte) dt.get(Calendar.DAY_OF_MONTH), (byte) dt.get(Calendar.HOUR_OF_DAY), (byte) dt.get(Calendar.MINUTE), (byte) dt.get(Calendar.SECOND) };
waitAck = true;
writeBytes(WEIGHT_MEASUREMENT_SERVICE, CMD_MEASUREMENT_CHARACTERISTIC, setClockCmd);
// 2-byte notification value f1 00 will be received after this command
// we will resume after receiving acknowledgement f1 00
stopMachineState();
break;
case 3:
// request historic measurements; they are followed by real-time measurements
historicMeasurement = true;
final byte[] getHistoryCmd = { (byte) 0xf2, (byte) 0x00 };
writeBytes(WEIGHT_MEASUREMENT_SERVICE, CMD_MEASUREMENT_CHARACTERISTIC, getHistoryCmd);
// 2-byte notification value f2 00 follows last historic measurement
break;
case 4:
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 BluetoothSenssun method synchroniseUser.
private void synchroniseUser() {
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
byte[] message = new byte[] { (byte) 0xA5, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
// message[2] = (byte)((selectedUser.getGender().isMale() ? (byte)0x80: (byte)0x00) + 1+selectedUser.getId());
message[2] = (byte) ((selectedUser.getGender().isMale() ? 15 : 0) * 16 + selectedUser.getId());
message[3] = (byte) selectedUser.getAge();
message[4] = (byte) selectedUser.getBodyHeight();
addChecksum(message);
writeBytes(writeService, writeCharacteristic, message);
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothStandardWeightProfile method chooseExistingScaleUser.
protected void chooseExistingScaleUser(Vector<ScaleUser> userList) {
final DateFormat dateFormat = DateFormat.getDateInstance();
int choicesCount = userList.size();
if (userList.size() < getVendorSpecificMaxUserCount()) {
choicesCount = userList.size() + 1;
}
CharSequence[] choiceStrings = new String[choicesCount];
int[] indexArray = new int[choicesCount];
int selectedItem = -1;
for (int i = 0; i < userList.size(); ++i) {
ScaleUser u = userList.get(i);
String name = u.getUserName();
choiceStrings[i] = (name.length() > 0 ? name : String.format("P%02d", u.getId())) + " " + context.getString(u.getGender().isMale() ? R.string.label_male : R.string.label_female).toLowerCase() + " " + context.getString(R.string.label_height).toLowerCase() + ":" + u.getBodyHeight() + " " + context.getString(R.string.label_birthday).toLowerCase() + ":" + dateFormat.format(u.getBirthday()) + " " + context.getString(R.string.label_activity_level).toLowerCase() + ":" + (u.getActivityLevel().toInt() + 1);
indexArray[i] = u.getId();
}
if (userList.size() < getVendorSpecificMaxUserCount()) {
choiceStrings[userList.size()] = context.getString(R.string.info_create_new_user_on_scale);
indexArray[userList.size()] = -1;
}
Pair<CharSequence[], int[]> choices = new Pair(choiceStrings, indexArray);
chooseScaleUserUi(choices);
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothExcelvanCF36xBLE method parseBytes.
private void parseBytes(byte[] weightBytes) {
float weight = Converters.fromUnsignedInt16Be(weightBytes, 4) / 10.0f;
float fat = Converters.fromUnsignedInt16Be(weightBytes, 6) / 10.0f;
float bone = (weightBytes[8] & 0xFF) / 10.0f;
float muscle = Converters.fromUnsignedInt16Be(weightBytes, 9) / 10.0f;
float visceralFat = weightBytes[11] & 0xFF;
float water = Converters.fromUnsignedInt16Be(weightBytes, 12) / 10.0f;
float bmr = Converters.fromUnsignedInt16Be(weightBytes, 14);
// weightBytes[16] is an (optional, ignored) "physiological age" in some scale variants.
ScaleMeasurement scaleBtData = new ScaleMeasurement();
final ScaleUser selectedUser = OpenScale.getInstance().getSelectedScaleUser();
scaleBtData.setWeight(Converters.toKilogram(weight, selectedUser.getScaleUnit()));
scaleBtData.setFat(fat);
scaleBtData.setMuscle(muscle);
scaleBtData.setWater(water);
scaleBtData.setBone(bone);
scaleBtData.setVisceralFat(visceralFat);
addScaleMeasurement(scaleBtData);
}
Aggregations