From a51113cfdf1690743b5e4cec150b5c7925f014e1 Mon Sep 17 00:00:00 2001 From: Roumen Georgiev Date: Tue, 23 Apr 2019 10:07:32 +0300 Subject: [PATCH 1/7] try to calculate direction of BG if missing --- .../nightscout/androidaps/db/BgReading.java | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java index 6fafdc4b6d..254c2a7318 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java +++ b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java @@ -18,6 +18,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.utils.DecimalFormatter; @DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS) @@ -74,7 +75,8 @@ public class BgReading implements DataPointWithLabelInterface { public String directionToSymbol() { String symbol = ""; if (direction == null) { - symbol = "??"; + direction = calculateDirection(); + this.directionToSymbol(); // possible endless loop ?!? } else if (direction.compareTo("DoubleDown") == 0) { symbol = "\u21ca"; } else if (direction.compareTo("SingleDown") == 0) { @@ -246,4 +248,37 @@ public class BgReading implements DataPointWithLabelInterface { return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction || isZTPrediction; } + + // Copied from xDrip+ + public String calculateDirection(){ + GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); + if (glucoseStatus == null || glucoseStatus.prev_glucose != 0) + return "??"; + +// double slope = glucoseStatus.delta / (glucoseStatus.previous_date - glucoseStatus.date); + double slope = (glucoseStatus.glucose - glucoseStatus.prev_glucose) / (glucoseStatus.previous_date - glucoseStatus.date); + log.debug("Slope is :"+slope+" delta "+glucoseStatus.delta+" date difference "+(glucoseStatus.date - glucoseStatus.previous_date)); + double slope_by_minute = slope * 60000; + String arrow = "NONE"; + + if (slope_by_minute <= (-3.5)) { + arrow = "DoubleDown"; + } else if (slope_by_minute <= (-2)) { + arrow = "SingleDown"; + } else if (slope_by_minute <= (-1)) { + arrow = "FortyFiveDown"; + } else if (slope_by_minute <= (1)) { + arrow = "Flat"; + } else if (slope_by_minute <= (2)) { + arrow = "FortyFiveUp"; + } else if (slope_by_minute <= (3.5)) { + arrow = "SingleUp"; + } else if (slope_by_minute <= (40)) { + arrow = "DoubleUp"; + } + log.debug("Direction set to: "+arrow); + return arrow; + + } + } From 87a6e006b2e6c5398a95429e888790937d664843 Mon Sep 17 00:00:00 2001 From: Roumen Georgiev Date: Tue, 23 Apr 2019 10:08:52 +0300 Subject: [PATCH 2/7] GlucoseStatus changes --- .../plugins/iob/iobCobCalculator/GlucoseStatus.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java index 191ce9e1cd..f2cb7502f0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java @@ -26,6 +26,8 @@ public class GlucoseStatus { public double short_avgdelta = 0d; public double long_avgdelta = 0d; public long date = 0L; + public long previous_date = 0L; + public double prev_glucose = 0d; public String log() { @@ -58,6 +60,8 @@ public class GlucoseStatus { // load 45min //long fromtime = DateUtil.now() - 60 * 1000L * 45; //List data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false); + long prevDate = 0; + double prevValue = 0; synchronized (IobCobCalculatorPlugin.getPlugin().getDataLock()) { @@ -94,6 +98,9 @@ public class GlucoseStatus { status.long_avgdelta = 0d; status.avgdelta = 0d; // for OpenAPS MA status.date = now_date; + status.previous_date = prevDate; // setting the previous value date for slope calculation + status.prev_glucose = prevValue; + if (L.isEnabled(L.GLUCOSE)) log.debug("sizeRecords==1"); return status.round(); @@ -118,6 +125,11 @@ public class GlucoseStatus { // multiply by 5 to get the same units as delta, i.e. mg/dL/5m change = now.value - then.value; avgdelta = change / minutesago * 5; + // save the value of date if it was 5 min ago or less than 10 min + if( minutesago >= 5 && minutesago < 10 ) { + prevDate = then_date; + prevValue = then.value; + } if (L.isEnabled(L.GLUCOSE)) log.debug(then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta); From 34969fdbfd1042e3696fb26730fdbf314448537c Mon Sep 17 00:00:00 2001 From: Roumen Georgiev Date: Thu, 25 Apr 2019 16:57:50 +0300 Subject: [PATCH 3/7] WIP: adding tests --- .../androidaps/db/BgReadingTest.java | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java diff --git a/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java b/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java new file mode 100644 index 0000000000..3467205fba --- /dev/null +++ b/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java @@ -0,0 +1,71 @@ +package info.nightscout.androidaps.db; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.logging.Logger; + +import info.AAPSMocker; +import info.nightscout.androidaps.Constants; +import info.nightscout.androidaps.MainApp; +import info.nightscout.androidaps.logging.L; +import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; +import info.nightscout.androidaps.utils.SP; + +import static org.junit.Assert.*; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({MainApp.class, Logger.class, L.class, SP.class}) +public class BgReadingTest { + private BgReading bgReading = new BgReading(); + @Mock + GlucoseStatus glucoseStatus; + + @Test + public void valueToUnits() { + bgReading.value = 18; + assertEquals(18, bgReading.valueToUnits(Constants.MGDL)*1, 0.01d); + assertEquals(1, bgReading.valueToUnits(Constants.MMOL)*1, 0.01d); + } + + @Test + public void directionToSymbol() { + bgReading = new BgReading(); + bgReading.direction = "DoubleDown"; + assertEquals("\u21ca", bgReading.directionToSymbol()); + bgReading.direction = "SingleDown"; + assertEquals("\u2193", bgReading.directionToSymbol()); + bgReading.direction = "FortyFiveDown"; + assertEquals("\u2198", bgReading.directionToSymbol()); + bgReading.direction = "Flat"; + assertEquals("\u2192", bgReading.directionToSymbol()); + bgReading.direction = "FortyFiveUp"; + assertEquals("\u2197", bgReading.directionToSymbol()); + bgReading.direction = "SingleUp"; + assertEquals("\u2191", bgReading.directionToSymbol()); + bgReading.direction = "DoubleUp"; + assertEquals("\u21c8", bgReading.directionToSymbol()); + bgReading.direction = "OUT OF RANGE"; + assertEquals("??", bgReading.directionToSymbol()); + + } + + @Test + public void calculateDirection() throws Exception { + assertEquals("??", bgReading.calculateDirection()); + + + } + + @Before + public void prepareMock() { + AAPSMocker.mockMainApp(); + AAPSMocker.mockApplicationContext(); + AAPSMocker.mockSP(); + AAPSMocker.mockL(); + } +} \ No newline at end of file From 85bf1fd6bd634463d8cb43887983049efff94deb Mon Sep 17 00:00:00 2001 From: Roumen Georgiev Date: Tue, 30 Apr 2019 15:07:43 +0300 Subject: [PATCH 4/7] Fix + more tests --- .../nightscout/androidaps/db/BgReading.java | 17 +++- .../androidaps/db/BgReadingTest.java | 83 +++++++++++++++++++ 2 files changed, 96 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java index 254c2a7318..6f87f232de 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java +++ b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java @@ -251,12 +251,16 @@ public class BgReading implements DataPointWithLabelInterface { // Copied from xDrip+ public String calculateDirection(){ - GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); - if (glucoseStatus == null || glucoseStatus.prev_glucose != 0) + GlucoseStatus glucoseStatus = getGlucoseStatus(); + double slope = 0; + if (glucoseStatus == null || glucoseStatus.prev_glucose == 0) return "??"; -// double slope = glucoseStatus.delta / (glucoseStatus.previous_date - glucoseStatus.date); - double slope = (glucoseStatus.glucose - glucoseStatus.prev_glucose) / (glucoseStatus.previous_date - glucoseStatus.date); + // Avoid division by 0 + if (glucoseStatus.date == glucoseStatus.previous_date) + slope = 0; + else + slope = (glucoseStatus.prev_glucose - glucoseStatus.glucose) / (glucoseStatus.previous_date - glucoseStatus.date); log.debug("Slope is :"+slope+" delta "+glucoseStatus.delta+" date difference "+(glucoseStatus.date - glucoseStatus.previous_date)); double slope_by_minute = slope * 60000; String arrow = "NONE"; @@ -281,4 +285,9 @@ public class BgReading implements DataPointWithLabelInterface { } + // Used for testing purpose + protected GlucoseStatus getGlucoseStatus() { + return GlucoseStatus.getGlucoseStatusData(); + } + } diff --git a/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java b/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java index 3467205fba..4a43f9fb7a 100644 --- a/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java +++ b/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java @@ -4,9 +4,11 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.Mockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import java.util.Date; import java.util.logging.Logger; import info.AAPSMocker; @@ -17,6 +19,7 @@ import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.utils.SP; import static org.junit.Assert.*; +import static org.powermock.api.mockito.PowerMockito.doReturn; @RunWith(PowerMockRunner.class) @PrepareForTest({MainApp.class, Logger.class, L.class, SP.class}) @@ -54,10 +57,90 @@ public class BgReadingTest { } + @Test + public void dateTest(){ + bgReading = new BgReading(); + long now = System.currentTimeMillis(); + bgReading.date = now; + Date nowDate = new Date(now); + assertEquals(now, bgReading.date(now).date); + assertEquals(now, bgReading.date(nowDate).date); + } + + @Test + public void valueTest(){ + bgReading = new BgReading(); + double valueToSet = 81; // 4.5 mmol + assertEquals(81d, bgReading.value(valueToSet).value, 0.01d); + } + + @Test + public void copyFromTest(){ + bgReading = new BgReading(); + BgReading copy = new BgReading(); + bgReading.value = 81; + long now = System.currentTimeMillis(); + bgReading.date = now; + copy.date = now; + + copy.copyFrom(bgReading); + + assertEquals(81, copy.value, 0.1d); + assertEquals(now, copy.date); + assertEquals(bgReading.directionToSymbol(), copy.directionToSymbol()); + } + + @Test + public void isEqualTest(){ + bgReading = new BgReading(); + BgReading copy = new BgReading(); + bgReading.value = 81; + long now = System.currentTimeMillis(); + bgReading.date = now; + copy.date = now; + + copy.copyFrom(bgReading); + + assertEquals(true, copy.isEqual(bgReading)); + assertEquals(false, copy.isEqual(new BgReading())); + } + @Test public void calculateDirection() throws Exception { assertEquals("??", bgReading.calculateDirection()); + bgReading = new BgReading(); + glucoseStatus = new GlucoseStatus(); + glucoseStatus.glucose = 0; + glucoseStatus.prev_glucose = 0; + glucoseStatus.date = 1000L * 60 * 12;; + glucoseStatus.previous_date = 1000L * 60 * 6; + BgReading newReading = Mockito.spy(new BgReading()); + doReturn(glucoseStatus).when(newReading).getGlucoseStatus(); + assertEquals("??", newReading.calculateDirection()); + glucoseStatus.glucose = 72; + glucoseStatus.prev_glucose = 10; + assertEquals("DoubleUp", newReading.calculateDirection()); + glucoseStatus.glucose = 72; + glucoseStatus.prev_glucose = 55; + assertEquals("SingleUp", newReading.calculateDirection()); + glucoseStatus.glucose = 72; + glucoseStatus.prev_glucose = 65; + assertEquals("FortyFiveUp", newReading.calculateDirection()); + glucoseStatus.glucose = 72; + glucoseStatus.prev_glucose = 70; + assertEquals("Flat", newReading.calculateDirection()); + glucoseStatus.glucose = 10; + glucoseStatus.prev_glucose = 72; + assertEquals("DoubleDown", newReading.calculateDirection()); + glucoseStatus.glucose = 55; + glucoseStatus.prev_glucose = 72; + assertEquals("SingleDown", newReading.calculateDirection()); + glucoseStatus.glucose = 65; + glucoseStatus.prev_glucose = 72; + assertEquals("FortyFiveDown", newReading.calculateDirection()); + + } From 62b2d83a1818c6e6ec70c6ff9e8850cf8fbeb05c Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Fri, 10 May 2019 08:47:32 +0200 Subject: [PATCH 5/7] cleanup (#68) --- .../nightscout/androidaps/db/BgReading.java | 51 +++++++++---------- .../iob/iobCobCalculator/GlucoseStatus.java | 6 ++- .../androidaps/db/BgReadingTest.java | 45 ++++++++-------- 3 files changed, 52 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java index 6f87f232de..bfedc94ad0 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java +++ b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java @@ -23,7 +23,7 @@ import info.nightscout.androidaps.utils.DecimalFormatter; @DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS) public class BgReading implements DataPointWithLabelInterface { - private static Logger log = LoggerFactory.getLogger(L.DATABASE); + private static Logger log = LoggerFactory.getLogger(L.GLUCOSE); @DatabaseField(id = true) public long date; @@ -74,10 +74,10 @@ public class BgReading implements DataPointWithLabelInterface { public String directionToSymbol() { String symbol = ""; - if (direction == null) { + if (direction == null) direction = calculateDirection(); - this.directionToSymbol(); // possible endless loop ?!? - } else if (direction.compareTo("DoubleDown") == 0) { + + if (direction.compareTo("DoubleDown") == 0) { symbol = "\u21ca"; } else if (direction.compareTo("SingleDown") == 0) { symbol = "\u2193"; @@ -97,18 +97,13 @@ public class BgReading implements DataPointWithLabelInterface { return symbol; } - public static boolean isSlopeNameInvalid(String direction) { - if (direction.compareTo("NOT_COMPUTABLE") == 0 || + private static boolean isSlopeNameInvalid(String direction) { + return direction.compareTo("NOT_COMPUTABLE") == 0 || direction.compareTo("NOT COMPUTABLE") == 0 || direction.compareTo("OUT_OF_RANGE") == 0 || direction.compareTo("OUT OF RANGE") == 0 || direction.compareTo("NONE") == 0 || - direction.compareTo("NotComputable") == 0 - ) { - return true; - } else { - return false; - } + direction.compareTo("NotComputable") == 0; } @@ -125,7 +120,8 @@ public class BgReading implements DataPointWithLabelInterface { public boolean isDataChanging(BgReading other) { if (date != other.date) { - log.error("Comparing different"); + if (L.isEnabled(L.GLUCOSE)) + log.error("Comparing different"); return false; } if (value != other.value) @@ -135,7 +131,8 @@ public class BgReading implements DataPointWithLabelInterface { public boolean isEqual(BgReading other) { if (date != other.date) { - log.error("Comparing different"); + if (L.isEnabled(L.GLUCOSE)) + log.error("Comparing different"); return false; } if (value != other.value) @@ -151,7 +148,8 @@ public class BgReading implements DataPointWithLabelInterface { public void copyFrom(BgReading other) { if (date != other.date) { - log.error("Copying different"); + if (L.isEnabled(L.GLUCOSE)) + log.error("Copying different"); return; } value = other.value; @@ -250,18 +248,21 @@ public class BgReading implements DataPointWithLabelInterface { // Copied from xDrip+ - public String calculateDirection(){ - GlucoseStatus glucoseStatus = getGlucoseStatus(); - double slope = 0; + String calculateDirection() { + GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); + double slope; if (glucoseStatus == null || glucoseStatus.prev_glucose == 0) - return "??"; + return "NONE"; // Avoid division by 0 if (glucoseStatus.date == glucoseStatus.previous_date) slope = 0; else slope = (glucoseStatus.prev_glucose - glucoseStatus.glucose) / (glucoseStatus.previous_date - glucoseStatus.date); - log.debug("Slope is :"+slope+" delta "+glucoseStatus.delta+" date difference "+(glucoseStatus.date - glucoseStatus.previous_date)); + + if (L.isEnabled(L.GLUCOSE)) + log.debug("Slope is :" + slope + " delta " + glucoseStatus.delta + " date difference " + (glucoseStatus.date - glucoseStatus.previous_date)); + double slope_by_minute = slope * 60000; String arrow = "NONE"; @@ -280,14 +281,8 @@ public class BgReading implements DataPointWithLabelInterface { } else if (slope_by_minute <= (40)) { arrow = "DoubleUp"; } - log.debug("Direction set to: "+arrow); + if (L.isEnabled(L.GLUCOSE)) + log.debug("Direction set to: " + arrow); return arrow; - } - - // Used for testing purpose - protected GlucoseStatus getGlucoseStatus() { - return GlucoseStatus.getGlucoseStatusData(); - } - } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java index f2cb7502f0..54cac18e70 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java @@ -98,8 +98,8 @@ public class GlucoseStatus { status.long_avgdelta = 0d; status.avgdelta = 0d; // for OpenAPS MA status.date = now_date; - status.previous_date = prevDate; // setting the previous value date for slope calculation - status.prev_glucose = prevValue; + status.previous_date = 0; // setting the previous value date for slope calculation + status.prev_glucose = 0; if (L.isEnabled(L.GLUCOSE)) log.debug("sizeRecords==1"); @@ -171,6 +171,8 @@ public class GlucoseStatus { status.long_avgdelta = average(long_deltas); status.avgdelta = status.short_avgdelta; // for OpenAPS MA + status.previous_date = prevDate; // setting the previous value date for slope calculation + status.prev_glucose = prevValue; if (L.isEnabled(L.GLUCOSE)) log.debug(status.log()); diff --git a/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java b/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java index 4a43f9fb7a..b1b61285f4 100644 --- a/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java +++ b/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java @@ -5,6 +5,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @@ -18,21 +19,23 @@ import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.utils.SP; -import static org.junit.Assert.*; -import static org.powermock.api.mockito.PowerMockito.doReturn; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; +import static org.mockito.Mockito.when; @RunWith(PowerMockRunner.class) -@PrepareForTest({MainApp.class, Logger.class, L.class, SP.class}) +@PrepareForTest({MainApp.class, Logger.class, L.class, SP.class, GlucoseStatus.class}) public class BgReadingTest { private BgReading bgReading = new BgReading(); - @Mock + GlucoseStatus glucoseStatus; @Test public void valueToUnits() { bgReading.value = 18; - assertEquals(18, bgReading.valueToUnits(Constants.MGDL)*1, 0.01d); - assertEquals(1, bgReading.valueToUnits(Constants.MMOL)*1, 0.01d); + assertEquals(18, bgReading.valueToUnits(Constants.MGDL) * 1, 0.01d); + assertEquals(1, bgReading.valueToUnits(Constants.MMOL) * 1, 0.01d); } @Test @@ -58,7 +61,7 @@ public class BgReadingTest { } @Test - public void dateTest(){ + public void dateTest() { bgReading = new BgReading(); long now = System.currentTimeMillis(); bgReading.date = now; @@ -68,14 +71,14 @@ public class BgReadingTest { } @Test - public void valueTest(){ + public void valueTest() { bgReading = new BgReading(); double valueToSet = 81; // 4.5 mmol assertEquals(81d, bgReading.value(valueToSet).value, 0.01d); } @Test - public void copyFromTest(){ + public void copyFromTest() { bgReading = new BgReading(); BgReading copy = new BgReading(); bgReading.value = 81; @@ -91,7 +94,7 @@ public class BgReadingTest { } @Test - public void isEqualTest(){ + public void isEqualTest() { bgReading = new BgReading(); BgReading copy = new BgReading(); bgReading.value = 81; @@ -101,23 +104,26 @@ public class BgReadingTest { copy.copyFrom(bgReading); - assertEquals(true, copy.isEqual(bgReading)); - assertEquals(false, copy.isEqual(new BgReading())); + assertTrue(copy.isEqual(bgReading)); + assertFalse(copy.isEqual(new BgReading())); } @Test - public void calculateDirection() throws Exception { - assertEquals("??", bgReading.calculateDirection()); + public void calculateDirection() { + assertEquals("NONE", bgReading.calculateDirection()); - bgReading = new BgReading(); glucoseStatus = new GlucoseStatus(); glucoseStatus.glucose = 0; glucoseStatus.prev_glucose = 0; - glucoseStatus.date = 1000L * 60 * 12;; + glucoseStatus.date = 1000L * 60 * 12; glucoseStatus.previous_date = 1000L * 60 * 6; - BgReading newReading = Mockito.spy(new BgReading()); - doReturn(glucoseStatus).when(newReading).getGlucoseStatus(); - assertEquals("??", newReading.calculateDirection()); + + BgReading newReading = new BgReading(); + + PowerMockito.mockStatic(GlucoseStatus.class); + when(GlucoseStatus.getGlucoseStatusData()).thenReturn(glucoseStatus); + + assertEquals("NONE", newReading.calculateDirection()); glucoseStatus.glucose = 72; glucoseStatus.prev_glucose = 10; assertEquals("DoubleUp", newReading.calculateDirection()); @@ -141,7 +147,6 @@ public class BgReadingTest { assertEquals("FortyFiveDown", newReading.calculateDirection()); - } @Before From 6e63d340cd29e23152b254e24d2be6f95b9817e5 Mon Sep 17 00:00:00 2001 From: Roumen Georgiev Date: Mon, 13 May 2019 14:18:10 +0300 Subject: [PATCH 6/7] reworked to use DBHelper --- .../nightscout/androidaps/db/BgReading.java | 25 ++++-- .../iob/iobCobCalculator/GlucoseStatus.java | 14 ---- .../androidaps/db/BgReadingTest.java | 81 ++++++++++--------- 3 files changed, 63 insertions(+), 57 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java index bfedc94ad0..8f7782cff2 100644 --- a/app/src/main/java/info/nightscout/androidaps/db/BgReading.java +++ b/app/src/main/java/info/nightscout/androidaps/db/BgReading.java @@ -7,6 +7,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.Date; +import java.util.List; import java.util.Objects; import info.nightscout.androidaps.Constants; @@ -18,8 +19,8 @@ import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv; import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin; import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface; import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries; -import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus; import info.nightscout.androidaps.utils.DecimalFormatter; +import info.nightscout.androidaps.utils.T; @DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS) public class BgReading implements DataPointWithLabelInterface { @@ -249,19 +250,29 @@ public class BgReading implements DataPointWithLabelInterface { // Copied from xDrip+ String calculateDirection() { - GlucoseStatus glucoseStatus = GlucoseStatus.getGlucoseStatusData(); - double slope; - if (glucoseStatus == null || glucoseStatus.prev_glucose == 0) + // Rework to get bgreaings from internal DB and calculate on that base + + List bgReadingsList = MainApp.getDbHelper().getAllBgreadingsDataFromTime(this.date - T.mins(10).msecs(), false); + if (bgReadingsList == null || bgReadingsList.size() < 2) return "NONE"; + BgReading current = bgReadingsList.get(1); + BgReading previous = bgReadingsList.get(0); + + if (bgReadingsList.get(1).date < bgReadingsList.get(0).date) { + current = bgReadingsList.get(0); + previous = bgReadingsList.get(1); + } + + double slope; // Avoid division by 0 - if (glucoseStatus.date == glucoseStatus.previous_date) + if (current.date == previous.date) slope = 0; else - slope = (glucoseStatus.prev_glucose - glucoseStatus.glucose) / (glucoseStatus.previous_date - glucoseStatus.date); + slope = (previous.value - current.value) / (previous.date - current.date); if (L.isEnabled(L.GLUCOSE)) - log.debug("Slope is :" + slope + " delta " + glucoseStatus.delta + " date difference " + (glucoseStatus.date - glucoseStatus.previous_date)); + log.debug("Slope is :" + slope + " delta " + (previous.value - current.value) + " date difference " + (current.date - previous.date)); double slope_by_minute = slope * 60000; String arrow = "NONE"; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java index 54cac18e70..191ce9e1cd 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/iob/iobCobCalculator/GlucoseStatus.java @@ -26,8 +26,6 @@ public class GlucoseStatus { public double short_avgdelta = 0d; public double long_avgdelta = 0d; public long date = 0L; - public long previous_date = 0L; - public double prev_glucose = 0d; public String log() { @@ -60,8 +58,6 @@ public class GlucoseStatus { // load 45min //long fromtime = DateUtil.now() - 60 * 1000L * 45; //List data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false); - long prevDate = 0; - double prevValue = 0; synchronized (IobCobCalculatorPlugin.getPlugin().getDataLock()) { @@ -98,9 +94,6 @@ public class GlucoseStatus { status.long_avgdelta = 0d; status.avgdelta = 0d; // for OpenAPS MA status.date = now_date; - status.previous_date = 0; // setting the previous value date for slope calculation - status.prev_glucose = 0; - if (L.isEnabled(L.GLUCOSE)) log.debug("sizeRecords==1"); return status.round(); @@ -125,11 +118,6 @@ public class GlucoseStatus { // multiply by 5 to get the same units as delta, i.e. mg/dL/5m change = now.value - then.value; avgdelta = change / minutesago * 5; - // save the value of date if it was 5 min ago or less than 10 min - if( minutesago >= 5 && minutesago < 10 ) { - prevDate = then_date; - prevValue = then.value; - } if (L.isEnabled(L.GLUCOSE)) log.debug(then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta); @@ -171,8 +159,6 @@ public class GlucoseStatus { status.long_avgdelta = average(long_deltas); status.avgdelta = status.short_avgdelta; // for OpenAPS MA - status.previous_date = prevDate; // setting the previous value date for slope calculation - status.prev_glucose = prevValue; if (L.isEnabled(L.GLUCOSE)) log.debug(status.log()); diff --git a/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java b/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java index b1b61285f4..991c2f7956 100644 --- a/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java +++ b/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java @@ -3,15 +3,16 @@ package info.nightscout.androidaps.db; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.Mockito; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; +import java.util.ArrayList; import java.util.Date; +import java.util.List; import java.util.logging.Logger; +import edu.emory.mathcs.backport.java.util.Arrays; import info.AAPSMocker; import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; @@ -22,6 +23,8 @@ import info.nightscout.androidaps.utils.SP; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.mockito.ArgumentMatchers.anyBoolean; +import static org.mockito.ArgumentMatchers.anyLong; import static org.mockito.Mockito.when; @RunWith(PowerMockRunner.class) @@ -110,41 +113,32 @@ public class BgReadingTest { @Test public void calculateDirection() { + List bgReadingsList = null; + AAPSMocker.mockDatabaseHelper(); + + when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); assertEquals("NONE", bgReading.calculateDirection()); - - glucoseStatus = new GlucoseStatus(); - glucoseStatus.glucose = 0; - glucoseStatus.prev_glucose = 0; - glucoseStatus.date = 1000L * 60 * 12; - glucoseStatus.previous_date = 1000L * 60 * 6; - - BgReading newReading = new BgReading(); - - PowerMockito.mockStatic(GlucoseStatus.class); - when(GlucoseStatus.getGlucoseStatusData()).thenReturn(glucoseStatus); - - assertEquals("NONE", newReading.calculateDirection()); - glucoseStatus.glucose = 72; - glucoseStatus.prev_glucose = 10; - assertEquals("DoubleUp", newReading.calculateDirection()); - glucoseStatus.glucose = 72; - glucoseStatus.prev_glucose = 55; - assertEquals("SingleUp", newReading.calculateDirection()); - glucoseStatus.glucose = 72; - glucoseStatus.prev_glucose = 65; - assertEquals("FortyFiveUp", newReading.calculateDirection()); - glucoseStatus.glucose = 72; - glucoseStatus.prev_glucose = 70; - assertEquals("Flat", newReading.calculateDirection()); - glucoseStatus.glucose = 10; - glucoseStatus.prev_glucose = 72; - assertEquals("DoubleDown", newReading.calculateDirection()); - glucoseStatus.glucose = 55; - glucoseStatus.prev_glucose = 72; - assertEquals("SingleDown", newReading.calculateDirection()); - glucoseStatus.glucose = 65; - glucoseStatus.prev_glucose = 72; - assertEquals("FortyFiveDown", newReading.calculateDirection()); + bgReadingsList = setReadings(72,0); + when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + assertEquals("DoubleUp", bgReading.calculateDirection()); + bgReadingsList = setReadings(76,60); + when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + assertEquals("SingleUp", bgReading.calculateDirection()); + bgReadingsList = setReadings(74,65); + when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + assertEquals("FortyFiveUp", bgReading.calculateDirection()); + bgReadingsList = setReadings(72,72); + when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + assertEquals("Flat", bgReading.calculateDirection()); + bgReadingsList = setReadings(0,72); + when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + assertEquals("DoubleDown", bgReading.calculateDirection()); + bgReadingsList = setReadings(60,76); + when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + assertEquals("SingleDown", bgReading.calculateDirection()); + bgReadingsList = setReadings(65,74); + when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + assertEquals("FortyFiveDown", bgReading.calculateDirection()); } @@ -155,5 +149,20 @@ public class BgReadingTest { AAPSMocker.mockApplicationContext(); AAPSMocker.mockSP(); AAPSMocker.mockL(); + AAPSMocker.mockDatabaseHelper(); + } + + public List setReadings(int current_value, int previous_value){ + BgReading now = new BgReading(); + now.value = current_value; + now.date = System.currentTimeMillis(); + BgReading previous = new BgReading(); + previous.value = previous_value; + previous.date = System.currentTimeMillis() - ( 6 * 60 * 1000L); + List bgReadings = new ArrayList() {{ + add(now); + add(previous); + }}; + return bgReadings; } } \ No newline at end of file From 453faf736d6b2b09164602d35f73e3e5bf3abc22 Mon Sep 17 00:00:00 2001 From: Roumen Georgiev Date: Wed, 19 Jun 2019 16:59:34 +0300 Subject: [PATCH 7/7] fix test moved the when().thenReturn to setReadings --- .../androidaps/db/BgReadingTest.java | 27 +++++++------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java b/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java index 991c2f7956..d8653d0914 100644 --- a/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java +++ b/app/src/test/java/info/nightscout/androidaps/db/BgReadingTest.java @@ -118,29 +118,20 @@ public class BgReadingTest { when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); assertEquals("NONE", bgReading.calculateDirection()); - bgReadingsList = setReadings(72,0); - when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + setReadings(72,0); assertEquals("DoubleUp", bgReading.calculateDirection()); - bgReadingsList = setReadings(76,60); - when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + setReadings(76,60); assertEquals("SingleUp", bgReading.calculateDirection()); - bgReadingsList = setReadings(74,65); - when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + setReadings(74,65); assertEquals("FortyFiveUp", bgReading.calculateDirection()); - bgReadingsList = setReadings(72,72); - when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + setReadings(72,72); assertEquals("Flat", bgReading.calculateDirection()); - bgReadingsList = setReadings(0,72); - when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + setReadings(0,72); assertEquals("DoubleDown", bgReading.calculateDirection()); - bgReadingsList = setReadings(60,76); - when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + setReadings(60,76); assertEquals("SingleDown", bgReading.calculateDirection()); - bgReadingsList = setReadings(65,74); - when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList); + setReadings(65,74); assertEquals("FortyFiveDown", bgReading.calculateDirection()); - - } @Before @@ -152,7 +143,7 @@ public class BgReadingTest { AAPSMocker.mockDatabaseHelper(); } - public List setReadings(int current_value, int previous_value){ + public void setReadings(int current_value, int previous_value){ BgReading now = new BgReading(); now.value = current_value; now.date = System.currentTimeMillis(); @@ -163,6 +154,6 @@ public class BgReadingTest { add(now); add(previous); }}; - return bgReadings; + when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadings); } } \ No newline at end of file