From a51113cfdf1690743b5e4cec150b5c7925f014e1 Mon Sep 17 00:00:00 2001 From: Roumen Georgiev Date: Tue, 23 Apr 2019 10:07:32 +0300 Subject: [PATCH 001/118] 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 002/118] 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 003/118] 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 004/118] 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 005/118] 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 006/118] 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 007/118] 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 From c8c830f51c79ddf7659c747c22fd904190dfeb84 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 15 Sep 2019 17:53:30 +0200 Subject: [PATCH 008/118] LocalProfileFragment -> kotlin --- .../profile/local/LocalProfileFragment.java | 212 ------------------ .../profile/local/LocalProfileFragment.kt | 169 ++++++++++++++ 2 files changed, 169 insertions(+), 212 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.java deleted file mode 100644 index f8969e9594..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.java +++ /dev/null @@ -1,212 +0,0 @@ -package info.nightscout.androidaps.plugins.profile.local; - - -import android.app.Activity; -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.RadioButton; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.fragment.app.Fragment; - -import java.text.DecimalFormat; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.events.EventInitializationChanged; -import info.nightscout.androidaps.interfaces.PumpDescription; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment; -import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog; -import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow; -import info.nightscout.androidaps.utils.DecimalFormatter; -import info.nightscout.androidaps.utils.FabricPrivacy; -import info.nightscout.androidaps.utils.NumberPicker; -import info.nightscout.androidaps.utils.SafeParse; -import info.nightscout.androidaps.utils.TimeListEdit; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; - -import static info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA; - -public class LocalProfileFragment extends Fragment { - private CompositeDisposable disposable = new CompositeDisposable(); - - private NumberPicker diaView; - private RadioButton mgdlView; - private RadioButton mmolView; - private TimeListEdit basalView; - private Button profileswitchButton; - private Button resetButton; - private Button saveButton; - - private TextView invalidProfile; - - private Runnable save = () -> { - doEdit(); - if (basalView != null) { - basalView.updateLabel(MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel()); - } - }; - - private TextWatcher textWatch = new TextWatcher() { - - @Override - public void afterTextChanged(Editable s) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, - int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, - int before, int count) { - LocalProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(diaView.getText().toString()); - doEdit(); - } - }; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - PumpDescription pumpDescription = ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription(); - View layout = inflater.inflate(R.layout.localprofile_fragment, container, false); - diaView = layout.findViewById(R.id.localprofile_dia); - diaView.setParams(LocalProfilePlugin.getPlugin().dia, MIN_DIA, 12d, 0.1d, new DecimalFormat("0.0"), false, layout.findViewById(R.id.localprofile_save), textWatch); - mgdlView = layout.findViewById(R.id.localprofile_mgdl); - mmolView = layout.findViewById(R.id.localprofile_mmol); - new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save); - new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save); - basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save); - new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save); - profileswitchButton = layout.findViewById(R.id.localprofile_profileswitch); - resetButton = layout.findViewById(R.id.localprofile_reset); - saveButton = layout.findViewById(R.id.localprofile_save); - - - invalidProfile = layout.findViewById(R.id.invalidprofile); - - if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isTempBasalCapable) { - layout.findViewById(R.id.localprofile_basal).setVisibility(View.GONE); - } - - mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); - mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); - - mgdlView.setOnClickListener(v -> { - LocalProfilePlugin.getPlugin().mgdl = mgdlView.isChecked(); - LocalProfilePlugin.getPlugin().mmol = !LocalProfilePlugin.getPlugin().mgdl; - mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); - doEdit(); - }); - mmolView.setOnClickListener(v -> { - LocalProfilePlugin.getPlugin().mmol = mmolView.isChecked(); - LocalProfilePlugin.getPlugin().mgdl = !LocalProfilePlugin.getPlugin().mmol; - mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); - doEdit(); - }); - - profileswitchButton.setOnClickListener(view -> { - NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCHDIRECT; - profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); - newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); - }); - - resetButton.setOnClickListener(view -> { - LocalProfilePlugin.getPlugin().loadSettings(); - mgdlView.setChecked(LocalProfilePlugin.getPlugin().mgdl); - mmolView.setChecked(LocalProfilePlugin.getPlugin().mmol); - diaView.setParams(LocalProfilePlugin.getPlugin().dia, MIN_DIA, 12d, 0.1d, new DecimalFormat("0.0"), false, view.findViewById(R.id.localprofile_save), textWatch); - new TimeListEdit(getContext(), layout, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50d, 0.1d, new DecimalFormat("0.0"), save); - new TimeListEdit(getContext(), layout, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500d, 0.1d, new DecimalFormat("0.0"), save); - basalView = new TimeListEdit(getContext(), layout, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + getSumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10, 0.01d, new DecimalFormat("0.00"), save); - new TimeListEdit(getContext(), layout, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3d, 200, 0.1d, new DecimalFormat("0.0"), save); - updateGUI(); - }); - - saveButton.setOnClickListener(view -> { - if (!LocalProfilePlugin.getPlugin().isValidEditState()) { - return; //Should not happen as saveButton should not be visible if not valid - } - LocalProfilePlugin.getPlugin().storeSettings(); - updateGUI(); - }); - - return layout; - } - - @Override - public synchronized void onResume() { - super.onResume(); - disposable.add(RxBus.INSTANCE - .toObservable(EventInitializationChanged.class) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(event -> updateGUI(), FabricPrivacy::logException) - ); - updateGUI(); - } - - @Override - public synchronized void onPause() { - super.onPause(); - disposable.clear(); - } - - public void doEdit() { - LocalProfilePlugin.getPlugin().setEdited(true); - updateGUI(); - } - - @NonNull - public String getSumLabel() { - ProfileStore profile = LocalProfilePlugin.getPlugin().createProfileStore(); - if (profile != null) - return " ∑" + DecimalFormatter.to2Decimal(profile.getDefaultProfile().baseBasalSum()) + MainApp.gs(R.string.insulin_unit_shortname); - else - return MainApp.gs(R.string.localprofile); - } - - protected void updateGUI() { - Activity activity = getActivity(); - if (activity != null) - activity.runOnUiThread(() -> { - boolean isValid = LocalProfilePlugin.getPlugin().isValidEditState(); - boolean isEdited = LocalProfilePlugin.getPlugin().isEdited(); - if (isValid) { - invalidProfile.setVisibility(View.GONE); //show invalid profile - - if (isEdited) { - //edited profile -> save first - profileswitchButton.setVisibility(View.GONE); - saveButton.setVisibility(View.VISIBLE); - } else { - profileswitchButton.setVisibility(View.VISIBLE); - saveButton.setVisibility(View.GONE); - } - } else { - invalidProfile.setVisibility(View.VISIBLE); - profileswitchButton.setVisibility(View.GONE); - saveButton.setVisibility(View.GONE); //don't save an invalid profile - } - - //Show reset button iff data was edited - if (isEdited) { - resetButton.setVisibility(View.VISIBLE); - } else { - resetButton.setVisibility(View.GONE); - } - }); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt new file mode 100644 index 0000000000..9824933616 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt @@ -0,0 +1,169 @@ +package info.nightscout.androidaps.plugins.profile.local + + +import android.os.Bundle +import android.text.Editable +import android.text.TextWatcher +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.events.EventInitializationChanged +import info.nightscout.androidaps.interfaces.PumpDescription +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin +import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment +import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog +import info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA +import info.nightscout.androidaps.utils.DecimalFormatter +import info.nightscout.androidaps.utils.FabricPrivacy +import info.nightscout.androidaps.utils.SafeParse +import info.nightscout.androidaps.utils.TimeListEdit +import io.reactivex.android.schedulers.AndroidSchedulers +import io.reactivex.disposables.CompositeDisposable +import kotlinx.android.synthetic.main.localprofile_fragment.* +import java.text.DecimalFormat + +class LocalProfileFragment : Fragment() { + private var disposable: CompositeDisposable = CompositeDisposable() + + private var basalView: TimeListEdit? = null + + private val save = Runnable { + doEdit() + basalView?.updateLabel(MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel()) + } + + private val textWatch = object : TextWatcher { + override fun afterTextChanged(s: Editable) {} + override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} + override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { + LocalProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(localprofile_dia.text.toString()) + doEdit() + } + } + + private fun sumLabel(): String { + val profile = LocalProfilePlugin.getPlugin().createProfileStore().defaultProfile + val sum = profile?.baseBasalSum() ?: 0.0 + return " ∑" + DecimalFormatter.to2Decimal(sum) + MainApp.gs(R.string.insulin_unit_shortname) + } + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle?): View? { + return inflater.inflate(R.layout.localprofile_fragment, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return + + localprofile_dia.setParams(LocalProfilePlugin.getPlugin().dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) + TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) + TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) + basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) + TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) + + + if (!pumpDescription.isTempBasalCapable) { + localprofile_basal.visibility = View.GONE + } + + localprofile_mgdl.isChecked = LocalProfilePlugin.getPlugin().mgdl + localprofile_mmol.isChecked = LocalProfilePlugin.getPlugin().mmol + + localprofile_mgdl.setOnClickListener { + LocalProfilePlugin.getPlugin().mgdl = localprofile_mgdl.isChecked + LocalProfilePlugin.getPlugin().mmol = !LocalProfilePlugin.getPlugin().mgdl + localprofile_mmol.isChecked = LocalProfilePlugin.getPlugin().mmol + doEdit() + } + localprofile_mmol.setOnClickListener { + LocalProfilePlugin.getPlugin().mmol = localprofile_mmol.isChecked + LocalProfilePlugin.getPlugin().mgdl = !LocalProfilePlugin.getPlugin().mmol + localprofile_mgdl.isChecked = LocalProfilePlugin.getPlugin().mgdl + doEdit() + } + + localprofile_profileswitch.setOnClickListener { + val newDialog = NewNSTreatmentDialog() + val profileSwitch = CareportalFragment.PROFILESWITCHDIRECT + profileSwitch.executeProfileSwitch = true + newDialog.setOptions(profileSwitch, R.string.careportal_profileswitch) + fragmentManager?.let { newDialog.show(it, "NewNSTreatmentDialog") } + } + + localprofile_reset.setOnClickListener { + LocalProfilePlugin.getPlugin().loadSettings() + localprofile_mgdl.isChecked = LocalProfilePlugin.getPlugin().mgdl + localprofile_mmol.isChecked = LocalProfilePlugin.getPlugin().mmol + localprofile_dia.setParams(LocalProfilePlugin.getPlugin().dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) + TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) + TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) + basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) + TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) + updateGUI() + } + + localprofile_save.setOnClickListener { + if (!LocalProfilePlugin.getPlugin().isValidEditState) { + return@setOnClickListener //Should not happen as saveButton should not be visible if not valid + } + LocalProfilePlugin.getPlugin().storeSettings() + updateGUI() + } + updateGUI() + } + + @Synchronized + override fun onResume() { + super.onResume() + disposable.add(RxBus + .toObservable(EventInitializationChanged::class.java) + .observeOn(AndroidSchedulers.mainThread()) + .subscribe({ updateGUI() }, { FabricPrivacy.logException(it) }) + ) + } + + @Synchronized + override fun onPause() { + super.onPause() + disposable.clear() + } + + fun doEdit() { + LocalProfilePlugin.getPlugin().isEdited = true + updateGUI() + } + + fun updateGUI() { + if (invalidprofile == null) return + val isValid = LocalProfilePlugin.getPlugin().isValidEditState + val isEdited = LocalProfilePlugin.getPlugin().isEdited + if (isValid) { + invalidprofile.visibility = View.GONE //show invalid profile + + if (isEdited) { + //edited profile -> save first + localprofile_profileswitch.visibility = View.GONE + localprofile_save.visibility = View.VISIBLE + } else { + localprofile_profileswitch.visibility = View.VISIBLE + localprofile_save.visibility = View.GONE + } + } else { + invalidprofile.visibility = View.VISIBLE + localprofile_profileswitch.visibility = View.GONE + localprofile_save.visibility = View.GONE //don't save an invalid profile + } + + //Show reset button iff data was edited + if (isEdited) { + localprofile_reset.visibility = View.VISIBLE + } else { + localprofile_reset.visibility = View.GONE + } + } +} From cf506a5439d876dbdeb4fdfdbdc18373c42bf552 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 15 Sep 2019 18:19:36 +0200 Subject: [PATCH 009/118] LocalProfilePlugin -> kotlin --- .../info/nightscout/androidaps/MainApp.java | 2 +- .../profile/local/LocalProfileFragment.kt | 59 +++-- .../profile/local/LocalProfilePlugin.java | 231 ------------------ .../profile/local/LocalProfilePlugin.kt | 217 ++++++++++++++++ .../androidaps/setupwizard/SWDefinition.java | 4 +- 5 files changed, 249 insertions(+), 264 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index a1300f59bc..89f08b908e 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -189,7 +189,7 @@ public class MainApp extends Application { if (Config.APS) pluginsList.add(OpenAPSSMBPlugin.getPlugin()); pluginsList.add(NSProfilePlugin.getPlugin()); if (Config.OTHERPROFILES) pluginsList.add(SimpleProfilePlugin.getPlugin()); - if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.getPlugin()); + if (Config.OTHERPROFILES) pluginsList.add(LocalProfilePlugin.INSTANCE); pluginsList.add(TreatmentsPlugin.getPlugin()); if (Config.SAFETY) pluginsList.add(SafetyPlugin.getPlugin()); if (Config.SAFETY) pluginsList.add(VersionCheckerPlugin.INSTANCE); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt index 9824933616..54cd41ee45 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt @@ -11,7 +11,6 @@ import androidx.fragment.app.Fragment import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R import info.nightscout.androidaps.events.EventInitializationChanged -import info.nightscout.androidaps.interfaces.PumpDescription import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment @@ -40,13 +39,13 @@ class LocalProfileFragment : Fragment() { override fun afterTextChanged(s: Editable) {} override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { - LocalProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(localprofile_dia.text.toString()) + LocalProfilePlugin.dia = SafeParse.stringToDouble(localprofile_dia.text.toString()) doEdit() } } private fun sumLabel(): String { - val profile = LocalProfilePlugin.getPlugin().createProfileStore().defaultProfile + val profile = LocalProfilePlugin.createProfileStore().defaultProfile val sum = profile?.baseBasalSum() ?: 0.0 return " ∑" + DecimalFormatter.to2Decimal(sum) + MainApp.gs(R.string.insulin_unit_shortname) } @@ -60,30 +59,30 @@ class LocalProfileFragment : Fragment() { super.onViewCreated(view, savedInstanceState) val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return - localprofile_dia.setParams(LocalProfilePlugin.getPlugin().dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) - TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) - TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) - basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) - TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) + localprofile_dia.setParams(LocalProfilePlugin.dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) + TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) + TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) + basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) + TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.targetLow, LocalProfilePlugin.targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) if (!pumpDescription.isTempBasalCapable) { localprofile_basal.visibility = View.GONE } - localprofile_mgdl.isChecked = LocalProfilePlugin.getPlugin().mgdl - localprofile_mmol.isChecked = LocalProfilePlugin.getPlugin().mmol + localprofile_mgdl.isChecked = LocalProfilePlugin.mgdl + localprofile_mmol.isChecked = LocalProfilePlugin.mmol localprofile_mgdl.setOnClickListener { - LocalProfilePlugin.getPlugin().mgdl = localprofile_mgdl.isChecked - LocalProfilePlugin.getPlugin().mmol = !LocalProfilePlugin.getPlugin().mgdl - localprofile_mmol.isChecked = LocalProfilePlugin.getPlugin().mmol + LocalProfilePlugin.mgdl = localprofile_mgdl.isChecked + LocalProfilePlugin.mmol = !LocalProfilePlugin.mgdl + localprofile_mmol.isChecked = LocalProfilePlugin.mmol doEdit() } localprofile_mmol.setOnClickListener { - LocalProfilePlugin.getPlugin().mmol = localprofile_mmol.isChecked - LocalProfilePlugin.getPlugin().mgdl = !LocalProfilePlugin.getPlugin().mmol - localprofile_mgdl.isChecked = LocalProfilePlugin.getPlugin().mgdl + LocalProfilePlugin.mmol = localprofile_mmol.isChecked + LocalProfilePlugin.mgdl = !LocalProfilePlugin.mmol + localprofile_mgdl.isChecked = LocalProfilePlugin.mgdl doEdit() } @@ -96,22 +95,22 @@ class LocalProfileFragment : Fragment() { } localprofile_reset.setOnClickListener { - LocalProfilePlugin.getPlugin().loadSettings() - localprofile_mgdl.isChecked = LocalProfilePlugin.getPlugin().mgdl - localprofile_mmol.isChecked = LocalProfilePlugin.getPlugin().mmol - localprofile_dia.setParams(LocalProfilePlugin.getPlugin().dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) - TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.getPlugin().ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) - TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.getPlugin().isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) - basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.getPlugin().basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) - TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.getPlugin().targetLow, LocalProfilePlugin.getPlugin().targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) + LocalProfilePlugin.loadSettings() + localprofile_mgdl.isChecked = LocalProfilePlugin.mgdl + localprofile_mmol.isChecked = LocalProfilePlugin.mmol + localprofile_dia.setParams(LocalProfilePlugin.dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) + TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) + TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) + basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) + TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.targetLow, LocalProfilePlugin.targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) updateGUI() } localprofile_save.setOnClickListener { - if (!LocalProfilePlugin.getPlugin().isValidEditState) { + if (!LocalProfilePlugin.isValidEditState()) { return@setOnClickListener //Should not happen as saveButton should not be visible if not valid } - LocalProfilePlugin.getPlugin().storeSettings() + LocalProfilePlugin.storeSettings() updateGUI() } updateGUI() @@ -134,14 +133,14 @@ class LocalProfileFragment : Fragment() { } fun doEdit() { - LocalProfilePlugin.getPlugin().isEdited = true + LocalProfilePlugin.isEdited = true updateGUI() } fun updateGUI() { if (invalidprofile == null) return - val isValid = LocalProfilePlugin.getPlugin().isValidEditState - val isEdited = LocalProfilePlugin.getPlugin().isEdited + val isValid = LocalProfilePlugin.isValidEditState() + val isEdited = LocalProfilePlugin.isEdited if (isValid) { invalidprofile.visibility = View.GONE //show invalid profile @@ -159,7 +158,7 @@ class LocalProfileFragment : Fragment() { localprofile_save.visibility = View.GONE //don't save an invalid profile } - //Show reset button iff data was edited + //Show reset button if data was edited if (isEdited) { localprofile_reset.visibility = View.VISIBLE } else { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.java deleted file mode 100644 index e3e068c1cb..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.java +++ /dev/null @@ -1,231 +0,0 @@ -package info.nightscout.androidaps.plugins.profile.local; - -import androidx.annotation.NonNull; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.events.EventProfileStoreChanged; -import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.PluginDescription; -import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.interfaces.ProfileInterface; -import info.nightscout.androidaps.logging.L; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.utils.DecimalFormatter; -import info.nightscout.androidaps.utils.SP; - -/** - * Created by mike on 05.08.2016. - */ -public class LocalProfilePlugin extends PluginBase implements ProfileInterface { - public static final String LOCAL_PROFILE = "LocalProfile"; - private static Logger log = LoggerFactory.getLogger(L.PROFILE); - - private static LocalProfilePlugin localProfilePlugin; - - public static LocalProfilePlugin getPlugin() { - if (localProfilePlugin == null) - localProfilePlugin = new LocalProfilePlugin(); - return localProfilePlugin; - } - - private ProfileStore convertedProfile = null; - - private static final String DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]"; - - public boolean isEdited() { - return edited; - } - - public void setEdited(boolean edited) { - this.edited = edited; - } - - boolean edited; - boolean mgdl; - boolean mmol; - Double dia; - JSONArray ic; - JSONArray isf; - JSONArray basal; - JSONArray targetLow; - JSONArray targetHigh; - - public LocalProfilePlugin() { - super(new PluginDescription() - .mainType(PluginType.PROFILE) - .fragmentClass(LocalProfileFragment.class.getName()) - .pluginName(R.string.localprofile) - .shortName(R.string.localprofile_shortname) - .description(R.string.description_profile_local) - ); - loadSettings(); - } - - public synchronized void storeSettings() { - SP.putBoolean(LOCAL_PROFILE + "mmol", mmol); - SP.putBoolean(LOCAL_PROFILE + "mgdl", mgdl); - SP.putString(LOCAL_PROFILE + "dia", dia.toString()); - SP.putString(LOCAL_PROFILE + "ic", ic.toString()); - SP.putString(LOCAL_PROFILE + "isf", isf.toString()); - SP.putString(LOCAL_PROFILE + "basal", basal.toString()); - SP.putString(LOCAL_PROFILE + "targetlow", targetLow.toString()); - SP.putString(LOCAL_PROFILE + "targethigh", targetHigh.toString()); - - createAndStoreConvertedProfile(); - edited = false; - if (L.isEnabled(L.PROFILE)) - log.debug("Storing settings: " + getRawProfile().getData().toString()); - RxBus.INSTANCE.send(new EventProfileStoreChanged()); - } - - public synchronized void loadSettings() { - if (L.isEnabled(L.PROFILE)) - log.debug("Loading stored settings"); - - mgdl = SP.getBoolean(LOCAL_PROFILE + "mgdl", false); - mmol = SP.getBoolean(LOCAL_PROFILE + "mmol", true); - dia = SP.getDouble(LOCAL_PROFILE + "dia", Constants.defaultDIA); - try { - ic = new JSONArray(SP.getString(LOCAL_PROFILE + "ic", DEFAULTARRAY)); - } catch (JSONException e1) { - try { - ic = new JSONArray(DEFAULTARRAY); - } catch (JSONException ignored) { - } - } - try { - isf = new JSONArray(SP.getString(LOCAL_PROFILE + "isf", DEFAULTARRAY)); - } catch (JSONException e1) { - try { - isf = new JSONArray(DEFAULTARRAY); - } catch (JSONException ignored) { - } - } - try { - basal = new JSONArray(SP.getString(LOCAL_PROFILE + "basal", DEFAULTARRAY)); - } catch (JSONException e1) { - try { - basal = new JSONArray(DEFAULTARRAY); - } catch (JSONException ignored) { - } - } - try { - targetLow = new JSONArray(SP.getString(LOCAL_PROFILE + "targetlow", DEFAULTARRAY)); - } catch (JSONException e1) { - try { - targetLow = new JSONArray(DEFAULTARRAY); - } catch (JSONException ignored) { - } - } - try { - targetHigh = new JSONArray(SP.getString(LOCAL_PROFILE + "targethigh", DEFAULTARRAY)); - } catch (JSONException e1) { - try { - targetHigh = new JSONArray(DEFAULTARRAY); - } catch (JSONException ignored) { - } - } - edited = false; - createAndStoreConvertedProfile(); - } - - /* - { - "_id": "576264a12771b7500d7ad184", - "startDate": "2016-06-16T08:35:00.000Z", - "defaultProfile": "Default", - "store": { - "Default": { - "dia": "3", - "carbratio": [{ - "time": "00:00", - "value": "30" - }], - "carbs_hr": "20", - "delay": "20", - "sens": [{ - "time": "00:00", - "value": "100" - }], - "timezone": "UTC", - "basal": [{ - "time": "00:00", - "value": "0.1" - }], - "target_low": [{ - "time": "00:00", - "value": "0" - }], - "target_high": [{ - "time": "00:00", - "value": "0" - }], - "startDate": "1970-01-01T00:00:00.000Z", - "units": "mmol" - } - }, - "created_at": "2016-06-16T08:34:41.256Z" - } - */ - private void createAndStoreConvertedProfile() { - convertedProfile = createProfileStore(); - } - - public synchronized boolean isValidEditState() { - return createProfileStore().getDefaultProfile().isValid(MainApp.gs(R.string.localprofile), false); - } - - @NonNull - public ProfileStore createProfileStore() { - JSONObject json = new JSONObject(); - JSONObject store = new JSONObject(); - JSONObject profile = new JSONObject(); - - try { - json.put("defaultProfile", LOCAL_PROFILE); - json.put("store", store); - profile.put("dia", dia); - profile.put("carbratio", ic); - profile.put("sens", isf); - profile.put("basal", basal); - profile.put("target_low", targetLow); - profile.put("target_high", targetHigh); - profile.put("units", mgdl ? Constants.MGDL : Constants.MMOL); - store.put(LOCAL_PROFILE, profile); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - return new ProfileStore(json); - } - - @Override - public ProfileStore getProfile() { - if (!convertedProfile.getDefaultProfile().isValid(MainApp.gs(R.string.localprofile))) - return null; - return convertedProfile; - } - - public ProfileStore getRawProfile() { - return convertedProfile; - } - - @Override - public String getUnits() { - return mgdl ? Constants.MGDL : Constants.MMOL; - } - - @Override - public String getProfileName() { - return DecimalFormatter.to2Decimal(convertedProfile.getDefaultProfile().percentageBasalSum()) + "U "; - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt new file mode 100644 index 0000000000..e9ead3e4d0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt @@ -0,0 +1,217 @@ +package info.nightscout.androidaps.plugins.profile.local + +import info.nightscout.androidaps.Constants +import info.nightscout.androidaps.MainApp +import info.nightscout.androidaps.R +import info.nightscout.androidaps.data.ProfileStore +import info.nightscout.androidaps.events.EventProfileStoreChanged +import info.nightscout.androidaps.interfaces.PluginBase +import info.nightscout.androidaps.interfaces.PluginDescription +import info.nightscout.androidaps.interfaces.PluginType +import info.nightscout.androidaps.interfaces.ProfileInterface +import info.nightscout.androidaps.logging.L +import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.utils.DecimalFormatter +import info.nightscout.androidaps.utils.SP +import org.json.JSONArray +import org.json.JSONException +import org.json.JSONObject +import org.slf4j.LoggerFactory + +/** + * Created by mike on 05.08.2016. + */ +object LocalProfilePlugin : PluginBase(PluginDescription() + .mainType(PluginType.PROFILE) + .fragmentClass(LocalProfileFragment::class.java.name) + .pluginName(R.string.localprofile) + .shortName(R.string.localprofile_shortname) + .description(R.string.description_profile_local)), ProfileInterface { + + private val log = LoggerFactory.getLogger(L.PROFILE) + + private var rawProfile: ProfileStore? = null + + const val LOCAL_PROFILE = "LocalProfile" + + private const val DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]" + + var isEdited: Boolean = false + internal var mgdl: Boolean = false + internal var mmol: Boolean = false + internal var dia: Double? = null + internal var ic: JSONArray? = null + internal var isf: JSONArray? = null + internal var basal: JSONArray? = null + internal var targetLow: JSONArray? = null + internal var targetHigh: JSONArray? = null + + @Synchronized + fun isValidEditState(): Boolean { + return createProfileStore().defaultProfile?.isValid(MainApp.gs(R.string.localprofile), false) + ?: false + } + + init { + loadSettings() + } + + @Synchronized + fun storeSettings() { + SP.putBoolean(LOCAL_PROFILE + "mmol", mmol) + SP.putBoolean(LOCAL_PROFILE + "mgdl", mgdl) + SP.putString(LOCAL_PROFILE + "dia", dia.toString()) + SP.putString(LOCAL_PROFILE + "ic", ic.toString()) + SP.putString(LOCAL_PROFILE + "isf", isf.toString()) + SP.putString(LOCAL_PROFILE + "basal", basal.toString()) + SP.putString(LOCAL_PROFILE + "targetlow", targetLow.toString()) + SP.putString(LOCAL_PROFILE + "targethigh", targetHigh.toString()) + + createAndStoreConvertedProfile() + isEdited = false + if (L.isEnabled(L.PROFILE)) + log.debug("Storing settings: " + rawProfile?.data.toString()) + RxBus.send(EventProfileStoreChanged()) + } + + @Synchronized + fun loadSettings() { + if (L.isEnabled(L.PROFILE)) + log.debug("Loading stored settings") + + mgdl = SP.getBoolean(LOCAL_PROFILE + "mgdl", false) + mmol = SP.getBoolean(LOCAL_PROFILE + "mmol", true) + dia = SP.getDouble(LOCAL_PROFILE + "dia", Constants.defaultDIA) + try { + ic = JSONArray(SP.getString(LOCAL_PROFILE + "ic", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + ic = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + + } + + try { + isf = JSONArray(SP.getString(LOCAL_PROFILE + "isf", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + isf = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + + } + + try { + basal = JSONArray(SP.getString(LOCAL_PROFILE + "basal", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + basal = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + + } + + try { + targetLow = JSONArray(SP.getString(LOCAL_PROFILE + "targetlow", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + targetLow = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + + } + + try { + targetHigh = JSONArray(SP.getString(LOCAL_PROFILE + "targethigh", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + targetHigh = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + + } + + isEdited = false + createAndStoreConvertedProfile() + } + + /* + { + "_id": "576264a12771b7500d7ad184", + "startDate": "2016-06-16T08:35:00.000Z", + "defaultProfile": "Default", + "store": { + "Default": { + "dia": "3", + "carbratio": [{ + "time": "00:00", + "value": "30" + }], + "carbs_hr": "20", + "delay": "20", + "sens": [{ + "time": "00:00", + "value": "100" + }], + "timezone": "UTC", + "basal": [{ + "time": "00:00", + "value": "0.1" + }], + "target_low": [{ + "time": "00:00", + "value": "0" + }], + "target_high": [{ + "time": "00:00", + "value": "0" + }], + "startDate": "1970-01-01T00:00:00.000Z", + "units": "mmol" + } + }, + "created_at": "2016-06-16T08:34:41.256Z" + } + */ + private fun createAndStoreConvertedProfile() { + rawProfile = createProfileStore() + } + + fun createProfileStore(): ProfileStore { + val json = JSONObject() + val store = JSONObject() + val profile = JSONObject() + + try { + json.put("defaultProfile", LOCAL_PROFILE) + json.put("store", store) + profile.put("dia", dia) + profile.put("carbratio", ic) + profile.put("sens", isf) + profile.put("basal", basal) + profile.put("target_low", targetLow) + profile.put("target_high", targetHigh) + profile.put("units", if (mgdl) Constants.MGDL else Constants.MMOL) + store.put(LOCAL_PROFILE, profile) + } catch (e: JSONException) { + log.error("Unhandled exception", e) + } + + return ProfileStore(json) + } + + override fun getProfile(): ProfileStore? { + return if (rawProfile?.defaultProfile?.isValid(MainApp.gs(R.string.localprofile)) != true) null else rawProfile + } + + override fun getUnits(): String { + return if (mgdl) Constants.MGDL else Constants.MMOL + } + + override fun getProfileName(): String { + return DecimalFormatter.to2Decimal(rawProfile?.defaultProfile?.percentageBasalSum() + ?: 0.0) + "U " + } + +} diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java index a8b09e7428..5ebfcefcbf 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.java @@ -271,8 +271,8 @@ public class SWDefinition { .skippable(false) .add(new SWFragment(this) .add(new LocalProfileFragment())) - .validator(() -> LocalProfilePlugin.getPlugin().getProfile() != null && LocalProfilePlugin.getPlugin().getProfile().getDefaultProfile() != null && LocalProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid("StartupWizard")) - .visibility(() -> LocalProfilePlugin.getPlugin().isEnabled(PluginType.PROFILE)); + .validator(() -> LocalProfilePlugin.INSTANCE.getProfile() != null && LocalProfilePlugin.INSTANCE.getProfile().getDefaultProfile() != null && LocalProfilePlugin.INSTANCE.getProfile().getDefaultProfile().isValid("StartupWizard")) + .visibility(() -> LocalProfilePlugin.INSTANCE.isEnabled(PluginType.PROFILE)); private SWScreen screenSimpleProfile = new SWScreen(R.string.simpleprofile) .skippable(false) From 60a113bda630a4536cebd2f88b217c559e842ec7 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 16 Sep 2019 09:20:23 +0200 Subject: [PATCH 010/118] fragment redesign --- .../main/res/layout/localprofile_fragment.xml | 148 +++++++++++++----- app/src/main/res/values/strings.xml | 2 + 2 files changed, 107 insertions(+), 43 deletions(-) diff --git a/app/src/main/res/layout/localprofile_fragment.xml b/app/src/main/res/layout/localprofile_fragment.xml index 1edeeb0b31..49fd413115 100644 --- a/app/src/main/res/layout/localprofile_fragment.xml +++ b/app/src/main/res/layout/localprofile_fragment.xml @@ -19,20 +19,99 @@ android:textColor="@android:color/holo_red_light" android:textStyle="bold" /> - + android:layout_height="match_parent" + android:gravity="start" + android:orientation="horizontal"> + + + + + + + + + + + + + + + + + + + + + + - - - + android:paddingTop="5dp"> - - + android:layout_gravity="center_vertical" + android:layout_marginStart="10dp" + android:text="@string/dia" + android:textAppearance="?android:attr/textAppearanceMedium" /> + + + android:layout_marginEnd="10dp" + android:layout_marginBottom="10dp" /> - - + android:text="@string/hours" + android:textAppearance="?android:attr/textAppearanceSmall"/> - - @@ -136,7 +198,7 @@ android:id="@+id/localprofile_profileswitch" style="?android:attr/buttonStyle" android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_height="0dp" android:layout_gravity="center_horizontal" android:layout_marginBottom="3dp" android:layout_marginLeft="10dp" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3139b71a38..f12ac4b06b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1604,5 +1604,7 @@ %1$.1fg IC: %2$.1f Bolus wizard min + Profile name: + Selected: From da447b8afee5e4fb76dc89a4a653846a0151b458 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 16 Sep 2019 15:49:45 +0200 Subject: [PATCH 011/118] LocalProfile allow more profiles --- .../activities/PreferencesActivity.java | 2 +- .../configBuilder/ProfileFunctions.java | 4 + .../profile/local/LocalProfileFragment.kt | 105 +++++--- .../profile/local/LocalProfilePlugin.kt | 246 ++++++++++++++---- .../main/res/layout/localprofile_fragment.xml | 15 +- app/src/main/res/values/arrays.xml | 9 + app/src/main/res/values/strings.xml | 3 + .../{pref_language.xml => pref_general.xml} | 10 + 8 files changed, 298 insertions(+), 96 deletions(-) rename app/src/main/res/xml/{pref_language.xml => pref_general.xml} (65%) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java index 941366f8f0..91093f5bf8 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java @@ -145,8 +145,8 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre if (!Config.NSCLIENT) { addPreferencesFromResource(R.xml.pref_password); } + addPreferencesFromResource(R.xml.pref_general); addPreferencesFromResource(R.xml.pref_age); - addPreferencesFromResource(R.xml.pref_language); addPreferencesFromResource(R.xml.pref_overview); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java index 025d8dac1e..93767bc662 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java @@ -116,6 +116,10 @@ public class ProfileFunctions { return getProfile(System.currentTimeMillis()); } + public static String getSystemUnits() { + return SP.getString(R.string.key_units, Constants.MGDL); + } + public String getProfileUnits() { Profile profile = getProfile(); return profile != null ? profile.getUnits() : Constants.MGDL; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt index 54cd41ee45..a47726c033 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt @@ -7,19 +7,21 @@ import android.text.TextWatcher import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.AdapterView +import android.widget.ArrayAdapter import androidx.fragment.app.Fragment +import info.nightscout.androidaps.Constants import info.nightscout.androidaps.MainApp import info.nightscout.androidaps.R +import info.nightscout.androidaps.data.Profile import info.nightscout.androidaps.events.EventInitializationChanged import info.nightscout.androidaps.plugins.bus.RxBus import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog import info.nightscout.androidaps.plugins.insulin.InsulinOrefBasePlugin.MIN_DIA -import info.nightscout.androidaps.utils.DecimalFormatter -import info.nightscout.androidaps.utils.FabricPrivacy -import info.nightscout.androidaps.utils.SafeParse -import info.nightscout.androidaps.utils.TimeListEdit +import info.nightscout.androidaps.utils.* import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable import kotlinx.android.synthetic.main.localprofile_fragment.* @@ -29,6 +31,7 @@ class LocalProfileFragment : Fragment() { private var disposable: CompositeDisposable = CompositeDisposable() private var basalView: TimeListEdit? = null + private var spinner: SpinnerHelper? = null private val save = Runnable { doEdit() @@ -39,7 +42,7 @@ class LocalProfileFragment : Fragment() { override fun afterTextChanged(s: Editable) {} override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {} override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) { - LocalProfilePlugin.dia = SafeParse.stringToDouble(localprofile_dia.text.toString()) + LocalProfilePlugin.currentProfile().dia = SafeParse.stringToDouble(localprofile_dia.text.toString()) doEdit() } } @@ -57,35 +60,71 @@ class LocalProfileFragment : Fragment() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) + build() + } + + fun build() { val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return + val units = ProfileFunctions.getSystemUnits() - localprofile_dia.setParams(LocalProfilePlugin.dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) - TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) - TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) - basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) - TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.targetLow, LocalProfilePlugin.targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) - - - if (!pumpDescription.isTempBasalCapable) { - localprofile_basal.visibility = View.GONE + localprofile_name.setText(LocalProfilePlugin.currentProfile().name) + localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, HardLimits.MINDIA, HardLimits.MAXDIA, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) + TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.currentProfile().ic, null, HardLimits.MINIC, HardLimits.MAXIC, 0.1, DecimalFormat("0.0"), save) + basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.currentProfile().basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) + if (units == Constants.MGDL) { + TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.currentProfile().isf, null, HardLimits.MINISF, HardLimits.MAXISF, 1.0, DecimalFormat("0"), save) + TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.currentProfile().targetLow, LocalProfilePlugin.currentProfile().targetHigh, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save) + } else { + TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.currentProfile().isf, null, Profile.fromMgdlToUnits(HardLimits.MINISF, Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.MAXISF, Constants.MMOL), 0.1, DecimalFormat("0.0"), save) + TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.currentProfile().targetLow, LocalProfilePlugin.currentProfile().targetHigh, Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), Constants.MMOL), 0.1, DecimalFormat("0.0"), save) } - localprofile_mgdl.isChecked = LocalProfilePlugin.mgdl - localprofile_mmol.isChecked = LocalProfilePlugin.mmol + // Spinner + spinner = SpinnerHelper(view?.findViewById(R.id.localprofile_spinner)) + val profileList: ArrayList = LocalProfilePlugin.profile?.profileList + ?: ArrayList() + context?.let { context -> + val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList) + spinner?.adapter = adapter + spinner?.setSelection(LocalProfilePlugin.currentProfileIndex) + } ?: return + spinner?.setOnItemSelectedListener(object : AdapterView.OnItemSelectedListener { + override fun onNothingSelected(parent: AdapterView<*>?) { + } - localprofile_mgdl.setOnClickListener { - LocalProfilePlugin.mgdl = localprofile_mgdl.isChecked - LocalProfilePlugin.mmol = !LocalProfilePlugin.mgdl - localprofile_mmol.isChecked = LocalProfilePlugin.mmol - doEdit() + override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { + if (LocalProfilePlugin.isEdited) { + context?.let { context -> + OKDialog.show(context, MainApp.gs(R.string.confirmation), MainApp.gs(R.string.doyouwantswitchprofile)) { + LocalProfilePlugin.currentProfileIndex = position + build() + } + } + } else { + LocalProfilePlugin.currentProfileIndex = position + build() + } + } + }) + + localprofile_profile_add.setOnClickListener { + LocalProfilePlugin.addNewProfile() + build() } - localprofile_mmol.setOnClickListener { - LocalProfilePlugin.mmol = localprofile_mmol.isChecked - LocalProfilePlugin.mgdl = !LocalProfilePlugin.mmol - localprofile_mgdl.isChecked = LocalProfilePlugin.mgdl - doEdit() + + localprofile_profile_remove.setOnClickListener { + LocalProfilePlugin.removeCurrentProfile() + build() } + // this is probably not possible because it leads to invalid profile + // if (!pumpDescription.isTempBasalCapable) localprofile_basal.visibility = View.GONE + + localprofile_mgdl.isChecked = LocalProfilePlugin.currentProfile().mgdl + localprofile_mmol.isChecked = !LocalProfilePlugin.currentProfile().mgdl + localprofile_mgdl.isEnabled = false + localprofile_mmol.isEnabled = false + localprofile_profileswitch.setOnClickListener { val newDialog = NewNSTreatmentDialog() val profileSwitch = CareportalFragment.PROFILESWITCHDIRECT @@ -96,13 +135,13 @@ class LocalProfileFragment : Fragment() { localprofile_reset.setOnClickListener { LocalProfilePlugin.loadSettings() - localprofile_mgdl.isChecked = LocalProfilePlugin.mgdl - localprofile_mmol.isChecked = LocalProfilePlugin.mmol - localprofile_dia.setParams(LocalProfilePlugin.dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) - TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) - TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) - basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) - TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.targetLow, LocalProfilePlugin.targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) + localprofile_mgdl.isChecked = LocalProfilePlugin.currentProfile().mgdl + localprofile_mmol.isChecked = !LocalProfilePlugin.currentProfile().mgdl + localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, MIN_DIA, 12.0, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) + TimeListEdit(context, view, R.id.localprofile_ic, MainApp.gs(R.string.nsprofileview_ic_label) + ":", LocalProfilePlugin.currentProfile().ic, null, 0.5, 50.0, 0.1, DecimalFormat("0.0"), save) + TimeListEdit(context, view, R.id.localprofile_isf, MainApp.gs(R.string.nsprofileview_isf_label) + ":", LocalProfilePlugin.currentProfile().isf, null, 0.5, 500.0, 0.1, DecimalFormat("0.0"), save) + basalView = TimeListEdit(context, view, R.id.localprofile_basal, MainApp.gs(R.string.nsprofileview_basal_label) + ": " + sumLabel(), LocalProfilePlugin.currentProfile().basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save) + TimeListEdit(context, view, R.id.localprofile_target, MainApp.gs(R.string.nsprofileview_target_label) + ":", LocalProfilePlugin.currentProfile().targetLow, LocalProfilePlugin.currentProfile().targetHigh, 3.0, 200.0, 0.1, DecimalFormat("0.0"), save) updateGUI() } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt index e9ead3e4d0..859154ca6a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfilePlugin.kt @@ -11,16 +11,17 @@ import info.nightscout.androidaps.interfaces.PluginType import info.nightscout.androidaps.interfaces.ProfileInterface import info.nightscout.androidaps.logging.L import info.nightscout.androidaps.plugins.bus.RxBus +import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions +import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.DecimalFormatter import info.nightscout.androidaps.utils.SP import org.json.JSONArray import org.json.JSONException import org.json.JSONObject import org.slf4j.LoggerFactory +import java.util.* +import kotlin.collections.ArrayList -/** - * Created by mike on 05.08.2016. - */ object LocalProfilePlugin : PluginBase(PluginDescription() .mainType(PluginType.PROFILE) .fragmentClass(LocalProfileFragment::class.java.name) @@ -36,15 +37,28 @@ object LocalProfilePlugin : PluginBase(PluginDescription() private const val DEFAULTARRAY = "[{\"time\":\"00:00\",\"timeAsSeconds\":0,\"value\":0}]" + class SingleProfile { + internal var name: String? = null + internal var mgdl: Boolean = false + internal var dia: Double = Constants.defaultDIA + internal var ic: JSONArray? = null + internal var isf: JSONArray? = null + internal var basal: JSONArray? = null + internal var targetLow: JSONArray? = null + internal var targetHigh: JSONArray? = null + } + var isEdited: Boolean = false - internal var mgdl: Boolean = false - internal var mmol: Boolean = false - internal var dia: Double? = null - internal var ic: JSONArray? = null - internal var isf: JSONArray? = null - internal var basal: JSONArray? = null - internal var targetLow: JSONArray? = null - internal var targetHigh: JSONArray? = null + var profiles: ArrayList = ArrayList() + + internal var numOfProfiles = 0 + internal var currentProfileIndex = 0 + + init { + loadSettings() + } + + fun currentProfile() = profiles[currentProfileIndex] @Synchronized fun isValidEditState(): Boolean { @@ -52,20 +66,22 @@ object LocalProfilePlugin : PluginBase(PluginDescription() ?: false } - init { - loadSettings() - } - @Synchronized fun storeSettings() { - SP.putBoolean(LOCAL_PROFILE + "mmol", mmol) - SP.putBoolean(LOCAL_PROFILE + "mgdl", mgdl) - SP.putString(LOCAL_PROFILE + "dia", dia.toString()) - SP.putString(LOCAL_PROFILE + "ic", ic.toString()) - SP.putString(LOCAL_PROFILE + "isf", isf.toString()) - SP.putString(LOCAL_PROFILE + "basal", basal.toString()) - SP.putString(LOCAL_PROFILE + "targetlow", targetLow.toString()) - SP.putString(LOCAL_PROFILE + "targethigh", targetHigh.toString()) + for (i in 0 until numOfProfiles) { + profiles[i].run { + val LOCAL_PROFILE_NUMBERED = LOCAL_PROFILE + "_" + i + "_" + SP.putString(LOCAL_PROFILE_NUMBERED + "name", name) + SP.putBoolean(LOCAL_PROFILE_NUMBERED + "mgdl", mgdl) + SP.putDouble(LOCAL_PROFILE_NUMBERED + "dia", dia) + SP.putString(LOCAL_PROFILE_NUMBERED + "ic", ic.toString()) + SP.putString(LOCAL_PROFILE_NUMBERED + "isf", isf.toString()) + SP.putString(LOCAL_PROFILE_NUMBERED + "basal", basal.toString()) + SP.putString(LOCAL_PROFILE_NUMBERED + "targetlow", targetLow.toString()) + SP.putString(LOCAL_PROFILE_NUMBERED + "targethigh", targetHigh.toString()) + } + } + SP.putInt(LOCAL_PROFILE + "_profiles", numOfProfiles) createAndStoreConvertedProfile() isEdited = false @@ -76,61 +92,146 @@ object LocalProfilePlugin : PluginBase(PluginDescription() @Synchronized fun loadSettings() { + if (SP.contains(LOCAL_PROFILE + "mgdl")) { + doConversion() + return + } + + numOfProfiles = SP.getInt(LOCAL_PROFILE + "_profiles", 0) + profiles.clear() + numOfProfiles = Math.max(numOfProfiles, 1) // create at least one default profile if none exists + + for (i in 0 until numOfProfiles) { + val p = SingleProfile() + val LOCAL_PROFILE_NUMBERED = LOCAL_PROFILE + "_" + i + "_" + + p.name = SP.getString(LOCAL_PROFILE_NUMBERED + "name", LOCAL_PROFILE + i) + p.mgdl = SP.getBoolean(LOCAL_PROFILE_NUMBERED + "mgdl", false) + p.dia = SP.getDouble(LOCAL_PROFILE_NUMBERED + "dia", Constants.defaultDIA) + try { + p.ic = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "ic", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.ic = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + log.error("Exception", e1) + } + + try { + p.isf = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "isf", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.isf = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + log.error("Exception", e1) + } + + try { + p.basal = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "basal", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.basal = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + log.error("Exception", e1) + } + + try { + p.targetLow = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "targetlow", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.targetLow = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + log.error("Exception", e1) + } + + try { + p.targetHigh = JSONArray(SP.getString(LOCAL_PROFILE_NUMBERED + "targethigh", DEFAULTARRAY)) + } catch (e1: JSONException) { + try { + p.targetHigh = JSONArray(DEFAULTARRAY) + } catch (ignored: JSONException) { + } + log.error("Exception", e1) + } + + profiles.add(p) + } + isEdited = false + createAndStoreConvertedProfile() + } + + @Synchronized + private fun doConversion() { // conversion from 2.3 to 2.4 format if (L.isEnabled(L.PROFILE)) log.debug("Loading stored settings") + val p = SingleProfile() - mgdl = SP.getBoolean(LOCAL_PROFILE + "mgdl", false) - mmol = SP.getBoolean(LOCAL_PROFILE + "mmol", true) - dia = SP.getDouble(LOCAL_PROFILE + "dia", Constants.defaultDIA) + p.mgdl = SP.getBoolean(LOCAL_PROFILE + "mgdl", ProfileFunctions.getSystemUnits() == Constants.MGDL) + p.dia = SP.getDouble(LOCAL_PROFILE + "dia", Constants.defaultDIA) try { - ic = JSONArray(SP.getString(LOCAL_PROFILE + "ic", DEFAULTARRAY)) + p.ic = JSONArray(SP.getString(LOCAL_PROFILE + "ic", DEFAULTARRAY)) } catch (e1: JSONException) { try { - ic = JSONArray(DEFAULTARRAY) + p.ic = JSONArray(DEFAULTARRAY) } catch (ignored: JSONException) { } - } try { - isf = JSONArray(SP.getString(LOCAL_PROFILE + "isf", DEFAULTARRAY)) + p.isf = JSONArray(SP.getString(LOCAL_PROFILE + "isf", DEFAULTARRAY)) } catch (e1: JSONException) { try { - isf = JSONArray(DEFAULTARRAY) + p.isf = JSONArray(DEFAULTARRAY) } catch (ignored: JSONException) { } - } try { - basal = JSONArray(SP.getString(LOCAL_PROFILE + "basal", DEFAULTARRAY)) + p.basal = JSONArray(SP.getString(LOCAL_PROFILE + "basal", DEFAULTARRAY)) } catch (e1: JSONException) { try { - basal = JSONArray(DEFAULTARRAY) + p.basal = JSONArray(DEFAULTARRAY) } catch (ignored: JSONException) { } - } try { - targetLow = JSONArray(SP.getString(LOCAL_PROFILE + "targetlow", DEFAULTARRAY)) + p.targetLow = JSONArray(SP.getString(LOCAL_PROFILE + "targetlow", DEFAULTARRAY)) } catch (e1: JSONException) { try { - targetLow = JSONArray(DEFAULTARRAY) + p.targetLow = JSONArray(DEFAULTARRAY) } catch (ignored: JSONException) { } - } try { - targetHigh = JSONArray(SP.getString(LOCAL_PROFILE + "targethigh", DEFAULTARRAY)) + p.targetHigh = JSONArray(SP.getString(LOCAL_PROFILE + "targethigh", DEFAULTARRAY)) } catch (e1: JSONException) { try { - targetHigh = JSONArray(DEFAULTARRAY) + p.targetHigh = JSONArray(DEFAULTARRAY) } catch (ignored: JSONException) { } - } + p.name = LOCAL_PROFILE + + SP.remove(LOCAL_PROFILE + "mgdl") + SP.remove(LOCAL_PROFILE + "mmol") + SP.remove(LOCAL_PROFILE + "dia") + SP.remove(LOCAL_PROFILE + "ic") + SP.remove(LOCAL_PROFILE + "isf") + SP.remove(LOCAL_PROFILE + "basal") + SP.remove(LOCAL_PROFILE + "targetlow") + SP.remove(LOCAL_PROFILE + "targethigh") + + currentProfileIndex = 0 + numOfProfiles = 1 + profiles.clear() + profiles.add(p) + storeSettings() isEdited = false createAndStoreConvertedProfile() @@ -178,22 +279,61 @@ object LocalProfilePlugin : PluginBase(PluginDescription() rawProfile = createProfileStore() } + fun addNewProfile() { + var free = 0 + for (i in 1..10000) { + if (rawProfile?.getSpecificProfile(LOCAL_PROFILE + i) == null) { + free = i; + break + } + } + val p = SingleProfile() + p.name = LOCAL_PROFILE + free + p.mgdl = ProfileFunctions.getSystemUnits() == Constants.MGDL + p.dia = Constants.defaultDIA + p.ic = JSONArray(DEFAULTARRAY) + p.isf = JSONArray(DEFAULTARRAY) + p.basal = JSONArray(DEFAULTARRAY) + p.targetLow = JSONArray(DEFAULTARRAY) + p.targetHigh = JSONArray(DEFAULTARRAY) + profiles.add(p) + currentProfileIndex = profiles.size - 1 + numOfProfiles++ + createAndStoreConvertedProfile() + storeSettings() + } + + fun removeCurrentProfile() { + profiles.removeAt(currentProfileIndex) + numOfProfiles-- + if (profiles.size == 0) addNewProfile() + currentProfileIndex = 0 + createAndStoreConvertedProfile() + storeSettings() + } + fun createProfileStore(): ProfileStore { val json = JSONObject() val store = JSONObject() - val profile = JSONObject() try { - json.put("defaultProfile", LOCAL_PROFILE) + for (i in 0 until numOfProfiles) { + profiles[i].run { + val profile = JSONObject() + profile.put("dia", dia) + profile.put("carbratio", ic) + profile.put("sens", isf) + profile.put("basal", basal) + profile.put("target_low", targetLow) + profile.put("target_high", targetHigh) + profile.put("units", if (mgdl) Constants.MGDL else Constants.MMOL) + profile.put("timezone", TimeZone.getDefault().id) + store.put(name, profile) + } + } + json.put("defaultProfile", currentProfile().name) + json.put("startDate", DateUtil.toISOAsUTC(DateUtil.now())) json.put("store", store) - profile.put("dia", dia) - profile.put("carbratio", ic) - profile.put("sens", isf) - profile.put("basal", basal) - profile.put("target_low", targetLow) - profile.put("target_high", targetHigh) - profile.put("units", if (mgdl) Constants.MGDL else Constants.MMOL) - store.put(LOCAL_PROFILE, profile) } catch (e: JSONException) { log.error("Unhandled exception", e) } @@ -202,11 +342,11 @@ object LocalProfilePlugin : PluginBase(PluginDescription() } override fun getProfile(): ProfileStore? { - return if (rawProfile?.defaultProfile?.isValid(MainApp.gs(R.string.localprofile)) != true) null else rawProfile + return rawProfile } override fun getUnits(): String { - return if (mgdl) Constants.MGDL else Constants.MMOL + return if (currentProfile().mgdl) Constants.MGDL else Constants.MMOL } override fun getProfileName(): String { diff --git a/app/src/main/res/layout/localprofile_fragment.xml b/app/src/main/res/layout/localprofile_fragment.xml index 49fd413115..19770a7257 100644 --- a/app/src/main/res/layout/localprofile_fragment.xml +++ b/app/src/main/res/layout/localprofile_fragment.xml @@ -35,32 +35,29 @@ android:textAppearance="?android:attr/textAppearanceMedium" /> diff --git a/app/src/main/res/values/arrays.xml b/app/src/main/res/values/arrays.xml index 864835bd87..1184f37e54 100644 --- a/app/src/main/res/values/arrays.xml +++ b/app/src/main/res/values/arrays.xml @@ -10,6 +10,15 @@ open + + mg/dL + mmol/L + + + mg/dl + mmol + + @string/en_lang @string/af_lang diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f12ac4b06b..3570604990 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1606,5 +1606,8 @@ min Profile name: Selected: + Units + units + Do you want to switch profile and discard changes made to current profile? diff --git a/app/src/main/res/xml/pref_language.xml b/app/src/main/res/xml/pref_general.xml similarity index 65% rename from app/src/main/res/xml/pref_language.xml rename to app/src/main/res/xml/pref_general.xml index 981de2b346..f1bcbdb858 100644 --- a/app/src/main/res/xml/pref_language.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -1,13 +1,23 @@ + + + + + \ No newline at end of file From 339765932030c53b22da41e9e8402805070a5855 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 15 Oct 2019 21:58:48 +0200 Subject: [PATCH 012/118] LocalProfile tweaking switching profiles --- .../profile/local/LocalProfileFragment.kt | 18 +++++++++++------ .../nightscout/androidaps/utils/OKDialog.java | 20 +++++++++++++++++++ 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt index a47726c033..1dc9ed1a8b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt @@ -65,7 +65,7 @@ class LocalProfileFragment : Fragment() { fun build() { val pumpDescription = ConfigBuilderPlugin.getPlugin().activePump?.pumpDescription ?: return - val units = ProfileFunctions.getSystemUnits() + val units = if (LocalProfilePlugin.currentProfile().mgdl) Constants.MGDL else Constants.MMOL localprofile_name.setText(LocalProfilePlugin.currentProfile().name) localprofile_dia.setParams(LocalProfilePlugin.currentProfile().dia, HardLimits.MINDIA, HardLimits.MAXDIA, 0.1, DecimalFormat("0.0"), false, localprofile_save, textWatch) @@ -94,11 +94,13 @@ class LocalProfileFragment : Fragment() { override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) { if (LocalProfilePlugin.isEdited) { - context?.let { context -> - OKDialog.show(context, MainApp.gs(R.string.confirmation), MainApp.gs(R.string.doyouwantswitchprofile)) { + activity?.let { activity -> + OKDialog.showConfirmation(activity, MainApp.gs(R.string.doyouwantswitchprofile), { LocalProfilePlugin.currentProfileIndex = position build() - } + }, { + spinner?.setSelection(LocalProfilePlugin.currentProfileIndex) + }) } } else { LocalProfilePlugin.currentProfileIndex = position @@ -113,8 +115,12 @@ class LocalProfileFragment : Fragment() { } localprofile_profile_remove.setOnClickListener { - LocalProfilePlugin.removeCurrentProfile() - build() + activity?.let { activity -> + OKDialog.showConfirmation(activity, MainApp.gs(R.string.doyouwantswitchprofile), { + LocalProfilePlugin.removeCurrentProfile() + build() + }, null) + } } // this is probably not possible because it leads to invalid profile diff --git a/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.java b/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.java index a45d329d63..cee3b7ea08 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.java +++ b/app/src/main/java/info/nightscout/androidaps/utils/OKDialog.java @@ -83,4 +83,24 @@ public class OKDialog { .show(); } + public static void showConfirmation(final Activity activity, String message, final Runnable ok, final Runnable cancel) { + AlertDialog alertDialog = new AlertDialog.Builder(new ContextThemeWrapper(activity, R.style.AppTheme)) + .setMessage(message) + .setPositiveButton(android.R.string.ok, (dialog, which) -> { + dialog.dismiss(); + if (ok != null) { + SystemClock.sleep(100); + activity.runOnUiThread(ok); + } + }) + .setNegativeButton(android.R.string.cancel, (dialog, which) -> { + dialog.dismiss(); + if (cancel != null) { + SystemClock.sleep(100); + activity.runOnUiThread(cancel); + } + }) + .show(); + } + } From 49b2aee320c6edb040be60c510ccfa460ebd2514 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Tue, 15 Oct 2019 22:35:04 +0200 Subject: [PATCH 013/118] TODO --- .../androidaps/plugins/profile/local/LocalProfileFragment.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt index 1dc9ed1a8b..ddc33ca4fb 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/profile/local/LocalProfileFragment.kt @@ -132,6 +132,7 @@ class LocalProfileFragment : Fragment() { localprofile_mmol.isEnabled = false localprofile_profileswitch.setOnClickListener { + // TODO: select in dialog LocalProfilePlugin.currentProfileIndex val newDialog = NewNSTreatmentDialog() val profileSwitch = CareportalFragment.PROFILESWITCHDIRECT profileSwitch.executeProfileSwitch = true From 64dba46a961e25def7f45154739423676ae6bc55 Mon Sep 17 00:00:00 2001 From: Rob Kresha Date: Sat, 2 Nov 2019 16:41:21 -0500 Subject: [PATCH 014/118] Typo with Daylight Savings Time strings -2 strings with Daylight missing a 't' -Savings not capitalized in the 3 string --- app/src/main/res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 70e05db6c4..4c43ba1193 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1331,9 +1331,9 @@ Upload BG tests smbmaxminutes - Dayligh Saving time - Dayligh Saving time change in 24h or less - Daylight saving time change less than 3 hours ago - Closed loop disabled + Daylight Saving time + Daylight Saving time change in 24h or less + Daylight Saving time change less than 3 hours ago - Closed loop disabled internal storage constraint Free at least %1$d MB from internal storage! Loop disabled! Wrong format From 70172bf8e468196f9cb55594ca91d02a657d2a1d Mon Sep 17 00:00:00 2001 From: Andreas <38214111+2flea@users.noreply.github.com> Date: Sun, 3 Nov 2019 16:20:20 +0100 Subject: [PATCH 015/118] Add temporary PS remaining time in profile name --- .../plugins/general/overview/OverviewFragment.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java index 5c2a7cac84..80c7c588bf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java @@ -58,6 +58,7 @@ import info.nightscout.androidaps.data.QuickWizardEntry; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.ExtendedBolus; +import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TemporaryBasal; @@ -76,6 +77,7 @@ import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; +import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.aps.loop.APSResult; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; @@ -1227,6 +1229,14 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, if (profile.getPercentage() != 100 || profile.getTimeshift() != 0) { activeProfileView.setBackgroundColor(MainApp.gc(R.color.ribbonWarning)); activeProfileView.setTextColor(MainApp.gc(R.color.ribbonTextWarning)); + + TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); + ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(System.currentTimeMillis()); + if (profileSwitch != null) { + if (profileSwitch.profileJson != null && profileSwitch.durationInMinutes != 0) { + activeProfileView.setText(ProfileFunctions.getInstance().getProfileName() + DateUtil.untilString(profileSwitch.originalEnd())); + } + } } else { activeProfileView.setBackgroundColor(MainApp.gc(R.color.ribbonDefault)); activeProfileView.setTextColor(MainApp.gc(R.color.ribbonTextDefault)); From 7371ae3315858602b48eed96f7427109dabb26e5 Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Mon, 4 Nov 2019 11:55:34 +0000 Subject: [PATCH 016/118] - added DetailedBolusInfoStorage add to deliverBolus --- .../pump/medtronic/MedtronicPumpPlugin.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java index ae6d754493..f2ee74275c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java @@ -48,6 +48,7 @@ import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperAc import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification; import info.nightscout.androidaps.plugins.general.overview.notifications.Notification; import info.nightscout.androidaps.plugins.pump.common.PumpPluginAbstract; +import info.nightscout.androidaps.plugins.pump.common.bolusInfo.DetailedBolusInfoStorage; import info.nightscout.androidaps.plugins.pump.common.defs.PumpDriverState; import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkConst; @@ -372,7 +373,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter refreshAnyStatusThatNeedsToBeRefreshed(); } - RxBus.INSTANCE.send(new EventMedtronicPumpValuesChanged()); + RxBus.INSTANCE.send(new EventMedtronicPumpValuesChanged()); } @@ -386,7 +387,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter RileyLinkServiceState rileyLinkServiceState = MedtronicUtil.getServiceState(); - if (rileyLinkServiceState==null) { + if (rileyLinkServiceState == null) { LOG.error("RileyLink unreachable. RileyLinkServiceState is null."); return false; } @@ -744,13 +745,13 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter ClockDTO clock = MedtronicUtil.getPumpTime(); - if (clock==null) { // retry + if (clock == null) { // retry medtronicUIComm.executeCommand(MedtronicCommandType.GetRealTimeClock); clock = MedtronicUtil.getPumpTime(); } - if (clock==null) + if (clock == null) return; int timeDiff = Math.abs(clock.timeDifference); @@ -867,6 +868,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter } TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true); + DetailedBolusInfoStorage.INSTANCE.add(detailedBolusInfo); // we subtract insulin, exact amount will be visible with next remainingInsulin update. getMDTPumpStatus().reservoirRemainingUnits -= detailedBolusInfo.insulin; @@ -1065,10 +1067,10 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter @Override public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) { - if (percent==0) { + if (percent == 0) { return setTempBasalAbsolute(0.0d, durationInMinutes, profile, enforceNew); } else { - double absoluteValue = profile.getBasal() * (percent /100.0d); + double absoluteValue = profile.getBasal() * (percent / 100.0d); getMDTPumpStatus(); absoluteValue = pumpStatusLocal.pumpType.determineCorrectBasalSize(absoluteValue); LOG.warn("setTempBasalPercent [MedtronicPumpPlugin] - You are trying to use setTempBasalPercent with percent other then 0% (%d). This will start setTempBasalAbsolute, with calculated value (%.3f). Result might not be 100% correct.", percent, absoluteValue); From 220bd20f1fcf051d643b98bdd2b9be8bbf6ccbd5 Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Mon, 4 Nov 2019 12:21:29 +0000 Subject: [PATCH 017/118] medtronic-2.5.1.1 - DetailedBolusInfo.add is used when Bolus delivered - fixed some logging problems with Gson for core objects - when bolus is given, date is changed to when it was actually delivered (in case contacting pump takes longer than exprected) --- app/build.gradle | 2 +- .../pump/medtronic/MedtronicPumpPlugin.java | 7 ++++++- .../pump/medtronic/data/MedtronicHistoryData.java | 15 ++++++++++++++- .../pump/medtronic/util/MedtronicUtil.java | 8 ++++---- .../plugins/treatments/TreatmentsPlugin.java | 4 ++-- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 94aaa78834..4ad49d22ba 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -109,7 +109,7 @@ android { targetSdkVersion 28 multiDexEnabled true versionCode 1500 - version "2.5.1" + version "medtronic-2.5.1.1" buildConfigField "String", "VERSION", '"' + version + '"' buildConfigField "String", "BUILDVERSION", '"' + generateGitBuild() + '-' + generateDate() + '"' buildConfigField "String", "REMOTE", '"' + generateGitRemote() + '"' diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java index f2ee74275c..f5b882eaf2 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/MedtronicPumpPlugin.java @@ -867,6 +867,11 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter }).start(); } + long now = System.currentTimeMillis(); + + detailedBolusInfo.date = now; + detailedBolusInfo.deliverAt = now; // not sure about that one + TreatmentsPlugin.getPlugin().addToHistoryTreatment(detailedBolusInfo, true); DetailedBolusInfoStorage.INSTANCE.add(detailedBolusInfo); @@ -879,7 +884,7 @@ public class MedtronicPumpPlugin extends PumpPluginAbstract implements PumpInter // calculate time for bolus and set driver to busy for that time int bolusTime = (int) (detailedBolusInfo.insulin * 42.0d); - long time = System.currentTimeMillis() + (bolusTime * 1000); + long time = now + (bolusTime * 1000); this.busyTimestamps.add(time); setEnableCustomAction(MedtronicCustomActionType.ClearBolusBlock, true); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java index 1eed440cdc..13fed8ba8b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java @@ -77,6 +77,7 @@ public class MedtronicHistoryData { private boolean isInit = false; private Gson gson; + private Gson gsonCore; private DatabaseHelper databaseHelper = MainApp.getDbHelper(); private ClockDTO pumpTime; @@ -94,10 +95,15 @@ public class MedtronicHistoryData { public MedtronicHistoryData() { this.allHistory = new ArrayList<>(); this.gson = MedtronicUtil.gsonInstance; + this.gsonCore = MedtronicUtil.getGsonInstanceCore(); if (this.gson == null) { this.gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); } + + if (this.gsonCore == null) { + this.gsonCore = new GsonBuilder().create(); + } } @@ -597,7 +603,7 @@ public class MedtronicHistoryData { if (doubleBolusDebug) LOG.debug("DoubleBolusDebug: List (before filter): {}, FromDb={}", gson.toJson(entryList), - gson.toJson(entriesFromHistory)); + gsonCore.toJson(entriesFromHistory)); filterOutAlreadyAddedEntries(entryList, entriesFromHistory); @@ -862,6 +868,7 @@ public class MedtronicHistoryData { return; List removeTreatmentsFromHistory = new ArrayList<>(); + List removeTreatmentsFromPH = new ArrayList<>(); for (DbObjectBase treatment : treatmentsFromHistory) { @@ -879,11 +886,17 @@ public class MedtronicHistoryData { if (selectedBolus != null) { entryList.remove(selectedBolus); + removeTreatmentsFromPH.add(selectedBolus); removeTreatmentsFromHistory.add(treatment); } } } + if (doubleBolusDebug) + LOG.debug("DoubleBolusDebug: filterOutAlreadyAddedEntries: PumpHistory={}, Treatments={}", + gson.toJson(removeTreatmentsFromPH), + gsonCore.toJson(removeTreatmentsFromHistory)); + treatmentsFromHistory.removeAll(removeTreatmentsFromHistory); } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicUtil.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicUtil.java index 96bf0a5d44..2c7ee69c2f 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicUtil.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/util/MedtronicUtil.java @@ -61,8 +61,7 @@ public class MedtronicUtil extends RileyLinkUtil { private static int doneBit = 1 << 7; private static ClockDTO pumpTime; public static Gson gsonInstance = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create(); - public static Gson gsonInstancePretty = new GsonBuilder().excludeFieldsWithoutExposeAnnotation() - .setPrettyPrinting().create(); + public static Gson gsonInstanceCore = new GsonBuilder().create(); private static BatteryType batteryType = BatteryType.None; @@ -70,8 +69,9 @@ public class MedtronicUtil extends RileyLinkUtil { return gsonInstance; } - public static Gson getGsonInstancePretty() { - return gsonInstancePretty; + + public static Gson getGsonInstanceCore() { + return gsonInstanceCore; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java index 28181da190..004f44858d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/treatments/TreatmentsPlugin.java @@ -349,7 +349,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface long time = System.currentTimeMillis(); synchronized (treatments) { if (MedtronicHistoryData.doubleBolusDebug) - log.debug("DoubleBolusDebug: AllTreatmentsInDb: {}", MedtronicUtil.getGsonInstance().toJson(treatments)); + log.debug("DoubleBolusDebug: AllTreatmentsInDb: {}", MedtronicUtil.getGsonInstanceCore().toJson(treatments)); for (Treatment t : treatments) { if (t.date <= time && t.date >= fromTimestamp) @@ -357,7 +357,7 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface } if (MedtronicHistoryData.doubleBolusDebug) - log.debug("DoubleBolusDebug: FilteredTreatments: AfterTime={}, Items={}", fromTimestamp, MedtronicUtil.getGsonInstance().toJson(in5minback)); + log.debug("DoubleBolusDebug: FilteredTreatments: AfterTime={}, Items={}", fromTimestamp, MedtronicUtil.getGsonInstanceCore().toJson(in5minback)); return in5minback; } From 3797e7671a5d56d843a7cc392d541084603afc06 Mon Sep 17 00:00:00 2001 From: Andy Rozman Date: Mon, 4 Nov 2019 12:25:21 +0000 Subject: [PATCH 018/118] - one missing core log --- .../plugins/pump/medtronic/data/MedtronicHistoryData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java index 13fed8ba8b..781f24b0ba 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/pump/medtronic/data/MedtronicHistoryData.java @@ -615,7 +615,7 @@ public class MedtronicHistoryData { if (doubleBolusDebug) LOG.debug("DoubleBolusDebug: List (after filter): {}, FromDb={}", gson.toJson(entryList), - gson.toJson(entriesFromHistory)); + gsonCore.toJson(entriesFromHistory)); if (isCollectionEmpty(entriesFromHistory)) { for (PumpHistoryEntry treatment : entryList) { From 2044fe6860fd2918ee53f8556f71a332a875b3e6 Mon Sep 17 00:00:00 2001 From: andreas <2flea@gmx.de> Date: Tue, 5 Nov 2019 15:43:11 +0100 Subject: [PATCH 019/118] Instead of computing name in overview fragment add function ProfileFunctions.getInstance().getProfileNameWithDuration() to be called --- .../configBuilder/ProfileFunctions.java | 26 ++++++++++++------- .../general/overview/OverviewFragment.java | 12 +-------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java index 025d8dac1e..91c20b095a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/configBuilder/ProfileFunctions.java @@ -27,6 +27,7 @@ import info.nightscout.androidaps.plugins.bus.RxBus; import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperActivity; import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin; import info.nightscout.androidaps.queue.Callback; +import info.nightscout.androidaps.utils.DateUtil; import info.nightscout.androidaps.utils.FabricPrivacy; import info.nightscout.androidaps.utils.SP; import io.reactivex.disposables.CompositeDisposable; @@ -75,35 +76,42 @@ public class ProfileFunctions { } public String getProfileName() { - return getProfileName(System.currentTimeMillis()); + return getProfileName(System.currentTimeMillis(), true, false); } public String getProfileName(boolean customized) { - return getProfileName(System.currentTimeMillis(), customized); + return getProfileName(System.currentTimeMillis(), customized, false); } - public String getProfileName(long time) { - return getProfileName(time, true); + public String getProfileNameWithDuration() { + return getProfileName(System.currentTimeMillis(), true, true); } - public String getProfileName(long time, boolean customized) { + public String getProfileName(long time, boolean customized, boolean showRemainingTime) { + String profileName = MainApp.gs(R.string.noprofileselected); + TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); ProfileInterface activeProfile = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface(); ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(time); if (profileSwitch != null) { if (profileSwitch.profileJson != null) { - return customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; + profileName = customized ? profileSwitch.getCustomizedName() : profileSwitch.profileName; } else { ProfileStore profileStore = activeProfile.getProfile(); if (profileStore != null) { Profile profile = profileStore.getSpecificProfile(profileSwitch.profileName); if (profile != null) - return profileSwitch.profileName; + profileName = profileSwitch.profileName; } } + + if (showRemainingTime && profileSwitch.durationInMinutes != 0) { + profileName += DateUtil.untilString(profileSwitch.originalEnd()); + } + return profileName; } - return MainApp.gs(R.string.noprofileselected); + return profileName; } public boolean isProfileValid(String from) { @@ -176,7 +184,7 @@ public class ProfileFunctions { profileSwitch = new ProfileSwitch(); profileSwitch.date = System.currentTimeMillis(); profileSwitch.source = Source.USER; - profileSwitch.profileName = getInstance().getProfileName(System.currentTimeMillis(), false); + profileSwitch.profileName = getInstance().getProfileName(System.currentTimeMillis(), false, false); profileSwitch.profileJson = getInstance().getProfile().getData().toString(); profileSwitch.profilePlugin = ConfigBuilderPlugin.getPlugin().getActiveProfileInterface().getClass().getName(); profileSwitch.durationInMinutes = duration; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java index 80c7c588bf..046290500d 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/OverviewFragment.java @@ -58,7 +58,6 @@ import info.nightscout.androidaps.data.QuickWizardEntry; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.ExtendedBolus; -import info.nightscout.androidaps.db.ProfileSwitch; import info.nightscout.androidaps.db.Source; import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.db.TemporaryBasal; @@ -77,7 +76,6 @@ import info.nightscout.androidaps.interfaces.Constraint; import info.nightscout.androidaps.interfaces.PluginType; import info.nightscout.androidaps.interfaces.PumpDescription; import info.nightscout.androidaps.interfaces.PumpInterface; -import info.nightscout.androidaps.interfaces.TreatmentsInterface; import info.nightscout.androidaps.logging.L; import info.nightscout.androidaps.plugins.aps.loop.APSResult; import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin; @@ -1225,18 +1223,10 @@ public class OverviewFragment extends Fragment implements View.OnClickListener, extendedBolusView.setVisibility(View.VISIBLE); } - activeProfileView.setText(ProfileFunctions.getInstance().getProfileName()); + activeProfileView.setText(ProfileFunctions.getInstance().getProfileNameWithDuration()); if (profile.getPercentage() != 100 || profile.getTimeshift() != 0) { activeProfileView.setBackgroundColor(MainApp.gc(R.color.ribbonWarning)); activeProfileView.setTextColor(MainApp.gc(R.color.ribbonTextWarning)); - - TreatmentsInterface activeTreatments = TreatmentsPlugin.getPlugin(); - ProfileSwitch profileSwitch = activeTreatments.getProfileSwitchFromHistory(System.currentTimeMillis()); - if (profileSwitch != null) { - if (profileSwitch.profileJson != null && profileSwitch.durationInMinutes != 0) { - activeProfileView.setText(ProfileFunctions.getInstance().getProfileName() + DateUtil.untilString(profileSwitch.originalEnd())); - } - } } else { activeProfileView.setBackgroundColor(MainApp.gc(R.color.ribbonDefault)); activeProfileView.setTextColor(MainApp.gc(R.color.ribbonTextDefault)); From a7589e4758c2379cff2dffff397b189e81288080 Mon Sep 17 00:00:00 2001 From: Dominik Dzienia Date: Tue, 5 Nov 2019 09:32:07 +0100 Subject: [PATCH 020/118] [#1806] For WearOS app, added option to make white status bar match background of whole watchface and blend in, switchable on Settings -> Matching divider --- .../androidaps/watchfaces/BaseWatchFace.java | 2 + .../androidaps/watchfaces/Home.java | 21 ++++--- .../androidaps/watchfaces/Home2.java | 61 ++++++++++++------- .../androidaps/watchfaces/LargeHome.java | 36 ++++++----- wear/src/main/res/xml/preferences.xml | 8 +++ 5 files changed, 83 insertions(+), 45 deletions(-) diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java index 229eb64f1b..24bb735067 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/BaseWatchFace.java @@ -71,6 +71,7 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen public boolean lowResMode = false; public boolean layoutSet = false; public boolean bIsRound = false; + public boolean dividerMatchesBg = false; public int pointSize = 2; public BgGraphBuilder bgGraphBuilder; public LineChartView chart; @@ -533,6 +534,7 @@ public abstract class BaseWatchFace extends WatchFace implements SharedPreferen } public void setColor() { + dividerMatchesBg = sharedPrefs.getBoolean("match_divider", false); if(lowResMode){ setColorLowRes(); } else if (sharedPrefs.getBoolean("dark", true)) { diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/Home.java b/wear/src/main/java/info/nightscout/androidaps/watchfaces/Home.java index 430a3feb47..786dbd8179 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/Home.java +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/Home.java @@ -65,7 +65,8 @@ public class Home extends BaseWatchFace { protected void setColorDark() { - mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_statusView)); + mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? + R.color.dark_background : R.color.dark_statusView)); mTime.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mTime)); mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_background)); if (sgvLevel == 1) { @@ -83,18 +84,21 @@ public class Home extends BaseWatchFace { } if (ageLevel == 1) { - mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mTimestamp1_home)); + mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? + R.color.dark_midColor : R.color.dark_mTimestamp1_home)); } else { mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_TimestampOld)); } if (batteryLevel == 1) { - mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_uploaderBattery)); + mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? + R.color.dark_midColor : R.color.dark_uploaderBattery)); } else { mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_uploaderBatteryEmpty)); } - mStatus.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mStatus_home)); + mStatus.setTextColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? + R.color.dark_midColor : R.color.dark_mStatus_home)); if (chart != null) { highColor = ContextCompat.getColor(getApplicationContext(), R.color.dark_highColor); @@ -131,7 +135,8 @@ public class Home extends BaseWatchFace { protected void setColorBright() { if (getCurrentWatchMode() == WatchMode.INTERACTIVE) { - mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.light_stripe_background)); + mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? + R.color.light_background : R.color.light_stripe_background)); mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.light_background)); if (sgvLevel == 1) { mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_highColor)); @@ -148,17 +153,17 @@ public class Home extends BaseWatchFace { } if (ageLevel == 1) { - mTimestamp.setTextColor(Color.WHITE); + mTimestamp.setTextColor(dividerMatchesBg ? Color.BLACK : Color.WHITE); } else { mTimestamp.setTextColor(Color.RED); } if (batteryLevel == 1) { - mUploaderBattery.setTextColor(Color.WHITE); + mUploaderBattery.setTextColor(dividerMatchesBg ? Color.BLACK : Color.WHITE); } else { mUploaderBattery.setTextColor(Color.RED); } - mStatus.setTextColor(Color.WHITE); + mStatus.setTextColor(dividerMatchesBg ? Color.BLACK : Color.WHITE); mTime.setTextColor(Color.BLACK); if (chart != null) { diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/Home2.java b/wear/src/main/java/info/nightscout/androidaps/watchfaces/Home2.java index 41c9fd3029..64ec7e17c8 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/Home2.java +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/Home2.java @@ -2,6 +2,7 @@ package info.nightscout.androidaps.watchfaces; import android.content.Intent; import android.graphics.Color; +import androidx.annotation.ColorInt; import androidx.core.content.ContextCompat; import android.support.wearable.watchface.WatchFaceStyle; import android.view.LayoutInflater; @@ -64,7 +65,14 @@ public class Home2 extends BaseWatchFace { } protected void setColorDark() { - mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_statusView)); + @ColorInt final int dividerTxtColor = dividerMatchesBg ? + ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor) : Color.BLACK; + @ColorInt final int dividerBatteryOkColor = ContextCompat.getColor(getApplicationContext(), + dividerMatchesBg ? R.color.dark_midColor : R.color.dark_uploaderBattery); + @ColorInt final int dividerBgColor = ContextCompat.getColor(getApplicationContext(), + dividerMatchesBg ? R.color.dark_background : R.color.dark_statusView); + + mLinearLayout.setBackgroundColor(dividerBgColor); mLinearLayout2.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_background)); mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_background)); mTime.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); @@ -96,15 +104,15 @@ public class Home2 extends BaseWatchFace { } if (batteryLevel == 1) { - mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_uploaderBattery)); + mUploaderBattery.setTextColor(dividerBatteryOkColor); } else { mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_uploaderBatteryEmpty)); } - mRigBattery.setTextColor(Color.BLACK); - mDelta.setTextColor(Color.BLACK); - mAvgDelta.setTextColor(Color.BLACK); - mBasalRate.setTextColor(Color.BLACK); - mBgi.setTextColor(Color.BLACK); + mRigBattery.setTextColor(dividerTxtColor); + mDelta.setTextColor(dividerTxtColor); + mAvgDelta.setTextColor(dividerTxtColor); + mBasalRate.setTextColor(dividerTxtColor); + mBgi.setTextColor(dividerTxtColor); if (loopLevel == 1) { mLoop.setBackgroundResource(R.drawable.loop_green_25); @@ -125,7 +133,12 @@ public class Home2 extends BaseWatchFace { } protected void setColorLowRes() { - mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_statusView)); + @ColorInt final int dividerTxtColor = dividerMatchesBg ? + ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor) : Color.BLACK; + @ColorInt final int dividerBgColor = ContextCompat.getColor(getApplicationContext(), + dividerMatchesBg ? R.color.dark_background : R.color.dark_statusView); + + mLinearLayout.setBackgroundColor(dividerBgColor); mLinearLayout2.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_background)); mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_background)); mLoop.setBackgroundResource(R.drawable.loop_grey_25); @@ -133,12 +146,12 @@ public class Home2 extends BaseWatchFace { mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); mDirection.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_Timestamp)); - mDelta.setTextColor(Color.BLACK); - mAvgDelta.setTextColor(Color.BLACK); - mRigBattery.setTextColor(Color.BLACK); - mUploaderBattery.setTextColor(Color.BLACK); - mBasalRate.setTextColor(Color.BLACK); - mBgi.setTextColor(Color.BLACK); + mDelta.setTextColor(dividerTxtColor); + mAvgDelta.setTextColor(dividerTxtColor); + mRigBattery.setTextColor(dividerTxtColor); + mUploaderBattery.setTextColor(dividerTxtColor); + mBasalRate.setTextColor(dividerTxtColor); + mBgi.setTextColor(dividerTxtColor); mIOB1.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); mIOB2.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); mCOB1.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); @@ -162,7 +175,13 @@ public class Home2 extends BaseWatchFace { protected void setColorBright() { if (getCurrentWatchMode() == WatchMode.INTERACTIVE) { - mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.light_stripe_background)); + + @ColorInt final int dividerTxtColor = dividerMatchesBg ? Color.BLACK : + ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor); + @ColorInt final int dividerBgColor = ContextCompat.getColor(getApplicationContext(), + dividerMatchesBg ? R.color.light_background : R.color.light_stripe_background); + + mLinearLayout.setBackgroundColor(dividerBgColor); mLinearLayout2.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.light_background)); mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.light_background)); mTime.setTextColor(Color.BLACK); @@ -194,15 +213,15 @@ public class Home2 extends BaseWatchFace { } if (batteryLevel == 1) { - mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); + mUploaderBattery.setTextColor(dividerTxtColor); } else { mUploaderBattery.setTextColor(Color.RED); } - mRigBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); - mDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); - mAvgDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); - mBasalRate.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); - mBgi.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); + mRigBattery.setTextColor(dividerTxtColor); + mDelta.setTextColor(dividerTxtColor); + mAvgDelta.setTextColor(dividerTxtColor); + mBasalRate.setTextColor(dividerTxtColor); + mBgi.setTextColor(dividerTxtColor); if (loopLevel == 1) { mLoop.setBackgroundResource(R.drawable.loop_green_25); diff --git a/wear/src/main/java/info/nightscout/androidaps/watchfaces/LargeHome.java b/wear/src/main/java/info/nightscout/androidaps/watchfaces/LargeHome.java index ffb8dce3ad..672b95dee0 100644 --- a/wear/src/main/java/info/nightscout/androidaps/watchfaces/LargeHome.java +++ b/wear/src/main/java/info/nightscout/androidaps/watchfaces/LargeHome.java @@ -49,7 +49,8 @@ public class LargeHome extends BaseWatchFace { @Override protected void setColorDark(){ - mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mLinearLayout)); + mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? + R.color.dark_background : R.color.dark_mLinearLayout)); mTime.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mTime)); mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_background)); if (sgvLevel == 1) { @@ -67,24 +68,27 @@ public class LargeHome extends BaseWatchFace { } if (ageLevel == 1) { - mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mTimestamp1_home)); + mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? + R.color.dark_midColor : R.color.dark_mTimestamp1_home)); } else { mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_TimestampOld)); } if (batteryLevel == 1) { - mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_uploaderBattery)); + mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? + R.color.dark_midColor : R.color.dark_uploaderBattery)); } else { mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_uploaderBatteryEmpty)); } - mStatus.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mStatus_home)); + mStatus.setTextColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? R.color.dark_midColor : R.color.dark_mStatus_home)); } @Override protected void setColorBright() { if (getCurrentWatchMode() == WatchMode.INTERACTIVE) { - mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.light_stripe_background)); + mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? + R.color.light_background : R.color.light_stripe_background)); mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.light_background)); if (sgvLevel == 1) { mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.light_highColor)); @@ -101,21 +105,21 @@ public class LargeHome extends BaseWatchFace { } if (ageLevel == 1) { - mTimestamp.setTextColor(Color.WHITE); + mTimestamp.setTextColor(dividerMatchesBg ? Color.BLACK : Color.WHITE); } else { mTimestamp.setTextColor(Color.RED); } if (batteryLevel == 1) { - mUploaderBattery.setTextColor(Color.WHITE); + mUploaderBattery.setTextColor(dividerMatchesBg ? Color.BLACK : Color.WHITE); } else { mUploaderBattery.setTextColor(Color.RED); } - mStatus.setTextColor(Color.WHITE); + mStatus.setTextColor(dividerMatchesBg ? Color.BLACK : Color.WHITE); mTime.setTextColor(Color.BLACK); } else { mRelativeLayout.setBackgroundColor(Color.BLACK); - mLinearLayout.setBackgroundColor(Color.LTGRAY); + mLinearLayout.setBackgroundColor(dividerMatchesBg ? Color.BLACK : Color.LTGRAY); if (sgvLevel == 1) { mSgv.setTextColor(Color.YELLOW); mDirection.setTextColor(Color.YELLOW); @@ -130,23 +134,23 @@ public class LargeHome extends BaseWatchFace { mDelta.setTextColor(Color.RED); } - mUploaderBattery.setTextColor(Color.BLACK); - mTimestamp.setTextColor(Color.BLACK); - mStatus.setTextColor(Color.BLACK); + mUploaderBattery.setTextColor(dividerMatchesBg ? Color.WHITE : Color.BLACK); + mTimestamp.setTextColor(dividerMatchesBg ? Color.WHITE : Color.BLACK); + mStatus.setTextColor(dividerMatchesBg ? Color.WHITE : Color.BLACK); mTime.setTextColor(Color.WHITE); } } @Override protected void setColorLowRes() { - mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mLinearLayout)); + mLinearLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? R.color.dark_background : R.color.dark_mLinearLayout)); mTime.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mTime)); mRelativeLayout.setBackgroundColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_background)); mSgv.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); mDelta.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); mDirection.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_midColor)); - mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mTimestamp1_home)); - mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_uploaderBattery)); - mStatus.setTextColor(ContextCompat.getColor(getApplicationContext(), R.color.dark_mStatus_home)); + mTimestamp.setTextColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? R.color.dark_midColor : R.color.dark_mTimestamp1_home)); + mUploaderBattery.setTextColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? R.color.dark_midColor : R.color.dark_uploaderBattery)); + mStatus.setTextColor(ContextCompat.getColor(getApplicationContext(), dividerMatchesBg ? R.color.dark_midColor : R.color.dark_mStatus_home)); } } diff --git a/wear/src/main/res/xml/preferences.xml b/wear/src/main/res/xml/preferences.xml index 0befaddfd0..f0fc4b5789 100644 --- a/wear/src/main/res/xml/preferences.xml +++ b/wear/src/main/res/xml/preferences.xml @@ -125,6 +125,14 @@ app:wear_iconOff="@drawable/settings_off" app:wear_iconOn="@drawable/settings_on"/> + + Date: Wed, 6 Nov 2019 12:21:31 +0100 Subject: [PATCH 021/118] Create CONTRIBUTING.md First draft of contribution guidelines --- CONTRIBUTING.md | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..f22d9cf3a1 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,43 @@ +This document speciffy hints and good practices for source code contributions. + +AndroidAPS is community effort and all contributions are welcome! If you wish help us improving AndroidAPS - please read and try to adhere to +this guidelines, to make the development and process of change aproval as smooth as possible :) + +General rules +============= + +* There are plenty of ways you can help, some of them are listed on wiki: + https://androidaps.readthedocs.io/en/latest/EN/Getting-Started/How-can-I-help.html +* If you wish to help with documentation or translating: + https://androidaps.readthedocs.io/en/latest/EN/translations.html + +Development guidelines +====================== + +Commiting Changes / Pull Requests +--------------------------------- + +1. Make fork of repository on github +2. Create separate branch for each feature, branch from most recent dev +3. Commit all changes to your fork +4. When ready, rebase on top of dev and make pull request to main repo + +Naming Conventions for Pull Requests / Branches +----------------------------------------------- + +TODO + +Translations +------------ + +* If possible, always use Android translation mechanism (with strings.xml and @strings/id) instead of hardcoded texts +* Provide only English strings - all other languages will be crowd translated via Crowdn https://translations.androidaps.org/ + +Hints +----- + +* Start small, it is easier to review smaller changes that affect fewer parts of code +* Take a look into Issues list (https://github.com/MilosKozak/AndroidAPS/issues) - maybe there is somthing you can fix or implement +* For new features, make sure there is Issue to track progress and have on-topic discussion +* Reach out to community, discuss idea on Gitter (https://gitter.im/MilosKozak/AndroidAPS) +* Speak with other developers to minimise merge conflicts. Find out who worked, working or plan to work on speciffic issue or part of app From 86d4b755eadc72e17139d5f9c3a2b4ca8b050154 Mon Sep 17 00:00:00 2001 From: fabriziocasellato Date: Thu, 7 Nov 2019 10:39:17 +0100 Subject: [PATCH 022/118] 1) Added SMS commands: - SMS DISABLE/STOP to disable SMS Service; - TARGET MEAL/ACTIVITY/HYPO to switch to the standard temp targets; - BOLUS 0.60 MEAL, to do a bolus and set the stadard meal TT (ie 90 mg/dL for 45'). 2) Modified the SMS Timeout in a range from 3' to 60'. This preference is useful for parents that will manage many boluses in a single meal (because often, eaten foods are unpredictable with babies, so parents need to perform many closed boluses). Due to safety reasons (prevent multiple boluses for stolen phones, cloned SIM, ...): - Added a further SMS command to disable SMS Services (SMS DISABLE/STOP); - To modify the default timeout of 15', 2 Phone Numbers are mandatory In this way, if unwanted/suspicious boluses are notified, the other parent can disable Remote Management (till to re-enable it directly with the AAPS in the master smartphone). --- .../activities/PreferencesActivity.java | 35 ++++ .../SmsCommunicatorPlugin.java | 180 +++++++++++++++++- app/src/main/res/values/strings.xml | 11 ++ app/src/main/res/xml/pref_smscommunicator.xml | 13 +- 4 files changed, 234 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java index 367429dbbf..bf69624c40 100644 --- a/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java +++ b/app/src/main/java/info/nightscout/androidaps/activities/PreferencesActivity.java @@ -13,6 +13,7 @@ import android.preference.PreferenceScreen; import android.text.TextUtils; import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.Constants; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.bus.RxBus; @@ -51,6 +52,8 @@ import info.nightscout.androidaps.utils.OKDialog; import info.nightscout.androidaps.utils.SP; import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin; +import com.andreabaccega.widget.ValidatingEditTextPreference; + public class PreferencesActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener { MyPreferenceFragment myPreferenceFragment; @@ -218,6 +221,38 @@ public class PreferencesActivity extends PreferenceActivity implements SharedPre TidepoolUploader.INSTANCE.testLogin(getActivity()); return false; }); + + final ValidatingEditTextPreference distance = (ValidatingEditTextPreference)findPreference(getString(R.string.key_smscommunicator_remotebolusmindistance)); + final EditTextPreference allowedNumbers = (EditTextPreference)findPreference(getString(R.string.key_smscommunicator_allowednumbers)); + if (distance != null && allowedNumbers != null) { + if (!SmsCommunicatorPlugin.areMoreNumbers(allowedNumbers.getText())) { + distance.setTitle(getString(R.string.smscommunicator_remotebolusmindistance) + + ".\n" + + getString(R.string.smscommunicator_remotebolusmindistance_caveat)); + distance.setEnabled(false); + } else { + distance.setTitle(getString(R.string.smscommunicator_remotebolusmindistance)); + distance.setEnabled(true); + } + + allowedNumbers.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() { + @Override + public boolean onPreferenceChange(Preference preference, Object newValue) { + if (!SmsCommunicatorPlugin.areMoreNumbers(((String)newValue))) { + distance.setText(String.valueOf(Constants.remoteBolusMinDistance/(60 * 1000L))); + distance.setTitle(getString(R.string.smscommunicator_remotebolusmindistance) + + ".\n" + + getString(R.string.smscommunicator_remotebolusmindistance_caveat)); + distance.setEnabled(false); + } else { + distance.setTitle(getString(R.string.smscommunicator_remotebolusmindistance)); + distance.setEnabled(true); + } + return true; + } + }); + } + } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index 264d7c3e52..f34a66ca4b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -23,6 +23,7 @@ import info.nightscout.androidaps.data.ProfileStore; import info.nightscout.androidaps.db.BgReading; import info.nightscout.androidaps.db.DatabaseHelper; import info.nightscout.androidaps.db.Source; +import info.nightscout.androidaps.db.TempTarget; import info.nightscout.androidaps.events.EventPreferenceChange; import info.nightscout.androidaps.events.EventRefreshOverview; import info.nightscout.androidaps.interfaces.Constraint; @@ -136,6 +137,8 @@ public class SmsCommunicatorPlugin extends PluginBase { case "EXTENDED": case "CAL": case "PROFILE": + case "TARGET": + case "SMS": return true; } if (messageToConfirm != null && messageToConfirm.requester.phoneNumber.equals(number)) @@ -242,7 +245,7 @@ public class SmsCommunicatorPlugin extends PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotebolusnotallowed)); else if (splitted.length == 2 && ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended()) sendSMS(new Sms(receivedSms.phoneNumber, R.string.pumpsuspended)); - else if (splitted.length == 2) + else if (splitted.length == 2 || splitted.length == 3) processBOLUS(splitted, receivedSms); else sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); @@ -255,6 +258,22 @@ public class SmsCommunicatorPlugin extends PluginBase { else sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); break; + case "TARGET": + if (!remoteCommandsAllowed) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); + else if (splitted.length == 2) + processTARGET(splitted, receivedSms); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + break; + case "SMS": + if (!remoteCommandsAllowed) + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_remotecommandnotallowed)); + else if (splitted.length == 2) + processSMS(splitted, receivedSms); + else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + break; default: // expect passCode here if (messageToConfirm != null && messageToConfirm.requester.phoneNumber.equals(receivedSms.phoneNumber)) { messageToConfirm.action(splitted[0]); @@ -680,10 +699,19 @@ public class SmsCommunicatorPlugin extends PluginBase { private void processBOLUS(String[] splitted, Sms receivedSms) { Double bolus = SafeParse.stringToDouble(splitted[1]); + final boolean isMeal = splitted.length > 2 && splitted[2].equalsIgnoreCase("MEAL"); bolus = MainApp.getConstraintChecker().applyBolusConstraints(new Constraint<>(bolus)).value(); - if (bolus > 0d) { + + if (splitted.length == 3 && !isMeal) { + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + } else if (bolus > 0d) { String passCode = generatePasscode(); - String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusreplywithcode), bolus, passCode); + String reply = ""; + if (isMeal) { + reply = String.format(MainApp.gs(R.string.smscommunicator_mealbolusreplywithcode), bolus, passCode); + } else { + reply = String.format(MainApp.gs(R.string.smscommunicator_bolusreplywithcode), bolus, passCode); + } receivedSms.processed = true; messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction(bolus) { @Override @@ -701,10 +729,40 @@ public class SmsCommunicatorPlugin extends PluginBase { public void run() { PumpInterface pump = ConfigBuilderPlugin.getPlugin().getActivePump(); if (resultSuccess) { - String reply = String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), resultBolusDelivered); + String reply = ""; + if (isMeal) { + reply = String.format(MainApp.gs(R.string.smscommunicator_mealbolusdelivered), resultBolusDelivered); + } else { + reply = String.format(MainApp.gs(R.string.smscommunicator_bolusdelivered), resultBolusDelivered); + } if (pump != null) reply += "\n" + pump.shortStatus(true); lastRemoteBolusTime = DateUtil.now(); + if (isMeal) { + Profile currentProfile = ProfileFunctions.getInstance().getProfile(); + int eatingSoonTTDuration = SP.getInt(R.string.key_eatingsoon_duration, Constants.defaultEatingSoonTTDuration); + eatingSoonTTDuration = eatingSoonTTDuration > 0 ? eatingSoonTTDuration : Constants.defaultEatingSoonTTDuration; + double eatingSoonTT = SP.getDouble(R.string.key_eatingsoon_target, currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl); + eatingSoonTT = eatingSoonTT > 0 ? eatingSoonTT : currentProfile.getUnits().equals(Constants.MMOL) ? Constants.defaultEatingSoonTTmmol : Constants.defaultEatingSoonTTmgdl; + + TempTarget tempTarget = new TempTarget() + .date(System.currentTimeMillis()) + .duration(eatingSoonTTDuration) + .reason(MainApp.gs(R.string.eatingsoon)) + .source(Source.USER) + .low(Profile.toMgdl(eatingSoonTT, currentProfile.getUnits())) + .high(Profile.toMgdl(eatingSoonTT, currentProfile.getUnits())); + TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); + String tt = ""; + if (currentProfile.getUnits().equals(Constants.MMOL)) { + tt = DecimalFormatter.to1Decimal(eatingSoonTT); + } else + tt = DecimalFormatter.to0Decimal(eatingSoonTT); + + reply += String.format(MainApp.gs(R.string.smscommunicator_mealbolusdelivered_tt), tt, eatingSoonTTDuration); + + + } sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); } else { String reply = MainApp.gs(R.string.smscommunicator_bolusfailed); @@ -722,6 +780,105 @@ public class SmsCommunicatorPlugin extends PluginBase { sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); } + private void processTARGET(String[] splitted, Sms receivedSms) { + boolean isMeal = splitted[1].equalsIgnoreCase("MEAL"); + boolean isActivity = splitted[1].equalsIgnoreCase("ACTIVITY"); + boolean isHypo = splitted[1].equalsIgnoreCase("HYPO"); + + if (isMeal || isActivity || isHypo) { + String passCode = generatePasscode(); + String reply = String.format(MainApp.gs(R.string.smscommunicator_temptargetwithcode), splitted[1].toUpperCase(), passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { + @Override + public void run() { + try { + Profile currentProfile = ProfileFunctions.getInstance().getProfile(); + + int keyDuration = 0; + Integer defaultTargetDuration = 0; + int keyTarget = 0; + double defaultTargetMMOL = 0d; + double defaultTargetMGDL = 0d; + + if (isMeal) { + keyDuration = R.string.key_eatingsoon_duration; + defaultTargetDuration = Constants.defaultEatingSoonTTDuration; + keyTarget = R.string.key_eatingsoon_target; + defaultTargetMMOL = Constants.defaultEatingSoonTTmmol; + defaultTargetMGDL = Constants.defaultEatingSoonTTmgdl; + } else if (isActivity) { + keyDuration = R.string.key_activity_duration; + defaultTargetDuration = Constants.defaultActivityTTDuration; + keyTarget = R.string.key_activity_target; + defaultTargetMMOL = Constants.defaultActivityTTmmol; + defaultTargetMGDL = Constants.defaultActivityTTmgdl; + + } else if (isHypo) { + keyDuration = R.string.key_hypo_duration; + defaultTargetDuration = Constants.defaultHypoTTDuration; + keyTarget = R.string.key_hypo_target; + defaultTargetMMOL = Constants.defaultHypoTTmmol; + defaultTargetMGDL = Constants.defaultHypoTTmgdl; + } + + int ttDuration = SP.getInt(keyDuration, defaultTargetDuration); + ttDuration = ttDuration > 0 ? ttDuration : defaultTargetDuration; + double tt = SP.getDouble(keyTarget, currentProfile.getUnits().equals(Constants.MMOL) ? defaultTargetMMOL : defaultTargetMGDL); + tt = tt > 0 ? tt : currentProfile.getUnits().equals(Constants.MMOL) ? defaultTargetMMOL : defaultTargetMGDL; + + TempTarget tempTarget = new TempTarget() + .date(System.currentTimeMillis()) + .duration(ttDuration) + .reason(MainApp.gs(R.string.eatingsoon)) + .source(Source.USER) + .low(Profile.toMgdl(tt, currentProfile.getUnits())) + .high(Profile.toMgdl(tt, currentProfile.getUnits())); + TreatmentsPlugin.getPlugin().addToHistoryTempTarget(tempTarget); + String ttString = ""; + if (currentProfile.getUnits().equals(Constants.MMOL)) + ttString = DecimalFormatter.to1Decimal(tt); + else + ttString = DecimalFormatter.to0Decimal(tt); + + String reply = String.format(MainApp.gs(R.string.smscommunicator_tt_set), ttString, ttDuration); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } catch (Exception e) { + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand)); + return; + } + } + }); + } else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + } + + private void processSMS(String[] splitted, Sms receivedSms) { + boolean isStop = splitted[1].equalsIgnoreCase("STOP") + || splitted[1].equalsIgnoreCase("DISABLE"); + + if (isStop) { + String passCode = generatePasscode(); + String reply = String.format(MainApp.gs(R.string.smscommunicator_stopsmswithcode), passCode); + receivedSms.processed = true; + messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { + @Override + public void run() { + try { + SP.putBoolean(R.string.key_smscommunicator_remotecommandsallowed, false); + String reply = String.format(MainApp.gs(R.string.smscommunicator_stoppedsms)); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); + } catch (Exception e) { + e.printStackTrace(); + sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand)); + return; + } + } + }); + } else + sendSMS(new Sms(receivedSms.phoneNumber, R.string.wrongformat)); + } + private void processCAL(String[] splitted, Sms receivedSms) { Double cal = SafeParse.stringToDouble(splitted[1]); if (cal > 0d) { @@ -809,4 +966,19 @@ public class SmsCommunicatorPlugin extends PluginBase { s = s.replaceAll("[\\p{InCombiningDiacriticalMarks}]", ""); return s; } + + public static boolean areMoreNumbers(String allowednumbers) { + int countNumbers = 0; + String[] substrings = allowednumbers.split(";"); + + for (String number : substrings) { + String cleaned = number.replaceAll("\\s+", ""); + if (cleaned.length()<4) continue; + if (cleaned.substring(0,1).compareTo("+")!=0) continue; + cleaned = cleaned.replace("+",""); + if (!cleaned.matches("[0-9]+")) continue; + countNumbers++; + } + return countNumbers > 1; + } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4c43ba1193..9f37cc9a85 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -292,11 +292,22 @@ Allowed phone numbers +XXXXXXXXXX;+YYYYYYYYYY To deliver bolus %1$.2fU reply with code %2$s + To deliver meal bolus %1$.2fU reply with code %2$s + To set the Temp Target %1$s reply with code %2$s + To disable the SMS Remote Service reply with code %1$s.\n\nKeep in mind that you\'ll able to reactivate it directly from the AAPS master smartphone only. + SMS Remote Service stopped. To reactivate it, use AAPS on master smartphone. To send calibration %1$.2f reply with code %2$s Bolus failed + smscommunicator_remotebolusmindistance + Minimum number of minutes that must elapse between one remote bolus and the next + How many minutes must elapse, at least, between one bolus and the next + For your safety, to edit this preference you need to add at least 2 phone numbers. Bolus %1$.2fU delivered successfully Going to deliver %1$.2fU Bolus %1$.2fU delivered successfully + Meal Bolus %1$.2fU delivered successfully + Target %1$s for %2$d minutes + Target %1$s for %2$d minutes set succesfully Delivering %1$.2fU Allow remote commands via SMS Finger diff --git a/app/src/main/res/xml/pref_smscommunicator.xml b/app/src/main/res/xml/pref_smscommunicator.xml index 202e7348c5..e76b1b15b2 100644 --- a/app/src/main/res/xml/pref_smscommunicator.xml +++ b/app/src/main/res/xml/pref_smscommunicator.xml @@ -1,5 +1,6 @@ - + @@ -8,6 +9,16 @@ android:key="@string/key_smscommunicator_allowednumbers" android:summary="@string/smscommunicator_allowednumbers_summary" android:title="@string/smscommunicator_allowednumbers" /> + Date: Thu, 7 Nov 2019 11:46:55 +0000 Subject: [PATCH 023/118] re-run calculateInsulin when OK is pressed to ensure changes to notes fields are used --- .../androidaps/plugins/general/overview/dialogs/WizardDialog.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt index 552ab502e7..efe800bef0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/overview/dialogs/WizardDialog.kt @@ -114,6 +114,7 @@ class WizardDialog : DialogFragment() { log.debug("guarding: ok already clicked") } else { okClicked = true + calculateInsulin() parentContext?.let { context -> wizard?.confirmAndExecute(context) } From d0550614ad07a5664c16d720f79284f40feb0c92 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Sun, 10 Nov 2019 13:37:04 +0100 Subject: [PATCH 024/118] gradle update --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 31658346b6..9618c68851 100644 --- a/build.gradle +++ b/build.gradle @@ -8,7 +8,7 @@ buildscript { maven { url 'https://maven.fabric.io/public' } } dependencies { - classpath 'com.android.tools.build:gradle:3.5.1' + classpath 'com.android.tools.build:gradle:3.5.2' classpath 'com.google.gms:google-services:4.3.2' classpath 'io.fabric.tools:gradle:1.31.0' From 2319536adc9cd34a884cf50deff0172aada402d5 Mon Sep 17 00:00:00 2001 From: fabriziocasellato Date: Mon, 11 Nov 2019 09:57:35 +0100 Subject: [PATCH 025/118] Cumulative corrections for Milos msgs in 2019, 7 Nov about try/catch and missed 'if null' contition --- .../SmsCommunicatorPlugin.java | 20 ++++++------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java index f34a66ca4b..f40d60523c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/smsCommunicator/SmsCommunicatorPlugin.java @@ -792,9 +792,8 @@ public class SmsCommunicatorPlugin extends PluginBase { messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { @Override public void run() { - try { - Profile currentProfile = ProfileFunctions.getInstance().getProfile(); - + Profile currentProfile = ProfileFunctions.getInstance().getProfile(); + if (currentProfile != null) { int keyDuration = 0; Integer defaultTargetDuration = 0; int keyTarget = 0; @@ -843,9 +842,8 @@ public class SmsCommunicatorPlugin extends PluginBase { String reply = String.format(MainApp.gs(R.string.smscommunicator_tt_set), ttString, ttDuration); sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } catch (Exception e) { + } else { sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand)); - return; } } }); @@ -864,15 +862,9 @@ public class SmsCommunicatorPlugin extends PluginBase { messageToConfirm = new AuthRequest(this, receivedSms, reply, passCode, new SmsAction() { @Override public void run() { - try { - SP.putBoolean(R.string.key_smscommunicator_remotecommandsallowed, false); - String reply = String.format(MainApp.gs(R.string.smscommunicator_stoppedsms)); - sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); - } catch (Exception e) { - e.printStackTrace(); - sendSMS(new Sms(receivedSms.phoneNumber, R.string.smscommunicator_unknowncommand)); - return; - } + SP.putBoolean(R.string.key_smscommunicator_remotecommandsallowed, false); + String reply = String.format(MainApp.gs(R.string.smscommunicator_stoppedsms)); + sendSMSToAllNumbers(new Sms(receivedSms.phoneNumber, reply)); } }); } else From 09c1ab5960d7a127d6f5dfb91da5bbd830018d03 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 11 Nov 2019 14:57:56 +0100 Subject: [PATCH 026/118] smbmaxminutes fix --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4c43ba1193..3233a531d8 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -814,7 +814,7 @@ BG upload settings Show detailed delta Show delta with one more decimal place - 45 60 75 90 105 120 + SMB max minutes Max minutes of basal to limit SMB to Unsupported pump firmware Send BG data to xDrip+ From 8fa4c49060de6d9aee6ef091d15321805c026489 Mon Sep 17 00:00:00 2001 From: Milos Kozak Date: Mon, 11 Nov 2019 16:42:29 +0100 Subject: [PATCH 027/118] remove simple profile --- .../info/nightscout/androidaps/MainApp.java | 2 - .../profile/simple/SimpleProfileFragment.java | 159 --------------- .../profile/simple/SimpleProfilePlugin.java | 181 ------------------ .../res/layout/simpleprofile_fragment.xml | 145 -------------- 4 files changed, 487 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfileFragment.java delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfilePlugin.java delete mode 100644 app/src/main/res/layout/simpleprofile_fragment.xml diff --git a/app/src/main/java/info/nightscout/androidaps/MainApp.java b/app/src/main/java/info/nightscout/androidaps/MainApp.java index 7899937a04..b8dbdd7ad3 100644 --- a/app/src/main/java/info/nightscout/androidaps/MainApp.java +++ b/app/src/main/java/info/nightscout/androidaps/MainApp.java @@ -59,7 +59,6 @@ import info.nightscout.androidaps.plugins.insulin.InsulinOrefUltraRapidActingPlu import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin; import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin; import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin; -import info.nightscout.androidaps.plugins.profile.simple.SimpleProfilePlugin; import info.nightscout.androidaps.plugins.pump.combo.ComboPlugin; import info.nightscout.androidaps.plugins.pump.danaR.DanaRPlugin; import info.nightscout.androidaps.plugins.pump.danaRKorean.DanaRKoreanPlugin; @@ -188,7 +187,6 @@ public class MainApp extends Application { if (Config.APS) pluginsList.add(OpenAPSAMAPlugin.getPlugin()); if (Config.APS) pluginsList.add(OpenAPSSMBPlugin.getPlugin()); pluginsList.add(NSProfilePlugin.getPlugin()); - if (!Config.NSCLIENT) pluginsList.add(SimpleProfilePlugin.getPlugin()); if (!Config.NSCLIENT) pluginsList.add(LocalProfilePlugin.INSTANCE); pluginsList.add(TreatmentsPlugin.getPlugin()); if (!Config.NSCLIENT) pluginsList.add(SafetyPlugin.getPlugin()); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfileFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfileFragment.java deleted file mode 100644 index ecf4fc423b..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfileFragment.java +++ /dev/null @@ -1,159 +0,0 @@ -package info.nightscout.androidaps.plugins.profile.simple; - - -import android.os.Bundle; -import android.text.Editable; -import android.text.TextWatcher; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.EditText; -import android.widget.RadioButton; -import android.widget.TextView; - -import androidx.fragment.app.Fragment; - -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.events.EventInitializationChanged; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin; -import info.nightscout.androidaps.plugins.general.careportal.CareportalFragment; -import info.nightscout.androidaps.plugins.general.careportal.Dialogs.NewNSTreatmentDialog; -import info.nightscout.androidaps.plugins.general.careportal.OptionsToShow; -import info.nightscout.androidaps.utils.FabricPrivacy; -import info.nightscout.androidaps.utils.SafeParse; -import io.reactivex.android.schedulers.AndroidSchedulers; -import io.reactivex.disposables.CompositeDisposable; - -public class SimpleProfileFragment extends Fragment { - private CompositeDisposable disposable = new CompositeDisposable(); - - EditText diaView; - RadioButton mgdlView; - RadioButton mmolView; - EditText icView; - EditText isfView; - EditText basalView; - EditText targetlowView; - EditText targethighView; - Button profileswitchButton; - TextView invalidProfile; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, - Bundle savedInstanceState) { - View layout = inflater.inflate(R.layout.simpleprofile_fragment, container, false); - diaView = (EditText) layout.findViewById(R.id.simpleprofile_dia); - mgdlView = (RadioButton) layout.findViewById(R.id.simpleprofile_mgdl); - mmolView = (RadioButton) layout.findViewById(R.id.simpleprofile_mmol); - icView = (EditText) layout.findViewById(R.id.simpleprofile_ic); - isfView = (EditText) layout.findViewById(R.id.simpleprofile_isf); - basalView = (EditText) layout.findViewById(R.id.simpleprofile_basalrate); - targetlowView = (EditText) layout.findViewById(R.id.simpleprofile_targetlow); - targethighView = (EditText) layout.findViewById(R.id.simpleprofile_targethigh); - profileswitchButton = (Button) layout.findViewById(R.id.simpleprofile_profileswitch); - invalidProfile = (TextView) layout.findViewById(R.id.invalidprofile); - - if (!ConfigBuilderPlugin.getPlugin().getActivePump().getPumpDescription().isTempBasalCapable) { - layout.findViewById(R.id.simpleprofile_basalrate).setVisibility(View.GONE); - layout.findViewById(R.id.simpleprofile_basalrate_label).setVisibility(View.GONE); - } - - mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl); - mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol); - diaView.setText(SimpleProfilePlugin.getPlugin().dia.toString()); - icView.setText(SimpleProfilePlugin.getPlugin().ic.toString()); - isfView.setText(SimpleProfilePlugin.getPlugin().isf.toString()); - basalView.setText(SimpleProfilePlugin.getPlugin().basal.toString()); - targetlowView.setText(SimpleProfilePlugin.getPlugin().targetLow.toString()); - targethighView.setText(SimpleProfilePlugin.getPlugin().targetHigh.toString()); - - mgdlView.setOnClickListener(v -> { - SimpleProfilePlugin.getPlugin().mgdl = mgdlView.isChecked(); - SimpleProfilePlugin.getPlugin().mmol = !SimpleProfilePlugin.getPlugin().mgdl; - mmolView.setChecked(SimpleProfilePlugin.getPlugin().mmol); - SimpleProfilePlugin.getPlugin().storeSettings(); - }); - mmolView.setOnClickListener(v -> { - SimpleProfilePlugin.getPlugin().mmol = mmolView.isChecked(); - SimpleProfilePlugin.getPlugin().mgdl = !SimpleProfilePlugin.getPlugin().mmol; - mgdlView.setChecked(SimpleProfilePlugin.getPlugin().mgdl); - SimpleProfilePlugin.getPlugin().storeSettings(); - }); - - profileswitchButton.setOnClickListener(view -> { - NewNSTreatmentDialog newDialog = new NewNSTreatmentDialog(); - final OptionsToShow profileswitch = CareportalFragment.PROFILESWITCH; - profileswitch.executeProfileSwitch = true; - newDialog.setOptions(profileswitch, R.string.careportal_profileswitch); - newDialog.show(getFragmentManager(), "NewNSTreatmentDialog"); - }); - - TextWatcher textWatch = new TextWatcher() { - - @Override - public void afterTextChanged(Editable s) { - } - - @Override - public void beforeTextChanged(CharSequence s, int start, - int count, int after) { - } - - @Override - public void onTextChanged(CharSequence s, int start, - int before, int count) { - SimpleProfilePlugin.getPlugin().dia = SafeParse.stringToDouble(diaView.getText().toString()); - SimpleProfilePlugin.getPlugin().ic = SafeParse.stringToDouble(icView.getText().toString()); - SimpleProfilePlugin.getPlugin().isf = SafeParse.stringToDouble(isfView.getText().toString()); - SimpleProfilePlugin.getPlugin().basal = SafeParse.stringToDouble(basalView.getText().toString()); - SimpleProfilePlugin.getPlugin().targetLow = SafeParse.stringToDouble(targetlowView.getText().toString()); - SimpleProfilePlugin.getPlugin().targetHigh = SafeParse.stringToDouble(targethighView.getText().toString()); - SimpleProfilePlugin.getPlugin().storeSettings(); - updateGUI(); - } - }; - - diaView.addTextChangedListener(textWatch); - icView.addTextChangedListener(textWatch); - isfView.addTextChangedListener(textWatch); - basalView.addTextChangedListener(textWatch); - targetlowView.addTextChangedListener(textWatch); - targethighView.addTextChangedListener(textWatch); - - return layout; - } - - @Override - public synchronized void onResume() { - super.onResume(); - disposable.add(RxBus.INSTANCE - .toObservable(EventInitializationChanged.class) - .observeOn(AndroidSchedulers.mainThread()) - .subscribe(event -> updateGUI(), FabricPrivacy::logException) - ); - updateGUI(); - } - - @Override - public synchronized void onPause() { - super.onPause(); - disposable.clear(); - } - - protected void updateGUI() { - boolean isValid = SimpleProfilePlugin.getPlugin().getProfile() != null && SimpleProfilePlugin.getPlugin().getProfile().getDefaultProfile().isValid(MainApp.gs(R.string.simpleprofile)); - if (!ConfigBuilderPlugin.getPlugin().getActivePump().isInitialized() || ConfigBuilderPlugin.getPlugin().getActivePump().isSuspended() || !isValid) { - profileswitchButton.setVisibility(View.GONE); - } else { - profileswitchButton.setVisibility(View.VISIBLE); - } - if (isValid) - invalidProfile.setVisibility(View.GONE); - else - invalidProfile.setVisibility(View.VISIBLE); - } - -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfilePlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfilePlugin.java deleted file mode 100644 index 61ca403f55..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/profile/simple/SimpleProfilePlugin.java +++ /dev/null @@ -1,181 +0,0 @@ -package info.nightscout.androidaps.plugins.profile.simple; - -import android.content.SharedPreferences; -import android.preference.PreferenceManager; - -import org.json.JSONArray; -import org.json.JSONException; -import org.json.JSONObject; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import info.nightscout.androidaps.Constants; -import info.nightscout.androidaps.MainApp; -import info.nightscout.androidaps.R; -import info.nightscout.androidaps.data.ProfileStore; -import info.nightscout.androidaps.events.EventProfileStoreChanged; -import info.nightscout.androidaps.interfaces.PluginBase; -import info.nightscout.androidaps.interfaces.PluginDescription; -import info.nightscout.androidaps.interfaces.PluginType; -import info.nightscout.androidaps.interfaces.ProfileInterface; -import info.nightscout.androidaps.logging.L; -import info.nightscout.androidaps.plugins.bus.RxBus; -import info.nightscout.androidaps.utils.SP; - -/** - * Created by mike on 05.08.2016. - */ -public class SimpleProfilePlugin extends PluginBase implements ProfileInterface { - private static Logger log = LoggerFactory.getLogger(L.PROFILE); - - private static SimpleProfilePlugin simpleProfilePlugin; - - public static SimpleProfilePlugin getPlugin() { - if (simpleProfilePlugin == null) - simpleProfilePlugin = new SimpleProfilePlugin(); - return simpleProfilePlugin; - } - - private static ProfileStore convertedProfile = null; - - boolean mgdl; - boolean mmol; - Double dia; - Double ic; - Double isf; - Double basal; - Double targetLow; - Double targetHigh; - - private SimpleProfilePlugin() { - super(new PluginDescription() - .mainType(PluginType.PROFILE) - .fragmentClass(SimpleProfileFragment.class.getName()) - .pluginName(R.string.simpleprofile) - .shortName(R.string.simpleprofile_shortname) - .description(R.string.description_profile_simple) - ); - loadSettings(); - } - - public void storeSettings() { - if (L.isEnabled(L.PROFILE)) - log.debug("Storing settings"); - SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(MainApp.instance().getApplicationContext()); - SharedPreferences.Editor editor = settings.edit(); - editor.putBoolean("SimpleProfile" + "mmol", mmol); - editor.putBoolean("SimpleProfile" + "mgdl", mgdl); - editor.putString("SimpleProfile" + "dia", dia.toString()); - editor.putString("SimpleProfile" + "ic", ic.toString()); - editor.putString("SimpleProfile" + "isf", isf.toString()); - editor.putString("SimpleProfile" + "basal", basal.toString()); - editor.putString("SimpleProfile" + "targetlow", targetLow.toString()); - editor.putString("SimpleProfile" + "targethigh", targetHigh.toString()); - - editor.apply(); - createConvertedProfile(); - if (L.isEnabled(L.PROFILE)) - log.debug("Storing settings: " + getRawProfile().getData().toString()); - RxBus.INSTANCE.send(new EventProfileStoreChanged()); - } - - private void loadSettings() { - if (L.isEnabled(L.PROFILE)) - log.debug("Loading stored settings"); - - mgdl = SP.getBoolean("SimpleProfile" + "mgdl", true); - mmol = SP.getBoolean("SimpleProfile" + "mmol", false); - dia = SP.getDouble("SimpleProfile" + "dia", Constants.defaultDIA); - ic = SP.getDouble("SimpleProfile" + "ic", 0d); - isf = SP.getDouble("SimpleProfile" + "isf", 0d); - basal = SP.getDouble("SimpleProfile" + "basal", 0d); - targetLow = SP.getDouble("SimpleProfile" + "targetlow", 0d); - targetHigh = SP.getDouble("SimpleProfile" + "targethigh", 0d); - } - - /* - { - "_id": "576264a12771b7500d7ad184", - "startDate": "2016-06-16T08:35:00.000Z", - "defaultProfile": "Default", - "store": { - "Default": { - "dia": "3", - "carbratio": [{ - "time": "00:00", - "value": "30" - }], - "carbs_hr": "20", - "delay": "20", - "sens": [{ - "time": "00:00", - "value": "100" - }], - "timezone": "UTC", - "basal": [{ - "time": "00:00", - "value": "0.1" - }], - "target_low": [{ - "time": "00:00", - "value": "0" - }], - "target_high": [{ - "time": "00:00", - "value": "0" - }], - "startDate": "1970-01-01T00:00:00.000Z", - "units": "mmol" - } - }, - "created_at": "2016-06-16T08:34:41.256Z" - } - */ - private void createConvertedProfile() { - JSONObject json = new JSONObject(); - JSONObject store = new JSONObject(); - JSONObject profile = new JSONObject(); - - try { - json.put("defaultProfile", "SimpleProfile"); - json.put("store", store); - profile.put("dia", dia); - profile.put("carbratio", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", ic))); - profile.put("sens", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", isf))); - profile.put("basal", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", basal))); - profile.put("target_low", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetLow))); - profile.put("target_high", new JSONArray().put(new JSONObject().put("time", "00:00").put("timeAsSeconds", 0).put("value", targetHigh))); - profile.put("units", mgdl ? Constants.MGDL : Constants.MMOL); - store.put("SimpleProfile", profile); - } catch (JSONException e) { - log.error("Unhandled exception", e); - } - convertedProfile = new ProfileStore(json); - } - - @Override - public ProfileStore getProfile() { - if (convertedProfile == null) - createConvertedProfile(); - if (!convertedProfile.getDefaultProfile().isValid(MainApp.gs(R.string.simpleprofile))) - return null; - return convertedProfile; - } - - public ProfileStore getRawProfile() { - if (convertedProfile == null) - createConvertedProfile(); - return convertedProfile; - } - - @Override - public String getUnits() { - return mgdl ? Constants.MGDL : Constants.MMOL; - } - - @Override - public String getProfileName() { - return "SimpleProfile"; - } - -} diff --git a/app/src/main/res/layout/simpleprofile_fragment.xml b/app/src/main/res/layout/simpleprofile_fragment.xml deleted file mode 100644 index 5a896f22a0..0000000000 --- a/app/src/main/res/layout/simpleprofile_fragment.xml +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -