use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothQNScale method parseCustom1Data.
private void parseCustom1Data(byte[] data) {
StringBuilder sb = new StringBuilder();
int len = data.length;
for (int i = 0; i < len; i++) {
sb.append(String.format("%02X ", new Object[] { Byte.valueOf(data[i]) }));
}
Timber.d(sb.toString());
float weightKg = 0;
switch(data[0]) {
case (byte) 16:
if (data[5] == (byte) 0) {
this.hasReceived = false;
// this.callback.onUnsteadyWeight(this.qnBleDevice, decodeWeight(data[3], data[4]));
} else if (data[5] == (byte) 1) {
// writeData(CmdBuilder.buildOverCmd(this.protocolType, 16));
if (!this.hasReceived) {
this.hasReceived = true;
weightKg = decodeWeight(data[3], data[4]);
int weightByteOne = data[3] & 0xFF;
int weightByteTwo = data[4] & 0xFF;
Timber.d("Weight byte 1 %d", weightByteOne);
Timber.d("Weight byte 2 %d", weightByteTwo);
Timber.d("Raw Weight: %f", weightKg);
if (weightKg > 0.0f) {
// QNData md = buildMeasuredData(this.qnUser, weight, decodeIntegerValue
// (data[6], data[7]), decodeIntegerValue(data[8], data[9]),
// new Date(), data);
int resistance1 = decodeIntegerValue(data[6], data[7]);
int resistance2 = decodeIntegerValue(data[8], data[9]);
Timber.d("resistance1: %d", resistance1);
Timber.d("resistance2: %d", resistance2);
final ScaleUser scaleUser = OpenScale.getInstance().getSelectedScaleUser();
Timber.d("scale user " + scaleUser);
ScaleMeasurement btScaleMeasurement = new ScaleMeasurement();
// TrisaBodyAnalyzeLib gives almost simillar values for QNScale body fat calcualtion
TrisaBodyAnalyzeLib qnscalelib = new TrisaBodyAnalyzeLib(scaleUser.getGender().isMale() ? 1 : 0, scaleUser.getAge(), (int) scaleUser.getBodyHeight());
// Now much difference between resistance1 and resistance2.
// Will use resistance 1 for now
float impedance = resistance1 < 410f ? 3.0f : 0.3f * (resistance1 - 400f);
btScaleMeasurement.setFat(qnscalelib.getFat(weightKg, impedance));
btScaleMeasurement.setWater(qnscalelib.getWater(weightKg, impedance));
btScaleMeasurement.setMuscle(qnscalelib.getMuscle(weightKg, impedance));
btScaleMeasurement.setBone(qnscalelib.getBone(weightKg, impedance));
btScaleMeasurement.setWeight(weightKg);
addScaleMeasurement(btScaleMeasurement);
}
}
}
break;
case (byte) 18:
byte protocolType = data[2];
this.weightScale = data[10] == (byte) 1 ? 100.0f : 10.0f;
int[] iArr = new int[5];
// writeData(CmdBuilder.buildCmd(19, this.protocolType, 1, 16, 0, 0, 0));
break;
case (byte) 33:
// writeBleData(CmdBuilder.buildCmd(34, this.protocolType, new int[0]));
break;
case (byte) 35:
weightKg = decodeWeight(data[9], data[10]);
if (weightKg > 0.0f) {
int resistance = decodeIntegerValue(data[11], data[12]);
int resistance500 = decodeIntegerValue(data[13], data[14]);
long differTime = 0;
for (int i = 0; i < 4; i++) {
differTime |= (((long) data[i + 5]) & 255) << (i * 8);
}
Date date = new Date(MILLIS_2000_YEAR + (1000 * differTime));
if (data[3] == data[4]) {
// TODO
}
}
break;
}
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothQNScale method onNextStep.
@Override
protected boolean onNextStep(int stepNr) {
switch(stepNr) {
case 0:
// set notification on for custom characteristic 1 (weight, time, and others)
setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, CUSTOM1_MEASUREMENT_CHARACTERISTIC);
break;
case 1:
// set indication on for weight measurement
setIndicationOn(WEIGHT_MEASUREMENT_SERVICE, CUSTOM2_MEASUREMENT_CHARACTERISTIC);
break;
case 2:
final ScaleUser scaleUser = OpenScale.getInstance().getSelectedScaleUser();
final Converters.WeightUnit scaleUserWeightUnit = scaleUser.getScaleUnit();
// Value of 0x01 = KG. 0x02 = LB. Requests with stones unit are sent as LB, with post-processing in vendor app.
byte weightUnitByte = (byte) 0x01;
// Default weight unit KG. If user config set to LB or ST, scale will show LB units, consistent with vendor app
if (scaleUserWeightUnit == Converters.WeightUnit.LB || scaleUserWeightUnit == Converters.WeightUnit.ST) {
weightUnitByte = (byte) 0x02;
}
// write magicnumber 0x130915[WEIGHT_BYTE]10000000[CHECK_SUM] to 0xffe3
// 0x01 weight byte = KG. 0x02 weight byte = LB.
byte[] ffe3magicBytes = new byte[] { (byte) 0x13, (byte) 0x09, (byte) 0x15, weightUnitByte, (byte) 0x10, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 };
// Set last byte to be checksum
ffe3magicBytes[ffe3magicBytes.length - 1] = sumChecksum(ffe3magicBytes, 0, ffe3magicBytes.length - 1);
writeBytes(WEIGHT_MEASUREMENT_SERVICE, CUSTOM3_MEASUREMENT_CHARACTERISTIC, ffe3magicBytes);
break;
case 3:
// send time magic number to receive weight data
long timestamp = new Date().getTime() / 1000;
timestamp -= SCALE_UNIX_TIMESTAMP_OFFSET;
byte[] date = new byte[4];
Converters.toInt32Le(date, 0, timestamp);
byte[] timeMagicBytes = new byte[] { (byte) 0x02, date[0], date[1], date[2], date[3] };
writeBytes(WEIGHT_MEASUREMENT_SERVICE, CUSTOM4_MEASUREMENT_CHARACTERISTIC, timeMagicBytes);
break;
case 4:
sendMessage(R.string.info_step_on_scale, 0);
break;
/*case 5:
// send stop command to scale (0x1f05151049)
writeBytes(CUSTOM3_MEASUREMENT_CHARACTERISTIC, new byte[]{(byte)0x1f, (byte)0x05, (byte)0x15, (byte)0x10, (byte)0x49});
break;*/
default:
return false;
}
return true;
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothSoehnle method handleWeightMeasurement.
private void handleWeightMeasurement(byte[] value) {
// kg
float weight = Converters.fromUnsignedInt16Be(value, 9) / 10.0f;
int soehnleUserIndex = (int) value[1];
final int year = Converters.fromUnsignedInt16Be(value, 2);
final int month = (int) value[4];
final int day = (int) value[5];
final int hours = (int) value[6];
final int min = (int) value[7];
final int sec = (int) value[8];
final int imp5 = Converters.fromUnsignedInt16Be(value, 11);
final int imp50 = Converters.fromUnsignedInt16Be(value, 13);
String date_string = year + "/" + month + "/" + day + "/" + hours + "/" + min;
Date date_time = new Date();
try {
date_time = new SimpleDateFormat("yyyy/MM/dd/HH/mm").parse(date_string);
} catch (ParseException e) {
Timber.e("parse error " + e.getMessage());
}
final ScaleUser scaleUser = OpenScale.getInstance().getSelectedScaleUser();
int activityLevel = 0;
switch(scaleUser.getActivityLevel()) {
case SEDENTARY:
activityLevel = 0;
break;
case MILD:
activityLevel = 1;
break;
case MODERATE:
activityLevel = 2;
break;
case HEAVY:
activityLevel = 4;
break;
case EXTREME:
activityLevel = 5;
break;
}
int openScaleUserId = prefs.getInt("userScaleIndex" + soehnleUserIndex, -1);
if (openScaleUserId == -1) {
Timber.e("Unknown Soehnle user index " + soehnleUserIndex);
} else {
SoehnleLib soehnleLib = new SoehnleLib(scaleUser.getGender().isMale(), scaleUser.getAge(), scaleUser.getBodyHeight(), activityLevel);
ScaleMeasurement scaleMeasurement = new ScaleMeasurement();
scaleMeasurement.setUserId(openScaleUserId);
scaleMeasurement.setWeight(weight);
scaleMeasurement.setDateTime(date_time);
scaleMeasurement.setWater(soehnleLib.getWater(weight, imp50));
scaleMeasurement.setFat(soehnleLib.getFat(weight, imp50));
scaleMeasurement.setMuscle(soehnleLib.getMuscle(weight, imp50, imp5));
addScaleMeasurement(scaleMeasurement);
}
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothSoehnle method onNextStep.
@Override
protected boolean onNextStep(int stepNr) {
switch(stepNr) {
case 0:
List<ScaleUser> openScaleUserList = OpenScale.getInstance().getScaleUserList();
int index = -1;
// check if an openScale user is stored as a Soehnle user otherwise do a factory reset
for (ScaleUser openScaleUser : openScaleUserList) {
index = getSoehnleUserIndex(openScaleUser.getId());
if (index != -1) {
break;
}
}
if (index == -1) {
invokeScaleFactoryReset();
}
break;
case 1:
setNotificationOn(BluetoothGattUuid.SERVICE_BATTERY_LEVEL, BluetoothGattUuid.CHARACTERISTIC_BATTERY_LEVEL);
readBytes(BluetoothGattUuid.SERVICE_BATTERY_LEVEL, BluetoothGattUuid.CHARACTERISTIC_BATTERY_LEVEL);
break;
case 2:
// Write the current time
BluetoothBytesParser parser = new BluetoothBytesParser();
parser.setCurrentTime(Calendar.getInstance());
writeBytes(BluetoothGattUuid.SERVICE_CURRENT_TIME, BluetoothGattUuid.CHARACTERISTIC_CURRENT_TIME, parser.getValue());
break;
case 3:
// Turn on notification for User Data Service
setNotificationOn(BluetoothGattUuid.SERVICE_USER_DATA, BluetoothGattUuid.CHARACTERISTIC_USER_CONTROL_POINT);
break;
case 4:
int openScaleUserId = OpenScale.getInstance().getSelectedScaleUserId();
int soehnleUserIndex = getSoehnleUserIndex(openScaleUserId);
if (soehnleUserIndex == -1) {
// create new user
Timber.d("create new Soehnle scale user");
writeBytes(BluetoothGattUuid.SERVICE_USER_DATA, BluetoothGattUuid.CHARACTERISTIC_USER_CONTROL_POINT, new byte[] { (byte) 0x01, (byte) 0x00, (byte) 0x00 });
} else {
// select user
Timber.d("select Soehnle scale user with index " + soehnleUserIndex);
writeBytes(BluetoothGattUuid.SERVICE_USER_DATA, BluetoothGattUuid.CHARACTERISTIC_USER_CONTROL_POINT, new byte[] { (byte) 0x02, (byte) soehnleUserIndex, (byte) 0x00, (byte) 0x00 });
}
break;
case 5:
// set age
writeBytes(BluetoothGattUuid.SERVICE_USER_DATA, BluetoothGattUuid.CHARACTERISTIC_USER_AGE, new byte[] { (byte) OpenScale.getInstance().getSelectedScaleUser().getAge() });
break;
case 6:
// set gender
writeBytes(BluetoothGattUuid.SERVICE_USER_DATA, BluetoothGattUuid.CHARACTERISTIC_USER_GENDER, new byte[] { OpenScale.getInstance().getSelectedScaleUser().getGender().isMale() ? (byte) 0x00 : (byte) 0x01 });
break;
case 7:
// set height
writeBytes(BluetoothGattUuid.SERVICE_USER_DATA, BluetoothGattUuid.CHARACTERISTIC_USER_HEIGHT, Converters.toInt16Le((int) OpenScale.getInstance().getSelectedScaleUser().getBodyHeight()));
break;
case 8:
setNotificationOn(WEIGHT_CUSTOM_SERVICE, WEIGHT_CUSTOM_A_CHARACTERISTIC);
setNotificationOn(WEIGHT_CUSTOM_SERVICE, WEIGHT_CUSTOM_B_CHARACTERISTIC);
// writeBytes(WEIGHT_CUSTOM_SERVICE, WEIGHT_CUSTOM_CMD_CHARACTERISTIC, new byte[] {(byte)0x0c, (byte)0xff});
break;
case 9:
for (int i = 1; i < 8; i++) {
// get history data for soehnle user index i
writeBytes(WEIGHT_CUSTOM_SERVICE, WEIGHT_CUSTOM_CMD_CHARACTERISTIC, new byte[] { (byte) 0x09, (byte) i });
}
break;
default:
return false;
}
return true;
}
use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.
the class BluetoothStandardWeightProfile method handleVendorSpecificUserList.
protected void handleVendorSpecificUserList(byte[] value) {
Timber.d(String.format("Got user data: <%s>", byteInHex(value)));
BluetoothBytesParser parser = new BluetoothBytesParser(value);
int userListStatus = parser.getIntValue(FORMAT_UINT8);
if (userListStatus == 2) {
Timber.d("scale have no users!");
storeUserScaleConsentCode(selectedUser.getId(), -1);
storeUserScaleIndex(selectedUser.getId(), -1);
jumpNextToStepNr(SM_STEPS.REGISTER_NEW_SCALE_USER.ordinal());
resumeMachineState();
return;
} else if (userListStatus == 1) {
for (int i = 0; i < scaleUserList.size(); i++) {
if (i == 0) {
Timber.d("scale user list:");
}
Timber.d("\n" + (i + 1) + ". " + scaleUserList.get(i));
}
if ((scaleUserList.size() == 0)) {
storeUserScaleConsentCode(selectedUser.getId(), -1);
storeUserScaleIndex(selectedUser.getId(), -1);
jumpNextToStepNr(SM_STEPS.REGISTER_NEW_SCALE_USER.ordinal());
resumeMachineState();
return;
}
if (getUserScaleIndex(selectedUser.getId()) == -1 || getUserScaleConsent(selectedUser.getId()) == -1) {
chooseExistingScaleUser(scaleUserList);
return;
}
resumeMachineState();
return;
}
int index = parser.getIntValue(FORMAT_UINT8);
String initials = parser.getStringValue();
int end = 3 > initials.length() ? initials.length() : 3;
initials = initials.substring(0, end);
if (initials.length() == 3) {
if (initials.charAt(0) == 0xff && initials.charAt(1) == 0xff && initials.charAt(2) == 0xff) {
initials = "";
}
}
parser.setOffset(5);
int year = parser.getIntValue(FORMAT_UINT16);
int month = parser.getIntValue(FORMAT_UINT8);
int day = parser.getIntValue(FORMAT_UINT8);
int height = parser.getIntValue(FORMAT_UINT8);
int gender = parser.getIntValue(FORMAT_UINT8);
int activityLevel = parser.getIntValue(FORMAT_UINT8);
GregorianCalendar calendar = new GregorianCalendar(year, month - 1, day);
ScaleUser scaleUser = new ScaleUser();
scaleUser.setUserName(initials);
scaleUser.setBirthday(calendar.getTime());
scaleUser.setBodyHeight(height);
scaleUser.setGender(Converters.Gender.fromInt(gender));
scaleUser.setActivityLevel(Converters.ActivityLevel.fromInt(activityLevel - 1));
scaleUser.setId(index);
scaleUserList.add(scaleUser);
if (scaleUserList.size() == getVendorSpecificMaxUserCount()) {
if (getUserScaleIndex(selectedUser.getId()) == -1 || getUserScaleConsent(selectedUser.getId()) == -1) {
chooseExistingScaleUser(scaleUserList);
return;
}
resumeMachineState();
}
}
Aggregations