Search in sources :

Example 36 with ScaleUser

use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.

the class BluetoothBeurerBF700_800 method onBluetoothDataChange.

@Override
public void onBluetoothDataChange(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic gattCharacteristic) {
    byte[] data = gattCharacteristic.getValue();
    if (data.length == 0)
        return;
    if ((data[0] & 0xFF) == 0xf6 && (data[1] & 0xFF) == 0x00) {
        Log.d(TAG, "ACK Scale is ready");
        return;
    }
    if ((data[0] & 0xFF) == 0xf7 && (data[1] & 0xFF) == 0xf0 && data[2] == 0x33) {
        Log.d(TAG, "ACK Got general user information");
        int count = (byte) (data[4] & 0xFF);
        int maxUsers = (byte) (data[5] & 0xFF);
        Log.d(TAG, "Count:" + count + " maxUsers:" + maxUsers);
        countRegisteredScaleUsers = count;
        // Check if any scale user is registered
        if (count == 0)
            // Unknown user
            currentScaleUserId = 0;
        maxRegisteredScaleUser = maxUsers;
        nextMachineStateStep();
        return;
    }
    if ((data[0] & 0xFF) == 0xf7 && (data[1] & 0xFF) == 0x34) {
        Log.d(TAG, "Ack Get UUIDSs List of Users");
        byte currentUserMax = (byte) (data[2] & 0xFF);
        byte currentUserID = (byte) (data[3] & 0xFF);
        byte userUuid = (byte) (data[11] & 0xFF);
        String name = new String(data, 12, 3);
        int year = (byte) (data[15] & 0xFF);
        final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser();
        // Check if we found the currently selected user
        if (selectedUser.getUserName().toLowerCase().startsWith(name.toLowerCase()) && selectedUser.getBirthday().getYear() == year) {
            // Found user
            currentScaleUserId = userUuid;
        }
        // Remember this uuid from the scale
        if (seenUsers.add((int) userUuid)) {
            if (currentScaleUserId == -1 && seenUsers.size() == countRegisteredScaleUsers) {
                // We have seen all users: user is unknown
                currentScaleUserId = 0;
            }
            Log.d(TAG, "Send ack gotUser");
            writeBytes(new byte[] { (byte) 0xf7, (byte) 0xf1, (byte) 0x34, currentUserMax, currentUserID });
        }
        return;
    }
    if ((data[0] & 0xFF) == 0xf7 && (data[1] & 0xFF) == 0xF0 && (data[2] & 0xFF) == 0x36) {
        Log.d(TAG, "Ack Get User Info Initials");
        String name = new String(data, 4, 3);
        byte year = (byte) (data[7] & 0xFF);
        byte month = (byte) (data[8] & 0xFF);
        byte day = (byte) (data[9] & 0xFF);
        int height = (data[10] & 0xFF);
        boolean male = (data[11] & 0xF0) != 0;
        byte activity = (byte) (data[11] & 0x0F);
        Log.d(TAG, "Name " + name + " YY-MM-DD: " + year + " " + month + " " + day + "Height: " + height + " Sex:" + (male ? "M" : "F") + "activity: " + activity);
        // Get scale status for user
        writeBytes(new byte[] { (byte) 0xf7, (byte) 0x4f, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) currentScaleUserId });
        return;
    }
    if ((data[0] & 0xFF) == 0xf7 && (data[1] & 0xFF) == 0xf0 && (data[2] & 0xFF) == 0x4F) {
        Log.d(TAG, "Ack Get scale status");
        int unknown = data[3];
        int batteryLevel = (data[4] & 0xFF);
        float weightThreshold = (data[5] & 0xFF) / 10f;
        float bodyFatThreshold = (data[6] & 0xFF) / 10f;
        // 1 kg, 2 lb (pounds), 3 st stone
        int unit = data[7];
        boolean userExists = (data[8] == 0);
        boolean userReferWeightExists = (data[9] == 0);
        boolean userMeasurementExist = (data[10] == 0);
        int scaleVersion = data[11];
        Log.d(TAG, "BatteryLevel:" + batteryLevel + " weightThreshold: " + weightThreshold + " BodyFatThresh: " + bodyFatThreshold + " Unit: " + unit + " userExists: " + userExists + " UserReference Weight Exists:" + userReferWeightExists + " UserMeasurementExists " + userMeasurementExist + " scaleVersion" + scaleVersion);
        return;
    }
    if ((data[0] & 0xFF) == 0xf7 && (data[1] & 0xFF) == 0xf0 && data[2] == 0x31) {
        Log.d(TAG, "Acknowledge creation of user");
        // Indicate user to step on scale
        sendMessage(R.string.info_step_on_scale, 0);
        // Request basement measurement
        writeBytes(new byte[] { (byte) 0xf7, 0x40, 0, 0, 0, 0, 0, 0, 0, (byte) (seenUsers.size() > 0 ? Collections.max(seenUsers) + 1 : 101) });
        return;
    }
    if ((data[0] & 0xFF) == 0xf7 && (data[1] & 0xFF) == 0xf0 && (data[2] & 0xFF) == 0x41) {
        Log.d(TAG, "Will start to receive measurements User Specific");
        byte nr_measurements = data[3];
        Log.d(TAG, "New measurements: " + nr_measurements / 2);
        return;
    }
    if ((data[0] & 0xFF) == 0xf7 && (data[1] & 0xFF) == 0x42) {
        Log.d(TAG, "Specific measurement User specific");
        // Measurements are split into two parts
        int max_items = data[2] & 0xFF;
        int current_item = data[3] & 0xFF;
        // Received even part
        if (current_item % 2 == 1) {
            receivedScaleData = new ByteArrayOutputStream();
        }
        try {
            receivedScaleData.write(Arrays.copyOfRange(data, 4, data.length));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // Send acknowledgement
        writeBytes(new byte[] { (byte) 0xf7, (byte) 0xf1, (byte) 0x42, (byte) (data[2] & 0xFF), (byte) (data[3] & 0xFF) });
        if (current_item % 2 == 0) {
            try {
                ScaleMeasurement parsedData = parseScaleData(receivedScaleData.toByteArray());
                addScaleData(parsedData);
            } catch (ParseException e) {
                Log.d(TAG, "Could not parse byte array: " + byteInHex(receivedScaleData.toByteArray()));
                e.printStackTrace();
            }
        }
        if (current_item == max_items) {
            // finish and delete
            deleteScaleData();
        }
        return;
    }
    if ((data[0] & 0xFF) == 0xf7 && (data[1] & 0xFF) == 0x58) {
        Log.d(TAG, "Active measurement");
        if ((data[2] & 0xFF) != 0x00) {
            // little endian
            float weight = ((float) (((data[3] & 0xFF) << 8) + (data[4] & 0xFF))) * 50.0f / // unit is 50g
            1000.0f;
            // temporary value;
            sendMessage(R.string.info_measuring, weight);
            return;
        }
        // stabilized value
        // little endian
        float weight = ((float) (((data[3] & 0xFF) << 8) + (data[4] & 0xFF))) * 50.0f / // unit is 50g
        1000.0f;
        Log.i(TAG, "Got weight: " + weight);
        writeBytes(new byte[] { (byte) 0xf7, (byte) 0xf1, (byte) (data[1] & 0xFF), (byte) (data[2] & 0xFF), (byte) (data[3] & 0xFF) });
        return;
    }
    if ((data[0] & 0xFF) == 0xf7 && (data[1] & 0xFF) == 0x59) {
        // Get stable measurement results
        Log.d(TAG, "Get measurement data " + ((int) data[3]));
        int max_items = (data[2] & 0xFF);
        int current_item = (data[3] & 0xFF);
        // Received first part
        if (current_item == 1) {
            receivedScaleData = new ByteArrayOutputStream();
        } else {
            try {
                receivedScaleData.write(Arrays.copyOfRange(data, 4, data.length));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // Send ack that we got the data
        writeBytes(new byte[] { (byte) 0xf7, (byte) 0xf1, (byte) (data[1] & 0xFF), (byte) (data[2] & 0xFF), (byte) (data[3] & 0xFF) });
        if (current_item == max_items) {
            // received all parts
            ScaleMeasurement parsedData = null;
            try {
                parsedData = parseScaleData(receivedScaleData.toByteArray());
                addScaleData(parsedData);
                // Delete data
                deleteScaleData();
            } catch (ParseException e) {
                Log.d(TAG, "Parse Exception " + byteInHex(receivedScaleData.toByteArray()));
            }
        }
        return;
    }
    if ((data[0] & 0xFF) == 0xf7 && (data[1] & 0xFF) == 0xf0 && (data[2] & 0xFF) == 0x43) {
        Log.d(TAG, "Acknowledge: Data deleted.");
        return;
    }
    Log.d(TAG, "DataChanged - not handled: " + byteInHex(data));
}
Also used : ScaleMeasurement(com.health.openscale.core.datatypes.ScaleMeasurement) ScaleUser(com.health.openscale.core.datatypes.ScaleUser) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) ParseException(java.text.ParseException)

Example 37 with ScaleUser

use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.

the class BluetoothExcelvanCF369BLE method parseBytes.

private void parseBytes(byte[] weightBytes) {
    float weight = (float) (((weightBytes[4] & 0xFF) << 8) | (weightBytes[5] & 0xFF)) / 10.0f;
    float fat = (float) (((weightBytes[6] & 0xFF) << 8) | (weightBytes[7] & 0xFF)) / 10.0f;
    float bone = (float) (weightBytes[8]) / 10.0f;
    float muscle = (float) (((weightBytes[9] & 0xFF) << 8) | (weightBytes[10] & 0xFF)) / 10.0f;
    float viscal_fat = (float) (weightBytes[11]);
    float water = (float) (((weightBytes[12] & 0xFF) << 8) | (weightBytes[13] & 0xFF)) / 10.0f;
    float bmr = (float) (((weightBytes[14] & 0xFF) << 8) | (weightBytes[15] & 0xFF));
    ScaleMeasurement scaleBtData = new ScaleMeasurement();
    final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser();
    scaleBtData.setConvertedWeight(weight, selectedUser.getScaleUnit());
    scaleBtData.setFat(fat);
    scaleBtData.setMuscle(muscle);
    scaleBtData.setWater(water);
    scaleBtData.setBone(bone);
    scaleBtData.setDateTime(new Date());
    addScaleData(scaleBtData);
}
Also used : ScaleMeasurement(com.health.openscale.core.datatypes.ScaleMeasurement) ScaleUser(com.health.openscale.core.datatypes.ScaleUser) Date(java.util.Date)

Example 38 with ScaleUser

use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.

the class BluetoothExcelvanCF369BLE method nextBluetoothCmd.

@Override
boolean nextBluetoothCmd(int stateNr) {
    switch(stateNr) {
        case 0:
            final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser();
            // 01 - male; 00 - female
            byte sex = selectedUser.getGender().isMale() ? (byte) 0x01 : (byte) 0x00;
            // cm
            byte height = (byte) (selectedUser.getBodyHeight() & 0xff);
            byte age = (byte) (selectedUser.getAge(new Date()) & 0xff);
            // kg
            byte unit = 0x01;
            switch(selectedUser.getScaleUnit()) {
                case LB:
                    unit = 0x02;
                    break;
                case ST:
                    unit = 0x04;
                    break;
            }
            byte xor_checksum = (byte) ((byte) (0x01) ^ sex ^ (byte) (0x01) ^ height ^ age ^ unit);
            byte[] configBytes = { (byte) (0xfe), (byte) (0x01), sex, (byte) (0x01), height, age, unit, xor_checksum };
            writeBytes(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_CHARACTERISTIC, configBytes);
            break;
        case 1:
            setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_CUSTOM0_CHARACTERISTIC, WEIGHT_MEASUREMENT_CONFIG);
            break;
        default:
            return false;
    }
    return false;
}
Also used : ScaleUser(com.health.openscale.core.datatypes.ScaleUser) Date(java.util.Date)

