From 05816ce0cfe030da39e4c28a9fc9795d2ad5e334 Mon Sep 17 00:00:00 2001 From: Krisjans Blukis Date: Tue, 27 Jul 2021 19:24:02 +0300 Subject: [PATCH] BluetoothStandardWeightProfile: merge previous and new measurement if new measurement lacks user id (and timestamp); Bluetooth scales usually implement both "Weight Scale Feature" and "Body Composition Feature". It seems that scale first transmits weight measurement (with user index and timestamp) and later transmits body composition measurement (without user index and timestamp). If previous measurement contains user index and new measurements does not then merge them and store as one. NOTE: On scales that implement only Weight Scale feature (or only Body Composition feature) this commit will cause last measurement transmitted to be delayed until disconnect. --- .../core/bluetooth/BluetoothBeurerBF600.java | 11 ---- .../BluetoothStandardWeightProfile.java | 54 ++++++++++++++++++- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothBeurerBF600.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothBeurerBF600.java index 486e2e4e..3d808c70 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothBeurerBF600.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothBeurerBF600.java @@ -92,17 +92,6 @@ public class BluetoothBeurerBF600 extends BluetoothStandardWeightProfile { BluetoothGattUuidBF600.CHARACTERISTIC_BEURER_BF600_TAKE_MEASUREMENT, parser.getValue()); } - @Override - protected void handleWeightMeasurement(byte[] value) { - scaleMeasurement = weightMeasurementToScaleMeasurement(value); - } - - @Override - protected void handleBodyCompositionMeasurement(byte[] value) { - scaleMeasurement.merge(bodyCompositionMeasurementToScaleMeasurement(value)); - addScaleMeasurement(scaleMeasurement); - } - @Override protected void setNotifyVendorSpecificUserList() { setNotificationOn(BluetoothGattUuidBF600.SERVICE_BEURER_CUSTOM_BF600, diff --git a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothStandardWeightProfile.java b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothStandardWeightProfile.java index b5ca3d7c..5d588d2b 100644 --- a/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothStandardWeightProfile.java +++ b/android_app/app/src/main/java/com/health/openscale/core/bluetooth/BluetoothStandardWeightProfile.java @@ -61,12 +61,14 @@ public class BluetoothStandardWeightProfile extends BluetoothCommunication { SharedPreferences prefs; protected boolean registerNewUser; ScaleUser selectedUser; + ScaleMeasurement previousMeasurement; public BluetoothStandardWeightProfile(Context context) { super(context); this.prefs = PreferenceManager.getDefaultSharedPreferences(context); this.selectedUser = OpenScale.getInstance().getSelectedScaleUser(); this.registerNewUser = false; + previousMeasurement = null; } @Override @@ -343,7 +345,7 @@ public class BluetoothStandardWeightProfile extends BluetoothCommunication { } protected void handleWeightMeasurement(byte[] value) { - addScaleMeasurement(weightMeasurementToScaleMeasurement(value)); + mergeWithPreviousScaleMeasurement(weightMeasurementToScaleMeasurement(value)); } protected ScaleMeasurement bodyCompositionMeasurementToScaleMeasurement(byte[] value) { @@ -472,7 +474,55 @@ public class BluetoothStandardWeightProfile extends BluetoothCommunication { } protected void handleBodyCompositionMeasurement(byte[] value) { - addScaleMeasurement(bodyCompositionMeasurementToScaleMeasurement(value)); + mergeWithPreviousScaleMeasurement(bodyCompositionMeasurementToScaleMeasurement(value)); + } + + /** + * Bluetooth scales usually implement both "Weight Scale Feature" and "Body Composition Feature". + * It seems that scale first transmits weight measurement (with user index and timestamp) and + * later transmits body composition measurement (without user index and timestamp). + * If previous measurement contains user index and new measurements does not then merge them and + * store as one. + * disconnect() function must store previousMeasurement to openScale db (if present). + * + * @param newMeasurement the scale data that should be merged with previous measurement or + * stored as previous measurement. + */ + protected void mergeWithPreviousScaleMeasurement(ScaleMeasurement newMeasurement) { + if (previousMeasurement == null) { + if (newMeasurement.getUserId() == -1) { + addScaleMeasurement(newMeasurement); + } + else { + previousMeasurement = newMeasurement; + } + } + else { + if ((newMeasurement.getUserId() == -1) && (previousMeasurement.getUserId() != -1)) { + previousMeasurement.merge(newMeasurement); + addScaleMeasurement(previousMeasurement); + previousMeasurement = null; + } + else { + addScaleMeasurement(previousMeasurement); + if (newMeasurement.getUserId() == -1) { + addScaleMeasurement(newMeasurement); + previousMeasurement = null; + } + else { + previousMeasurement = newMeasurement; + } + } + } + } + + @Override + public void disconnect() { + if (previousMeasurement != null) { + addScaleMeasurement(previousMeasurement); + previousMeasurement = null; + } + super.disconnect(); } protected void setNotifyVendorSpecificUserList() {