Search in sources :

Example 6 with ScaleUser

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

Example 7 with ScaleUser

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

Example 8 with ScaleUser

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

Example 9 with ScaleUser

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() + ")");
    }
}
Also used : ScaleMeasurement(com.health.openscale.core.datatypes.ScaleMeasurement) ScaleUser(com.health.openscale.core.datatypes.ScaleUser) ParseException(java.text.ParseException) SimpleDateFormat(java.text.SimpleDateFormat) MiScaleLib(com.health.openscale.core.bluetooth.lib.MiScaleLib) Date(java.util.Date)

Example 10 with ScaleUser

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

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