Example 39 with ScaleUser

use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.

the class ScaleUserDatabase method getScaleUserList.

public ArrayList<ScaleUser> getScaleUserList() {
    SQLiteDatabase db = getReadableDatabase();
    ArrayList<ScaleUser> scaleUserDBEntries = new ArrayList<ScaleUser>();
    String sortOrder = COLUMN_NAME_ID + " ASC";
    Cursor cursorScaleDB = db.query(// The table to query
    TABLE_NAME, // The columns to return
    projection, // The columns for the WHERE clause
    null, // The values for the WHERE clause
    null, // don't group the rows
    null, // don't filter by row groups
    null, // The sort order
    sortOrder);
    cursorScaleDB.moveToFirst();
    while (!cursorScaleDB.isAfterLast()) {
        scaleUserDBEntries.add(readAtCursor(cursorScaleDB));
        cursorScaleDB.moveToNext();
    }
    cursorScaleDB.close();
    return scaleUserDBEntries;
}
Also used : SQLiteDatabase(android.database.sqlite.SQLiteDatabase) ScaleUser(com.health.openscale.core.datatypes.ScaleUser) ArrayList(java.util.ArrayList) Cursor(android.database.Cursor)

Example 40 with ScaleUser

use of com.health.openscale.core.datatypes.ScaleUser in project openScale by oliexdev.

