cob display
This commit is contained in:
parent
638f6bc291
commit
5ef034b4fc
11 changed files with 363 additions and 96 deletions
|
@ -4,6 +4,8 @@ package info.nightscout.androidaps;
|
|||
* Created by mike on 07.06.2016.
|
||||
*/
|
||||
public class Config {
|
||||
public static final boolean CACHECALCULATIONS = true;
|
||||
|
||||
// MAIN FUCTIONALITY
|
||||
public static final boolean APS = BuildConfig.APS;
|
||||
// PLUGINS
|
||||
|
|
|
@ -16,4 +16,5 @@ public interface TreatmentsInterface {
|
|||
IobTotal getCalculationToTime(long time);
|
||||
MealData getMealData();
|
||||
List<Treatment> getTreatments();
|
||||
List<Treatment> getTreatments5MinBack(long time);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
package info.nightscout.androidaps.plugins.IobCobCalculator;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* Created by mike on 25.04.2017.
|
||||
*/
|
||||
|
||||
public class AutosensData {
|
||||
String pastSensitivity = "";
|
||||
double deviation = 0d;
|
||||
double absorbed = 0d;
|
||||
double carbsFromBolus = 0d;
|
||||
public double cob = 0;
|
||||
|
||||
public String log(long time) {
|
||||
return "AutosensData: " + new Date(time).toLocaleString() + " " + pastSensitivity + " Deviation=" + deviation + " Absorbed=" + absorbed + " CarbsFromBolus=" + carbsFromBolus + " COB=" + cob;
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.IobCobCalculator;
|
|||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.util.LongSparseArray;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
||||
|
@ -15,16 +16,23 @@ import java.util.Date;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.MealData;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.Treatment;
|
||||
import info.nightscout.androidaps.events.EventNewBG;
|
||||
import info.nightscout.androidaps.events.EventNewBasalProfile;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.TreatmentsInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.events.EventNewHistoryData;
|
||||
import info.nightscout.androidaps.plugins.NSClientInternal.data.NSProfile;
|
||||
import info.nightscout.androidaps.plugins.OpenAPSAMA.Autosens;
|
||||
import info.nightscout.androidaps.plugins.Treatments.TreatmentsPlugin;
|
||||
import info.nightscout.utils.SP;
|
||||
|
||||
/**
|
||||
* Created by mike on 24.04.2017.
|
||||
|
@ -33,8 +41,8 @@ import info.nightscout.androidaps.plugins.NSClientInternal.data.NSProfile;
|
|||
public class IobCobCalculatorPlugin implements PluginBase {
|
||||
private static Logger log = LoggerFactory.getLogger(IobCobCalculatorPlugin.class);
|
||||
|
||||
private static HashMap<Long, IobTotal> iobTable = new HashMap<Long, IobTotal>();
|
||||
private static HashMap<Long, MealData> mealDataTable = new HashMap<Long, MealData>();
|
||||
private static LongSparseArray<IobTotal> iobTable = new LongSparseArray<>();
|
||||
private static LongSparseArray<AutosensData> autosensDataTable = new LongSparseArray<>();
|
||||
|
||||
private static List<BgReading> bgReadings = null; // newest at index 0
|
||||
private static List<BgReading> bucketed_data = null;
|
||||
|
@ -121,6 +129,13 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
return -1;
|
||||
}
|
||||
|
||||
public static long roundUpTime(long time) {
|
||||
if (time % 60000 == 0)
|
||||
return time;
|
||||
long rouded = (time / 60000 + 1) * 60000;
|
||||
return rouded;
|
||||
}
|
||||
|
||||
private void loadBgData() {
|
||||
onNewProfile(new EventNewBasalProfile(null));
|
||||
bgReadings = MainApp.getDbHelper().getBgreadingsDataFromTime((long) (new Date().getTime() - 60 * 60 * 1000L * (24 + dia)), false);
|
||||
|
@ -189,23 +204,139 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
log.debug("Bucketed data created. Size: " + bucketed_data.size());
|
||||
}
|
||||
|
||||
public static IobTotal calulateFromTreatmentsAndTemps() {
|
||||
ConfigBuilderPlugin.getActiveTreatments().updateTotalIOB();
|
||||
IobTotal bolusIob = ConfigBuilderPlugin.getActiveTreatments().getLastCalculation().round();
|
||||
ConfigBuilderPlugin.getActiveTempBasals().updateTotalIOB();
|
||||
IobTotal basalIob = ConfigBuilderPlugin.getActiveTempBasals().getLastCalculation().round();
|
||||
IobTotal iobTotal = IobTotal.combine(bolusIob, basalIob).round();
|
||||
return iobTotal;
|
||||
public void calculateSensitivityData() {
|
||||
NSProfile profile = ConfigBuilderPlugin.getActiveProfile() != null ? ConfigBuilderPlugin.getActiveProfile().getProfile() : null;
|
||||
|
||||
if (profile == null) {
|
||||
log.debug("calculateSensitivityData: No profile available");
|
||||
return;
|
||||
}
|
||||
|
||||
if (ConfigBuilderPlugin.getActiveTreatments() == null) {
|
||||
log.debug("calculateSensitivityData: No treatments plugin");
|
||||
return;
|
||||
}
|
||||
|
||||
TreatmentsInterface treatmentsInterface = ConfigBuilderPlugin.getActiveTreatments();
|
||||
if (bucketed_data == null || bucketed_data.size() < 3) {
|
||||
log.debug("calculateSensitivityData: No bucketed data available");
|
||||
return;
|
||||
}
|
||||
|
||||
long prevDataTime = roundUpTime(bucketed_data.get(bucketed_data.size() - 3).timeIndex);
|
||||
log.debug("Prev data time: " + new Date(prevDataTime).toLocaleString());
|
||||
AutosensData previous = autosensDataTable.get(prevDataTime);
|
||||
// start from oldest to be able sub cob
|
||||
for (int i = bucketed_data.size() - 4; i >= 0; i--) {
|
||||
// check if data already exists
|
||||
long bgTime = bucketed_data.get(i).timeIndex;
|
||||
bgTime = roundUpTime(bgTime);
|
||||
|
||||
AutosensData existing;
|
||||
if ((existing = autosensDataTable.get(bgTime)) != null) {
|
||||
previous = existing;
|
||||
continue;
|
||||
}
|
||||
|
||||
int secondsFromMidnight = NSProfile.secondsFromMidnight(bgTime);
|
||||
double sens = NSProfile.toMgdl(profile.getIsf(secondsFromMidnight), profile.getUnits());
|
||||
|
||||
AutosensData autosensData = new AutosensData();
|
||||
|
||||
//console.error(bgTime , bucketed_data[i].glucose);
|
||||
double bg;
|
||||
double avgDelta;
|
||||
double delta;
|
||||
bg = bucketed_data.get(i).value;
|
||||
if (bg < 39 || bucketed_data.get(i + 3).value < 39) {
|
||||
log.error("! value < 39");
|
||||
continue;
|
||||
}
|
||||
avgDelta = (bg - bucketed_data.get(i + 3).value) / 3;
|
||||
delta = (bg - bucketed_data.get(i + 1).value);
|
||||
|
||||
IobTotal iob = calulateFromTreatmentsAndTemps(bgTime);
|
||||
|
||||
double bgi = Math.round((-iob.activity * sens * 5) * 100) / 100d;
|
||||
double deviation = delta - bgi;
|
||||
|
||||
List<Treatment> recentTreatments = treatmentsInterface.getTreatments5MinBack(bgTime);
|
||||
for (int ir = 0; ir < recentTreatments.size(); ir++) {
|
||||
autosensData.carbsFromBolus += recentTreatments.get(ir).carbs;
|
||||
}
|
||||
|
||||
// if we absorbing carbs
|
||||
if (previous != null && previous.cob > 0) {
|
||||
// figure out how many carbs that represents
|
||||
// but always assume at least 3mg/dL/5m (default) absorption
|
||||
double ci = Math.max(deviation, SP.getDouble("openapsama_min_5m_carbimpact", 3.0));
|
||||
autosensData.absorbed = ci * profile.getIc(secondsFromMidnight) / sens;
|
||||
// and add that to the running total carbsAbsorbed
|
||||
autosensData.cob = Math.max(previous.cob - autosensData.absorbed, 0d);
|
||||
}
|
||||
autosensData.cob += autosensData.carbsFromBolus;
|
||||
|
||||
// calculate autosens only without COB
|
||||
if (autosensData.cob <= 0) {
|
||||
if (deviation > 0) {
|
||||
autosensData.pastSensitivity += "+";
|
||||
} else if (deviation == 0) {
|
||||
autosensData.pastSensitivity += "=";
|
||||
} else {
|
||||
autosensData.pastSensitivity += "-";
|
||||
}
|
||||
//avgDeltas[i] = avgDelta;
|
||||
//bgis[i] = bgi;
|
||||
autosensData.deviation = deviation;
|
||||
} else {
|
||||
autosensData.pastSensitivity += "C";
|
||||
//console.error(bgTime);
|
||||
}
|
||||
//log.debug("TIME: " + new Date(bgTime).toString() + " BG: " + bg + " SENS: " + sens + " DELTA: " + delta + " AVGDELTA: " + avgDelta + " IOB: " + iob.iob + " ACTIVITY: " + iob.activity + " BGI: " + bgi + " DEVIATION: " + deviation);
|
||||
|
||||
previous = autosensData;
|
||||
autosensDataTable.put(bgTime, autosensData);
|
||||
log.debug(autosensData.log(bgTime));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static IobTotal calulateFromTreatmentsAndTemps(long time) {
|
||||
long now = new Date().getTime();
|
||||
time = roundUpTime(time);
|
||||
if (Config.CACHECALCULATIONS && time < now && iobTable.get(time) != null) {
|
||||
//log.debug(">>> Cache hit");
|
||||
return iobTable.get(time);
|
||||
} else {
|
||||
//log.debug(">>> Cache miss " + new Date(time).toLocaleString());
|
||||
}
|
||||
IobTotal bolusIob = ConfigBuilderPlugin.getActiveTreatments().getCalculationToTime(time).round();
|
||||
IobTotal basalIob = ConfigBuilderPlugin.getActiveTempBasals().getCalculationToTime(time).round();
|
||||
/*
|
||||
if (basalIob.basaliob > 0) {
|
||||
log.debug(new Date(time).toLocaleString() + " basaliob: " + basalIob.basaliob );
|
||||
}
|
||||
*/
|
||||
IobTotal iobTotal = IobTotal.combine(bolusIob, basalIob).round();
|
||||
return iobTotal;
|
||||
if (Config.CACHECALCULATIONS && time < new Date().getTime()) {
|
||||
iobTable.put(time, iobTotal);
|
||||
}
|
||||
return iobTotal;
|
||||
}
|
||||
|
||||
public static AutosensData getAutosensData(long time) {
|
||||
long now = new Date().getTime();
|
||||
if (time > now )
|
||||
return null;
|
||||
time = roundUpTime(time);
|
||||
AutosensData data = autosensDataTable.get(time);
|
||||
if (Config.CACHECALCULATIONS && data != null) {
|
||||
log.debug(">>> Cache hit " + data.log(time));
|
||||
return data;
|
||||
} else {
|
||||
log.debug(">>> Cache miss " + new Date(time).toLocaleString());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static IobTotal[] calculateIobArrayInDia() {
|
||||
|
@ -215,7 +346,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
int len = (int) ((profile.getDia() * 60 + 30) / 5);
|
||||
IobTotal[] array = new IobTotal[len];
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; i++){
|
||||
for (int i = 0; i < len; i++) {
|
||||
long t = time + i * 5 * 60000;
|
||||
IobTotal iob = calulateFromTreatmentsAndTemps(t);
|
||||
array[pos] = iob;
|
||||
|
@ -226,7 +357,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
|
||||
public static JSONArray convertToJSONArray(IobTotal[] iobArray) {
|
||||
JSONArray array = new JSONArray();
|
||||
for (int i = 0; i < iobArray.length; i ++) {
|
||||
for (int i = 0; i < iobArray.length; i++) {
|
||||
array.put(iobArray[i].determineBasalJson());
|
||||
}
|
||||
return array;
|
||||
|
@ -239,6 +370,7 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
public void run() {
|
||||
loadBgData();
|
||||
createBucketedData();
|
||||
calculateSensitivityData();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -253,4 +385,27 @@ public class IobCobCalculatorPlugin implements PluginBase {
|
|||
}
|
||||
}
|
||||
|
||||
// When historical data is changed (comming from NS etc) finished calculations after this date must be invalidated
|
||||
@Subscribe
|
||||
public void onNewHistoryData(EventNewHistoryData ev) {
|
||||
long time = ev.time;
|
||||
log.debug("Invalidating cached data to: " + new Date(time).toLocaleString());
|
||||
for (int index = iobTable.size() - 1; index >= 0; index--) {
|
||||
if (iobTable.keyAt(index) > time) {
|
||||
log.debug("Removing from iobTable: " + new Date(iobTable.keyAt(index)).toLocaleString());
|
||||
iobTable.removeAt(index);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int index = autosensDataTable.size() - 1; index >= 0; index--) {
|
||||
if (autosensDataTable.keyAt(index) > time) {
|
||||
log.debug("Removing from autosensDataTable: " + new Date(autosensDataTable.keyAt(index)).toLocaleString());
|
||||
autosensDataTable.removeAt(index);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package info.nightscout.androidaps.plugins.IobCobCalculator.events;
|
||||
|
||||
/**
|
||||
* Created by mike on 26.04.2017.
|
||||
*/
|
||||
|
||||
public class EventNewHistoryData {
|
||||
public long time = 0;
|
||||
|
||||
public EventNewHistoryData(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
}
|
|
@ -25,7 +25,6 @@ public class Autosens {
|
|||
|
||||
//console.error(mealTime);
|
||||
|
||||
double deviationSum = 0;
|
||||
double carbsAbsorbed = 0;
|
||||
|
||||
List<BgReading> bucketed_data = IobCobCalculatorPlugin.getBucketedData(dataFromTime);
|
||||
|
@ -33,8 +32,8 @@ public class Autosens {
|
|||
return new AutosensResult();
|
||||
|
||||
//console.error(bucketed_data);
|
||||
double[] avgDeltas = new double[bucketed_data.size() - 2];
|
||||
double[] bgis = new double[bucketed_data.size() - 2];
|
||||
//double[] avgDeltas = new double[bucketed_data.size() - 2];
|
||||
//double[] bgis = new double[bucketed_data.size() - 2];
|
||||
double[] deviations = new double[bucketed_data.size() - 2];
|
||||
|
||||
String pastSensitivity = "";
|
||||
|
@ -81,10 +80,9 @@ public class Autosens {
|
|||
} else {
|
||||
pastSensitivity += "-";
|
||||
}
|
||||
avgDeltas[i] = avgDelta;
|
||||
bgis[i] = bgi;
|
||||
//avgDeltas[i] = avgDelta;
|
||||
//bgis[i] = bgi;
|
||||
deviations[i] = deviation;
|
||||
deviationSum += deviation;
|
||||
} else {
|
||||
pastSensitivity += ">";
|
||||
//console.error(bgTime);
|
||||
|
@ -112,8 +110,8 @@ public class Autosens {
|
|||
log.debug(pastSensitivity);
|
||||
//console.log(JSON.stringify(avgDeltas));
|
||||
//console.log(JSON.stringify(bgis));
|
||||
Arrays.sort(avgDeltas);
|
||||
Arrays.sort(bgis);
|
||||
//Arrays.sort(avgDeltas);
|
||||
//Arrays.sort(bgis);
|
||||
Arrays.sort(deviations);
|
||||
|
||||
for (double i = 0.9; i > 0.1; i = i - 0.02) {
|
||||
|
|
|
@ -50,6 +50,10 @@ import java.util.Calendar;
|
|||
import java.util.Date;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import info.nightscout.androidaps.Config;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
|
@ -76,6 +80,7 @@ import info.nightscout.androidaps.plugins.Careportal.Dialogs.NewNSTreatmentDialo
|
|||
import info.nightscout.androidaps.plugins.Careportal.OptionsToShow;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.ConstraintsObjectives.ObjectivesPlugin;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.AutosensData;
|
||||
import info.nightscout.androidaps.plugins.IobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.Loop.events.EventNewOpenLoopNotification;
|
||||
|
@ -155,6 +160,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
private static Handler sHandler;
|
||||
private static HandlerThread sHandlerThread;
|
||||
|
||||
private static final ScheduledExecutorService worker = Executors.newSingleThreadScheduledExecutor();
|
||||
private static ScheduledFuture<?> scheduledUpdate = null;
|
||||
|
||||
public OverviewFragment() {
|
||||
super();
|
||||
if (sHandlerThread == null) {
|
||||
|
@ -272,19 +280,19 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
switch (buttonView.getId()) {
|
||||
case R.id.overview_showprediction:
|
||||
SP.putBoolean("showprediction", showPredictionView.isChecked());
|
||||
updateGUI("onPredictionCheckedChanged");
|
||||
scheduleUpdateGUI("onPredictionCheckedChanged");
|
||||
break;
|
||||
case R.id.overview_showbasals:
|
||||
SP.putBoolean("showbasals", showPredictionView.isChecked());
|
||||
updateGUI("onBasalsCheckedChanged");
|
||||
scheduleUpdateGUI("onBasalsCheckedChanged");
|
||||
break;
|
||||
case R.id.overview_showiob:
|
||||
SP.putBoolean("showiob", showIobView.isChecked());
|
||||
updateGUI("onIobCheckedChanged");
|
||||
scheduleUpdateGUI("onIobCheckedChanged");
|
||||
break;
|
||||
case R.id.overview_showcob:
|
||||
SP.putBoolean("showcob", showCobView.isChecked());
|
||||
updateGUI("onCobCheckedChanged");
|
||||
scheduleUpdateGUI("onCobCheckedChanged");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -296,15 +304,17 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
activeloop.setFragmentEnabled(PluginBase.LOOP, false);
|
||||
activeloop.setFragmentVisible(PluginBase.LOOP, false);
|
||||
MainApp.getConfigBuilder().storeSettings();
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.enableloop))) {
|
||||
activeloop.setFragmentEnabled(PluginBase.LOOP, true);
|
||||
activeloop.setFragmentVisible(PluginBase.LOOP, true);
|
||||
MainApp.getConfigBuilder().storeSettings();
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.resume))) {
|
||||
activeloop.suspendTo(0L);
|
||||
updateGUI("suspendmenu");
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
sHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -317,23 +327,23 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor1h))) {
|
||||
activeloop.suspendTo(new Date().getTime() + 60L * 60 * 1000);
|
||||
updateGUI("suspendmenu");
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor2h))) {
|
||||
activeloop.suspendTo(new Date().getTime() + 2 * 60L * 60 * 1000);
|
||||
updateGUI("suspendmenu");
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor3h))) {
|
||||
activeloop.suspendTo(new Date().getTime() + 3 * 60L * 60 * 1000);
|
||||
updateGUI("suspendmenu");
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.suspendloopfor10h))) {
|
||||
activeloop.suspendTo(new Date().getTime() + 10 * 60L * 60 * 1000);
|
||||
updateGUI("suspendmenu");
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor30m))) {
|
||||
activeloop.suspendTo(new Date().getTime() + 30L * 60 * 1000);
|
||||
updateGUI("suspendmenu");
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
sHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -346,7 +356,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor1h))) {
|
||||
activeloop.suspendTo(new Date().getTime() + 1 * 60L * 60 * 1000);
|
||||
updateGUI("suspendmenu");
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
sHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -359,7 +369,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor2h))) {
|
||||
activeloop.suspendTo(new Date().getTime() + 2 * 60L * 60 * 1000);
|
||||
updateGUI("suspendmenu");
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
sHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -372,7 +382,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
return true;
|
||||
} else if (item.getTitle().equals(MainApp.sResources.getString(R.string.disconnectpumpfor3h))) {
|
||||
activeloop.suspendTo(new Date().getTime() + 3 * 60L * 60 * 1000);
|
||||
updateGUI("suspendmenu");
|
||||
scheduleUpdateGUI("suspendmenu");
|
||||
sHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -461,7 +471,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
objectivesPlugin.saveProgress();
|
||||
}
|
||||
}
|
||||
updateGUIIfVisible("onClickAcceptTemp");
|
||||
scheduleUpdateGUI("onClickAcceptTemp");
|
||||
}
|
||||
});
|
||||
Answers.getInstance().logCustom(new CustomEvent("AcceptTemp"));
|
||||
|
@ -585,58 +595,58 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
sRefreshLoop = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateGUIIfVisible("refreshLoop");
|
||||
scheduleUpdateGUI("refreshLoop");
|
||||
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
|
||||
}
|
||||
};
|
||||
sLoopHandler.postDelayed(sRefreshLoop, 60 * 1000L);
|
||||
registerForContextMenu(apsModeView);
|
||||
updateGUIIfVisible("onResume");
|
||||
updateGUI("onResume");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventInitializationChanged ev) {
|
||||
updateGUIIfVisible("EventInitializationChanged");
|
||||
scheduleUpdateGUI("EventInitializationChanged");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventPreferenceChange ev) {
|
||||
updateGUIIfVisible("EventPreferenceChange");
|
||||
scheduleUpdateGUI("EventPreferenceChange");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventRefreshGui ev) {
|
||||
updateGUIIfVisible("EventRefreshGui");
|
||||
scheduleUpdateGUI("EventRefreshGui");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventTreatmentChange ev) {
|
||||
updateGUIIfVisible("EventTreatmentChange");
|
||||
scheduleUpdateGUI("EventTreatmentChange");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventTempBasalChange ev) {
|
||||
updateGUIIfVisible("EventTempBasalChange");
|
||||
scheduleUpdateGUI("EventTempBasalChange");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventNewBG ev) {
|
||||
updateGUIIfVisible("EventTempBasalChange");
|
||||
scheduleUpdateGUI("EventTempBasalChange");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventNewOpenLoopNotification ev) {
|
||||
updateGUIIfVisible("EventNewOpenLoopNotification");
|
||||
scheduleUpdateGUI("EventNewOpenLoopNotification");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventNewBasalProfile ev) {
|
||||
updateGUIIfVisible("EventNewBasalProfile");
|
||||
scheduleUpdateGUI("EventNewBasalProfile");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventTempTargetRangeChange ev) {
|
||||
updateGUIIfVisible("EventTempTargetRangeChange");
|
||||
scheduleUpdateGUI("EventTempTargetRangeChange");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
@ -672,17 +682,6 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
});
|
||||
}
|
||||
|
||||
private void updateGUIIfVisible(final String from) {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateGUI(from);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updatePumpStatus(String status) {
|
||||
PumpInterface pump = MainApp.getConfigBuilder();
|
||||
if (!status.equals("")) {
|
||||
|
@ -697,6 +696,29 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
}
|
||||
}
|
||||
|
||||
public void scheduleUpdateGUI(final String from) {
|
||||
class UpdateRunnable implements Runnable {
|
||||
public void run() {
|
||||
Activity activity = getActivity();
|
||||
if (activity != null)
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
updateGUI(from);
|
||||
scheduledUpdate = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
// prepare task for execution in 400 msec
|
||||
// cancel waiting task to prevent multiple updates
|
||||
if (scheduledUpdate != null)
|
||||
scheduledUpdate.cancel(false);
|
||||
Runnable task = new UpdateRunnable();
|
||||
final int msec = 400;
|
||||
scheduledUpdate = worker.schedule(task, msec, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
public void updateGUI(String from) {
|
||||
log.debug("updateGUI entered from: " + from);
|
||||
|
@ -1044,7 +1066,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
paint.setStyle(Paint.Style.STROKE);
|
||||
paint.setStrokeWidth(2);
|
||||
paint.setPathEffect(new DashPathEffect(new float[]{2, 4}, 0));
|
||||
paint.setColor(Color.CYAN);
|
||||
paint.setColor(MainApp.sResources.getColor(R.color.basal));
|
||||
basalsLineSeries.setCustomPaint(paint);
|
||||
}
|
||||
|
||||
|
@ -1058,48 +1080,56 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
Date start = new Date();
|
||||
List<DataPoint> iobArray = new ArrayList<>();
|
||||
List<DataPoint> cobArray = new ArrayList<>();
|
||||
double lastIob = -1000;
|
||||
for (long time = fromTime; time <= endTime; time += 5 * 60 * 1000L) {
|
||||
for (long time = fromTime; time <= now; time += 5 * 60 * 1000L) {
|
||||
if (showIobView.isChecked()) {
|
||||
IobTotal iob = IobCobCalculatorPlugin.calulateFromTreatmentsAndTemps(time);
|
||||
if (lastIob != iob.iob) {
|
||||
iobArray.add(new DataPoint(time, iob.iob));
|
||||
maxIobValueFound = Math.max(maxIobValueFound, Math.abs(iob.iob));
|
||||
lastIob = iob.iob;
|
||||
}
|
||||
iobArray.add(new DataPoint(time, iob.iob));
|
||||
maxIobValueFound = Math.max(maxIobValueFound, Math.abs(iob.iob));
|
||||
}
|
||||
if (showCobView.isChecked()) {
|
||||
//MealData mealData = MainApp.getConfigBuilder().getActiveTreatments().getMealData();
|
||||
//cobArray.add(new DataPoint(time, mealData.mealCOB));
|
||||
//maxCobValueFound = Math.max(maxCobValueFound, mealData.mealCOB);
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getAutosensData(time);
|
||||
if (autosensData != null) {
|
||||
cobArray.add(new DataPoint(time, autosensData.cob));
|
||||
maxCobValueFound = Math.max(maxCobValueFound, autosensData.cob);
|
||||
}
|
||||
}
|
||||
}
|
||||
Profiler.log(log,"IOB precessed", start);
|
||||
Profiler.log(log, "IOB processed", start);
|
||||
DataPoint[] iobData = new DataPoint[iobArray.size()];
|
||||
iobData = iobArray.toArray(iobData);
|
||||
iobSeries = new FixedLineGraphSeries<>(iobData);
|
||||
iobSeries.setDrawBackground(true);
|
||||
iobSeries.setBackgroundColor(0x80FFFFFF & MainApp.sResources.getColor(R.color.ioborange)); //50%
|
||||
iobSeries.setColor(MainApp.sResources.getColor(R.color.ioborange));
|
||||
iobSeries.setBackgroundColor(0x80FFFFFF & MainApp.sResources.getColor(R.color.iob)); //50%
|
||||
iobSeries.setColor(MainApp.sResources.getColor(R.color.iob));
|
||||
iobSeries.setThickness(3);
|
||||
iobSeries.setTitle("IOB");
|
||||
iobGraph.getGridLabelRenderer().setVerticalLabelsAlign(Paint.Align.LEFT);
|
||||
|
||||
|
||||
if (showIobView.isChecked() && showCobView.isChecked()) {
|
||||
List<DataPoint> cobArrayRescaled = new ArrayList<>();
|
||||
for (int ci = 0; ci < cobArray.size(); ci++) {
|
||||
cobArrayRescaled.add(new DataPoint(cobArray.get(ci).getX(), cobArray.get(ci).getY() * maxIobValueFound / maxCobValueFound / 2));
|
||||
}
|
||||
cobArray = cobArrayRescaled;
|
||||
}
|
||||
DataPoint[] cobData = new DataPoint[cobArray.size()];
|
||||
cobData = cobArray.toArray(cobData);
|
||||
cobSeries = new FixedLineGraphSeries<>(cobData);
|
||||
cobSeries.setDrawBackground(true);
|
||||
cobSeries.setBackgroundColor(Color.RED);
|
||||
cobSeries.setThickness(0);
|
||||
cobSeries.setBackgroundColor(0xB0FFFFFF & MainApp.sResources.getColor(R.color.cob)); //50%
|
||||
cobSeries.setColor(MainApp.sResources.getColor(R.color.cob));
|
||||
cobSeries.setThickness(3);
|
||||
cobSeries.setTitle("COB");
|
||||
|
||||
iobGraph.removeAllSeries();
|
||||
|
||||
if (showIobView.isChecked()) {
|
||||
iobGraph.addSeries(iobSeries);
|
||||
}
|
||||
if (showCobView.isChecked()) {
|
||||
iobGraph.getSecondScale().addSeries(cobSeries);
|
||||
iobGraph.getSecondScale().setLabelFormatter(new LabelFormatter() {
|
||||
if (showCobView.isChecked() && cobData.length > 0) {
|
||||
iobGraph.addSeries(cobSeries);
|
||||
/* iobGraph.getSecondScale().setLabelFormatter(new LabelFormatter() {
|
||||
@Override
|
||||
public String formatLabel(double value, boolean isValueX) {
|
||||
return "";
|
||||
|
@ -1107,10 +1137,9 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
|
||||
@Override
|
||||
public void setViewport(Viewport viewport) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
*/ }
|
||||
iobGraphLayout.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
iobGraphLayout.setVisibility(View.GONE);
|
||||
|
@ -1194,7 +1223,7 @@ public class OverviewFragment extends Fragment implements View.OnClickListener,
|
|||
bgGraph.addSeries(predSeries = new PointsGraphSeries<BgReading>(pred));
|
||||
predSeries.setShape(PointsGraphSeries.Shape.POINT);
|
||||
predSeries.setSize(4);
|
||||
predSeries.setColor(Color.MAGENTA);
|
||||
predSeries.setColor(MainApp.sResources.getColor(R.color.prediction));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.squareup.otto.Subscribe;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -163,6 +164,17 @@ public class TreatmentsPlugin implements PluginBase, TreatmentsInterface {
|
|||
return treatments;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Treatment> getTreatments5MinBack(long time) {
|
||||
List<Treatment> in5minback = new ArrayList<>();
|
||||
for (Integer pos = 0; pos < treatments.size(); pos++) {
|
||||
Treatment t = treatments.get(pos);
|
||||
if (t.created_at.getTime() <= time && t.created_at.getTime() > time - 5 * 60 * 1000)
|
||||
in5minback.add(t);
|
||||
}
|
||||
return in5minback;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onStatusEvent(final EventTreatmentChange ev) {
|
||||
initializeData();
|
||||
|
|
|
@ -218,16 +218,6 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="80dip" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentTop="true"
|
||||
android:paddingRight="10dp"
|
||||
android:paddingTop="5dp"
|
||||
android:text="@string/iob"
|
||||
android:textColor="@color/ioborange"
|
||||
android:textStyle="bold" />
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -237,30 +227,73 @@
|
|||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/predictionshortlabel"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="@color/prediction"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/overview_showprediction"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:buttonTint="@color/magenta" />
|
||||
android:layout_marginBottom="-5dp"
|
||||
android:layout_marginTop="-9dp"
|
||||
app:buttonTint="@color/prediction" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/basalshortlabel"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="@color/basal"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/overview_showbasals"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:buttonTint="@color/cyan" />
|
||||
android:layout_marginBottom="-5dp"
|
||||
android:layout_marginTop="-9dp"
|
||||
app:buttonTint="@color/basal" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/iob"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="@color/iob"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/overview_showiob"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:buttonTint="@color/ioborange" />
|
||||
android:layout_marginBottom="-5dp"
|
||||
android:layout_marginTop="-9dp"
|
||||
app:buttonTint="@color/iob" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:text="@string/cob"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:textColor="@color/cob"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/overview_showcob"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:buttonTint="@color/cyan" />
|
||||
android:layout_marginBottom="-5dp"
|
||||
android:layout_marginTop="-9dp"
|
||||
app:buttonTint="@color/cob" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="magenta">#ff00ff</color>
|
||||
<color name="cyan">#00ffff</color>
|
||||
<color name="ioborange">#FFFB8C00</color>
|
||||
<color name="prediction">#ff00ff</color>
|
||||
<color name="basal">#00ffff</color>
|
||||
<color name="iob">#FFFB8C00</color>
|
||||
<color name="cob">#fbf300</color>
|
||||
|
||||
<color name="colorPrimary">#3F51B5</color>
|
||||
<color name="colorPrimaryDark">#303F9F</color>
|
||||
|
|
|
@ -593,4 +593,7 @@
|
|||
<string name="enablesuperbolus">Enable superbolus in wizard</string>
|
||||
<string name="enablesuperbolus_summary">Enable superbolus functionality in wizard. Do not enable until you learn what it really does. IT MAY CAUSE INSULIN OVERDOSE IF USED BLINDLY!</string>
|
||||
<string name="iob">IOB</string>
|
||||
<string name="cob">COB</string>
|
||||
<string name="predictionshortlabel">PRE</string>
|
||||
<string name="basalshortlabel">BAS</string>
|
||||
</resources>
|
||||
|
|
Loading…
Reference in a new issue