diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCommunication.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCommunication.java index ba0a1306..e46a7f3c 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCommunication.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothCommunication.java @@ -87,6 +87,8 @@ public abstract class BluetoothCommunication { return new BluetoothMedisanaBS444(context); case 4: return new BluetoothDigooDGSO38H(context); + case 5: + return new BluetoothExcelvanCF369BLE(context); } return null; diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothDigooDGSO38H.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothDigooDGSO38H.java index 0146f3ae..372dbc82 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothDigooDGSO38H.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothDigooDGSO38H.java @@ -26,7 +26,6 @@ import com.health.openscale.core.datatypes.ScaleData; import com.health.openscale.core.datatypes.ScaleUser; import java.util.ArrayList; -import java.util.Calendar; import java.util.Date; import java.util.UUID; @@ -116,12 +115,7 @@ public class BluetoothDigooDGSO38H extends BluetoothCommunication { final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser(); byte gender = selectedUser.isMale() ? (byte)0x00: (byte)0x01; byte height = (byte) (selectedUser.body_height & 0xFF); - Calendar today = Calendar.getInstance(); - Calendar birthday = Calendar.getInstance(); - birthday.setTime(selectedUser.birthday); - int userAge = today.get(Calendar.YEAR) - birthday.get(Calendar.YEAR); - if (today.get(Calendar.DAY_OF_YEAR) < birthday.get(Calendar.DAY_OF_YEAR)) userAge--; - byte age = (byte)(userAge & 0xff); + byte age = (byte)(selectedUser.getAge() & 0xff); byte unit; switch (selectedUser.scale_unit) { case 0: diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothExcelvanCF369BLE.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothExcelvanCF369BLE.java new file mode 100644 index 00000000..0479a482 --- /dev/null +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothExcelvanCF369BLE.java @@ -0,0 +1,152 @@ +/* Copyright (C) 2017 olie.xdev +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see +*/ + +package com.health.openscale.core.bluetooth; + +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCharacteristic; +import android.content.Context; + +import com.health.openscale.core.OpenScale; +import com.health.openscale.core.datatypes.ScaleData; +import com.health.openscale.core.datatypes.ScaleUser; + +import java.util.ArrayList; +import java.util.Date; +import java.util.UUID; + +public class BluetoothExcelvanCF369BLE extends BluetoothCommunication { + private final UUID WEIGHT_MEASUREMENT_SERVICE = UUID.fromString("f000ffc0-0451-4000-b000-000000000000"); + private final UUID WEIGHT_MEASUREMENT_CHARACTERISTIC = UUID.fromString("0000FFF0-0000-1000-8000-00805f9b34fb"); + private final UUID WEIGHT_MEASUREMENT_CONFIG = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); + + public BluetoothExcelvanCF369BLE(Context context) { + super(context); + } + + @Override + public String deviceName() { + return "Excelvan CF369BLE"; + } + + @Override + public String defaultDeviceName() { + return "CF369BLE"; + } + + @Override + public boolean historySupported() { + return false; + } + + + @Override + public ArrayList hwAddresses() { + ArrayList hwAddresses = new ArrayList(); + hwAddresses.add("FFFFFF"); + + return hwAddresses; + } + + @Override + boolean nextInitCmd(int stateNr) { + switch (stateNr) { + case 0: + setNotificationOn(WEIGHT_MEASUREMENT_SERVICE, WEIGHT_MEASUREMENT_CHARACTERISTIC, WEIGHT_MEASUREMENT_CONFIG); + break; + default: + return false; + } + + return true; + } + + @Override + boolean nextBluetoothCmd(int stateNr) { + switch (stateNr) { + case 0: + final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser(); + + byte sex = selectedUser.isMale() ? (byte)0x01 : (byte)0x00; // 01 - male; 00 - female + byte height = (byte)(selectedUser.body_height & 0xff); // cm + byte age = (byte)(selectedUser.getAge() & 0xff); + byte unit; + + switch (selectedUser.scale_unit) { + case 0: + unit = 0x01; // kg + break; + case 1: + unit = 0x02; // lb + break; + case 2: + unit = 0x04; // st + break; + default: + unit = 0x01; // kg + } + + byte xor_checksum = (byte)((0x01) ^ sex ^ (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; + default: + return false; + } + + return false; + } + + @Override + boolean nextCleanUpCmd(int stateNr) { + return false; + } + + @Override + public void onBluetoothDataChange(BluetoothGatt bluetoothGatt, BluetoothGattCharacteristic gattCharacteristic) { + final byte[] data = gattCharacteristic.getValue(); + + if (data != null && data.length > 0) { + + // if data is body scale type + if (data[0] == 0xcf) { + parseBytes(data); + } + } + } + + 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)); + + ScaleData scaleBtData = new ScaleData(); + + final ScaleUser selectedUser = OpenScale.getInstance(context).getSelectedScaleUser(); + + scaleBtData.setConvertedWeight(weight, selectedUser.scale_unit); + scaleBtData.setFat(fat); + scaleBtData.setMuscle(muscle); + scaleBtData.setWater(water); + scaleBtData.setDateTime(new Date()); + } +} diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java index 3a45c965..82535bbd 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothMiScale.java @@ -49,7 +49,7 @@ public class BluetoothMiScale extends BluetoothCommunication { @Override public String deviceName() { - return "Xiaomi Mi Scale"; + return "Xiaomi Mi Scale v1"; } @Override diff --git a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java index a9c1aada..7f0d5c88 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java +++ b/android_app/app/src/main/java/com/health/openscale/core/datatypes/ScaleUser.java @@ -16,6 +16,7 @@ package com.health.openscale.core.datatypes; +import java.util.Calendar; import java.util.Date; public class ScaleUser { @@ -51,6 +52,16 @@ public class ScaleUser { return false; } + public int getAge() { + Calendar cal_today = Calendar.getInstance(); + Calendar cal_birthday = Calendar.getInstance(); + cal_birthday.setTime(birthday); + int userAge = cal_today.get(Calendar.YEAR) - cal_birthday.get(Calendar.YEAR); + if (cal_today.get(Calendar.DAY_OF_YEAR) < cal_birthday.get(Calendar.DAY_OF_YEAR)) userAge--; + + return userAge; + } + @Override public String toString() {