the class ScaleUserDatabase method readAtCursor.

private ScaleUser readAtCursor(Cursor cur) {
    ScaleUser scaleUser = new ScaleUser();
    try {
        scaleUser.setId(cur.getInt(cur.getColumnIndexOrThrow(COLUMN_NAME_ID)));
        scaleUser.setUserName(cur.getString(cur.getColumnIndexOrThrow(COLUMN_NAME_USER_NAME)));
        String birthday = cur.getString(cur.getColumnIndexOrThrow(COLUMN_NAME_BIRTHDAY));
        scaleUser.setBodyHeight(cur.getInt(cur.getColumnIndexOrThrow(COLUMN_NAME_BODY_HEIGHT)));
        scaleUser.setScaleUnit(Converters.fromWeightUnitInt(cur.getInt(cur.getColumnIndexOrThrow(COLUMN_NAME_SCALE_UNIT))));
        scaleUser.setGender(Converters.fromGenderInt(cur.getInt(cur.getColumnIndexOrThrow(COLUMN_NAME_GENDER))));
        double initial_weight = cur.getFloat(cur.getColumnIndexOrThrow(COLUMN_NAME_INITIAL_WEIGHT));
        double goal_weight = cur.getFloat(cur.getColumnIndexOrThrow(COLUMN_NAME_GOAL_WEIGHT));
        String goal_date = cur.getString(cur.getColumnIndexOrThrow(COLUMN_NAME_GOAL_DATE));
        scaleUser.setBirthday(formatDateTime.parse(birthday));
        scaleUser.setGoalDate(formatDateTime.parse(goal_date));
        scaleUser.setInitialWeight(Math.round(initial_weight * 100.0f) / 100.0f);
        scaleUser.setGoalWeight(Math.round(goal_weight * 100.0f) / 100.0f);
    } catch (ParseException ex) {
        Log.e("ScaleDatabase", "Can't parse the date time string: " + ex.getMessage());
    } catch (IllegalArgumentException ex) {
        Log.e("ScaleDatabase", "Illegal argument while reading from scale database: " + ex.getMessage());
    }
    return scaleUser;
}
Also used : ScaleUser(com.health.openscale.core.datatypes.ScaleUser) ParseException(java.text.ParseException)

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