Search in sources :

Example 11 with ScaleMeasurement

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

the class BluetoothSanitasSbf70 method onBluetoothDataChange.

@Override
public void onBluetoothDataChange(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic gattCharacteristic) {
    byte[] data = gattCharacteristic.getValue();
    if (data.length == 0)
        return;
    if ((data[0] & 0xFF) == 0xe6 && (data[1] & 0xFF) == 0x00) {
        Log.d(TAG, "ACK Scale is ready");
        return;
    }
    if ((data[0] & 0xFF) == 0xe7 && (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) == 0xe7 && (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) 0xe7, (byte) 0xf1, (byte) 0x34, currentUserMax, currentUserID });
        }
        return;
    }
    if ((data[0] & 0xFF) == 0xe7 && (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) 0xe7, (byte) 0x4f, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) 0x0, (byte) currentScaleUserId });
        return;
    }
    if ((data[0] & 0xFF) == 0xe7 && (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) == 0xe7 && (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) 0xe7, 0x40, 0, 0, 0, 0, 0, 0, 0, (byte) (seenUsers.size() > 0 ? Collections.max(seenUsers) + 1 : 101) });
        return;
    }
    if ((data[0] & 0xFF) == 0xe7 && (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) == 0xe7 && (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) 0xe7, (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) == 0xe7 && (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) 0xe7, (byte) 0xf1, (byte) (data[1] & 0xFF), (byte) (data[2] & 0xFF), (byte) (data[3] & 0xFF) });
        return;
    }
    if ((data[0] & 0xFF) == 0xe7 && (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) 0xe7, (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) == 0xe7 && (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 12 with ScaleMeasurement

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

the class BluetoothYunmaiMini method parseBytes.

private void parseBytes(byte[] weightBytes) {
    long unix_timestamp = ((weightBytes[5] & 0xFF) << 24) | ((weightBytes[6] & 0xFF) << 16) | ((weightBytes[7] & 0xFF) << 8) | (weightBytes[8] & 0xFF);
    Date btDate = new Date();
    btDate.setTime(unix_timestamp * 1000);
    float weight = (float) (((weightBytes[13] & 0xFF) << 8) | (weightBytes[14] & 0xFF)) / 100.0f;
    float fat = (float) (((weightBytes[17] & 0xFF) << 8) | (weightBytes[18] & 0xFF)) / 100.0f;
    ScaleMeasurement scaleBtData = new ScaleMeasurement();
    final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser();
    scaleBtData.setConvertedWeight(weight, selectedUser.getScaleUnit());
    scaleBtData.setFat(fat);
    scaleBtData.setDateTime(btDate);
    addScaleData(scaleBtData);
}
Also used : ScaleMeasurement(com.health.openscale.core.datatypes.ScaleMeasurement) ScaleUser(com.health.openscale.core.datatypes.ScaleUser) Date(java.util.Date)

Example 13 with ScaleMeasurement

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

the class BluetoothYunmaiSE method parseBytes.

private void parseBytes(byte[] weightBytes) {
    long unix_timestamp = ((weightBytes[5] & 0xFF) << 24) | ((weightBytes[6] & 0xFF) << 16) | ((weightBytes[7] & 0xFF) << 8) | (weightBytes[8] & 0xFF);
    Date btDate = new Date();
    btDate.setTime(unix_timestamp * 1000);
    float weight = (float) (((weightBytes[13] & 0xFF) << 8) | (weightBytes[14] & 0xFF)) / 100.0f;
    ScaleMeasurement scaleBtData = new ScaleMeasurement();
    final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser();
    scaleBtData.setConvertedWeight(weight, selectedUser.getScaleUnit());
    scaleBtData.setDateTime(btDate);
    addScaleData(scaleBtData);
}
Also used : ScaleMeasurement(com.health.openscale.core.datatypes.ScaleMeasurement) ScaleUser(com.health.openscale.core.datatypes.ScaleUser) Date(java.util.Date)

Example 14 with ScaleMeasurement

use of com.health.openscale.core.datatypes.ScaleMeasurement 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 15 with ScaleMeasurement

use of com.health.openscale.core.datatypes.ScaleMeasurement 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)

Aggregations

ScaleMeasurement (com.health.openscale.core.datatypes.ScaleMeasurement)39 Date (java.util.Date)13 ScaleUser (com.health.openscale.core.datatypes.ScaleUser)12 BufferedReader (java.io.BufferedReader)9 ParseException (java.text.ParseException)9 StringReader (java.io.StringReader)8 Test (org.junit.Test)8 ArrayList (java.util.ArrayList)7 Calendar (java.util.Calendar)7 MeasurementView (com.health.openscale.gui.views.MeasurementView)6 SimpleDateFormat (java.text.SimpleDateFormat)5 BMRMeasurementView (com.health.openscale.gui.views.BMRMeasurementView)4 FloatMeasurementView (com.health.openscale.gui.views.FloatMeasurementView)4 WeightMeasurementView (com.health.openscale.gui.views.WeightMeasurementView)4 IOException (java.io.IOException)4 ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 Stack (java.util.Stack)2 SimpleLineChartValueFormatter (lecho.lib.hellocharts.formatter.SimpleLineChartValueFormatter)2 Axis (lecho.lib.hellocharts.model.Axis)2 AxisValue (lecho.lib.hellocharts.model.AxisValue)2