Search in sources :

Example 56 with ScaleUser

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

Example 57 with ScaleUser

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

Example 58 with ScaleUser

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

Example 59 with ScaleUser

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

Example 60 with ScaleUser

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

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