Merge pull request #1747 from MilosKozak/glucosestatusfix
Fix GlucoseStatus calcuation
This commit is contained in:
commit
4b71be4992
|
@ -1,178 +0,0 @@
|
||||||
package info.nightscout.androidaps.data;
|
|
||||||
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
|
||||||
import info.nightscout.androidaps.logging.L;
|
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
|
||||||
import info.nightscout.androidaps.utils.Round;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mike on 04.01.2017.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class GlucoseStatus {
|
|
||||||
private static Logger log = LoggerFactory.getLogger(GlucoseStatus.class);
|
|
||||||
public double glucose = 0d;
|
|
||||||
public double delta = 0d;
|
|
||||||
public double avgdelta = 0d;
|
|
||||||
public double short_avgdelta = 0d;
|
|
||||||
public double long_avgdelta = 0d;
|
|
||||||
public long date = 0L;
|
|
||||||
|
|
||||||
|
|
||||||
public String log() {
|
|
||||||
return "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " +
|
|
||||||
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" +
|
|
||||||
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl " +
|
|
||||||
"Long avg. delta: " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl";
|
|
||||||
}
|
|
||||||
|
|
||||||
public GlucoseStatus() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public GlucoseStatus round() {
|
|
||||||
this.glucose = Round.roundTo(this.glucose, 0.1);
|
|
||||||
this.delta = Round.roundTo(this.delta, 0.01);
|
|
||||||
this.avgdelta = Round.roundTo(this.avgdelta, 0.01);
|
|
||||||
this.short_avgdelta = Round.roundTo(this.short_avgdelta, 0.01);
|
|
||||||
this.long_avgdelta = Round.roundTo(this.long_avgdelta, 0.01);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static GlucoseStatus getGlucoseStatusData() {
|
|
||||||
return getGlucoseStatusData(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) {
|
|
||||||
// load 45min
|
|
||||||
//long fromtime = DateUtil.now() - 60 * 1000L * 45;
|
|
||||||
//List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false);
|
|
||||||
|
|
||||||
List<BgReading> data = IobCobCalculatorPlugin.getPlugin().getBgReadings();
|
|
||||||
|
|
||||||
if (data == null) {
|
|
||||||
if (L.isEnabled(L.GLUCOSE))
|
|
||||||
log.debug("data=null");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sizeRecords = data.size();
|
|
||||||
if (sizeRecords == 0) {
|
|
||||||
if (L.isEnabled(L.GLUCOSE))
|
|
||||||
log.debug("sizeRecords==0");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
|
|
||||||
if (L.isEnabled(L.GLUCOSE))
|
|
||||||
log.debug("olddata");
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
BgReading now = data.get(0);
|
|
||||||
long now_date = now.date;
|
|
||||||
double change;
|
|
||||||
|
|
||||||
if (sizeRecords == 1) {
|
|
||||||
GlucoseStatus status = new GlucoseStatus();
|
|
||||||
status.glucose = now.value;
|
|
||||||
status.short_avgdelta = 0d;
|
|
||||||
status.delta = 0d;
|
|
||||||
status.long_avgdelta = 0d;
|
|
||||||
status.avgdelta = 0d; // for OpenAPS MA
|
|
||||||
status.date = now_date;
|
|
||||||
if (L.isEnabled(L.GLUCOSE))
|
|
||||||
log.debug("sizeRecords==1");
|
|
||||||
return status.round();
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<Double> now_value_list = new ArrayList<>();
|
|
||||||
ArrayList<Double> last_deltas = new ArrayList<>();
|
|
||||||
ArrayList<Double> short_deltas = new ArrayList<>();
|
|
||||||
ArrayList<Double> long_deltas = new ArrayList<>();
|
|
||||||
|
|
||||||
// Use the latest sgv value in the now calculations
|
|
||||||
now_value_list.add(now.value);
|
|
||||||
|
|
||||||
for (int i = 1; i < sizeRecords; i++) {
|
|
||||||
if (data.get(i).value > 38) {
|
|
||||||
BgReading then = data.get(i);
|
|
||||||
long then_date = then.date;
|
|
||||||
double avgdelta;
|
|
||||||
long minutesago;
|
|
||||||
|
|
||||||
minutesago = Math.round((now_date - then_date) / (1000d * 60));
|
|
||||||
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
|
|
||||||
change = now.value - then.value;
|
|
||||||
avgdelta = change / minutesago * 5;
|
|
||||||
|
|
||||||
if (L.isEnabled(L.GLUCOSE))
|
|
||||||
log.debug(then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta);
|
|
||||||
|
|
||||||
// use the average of all data points in the last 2.5m for all further "now" calculations
|
|
||||||
if (0 < minutesago && minutesago < 2.5) {
|
|
||||||
// Keep and average all values within the last 2.5 minutes
|
|
||||||
now_value_list.add(then.value);
|
|
||||||
now.value = average(now_value_list);
|
|
||||||
// short_deltas are calculated from everything ~5-15 minutes ago
|
|
||||||
} else if (2.5 < minutesago && minutesago < 17.5) {
|
|
||||||
//console.error(minutesago, avgdelta);
|
|
||||||
short_deltas.add(avgdelta);
|
|
||||||
// last_deltas are calculated from everything ~5 minutes ago
|
|
||||||
if (2.5 < minutesago && minutesago < 7.5) {
|
|
||||||
last_deltas.add(avgdelta);
|
|
||||||
}
|
|
||||||
// long_deltas are calculated from everything ~20-40 minutes ago
|
|
||||||
} else if (17.5 < minutesago && minutesago < 42.5) {
|
|
||||||
long_deltas.add(avgdelta);
|
|
||||||
} else {
|
|
||||||
// Do not process any more records after >= 42.5 minutes
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
GlucoseStatus status = new GlucoseStatus();
|
|
||||||
status.glucose = now.value;
|
|
||||||
status.date = now_date;
|
|
||||||
|
|
||||||
status.short_avgdelta = average(short_deltas);
|
|
||||||
|
|
||||||
if (last_deltas.isEmpty()) {
|
|
||||||
status.delta = status.short_avgdelta;
|
|
||||||
} else {
|
|
||||||
status.delta = average(last_deltas);
|
|
||||||
}
|
|
||||||
|
|
||||||
status.long_avgdelta = average(long_deltas);
|
|
||||||
status.avgdelta = status.short_avgdelta; // for OpenAPS MA
|
|
||||||
|
|
||||||
if (L.isEnabled(L.GLUCOSE))
|
|
||||||
log.debug(status.log());
|
|
||||||
return status.round();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static double average(ArrayList<Double> array) {
|
|
||||||
double sum = 0d;
|
|
||||||
|
|
||||||
if (array.size() == 0)
|
|
||||||
return 0d;
|
|
||||||
|
|
||||||
for (Double value : array) {
|
|
||||||
sum += value;
|
|
||||||
}
|
|
||||||
return sum / array.size();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,6 +12,7 @@ import info.nightscout.androidaps.db.BgReading;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.CobInfo;
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
|
|
@ -17,7 +17,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.lang.reflect.InvocationTargetException;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.MealData;
|
import info.nightscout.androidaps.data.MealData;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
|
|
|
@ -39,7 +39,7 @@ import java.util.List;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
|
|
|
@ -56,7 +56,7 @@ import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.QuickWizardEntry;
|
import info.nightscout.androidaps.data.QuickWizardEntry;
|
||||||
|
|
|
@ -18,7 +18,7 @@ import java.text.DecimalFormat;
|
||||||
|
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||||
import info.nightscout.androidaps.utils.NumberPicker;
|
import info.nightscout.androidaps.utils.NumberPicker;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainActivity;
|
import info.nightscout.androidaps.MainActivity;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
import info.nightscout.androidaps.db.DatabaseHelper;
|
import info.nightscout.androidaps.db.DatabaseHelper;
|
||||||
|
|
|
@ -20,7 +20,7 @@ import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
import info.nightscout.androidaps.data.DetailedBolusInfo;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.data.ProfileStore;
|
import info.nightscout.androidaps.data.ProfileStore;
|
||||||
|
|
|
@ -32,17 +32,11 @@ import com.google.android.gms.wearable.PutDataRequest;
|
||||||
import com.google.android.gms.wearable.Wearable;
|
import com.google.android.gms.wearable.Wearable;
|
||||||
import com.google.android.gms.wearable.WearableListenerService;
|
import com.google.android.gms.wearable.WearableListenerService;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import info.nightscout.androidaps.Config;
|
import info.nightscout.androidaps.Config;
|
||||||
import info.nightscout.androidaps.Constants;
|
import info.nightscout.androidaps.Constants;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.R;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
|
@ -55,15 +49,11 @@ import info.nightscout.androidaps.interfaces.PluginType;
|
||||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSDeviceStatus;
|
||||||
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
|
import info.nightscout.androidaps.plugins.general.overview.OverviewPlugin;
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
|
import info.nightscout.androidaps.plugins.general.wear.ActionStringHandler;
|
||||||
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
|
import info.nightscout.androidaps.plugins.general.wear.WearPlugin;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
|
||||||
import info.nightscout.androidaps.plugins.treatments.Treatment;
|
|
||||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
|
||||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||||
import info.nightscout.androidaps.utils.SP;
|
import info.nightscout.androidaps.utils.SP;
|
||||||
import info.nightscout.androidaps.utils.SafeParse;
|
import info.nightscout.androidaps.utils.SafeParse;
|
||||||
|
|
|
@ -0,0 +1,180 @@
|
||||||
|
package info.nightscout.androidaps.plugins.iob.iobCobCalculator;
|
||||||
|
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
|
import info.nightscout.androidaps.logging.L;
|
||||||
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
|
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||||
|
import info.nightscout.androidaps.utils.Round;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mike on 04.01.2017.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class GlucoseStatus {
|
||||||
|
private static Logger log = LoggerFactory.getLogger(GlucoseStatus.class);
|
||||||
|
public double glucose = 0d;
|
||||||
|
public double delta = 0d;
|
||||||
|
public double avgdelta = 0d;
|
||||||
|
public double short_avgdelta = 0d;
|
||||||
|
public double long_avgdelta = 0d;
|
||||||
|
public long date = 0L;
|
||||||
|
|
||||||
|
|
||||||
|
public String log() {
|
||||||
|
return "Glucose: " + DecimalFormatter.to0Decimal(glucose) + " mg/dl " +
|
||||||
|
"Delta: " + DecimalFormatter.to0Decimal(delta) + " mg/dl" +
|
||||||
|
"Short avg. delta: " + " " + DecimalFormatter.to2Decimal(short_avgdelta) + " mg/dl " +
|
||||||
|
"Long avg. delta: " + DecimalFormatter.to2Decimal(long_avgdelta) + " mg/dl";
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlucoseStatus() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public GlucoseStatus round() {
|
||||||
|
this.glucose = Round.roundTo(this.glucose, 0.1);
|
||||||
|
this.delta = Round.roundTo(this.delta, 0.01);
|
||||||
|
this.avgdelta = Round.roundTo(this.avgdelta, 0.01);
|
||||||
|
this.short_avgdelta = Round.roundTo(this.short_avgdelta, 0.01);
|
||||||
|
this.long_avgdelta = Round.roundTo(this.long_avgdelta, 0.01);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static GlucoseStatus getGlucoseStatusData() {
|
||||||
|
return getGlucoseStatusData(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static GlucoseStatus getGlucoseStatusData(boolean allowOldData) {
|
||||||
|
// load 45min
|
||||||
|
//long fromtime = DateUtil.now() - 60 * 1000L * 45;
|
||||||
|
//List<BgReading> data = MainApp.getDbHelper().getBgreadingsDataFromTime(fromtime, false);
|
||||||
|
|
||||||
|
synchronized (IobCobCalculatorPlugin.getPlugin().getDataLock()) {
|
||||||
|
|
||||||
|
List<BgReading> data = IobCobCalculatorPlugin.getPlugin().getBgReadings();
|
||||||
|
|
||||||
|
if (data == null) {
|
||||||
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
log.debug("data=null");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sizeRecords = data.size();
|
||||||
|
if (sizeRecords == 0) {
|
||||||
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
log.debug("sizeRecords==0");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.get(0).date < DateUtil.now() - 7 * 60 * 1000L && !allowOldData) {
|
||||||
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
log.debug("olddata");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
BgReading now = data.get(0);
|
||||||
|
long now_date = now.date;
|
||||||
|
double change;
|
||||||
|
|
||||||
|
if (sizeRecords == 1) {
|
||||||
|
GlucoseStatus status = new GlucoseStatus();
|
||||||
|
status.glucose = now.value;
|
||||||
|
status.short_avgdelta = 0d;
|
||||||
|
status.delta = 0d;
|
||||||
|
status.long_avgdelta = 0d;
|
||||||
|
status.avgdelta = 0d; // for OpenAPS MA
|
||||||
|
status.date = now_date;
|
||||||
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
log.debug("sizeRecords==1");
|
||||||
|
return status.round();
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayList<Double> now_value_list = new ArrayList<>();
|
||||||
|
ArrayList<Double> last_deltas = new ArrayList<>();
|
||||||
|
ArrayList<Double> short_deltas = new ArrayList<>();
|
||||||
|
ArrayList<Double> long_deltas = new ArrayList<>();
|
||||||
|
|
||||||
|
// Use the latest sgv value in the now calculations
|
||||||
|
now_value_list.add(now.value);
|
||||||
|
|
||||||
|
for (int i = 1; i < sizeRecords; i++) {
|
||||||
|
if (data.get(i).value > 38) {
|
||||||
|
BgReading then = data.get(i);
|
||||||
|
long then_date = then.date;
|
||||||
|
double avgdelta;
|
||||||
|
long minutesago;
|
||||||
|
|
||||||
|
minutesago = Math.round((now_date - then_date) / (1000d * 60));
|
||||||
|
// multiply by 5 to get the same units as delta, i.e. mg/dL/5m
|
||||||
|
change = now.value - then.value;
|
||||||
|
avgdelta = change / minutesago * 5;
|
||||||
|
|
||||||
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
log.debug(then.toString() + " minutesago=" + minutesago + " avgdelta=" + avgdelta);
|
||||||
|
|
||||||
|
// use the average of all data points in the last 2.5m for all further "now" calculations
|
||||||
|
if (0 < minutesago && minutesago < 2.5) {
|
||||||
|
// Keep and average all values within the last 2.5 minutes
|
||||||
|
now_value_list.add(then.value);
|
||||||
|
now.value = average(now_value_list);
|
||||||
|
// short_deltas are calculated from everything ~5-15 minutes ago
|
||||||
|
} else if (2.5 < minutesago && minutesago < 17.5) {
|
||||||
|
//console.error(minutesago, avgdelta);
|
||||||
|
short_deltas.add(avgdelta);
|
||||||
|
// last_deltas are calculated from everything ~5 minutes ago
|
||||||
|
if (2.5 < minutesago && minutesago < 7.5) {
|
||||||
|
last_deltas.add(avgdelta);
|
||||||
|
}
|
||||||
|
// long_deltas are calculated from everything ~20-40 minutes ago
|
||||||
|
} else if (17.5 < minutesago && minutesago < 42.5) {
|
||||||
|
long_deltas.add(avgdelta);
|
||||||
|
} else {
|
||||||
|
// Do not process any more records after >= 42.5 minutes
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GlucoseStatus status = new GlucoseStatus();
|
||||||
|
status.glucose = now.value;
|
||||||
|
status.date = now_date;
|
||||||
|
|
||||||
|
status.short_avgdelta = average(short_deltas);
|
||||||
|
|
||||||
|
if (last_deltas.isEmpty()) {
|
||||||
|
status.delta = status.short_avgdelta;
|
||||||
|
} else {
|
||||||
|
status.delta = average(last_deltas);
|
||||||
|
}
|
||||||
|
|
||||||
|
status.long_avgdelta = average(long_deltas);
|
||||||
|
status.avgdelta = status.short_avgdelta; // for OpenAPS MA
|
||||||
|
|
||||||
|
if (L.isEnabled(L.GLUCOSE))
|
||||||
|
log.debug(status.log());
|
||||||
|
return status.round();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double average(ArrayList<Double> array) {
|
||||||
|
double sum = 0d;
|
||||||
|
|
||||||
|
if (array.size() == 0)
|
||||||
|
return 0d;
|
||||||
|
|
||||||
|
for (Double value : array) {
|
||||||
|
sum += value;
|
||||||
|
}
|
||||||
|
return sum / array.size();
|
||||||
|
}
|
||||||
|
}
|
|
@ -65,7 +65,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
private volatile List<BgReading> bgReadings = null; // newest at index 0
|
private volatile List<BgReading> bgReadings = null; // newest at index 0
|
||||||
private volatile List<BgReading> bucketed_data = null;
|
private volatile List<BgReading> bucketed_data = null;
|
||||||
|
|
||||||
final Object dataLock = new Object();
|
private final Object dataLock = new Object();
|
||||||
|
|
||||||
boolean stopCalculationTrigger = false;
|
boolean stopCalculationTrigger = false;
|
||||||
private Thread thread = null;
|
private Thread thread = null;
|
||||||
|
@ -108,6 +108,10 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
||||||
return bucketed_data;
|
return bucketed_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object getDataLock() {
|
||||||
|
return dataLock;
|
||||||
|
}
|
||||||
|
|
||||||
// roundup to whole minute
|
// roundup to whole minute
|
||||||
public static long roundUpTime(long time) {
|
public static long roundUpTime(long time) {
|
||||||
if (time % 60000 == 0)
|
if (time % 60000 == 0)
|
||||||
|
|
|
@ -96,7 +96,7 @@ public class IobCobOref1Thread extends Thread {
|
||||||
|
|
||||||
long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable);
|
long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable);
|
||||||
|
|
||||||
synchronized (iobCobCalculatorPlugin.dataLock) {
|
synchronized (iobCobCalculatorPlugin.getDataLock()) {
|
||||||
if (bgDataReload) {
|
if (bgDataReload) {
|
||||||
iobCobCalculatorPlugin.loadBgData(end);
|
iobCobCalculatorPlugin.loadBgData(end);
|
||||||
iobCobCalculatorPlugin.createBucketedData();
|
iobCobCalculatorPlugin.createBucketedData();
|
||||||
|
|
|
@ -95,7 +95,7 @@ public class IobCobThread extends Thread {
|
||||||
|
|
||||||
long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable);
|
long oldestTimeWithData = iobCobCalculatorPlugin.calculateDetectionStart(end, limitDataToOldestAvailable);
|
||||||
|
|
||||||
synchronized (iobCobCalculatorPlugin.dataLock) {
|
synchronized (iobCobCalculatorPlugin.getDataLock()) {
|
||||||
if (bgDataReload) {
|
if (bgDataReload) {
|
||||||
iobCobCalculatorPlugin.loadBgData(end);
|
iobCobCalculatorPlugin.loadBgData(end);
|
||||||
iobCobCalculatorPlugin.createBucketedData();
|
iobCobCalculatorPlugin.createBucketedData();
|
||||||
|
|
|
@ -3,7 +3,7 @@ package info.nightscout.androidaps.utils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.db.TempTarget;
|
import info.nightscout.androidaps.db.TempTarget;
|
||||||
|
|
|
@ -282,10 +282,13 @@ public class AAPSMocker {
|
||||||
PowerMockito.when(ProfileFunctions.getInstance().getProfileName()).thenReturn(TESTPROFILENAME);
|
PowerMockito.when(ProfileFunctions.getInstance().getProfileName()).thenReturn(TESTPROFILENAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void mockIobCobCalculatorPlugin() {
|
public static IobCobCalculatorPlugin mockIobCobCalculatorPlugin() {
|
||||||
PowerMockito.mockStatic(IobCobCalculatorPlugin.class);
|
PowerMockito.mockStatic(IobCobCalculatorPlugin.class);
|
||||||
IobCobCalculatorPlugin iobCobCalculatorPlugin = PowerMockito.mock(IobCobCalculatorPlugin.class);
|
IobCobCalculatorPlugin iobCobCalculatorPlugin = PowerMockito.mock(IobCobCalculatorPlugin.class);
|
||||||
PowerMockito.when(IobCobCalculatorPlugin.getPlugin()).thenReturn(iobCobCalculatorPlugin);
|
PowerMockito.when(IobCobCalculatorPlugin.getPlugin()).thenReturn(iobCobCalculatorPlugin);
|
||||||
|
Object dataLock = new Object();
|
||||||
|
PowerMockito.when(iobCobCalculatorPlugin.getDataLock()).thenReturn(dataLock);
|
||||||
|
return iobCobCalculatorPlugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static MockedBus bus = new MockedBus();
|
private static MockedBus bus = new MockedBus();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package info.nightscout.androidaps.data;
|
package info.nightscout.androidaps.plugins.iob.iobCobCalculatorPlugin;
|
||||||
|
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
@ -16,6 +16,7 @@ import java.util.List;
|
||||||
import info.AAPSMocker;
|
import info.AAPSMocker;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.db.BgReading;
|
import info.nightscout.androidaps.db.BgReading;
|
||||||
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||||
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv;
|
import info.nightscout.androidaps.plugins.general.nsclient.data.NSSgv;
|
||||||
import info.nightscout.androidaps.utils.DateUtil;
|
import info.nightscout.androidaps.utils.DateUtil;
|
||||||
|
@ -133,10 +134,7 @@ public class GlucoseStatusTest {
|
||||||
public void initMocking() {
|
public void initMocking() {
|
||||||
AAPSMocker.mockMainApp();
|
AAPSMocker.mockMainApp();
|
||||||
AAPSMocker.mockStrings();
|
AAPSMocker.mockStrings();
|
||||||
|
iobCobCalculatorPlugin = AAPSMocker.mockIobCobCalculatorPlugin();
|
||||||
PowerMockito.mockStatic(IobCobCalculatorPlugin.class);
|
|
||||||
iobCobCalculatorPlugin = mock(IobCobCalculatorPlugin.class);
|
|
||||||
when(IobCobCalculatorPlugin.getPlugin()).thenReturn(iobCobCalculatorPlugin);
|
|
||||||
|
|
||||||
PowerMockito.mockStatic(DateUtil.class);
|
PowerMockito.mockStatic(DateUtil.class);
|
||||||
when(DateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs());
|
when(DateUtil.now()).thenReturn(1514766900000L + T.mins(1).msecs());
|
|
@ -9,7 +9,7 @@ import org.powermock.modules.junit4.PowerMockRunner;
|
||||||
|
|
||||||
import info.AAPSMocker;
|
import info.AAPSMocker;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.data.GlucoseStatus;
|
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus;
|
||||||
import info.nightscout.androidaps.data.IobTotal;
|
import info.nightscout.androidaps.data.IobTotal;
|
||||||
import info.nightscout.androidaps.data.Profile;
|
import info.nightscout.androidaps.data.Profile;
|
||||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||||
|
|
Loading…
Reference in a new issue