Merge pull request #1758 from PoweRGbg/patch-1
try to calculate direction of BG if missing
This commit is contained in:
commit
0b559da27d
|
@ -7,6 +7,7 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
|
@ -19,10 +20,11 @@ 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.DataPointWithLabelInterface;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
|
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||||
|
import info.nightscout.androidaps.utils.T;
|
||||||
|
|
||||||
@DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS)
|
@DatabaseTable(tableName = DatabaseHelper.DATABASE_BGREADINGS)
|
||||||
public class BgReading implements DataPointWithLabelInterface {
|
public class BgReading implements DataPointWithLabelInterface {
|
||||||
private static Logger log = LoggerFactory.getLogger(L.DATABASE);
|
private static Logger log = LoggerFactory.getLogger(L.GLUCOSE);
|
||||||
|
|
||||||
@DatabaseField(id = true)
|
@DatabaseField(id = true)
|
||||||
public long date;
|
public long date;
|
||||||
|
@ -73,9 +75,10 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
public String directionToSymbol() {
|
public String directionToSymbol() {
|
||||||
String symbol = "";
|
String symbol = "";
|
||||||
if (direction == null) {
|
if (direction == null)
|
||||||
symbol = "??";
|
direction = calculateDirection();
|
||||||
} else if (direction.compareTo("DoubleDown") == 0) {
|
|
||||||
|
if (direction.compareTo("DoubleDown") == 0) {
|
||||||
symbol = "\u21ca";
|
symbol = "\u21ca";
|
||||||
} else if (direction.compareTo("SingleDown") == 0) {
|
} else if (direction.compareTo("SingleDown") == 0) {
|
||||||
symbol = "\u2193";
|
symbol = "\u2193";
|
||||||
|
@ -95,18 +98,13 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
return symbol;
|
return symbol;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isSlopeNameInvalid(String direction) {
|
private static boolean isSlopeNameInvalid(String direction) {
|
||||||
if (direction.compareTo("NOT_COMPUTABLE") == 0 ||
|
return direction.compareTo("NOT_COMPUTABLE") == 0 ||
|
||||||
direction.compareTo("NOT COMPUTABLE") == 0 ||
|
direction.compareTo("NOT COMPUTABLE") == 0 ||
|
||||||
direction.compareTo("OUT_OF_RANGE") == 0 ||
|
direction.compareTo("OUT_OF_RANGE") == 0 ||
|
||||||
direction.compareTo("OUT OF RANGE") == 0 ||
|
direction.compareTo("OUT OF RANGE") == 0 ||
|
||||||
direction.compareTo("NONE") == 0 ||
|
direction.compareTo("NONE") == 0 ||
|
||||||
direction.compareTo("NotComputable") == 0
|
direction.compareTo("NotComputable") == 0;
|
||||||
) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -123,7 +121,8 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
public boolean isDataChanging(BgReading other) {
|
public boolean isDataChanging(BgReading other) {
|
||||||
if (date != other.date) {
|
if (date != other.date) {
|
||||||
log.error("Comparing different");
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
log.error("Comparing different");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (value != other.value)
|
if (value != other.value)
|
||||||
|
@ -133,7 +132,8 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
public boolean isEqual(BgReading other) {
|
public boolean isEqual(BgReading other) {
|
||||||
if (date != other.date) {
|
if (date != other.date) {
|
||||||
log.error("Comparing different");
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
log.error("Comparing different");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (value != other.value)
|
if (value != other.value)
|
||||||
|
@ -149,7 +149,8 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
|
|
||||||
public void copyFrom(BgReading other) {
|
public void copyFrom(BgReading other) {
|
||||||
if (date != other.date) {
|
if (date != other.date) {
|
||||||
log.error("Copying different");
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
log.error("Copying different");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
value = other.value;
|
value = other.value;
|
||||||
|
@ -245,4 +246,53 @@ public class BgReading implements DataPointWithLabelInterface {
|
||||||
return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction || isZTPrediction;
|
return isaCOBPrediction || isCOBPrediction || isIOBPrediction || isUAMPrediction || isZTPrediction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Copied from xDrip+
|
||||||
|
String calculateDirection() {
|
||||||
|
// Rework to get bgreaings from internal DB and calculate on that base
|
||||||
|
|
||||||
|
List<BgReading> 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 (current.date == previous.date)
|
||||||
|
slope = 0;
|
||||||
|
else
|
||||||
|
slope = (previous.value - current.value) / (previous.date - current.date);
|
||||||
|
|
||||||
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
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";
|
||||||
|
|
||||||
|
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";
|
||||||
|
}
|
||||||
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
log.debug("Direction set to: " + arrow);
|
||||||
|
return arrow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
package info.nightscout.androidaps.db;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
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;
|
||||||
|
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.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)
|
||||||
|
@PrepareForTest({MainApp.class, Logger.class, L.class, SP.class, GlucoseStatus.class})
|
||||||
|
public class BgReadingTest {
|
||||||
|
private BgReading bgReading = new BgReading();
|
||||||
|
|
||||||
|
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 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);
|
||||||
|
|
||||||
|
assertTrue(copy.isEqual(bgReading));
|
||||||
|
assertFalse(copy.isEqual(new BgReading()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void calculateDirection() {
|
||||||
|
List<BgReading> bgReadingsList = null;
|
||||||
|
AAPSMocker.mockDatabaseHelper();
|
||||||
|
|
||||||
|
when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadingsList);
|
||||||
|
assertEquals("NONE", bgReading.calculateDirection());
|
||||||
|
setReadings(72,0);
|
||||||
|
assertEquals("DoubleUp", bgReading.calculateDirection());
|
||||||
|
setReadings(76,60);
|
||||||
|
assertEquals("SingleUp", bgReading.calculateDirection());
|
||||||
|
setReadings(74,65);
|
||||||
|
assertEquals("FortyFiveUp", bgReading.calculateDirection());
|
||||||
|
setReadings(72,72);
|
||||||
|
assertEquals("Flat", bgReading.calculateDirection());
|
||||||
|
setReadings(0,72);
|
||||||
|
assertEquals("DoubleDown", bgReading.calculateDirection());
|
||||||
|
setReadings(60,76);
|
||||||
|
assertEquals("SingleDown", bgReading.calculateDirection());
|
||||||
|
setReadings(65,74);
|
||||||
|
assertEquals("FortyFiveDown", bgReading.calculateDirection());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void prepareMock() {
|
||||||
|
AAPSMocker.mockMainApp();
|
||||||
|
AAPSMocker.mockApplicationContext();
|
||||||
|
AAPSMocker.mockSP();
|
||||||
|
AAPSMocker.mockL();
|
||||||
|
AAPSMocker.mockDatabaseHelper();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void 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<BgReading> bgReadings = new ArrayList() {{
|
||||||
|
add(now);
|
||||||
|
add(previous);
|
||||||
|
}};
|
||||||
|
when(MainApp.getDbHelper().getAllBgreadingsDataFromTime(anyLong(),anyBoolean())).thenReturn(bgReadings);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue