cob display

This commit is contained in:
Milos Kozak 2017-04-26 23:45:40 +02:00
parent 638f6bc291
commit 5ef034b4fc
11 changed files with 363 additions and 96 deletions

View file

@ -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

View file

@ -16,4 +16,5 @@ public interface TreatmentsInterface {
IobTotal getCalculationToTime(long time);
MealData getMealData();
List<Treatment> getTreatments();
List<Treatment> getTreatments5MinBack(long time);
}

View file

@ -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;
}
}

View file

@ -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;
}
}
}
}

View file

@ -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;
}
}

View file

@ -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) {

View file

@ -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));
}
}

View file

@ -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();

View file

@ -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>

View file

@ -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>

View file

@ -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>