Search in sources :

Example 11 with ScaleUser

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;
        }
    }
}
Also used : OneByoneLib(com.health.openscale.core.bluetooth.lib.OneByoneLib) ScaleMeasurement(com.health.openscale.core.datatypes.ScaleMeasurement) ScaleUser(com.health.openscale.core.datatypes.ScaleUser) Calendar(java.util.Calendar)

Example 12 with ScaleUser

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;
}
Also used : ScaleUser(com.health.openscale.core.datatypes.ScaleUser) Calendar(java.util.Calendar)

Example 13 with ScaleUser

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);
}
Also used : ScaleUser(com.health.openscale.core.datatypes.ScaleUser)

Example 14 with ScaleUser

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);
}
Also used : ScaleUser(com.health.openscale.core.datatypes.ScaleUser) DateFormat(java.text.DateFormat) Pair(android.util.Pair)

Example 15 with ScaleUser

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);
}
Also used : ScaleMeasurement(com.health.openscale.core.datatypes.ScaleMeasurement) ScaleUser(com.health.openscale.core.datatypes.ScaleUser)

Aggregations

ScaleUser (com.health.openscale.core.datatypes.ScaleUser)69 ScaleMeasurement (com.health.openscale.core.datatypes.ScaleMeasurement)23 Date (java.util.Date)21 Calendar (java.util.Calendar)9 OpenScale (com.health.openscale.core.OpenScale)8 ParseException (java.text.ParseException)6 Converters (com.health.openscale.core.utils.Converters)5 ArrayList (java.util.ArrayList)5 Test (org.junit.Test)4 Intent (android.content.Intent)3 SharedPreferences (android.content.SharedPreferences)3 SimpleDateFormat (java.text.SimpleDateFormat)3 AlertDialog (android.app.AlertDialog)2 Context (android.content.Context)2 DialogInterface (android.content.DialogInterface)2 Uri (android.net.Uri)2 ArrayAdapter (android.widget.ArrayAdapter)2 Spinner (android.widget.Spinner)2 TableRow (android.widget.TableRow)2 TextView (android.widget.TextView)2