From dba61884f4d6258181f71cbe92db520bc20249e5 Mon Sep 17 00:00:00 2001 From: jordipbou Date: Sun, 28 Feb 2021 02:02:43 +0100 Subject: [PATCH 1/4] Added synchronization and graph display of Libre2RawValue readings to xDrip+ Followers. --- .../eveningoutpost/dexdrip/GcmActivity.java | 12 +++++ .../dexdrip/GcmListenerSvc.java | 4 ++ .../eveningoutpost/dexdrip/LibreReceiver.java | 7 +++ .../dexdrip/models/Libre2RawValue.java | 54 ++++++++++++++++--- .../dexdrip/utilitymodels/BgGraphBuilder.java | 8 +-- 5 files changed, 76 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/GcmActivity.java b/app/src/main/java/com/eveningoutpost/dexdrip/GcmActivity.java index c57e638d4d..ae6550aa09 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/GcmActivity.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/GcmActivity.java @@ -21,6 +21,7 @@ import com.eveningoutpost.dexdrip.models.Calibration; import com.eveningoutpost.dexdrip.models.DesertSync; import com.eveningoutpost.dexdrip.models.JoH; +import com.eveningoutpost.dexdrip.models.Libre2RawValue; import com.eveningoutpost.dexdrip.models.RollCall; import com.eveningoutpost.dexdrip.models.Sensor; import com.eveningoutpost.dexdrip.models.Treatments; @@ -293,6 +294,17 @@ public synchronized static void syncBGReading(BgReading bgReading) { } } + // Synchronization of Libre2 patched app received raw values, + // called from LibreReceiver only if option Libre2_showRawGraph is activated. + public synchronized static void syncLibre2RawReading(Libre2RawValue rawValue) { + if (rawValue == null) { + UserError.Log.wtf(TAG, "Cannot sync null libre2rawvalue - should never occur"); + return; + } + Log.d(TAG, "syncLibre2RawReading called"); + GcmActivity.sendMessage("l2rs", rawValue.toJSON()); + } + // called only from interactive or evaluated new data public synchronized static void syncBloodTests() { Log.d(TAG, "syncBloodTests called"); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/GcmListenerSvc.java b/app/src/main/java/com/eveningoutpost/dexdrip/GcmListenerSvc.java index 0e2211199d..c5c4c883e8 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/GcmListenerSvc.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/GcmListenerSvc.java @@ -21,6 +21,7 @@ import com.eveningoutpost.dexdrip.models.Calibration; import com.eveningoutpost.dexdrip.models.DesertSync; import com.eveningoutpost.dexdrip.models.JoH; +import com.eveningoutpost.dexdrip.models.Libre2RawValue; import com.eveningoutpost.dexdrip.models.LibreBlock; import com.eveningoutpost.dexdrip.models.RollCall; import com.eveningoutpost.dexdrip.models.Sensor; @@ -562,6 +563,9 @@ public void run() { } } else if (action.equals("libreBlock") || action.equals("libreBlck")) { HandleLibreBlock(payload); + } else if (action.equals("l2rs")) { + Libre2RawValue currentRawValue = Libre2RawValue.fromJSON(payload); + currentRawValue.save(); } else { Log.e(TAG, "Received message action we don't know about: " + action); } diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java b/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java index 49cd1c1974..b7ee8a5bdd 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java @@ -150,7 +150,14 @@ public void run() { processValues(currentRawValue, smoothingValues, smoothing_minutes, context); } currentRawValue.save(); + clearNFCsensorAge(); + + // Libre2 Raw readings are also sent to Sync+ Followers if + // show raw graph for Libre2 option is activated. + if (Pref.getBoolean("Libre2_showRawGraph", false)) + GcmActivity.syncLibre2RawReading(currentRawValue); + break; default: diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/models/Libre2RawValue.java b/app/src/main/java/com/eveningoutpost/dexdrip/models/Libre2RawValue.java index ed0f10593a..780ec8a641 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/models/Libre2RawValue.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/models/Libre2RawValue.java @@ -1,24 +1,29 @@ package com.eveningoutpost.dexdrip.models; - import android.provider.BaseColumns; +import android.util.Log; import com.activeandroid.annotation.Column; import com.activeandroid.annotation.Table; import com.activeandroid.query.Delete; import com.activeandroid.query.Select; import com.eveningoutpost.dexdrip.utilitymodels.Constants; - import java.util.Date; import java.util.List; +import com.google.gson.GsonBuilder; +import com.google.gson.annotations.Expose; +import org.json.JSONException; +import org.json.JSONObject; + @Table(name = "Libre2RawValue2", id = BaseColumns._ID) public class Libre2RawValue extends PlusModel { + private static final String TAG = "libre2rawvalue"; static final String[] schema = { - "DROP TABLE Libre2RawValue;", - "CREATE TABLE Libre2RawValue2 (_id INTEGER PRIMARY KEY AUTOINCREMENT, ts INTEGER, serial STRING, glucose REAL);", - "CREATE INDEX index_Libre2RawValue2_ts on Libre2RawValue2(ts);" + "DROP TABLE Libre2RawValue;", + "CREATE TABLE Libre2RawValue2 (_id INTEGER PRIMARY KEY AUTOINCREMENT, ts INTEGER, serial STRING, glucose REAL);", + "CREATE INDEX index_Libre2RawValue2_ts on Libre2RawValue2(ts);" }; @Column(name = "serial", index = true) @@ -69,4 +74,41 @@ public static List cleanup(final int retention_days) { public static void updateDB() { fixUpTable(schema, false); } -} \ No newline at end of file + + public String toJSON() { + final JSONObject jsonObject = new JSONObject(); + try { + jsonObject.put("serial", serial); + jsonObject.put("timestamp", timestamp); + jsonObject.put("glucose", glucose); + + return jsonObject.toString(); + } catch (JSONException e) { + UserError.Log.wtf(TAG, "Error producing in toJSON: " + e); + if (Double.isNaN(glucose)) UserError.Log.e(TAG, "glucose is NaN"); + if (Double.isNaN(timestamp)) UserError.Log.e(TAG, "timestamp is NaN"); + return ""; + } + } + + public static Libre2RawValue fromJSON(String json) { + NewLibre2RawValue nl2rv = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().fromJson(json, NewLibre2RawValue.class); + Libre2RawValue l2rv = new Libre2RawValue(); + l2rv.serial = nl2rv.serial; + l2rv.glucose = nl2rv.glucose; + l2rv.timestamp = nl2rv.timestamp; + Log.d(TAG, "Object form json: " + l2rv.serial + ", " + l2rv.glucose + ", " + l2rv.timestamp); + return l2rv; + } +} + +class NewLibre2RawValue { + @Expose + double glucose; + + @Expose + long timestamp; + + @Expose + String serial; +} diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/utilitymodels/BgGraphBuilder.java b/app/src/main/java/com/eveningoutpost/dexdrip/utilitymodels/BgGraphBuilder.java index 221ba90404..939c56a74d 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/utilitymodels/BgGraphBuilder.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/utilitymodels/BgGraphBuilder.java @@ -220,8 +220,9 @@ public BgGraphBuilder(Context context, long start, long end, int numValues, bool loaded_start = start; loaded_end = end; bgReadings = BgReading.latestForGraph(numValues, start, end); - if (DexCollectionType.getDexCollectionType() == DexCollectionType.LibreReceiver) - Libre2RawValues = Libre2RawValue.latestForGraph(numValues, start, end); + if (DexCollectionType.getDexCollectionType() == DexCollectionType.LibreReceiver + || (DexCollectionType.getDexCollectionType() == DexCollectionType.Follower && prefs.getBoolean("Libre2_showRawGraph",false))) + Libre2RawValues = Libre2RawValue.latestForGraph(numValues * 5, start, end); plugin_adjusted = false; smoother_adjusted = false; } finally { @@ -1343,7 +1344,8 @@ private synchronized void addBgReadingValues(final boolean simple) { } try { - if (DexCollectionType.getDexCollectionType() == DexCollectionType.LibreReceiver && prefs.getBoolean("Libre2_showRawGraph", false)) { + if ((DexCollectionType.getDexCollectionType() == DexCollectionType.LibreReceiver || DexCollectionType.getDexCollectionType () == DexCollectionType.Follower) + && prefs.getBoolean("Libre2_showRawGraph", false)) { for (final Libre2RawValue bgLibre : Libre2RawValues) { if (bgLibre.glucose > 0) { rawInterpretedValues.add(new HPointValue((double) (bgLibre.timestamp / FUZZER), (float) unitized(bgLibre.glucose))); From b8085f5d5a7acb3886aaa71ba0aa591188fbd9be Mon Sep 17 00:00:00 2001 From: jordipbou Date: Sun, 28 Feb 2021 02:34:10 +0100 Subject: [PATCH 2/4] Libre2Raw data not sent if device is not sync master --- app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java b/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java index b7ee8a5bdd..a1aa6dc90c 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java @@ -155,7 +155,7 @@ public void run() { // Libre2 Raw readings are also sent to Sync+ Followers if // show raw graph for Libre2 option is activated. - if (Pref.getBoolean("Libre2_showRawGraph", false)) + if (Pref.getBoolean("plus_follow_master", false) && Pref.getBoolean("Libre2_showRawGraph", false)) GcmActivity.syncLibre2RawReading(currentRawValue); break; From 3155d0d11a19496eff42f903c42aebc1cffd5682 Mon Sep 17 00:00:00 2001 From: jodli Date: Thu, 29 Feb 2024 00:10:34 +0100 Subject: [PATCH 3/4] Add test for json parsing of Libre2RawValue --- .../dexdrip/models/Libre2RawValue.java | 1 - .../dexdrip/models/Libre2RawValueTest.java | 29 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 app/src/test/java/com/eveningoutpost/dexdrip/models/Libre2RawValueTest.java diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/models/Libre2RawValue.java b/app/src/main/java/com/eveningoutpost/dexdrip/models/Libre2RawValue.java index 780ec8a641..2dcaf69036 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/models/Libre2RawValue.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/models/Libre2RawValue.java @@ -86,7 +86,6 @@ public String toJSON() { } catch (JSONException e) { UserError.Log.wtf(TAG, "Error producing in toJSON: " + e); if (Double.isNaN(glucose)) UserError.Log.e(TAG, "glucose is NaN"); - if (Double.isNaN(timestamp)) UserError.Log.e(TAG, "timestamp is NaN"); return ""; } } diff --git a/app/src/test/java/com/eveningoutpost/dexdrip/models/Libre2RawValueTest.java b/app/src/test/java/com/eveningoutpost/dexdrip/models/Libre2RawValueTest.java new file mode 100644 index 0000000000..9b17427e26 --- /dev/null +++ b/app/src/test/java/com/eveningoutpost/dexdrip/models/Libre2RawValueTest.java @@ -0,0 +1,29 @@ +package com.eveningoutpost.dexdrip.models; + +import static com.google.common.truth.Truth.assertThat; + +import com.eveningoutpost.dexdrip.RobolectricTestWithConfig; + +import org.junit.Test; + +import java.util.Date; + +public class Libre2RawValueTest extends RobolectricTestWithConfig { + + @Test + public void jsonParsingWorks() { + Libre2RawValue value = new Libre2RawValue(); + value.serial = "Hello World"; + value.timestamp = new Date().getTime(); + value.glucose = 123.456; + + String json = value.toJSON(); + + Libre2RawValue new_value = Libre2RawValue.fromJSON(json); + + assertThat(value.serial).isEqualTo(new_value.serial); + assertThat(value.timestamp).isEqualTo(new_value.timestamp); + assertThat(value.glucose).isEqualTo(new_value.glucose); + } +} + From bb4046c349695f1d14a0da4f26bc8f3bd8a81fe5 Mon Sep 17 00:00:00 2001 From: jodli Date: Mon, 18 Mar 2024 13:31:07 +0100 Subject: [PATCH 4/4] Add plus_follower_save_power to syncing and make conditions more clear. --- .../main/java/com/eveningoutpost/dexdrip/GcmActivity.java | 3 +-- .../java/com/eveningoutpost/dexdrip/LibreReceiver.java | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/GcmActivity.java b/app/src/main/java/com/eveningoutpost/dexdrip/GcmActivity.java index ae6550aa09..e9412b8995 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/GcmActivity.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/GcmActivity.java @@ -294,8 +294,7 @@ public synchronized static void syncBGReading(BgReading bgReading) { } } - // Synchronization of Libre2 patched app received raw values, - // called from LibreReceiver only if option Libre2_showRawGraph is activated. + // Synchronization of Libre2 patched app received raw values public synchronized static void syncLibre2RawReading(Libre2RawValue rawValue) { if (rawValue == null) { UserError.Log.wtf(TAG, "Cannot sync null libre2rawvalue - should never occur"); diff --git a/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java b/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java index a1aa6dc90c..41a66630a0 100644 --- a/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java +++ b/app/src/main/java/com/eveningoutpost/dexdrip/LibreReceiver.java @@ -153,9 +153,10 @@ public void run() { clearNFCsensorAge(); - // Libre2 Raw readings are also sent to Sync+ Followers if - // show raw graph for Libre2 option is activated. - if (Pref.getBoolean("plus_follow_master", false) && Pref.getBoolean("Libre2_showRawGraph", false)) + // send raw values to sync+ followers + if (Pref.getBooleanDefaultFalse("plus_follow_master") // we are the master + && !Pref.getBooleanDefaultFalse("plus_follower_save_power") // we don't want to save power + && Pref.getBooleanDefaultFalse("Libre2_showRawGraph")) // we want to see raw values GcmActivity.syncLibre2RawReading(currentRawValue); break;