calculate iob prediction based on autosens
This commit is contained in:
parent
76932d6899
commit
985f562518
|
@ -22,7 +22,7 @@ public abstract class Intervals<T extends Interval> {
|
|||
rawData = new LongSparseArray<T>();
|
||||
}
|
||||
|
||||
public synchronized Intervals reset() {
|
||||
public synchronized Intervals<T> reset() {
|
||||
rawData = new LongSparseArray<T>();
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -9,10 +9,12 @@ import org.slf4j.LoggerFactory;
|
|||
|
||||
import java.util.Date;
|
||||
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.Round;
|
||||
|
||||
public class IobTotal {
|
||||
public class IobTotal implements DataPointWithLabelInterface {
|
||||
private static Logger log = LoggerFactory.getLogger(IobTotal.class);
|
||||
|
||||
public double iob;
|
||||
|
@ -133,4 +135,52 @@ public class IobTotal {
|
|||
return json;
|
||||
}
|
||||
|
||||
// DataPoint interface
|
||||
|
||||
int color;
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return time;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return iob;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setY(double y) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLabel() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getDuration() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointsWithLabelGraphSeries.Shape getShape() {
|
||||
return PointsWithLabelGraphSeries.Shape.IOBPREDICTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSize() {
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public IobTotal setColor(int color) {
|
||||
this.color = color;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,7 @@ public class ProfileIntervals<T extends Interval> {
|
|||
rawData = other.rawData.clone();
|
||||
}
|
||||
|
||||
public synchronized ProfileIntervals reset() {
|
||||
public synchronized ProfileIntervals<T> reset() {
|
||||
rawData = new LongSparseArray<>();
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -18,12 +18,14 @@ import java.util.Objects;
|
|||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.data.Iob;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.interfaces.InsulinInterface;
|
||||
import info.nightscout.androidaps.interfaces.Interval;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult;
|
||||
import info.nightscout.androidaps.plugins.treatments.Treatment;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||
|
@ -219,7 +221,7 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
|||
IobTotal result = new IobTotal(time);
|
||||
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
|
||||
|
||||
int realDuration = getDurationToTime(time);
|
||||
double realDuration = getDurationToTime(time);
|
||||
|
||||
if (realDuration > 0) {
|
||||
double dia_ago = time - dia * 60 * 60 * 1000;
|
||||
|
@ -247,6 +249,56 @@ public class ExtendedBolus implements Interval, DataPointWithLabelInterface {
|
|||
return result;
|
||||
}
|
||||
|
||||
public IobTotal iobCalc(long time, Profile profile, AutosensResult lastAutosensResult, boolean exercise_mode, int half_basal_exercise_target, boolean isTempTarget) {
|
||||
IobTotal result = new IobTotal(time);
|
||||
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
|
||||
|
||||
double realDuration = getDurationToTime(time);
|
||||
double netBasalAmount = 0d;
|
||||
|
||||
double sensitivityRatio = lastAutosensResult.ratio;
|
||||
double normalTarget = 100;
|
||||
|
||||
if (exercise_mode && isTempTarget && profile.getTarget() >= normalTarget + 5) {
|
||||
// w/ target 100, temp target 110 = .89, 120 = 0.8, 140 = 0.67, 160 = .57, and 200 = .44
|
||||
// e.g.: Sensitivity ratio set to 0.8 based on temp target of 120; Adjusting basal from 1.65 to 1.35; ISF from 58.9 to 73.6
|
||||
double c = half_basal_exercise_target - normalTarget;
|
||||
sensitivityRatio = c / (c + profile.getTarget() - normalTarget);
|
||||
}
|
||||
|
||||
if (realDuration > 0) {
|
||||
double netBasalRate;
|
||||
double dia_ago = time - dia * 60 * 60 * 1000;
|
||||
int aboutFiveMinIntervals = (int) Math.ceil(realDuration / 5d);
|
||||
double spacing = realDuration / aboutFiveMinIntervals;
|
||||
|
||||
for (long j = 0L; j < aboutFiveMinIntervals; j++) {
|
||||
// find middle of the interval
|
||||
long calcdate = (long) (date + j * spacing * 60 * 1000 + 0.5d * spacing * 60 * 1000);
|
||||
|
||||
double basalRate = profile.getBasal(calcdate);
|
||||
double basalRateCorrection = basalRate * (sensitivityRatio - 1);
|
||||
|
||||
|
||||
netBasalRate = absoluteRate() - basalRateCorrection;
|
||||
|
||||
if (calcdate > dia_ago && calcdate <= time) {
|
||||
double tempBolusSize = netBasalRate * spacing / 60d;
|
||||
|
||||
Treatment tempBolusPart = new Treatment();
|
||||
tempBolusPart.insulin = tempBolusSize;
|
||||
tempBolusPart.date = calcdate;
|
||||
|
||||
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
|
||||
result.iob += aIOB.iobContrib;
|
||||
result.activity += aIOB.activityContrib;
|
||||
result.extendedBolusInsulin += tempBolusPart.insulin;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public int getRealDuration() {
|
||||
return getDurationToTime(System.currentTimeMillis());
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ import info.nightscout.androidaps.interfaces.Interval;
|
|||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult;
|
||||
import info.nightscout.androidaps.plugins.treatments.Treatment;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||
|
@ -233,7 +234,7 @@ public class TemporaryBasal implements Interval {
|
|||
double netBasalAmount = 0d;
|
||||
|
||||
if (realDuration > 0) {
|
||||
double netBasalRate = 0d;
|
||||
double netBasalRate;
|
||||
double dia = profile.getDia();
|
||||
double dia_ago = time - dia * 60 * 60 * 1000;
|
||||
int aboutFiveMinIntervals = (int) Math.ceil(realDuration / 5d);
|
||||
|
@ -243,10 +244,74 @@ public class TemporaryBasal implements Interval {
|
|||
// find middle of the interval
|
||||
long calcdate = (long) (date + j * tempBolusSpacing * 60 * 1000 + 0.5d * tempBolusSpacing * 60 * 1000);
|
||||
|
||||
Double basalRate = profile.getBasal(calcdate);
|
||||
double basalRate = profile.getBasal(calcdate);
|
||||
|
||||
if (isAbsolute) {
|
||||
netBasalRate = absoluteRate - basalRate;
|
||||
} else {
|
||||
netBasalRate = (percentRate - 100) / 100d * basalRate;
|
||||
}
|
||||
|
||||
if (calcdate > dia_ago && calcdate <= time) {
|
||||
double tempBolusSize = netBasalRate * tempBolusSpacing / 60d;
|
||||
netBasalAmount += tempBolusSize;
|
||||
|
||||
Treatment tempBolusPart = new Treatment();
|
||||
tempBolusPart.insulin = tempBolusSize;
|
||||
tempBolusPart.date = calcdate;
|
||||
|
||||
Iob aIOB = insulinInterface.iobCalcForTreatment(tempBolusPart, time, dia);
|
||||
result.basaliob += aIOB.iobContrib;
|
||||
result.activity += aIOB.activityContrib;
|
||||
result.netbasalinsulin += tempBolusPart.insulin;
|
||||
if (tempBolusPart.insulin > 0) {
|
||||
result.hightempinsulin += tempBolusPart.insulin;
|
||||
}
|
||||
}
|
||||
result.netRatio = netBasalRate; // ratio at the end of interval
|
||||
}
|
||||
}
|
||||
result.netInsulin = netBasalAmount;
|
||||
return result;
|
||||
}
|
||||
|
||||
public IobTotal iobCalc(long time, Profile profile, AutosensResult lastAutosensResult, boolean exercise_mode, int half_basal_exercise_target, boolean isTempTarget) {
|
||||
|
||||
if (isFakeExtended) {
|
||||
log.error("iobCalc should only be called on Extended boluses separately");
|
||||
return new IobTotal(time);
|
||||
}
|
||||
|
||||
IobTotal result = new IobTotal(time);
|
||||
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
|
||||
|
||||
double realDuration = getDurationToTime(time);
|
||||
double netBasalAmount = 0d;
|
||||
|
||||
double sensitivityRatio = lastAutosensResult.ratio;
|
||||
double normalTarget = 100;
|
||||
|
||||
if (exercise_mode && isTempTarget && profile.getTarget() >= normalTarget + 5) {
|
||||
// w/ target 100, temp target 110 = .89, 120 = 0.8, 140 = 0.67, 160 = .57, and 200 = .44
|
||||
// e.g.: Sensitivity ratio set to 0.8 based on temp target of 120; Adjusting basal from 1.65 to 1.35; ISF from 58.9 to 73.6
|
||||
double c = half_basal_exercise_target - normalTarget;
|
||||
sensitivityRatio = c / (c + profile.getTarget() - normalTarget);
|
||||
}
|
||||
|
||||
if (realDuration > 0) {
|
||||
double netBasalRate;
|
||||
double dia = profile.getDia();
|
||||
double dia_ago = time - dia * 60 * 60 * 1000;
|
||||
int aboutFiveMinIntervals = (int) Math.ceil(realDuration / 5d);
|
||||
double tempBolusSpacing = realDuration / aboutFiveMinIntervals;
|
||||
|
||||
for (long j = 0L; j < aboutFiveMinIntervals; j++) {
|
||||
// find middle of the interval
|
||||
long calcdate = (long) (date + j * tempBolusSpacing * 60 * 1000 + 0.5d * tempBolusSpacing * 60 * 1000);
|
||||
|
||||
double basalRate = profile.getBasal(calcdate);
|
||||
basalRate *= sensitivityRatio;
|
||||
|
||||
if (basalRate == null)
|
||||
continue;
|
||||
if (isAbsolute) {
|
||||
netBasalRate = absoluteRate - basalRate;
|
||||
} else {
|
||||
|
@ -331,8 +396,10 @@ public class TemporaryBasal implements Interval {
|
|||
if (isFakeExtended) {
|
||||
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if (profile == null)
|
||||
return "null";
|
||||
Double currentBasalRate = profile.getBasal();
|
||||
double rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
|
||||
double rate = currentBasalRate + netExtendedRate;
|
||||
return getCalcuatedPercentageIfNeeded() + DecimalFormatter.to2Decimal(rate) + "U/h (" + DecimalFormatter.to2Decimal(netExtendedRate) + "E) @" +
|
||||
DateUtil.timeString(date) +
|
||||
" " + getRealDuration() + "/" + durationInMinutes + "'";
|
||||
|
@ -350,12 +417,14 @@ public class TemporaryBasal implements Interval {
|
|||
public String toStringShort() {
|
||||
if (isAbsolute || isFakeExtended) {
|
||||
|
||||
double rate = 0d;
|
||||
double rate;
|
||||
if (isFakeExtended) {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
Double currentBasalRate = profile.getBasal();
|
||||
rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
|
||||
} else if (isAbsolute) {
|
||||
if (profile == null)
|
||||
return "null";
|
||||
double currentBasalRate = profile.getBasal();
|
||||
rate = currentBasalRate + netExtendedRate;
|
||||
} else {
|
||||
rate = absoluteRate;
|
||||
}
|
||||
|
||||
|
@ -375,24 +444,25 @@ public class TemporaryBasal implements Interval {
|
|||
}
|
||||
|
||||
private String getCalcuatedPercentageIfNeeded() {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
|
||||
if (profile == null)
|
||||
return "null";
|
||||
|
||||
if (isAbsolute || isFakeExtended) {
|
||||
|
||||
double rate = 0d;
|
||||
double rate;
|
||||
if (isFakeExtended) {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
Double currentBasalRate = profile.getBasal();
|
||||
rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
|
||||
} else if (isAbsolute) {
|
||||
double currentBasalRate = profile.getBasal();
|
||||
rate = currentBasalRate + netExtendedRate;
|
||||
} else {
|
||||
rate = absoluteRate;
|
||||
}
|
||||
|
||||
if (SP.getBoolean(R.string.key_danar_visualizeextendedaspercentage, false) && SP.getBoolean(R.string.key_danar_useextended, false)) {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if (profile != null) {
|
||||
double basal = profile.getBasal();
|
||||
if (basal != 0) {
|
||||
return Math.round(rate * 100d / basal) + "% ";
|
||||
}
|
||||
double basal = profile.getBasal();
|
||||
if (basal != 0) {
|
||||
return Math.round(rate * 100d / basal) + "% ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -400,14 +470,18 @@ public class TemporaryBasal implements Interval {
|
|||
}
|
||||
|
||||
public String toStringVeryShort() {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
|
||||
if (profile == null)
|
||||
return "null";
|
||||
|
||||
if (isAbsolute || isFakeExtended) {
|
||||
|
||||
double rate = 0d;
|
||||
double rate;
|
||||
if (isFakeExtended) {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
Double currentBasalRate = profile.getBasal();
|
||||
rate = (currentBasalRate == null) ? 0d : (currentBasalRate + netExtendedRate);
|
||||
} else if (isAbsolute) {
|
||||
double currentBasalRate = profile.getBasal();
|
||||
rate = currentBasalRate + netExtendedRate;
|
||||
} else {
|
||||
rate = absoluteRate;
|
||||
}
|
||||
return DecimalFormatter.to2Decimal(rate) + "U/h ";
|
||||
|
|
|
@ -25,7 +25,7 @@ public interface TreatmentsInterface {
|
|||
IobTotal getLastCalculationTreatments();
|
||||
IobTotal getCalculationToTimeTreatments(long time);
|
||||
IobTotal getLastCalculationTempBasals();
|
||||
IobTotal getCalculationToTimeTempBasals(long time, Profile profile);
|
||||
IobTotal getCalculationToTimeTempBasals(long time);
|
||||
|
||||
MealData getMealData();
|
||||
|
||||
|
|
|
@ -139,11 +139,7 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
|
|||
|
||||
long start = System.currentTimeMillis();
|
||||
long startPart = System.currentTimeMillis();
|
||||
IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayForSMB(profile);
|
||||
if (L.isEnabled(L.APS))
|
||||
Profiler.log(log, "calculateIobArrayInDia()", startPart);
|
||||
|
||||
startPart = System.currentTimeMillis();
|
||||
MealData mealData = TreatmentsPlugin.getPlugin().getMealData();
|
||||
if (L.isEnabled(L.APS))
|
||||
Profiler.log(log, "getMealData()", startPart);
|
||||
|
@ -190,6 +186,11 @@ public class OpenAPSSMBPlugin extends PluginBase implements APSInterface, Constr
|
|||
lastAutosensResult.sensResult = "autosens disabled";
|
||||
}
|
||||
|
||||
IobTotal[] iobArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget);
|
||||
if (L.isEnabled(L.APS))
|
||||
Profiler.log(log, "calculateIobArrayInDia()", startPart);
|
||||
|
||||
startPart = System.currentTimeMillis();
|
||||
Constraint<Boolean> smbAllowed = new Constraint<>(!tempBasalFallback);
|
||||
MainApp.getConstraintChecker().isSMBModeEnabled(smbAllowed);
|
||||
inputConstraints.copyReasons(smbAllowed);
|
||||
|
|
|
@ -21,6 +21,7 @@ import java.util.List;
|
|||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.MainApp;
|
||||
import info.nightscout.androidaps.R;
|
||||
import info.nightscout.androidaps.data.IobTotal;
|
||||
import info.nightscout.androidaps.data.Profile;
|
||||
import info.nightscout.androidaps.db.BgReading;
|
||||
import info.nightscout.androidaps.db.CareportalEvent;
|
||||
|
@ -28,13 +29,11 @@ import info.nightscout.androidaps.db.ExtendedBolus;
|
|||
import info.nightscout.androidaps.db.ProfileSwitch;
|
||||
import info.nightscout.androidaps.db.TempTarget;
|
||||
import info.nightscout.androidaps.logging.L;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.BasalData;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult;
|
||||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin;
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ProfileFunctions;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.AreaGraphSeries;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DoubleDataPoint;
|
||||
|
@ -43,8 +42,13 @@ import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Point
|
|||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.ScaledDataPoint;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.TimeAsXAxisLabelFormatter;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.BasalData;
|
||||
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.Round;
|
||||
|
||||
/**
|
||||
|
@ -374,6 +378,38 @@ public class GraphData {
|
|||
iobSeries.setColor(MainApp.gc(R.color.iob));
|
||||
iobSeries.setThickness(3);
|
||||
|
||||
List<DataPointWithLabelInterface> iobPred = new ArrayList<>();
|
||||
|
||||
AutosensResult lastAutosensResult;
|
||||
AutosensData autosensData = IobCobCalculatorPlugin.getPlugin().getLastAutosensDataSynchronized("GraphData");
|
||||
if (autosensData == null)
|
||||
lastAutosensResult = new AutosensResult();
|
||||
else
|
||||
lastAutosensResult = autosensData.autosensResult;
|
||||
boolean isTempTarget = TreatmentsPlugin.getPlugin().getTempTargetFromHistory(System.currentTimeMillis()) != null;
|
||||
IobTotal[] iobPredArray = IobCobCalculatorPlugin.getPlugin().calculateIobArrayForSMB(lastAutosensResult, SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget);
|
||||
|
||||
for (IobTotal i : iobPredArray) {
|
||||
iobPred.add(i.setColor(R.color.iobPredAS));
|
||||
maxIobValueFound = Math.max(maxIobValueFound, Math.abs(i.iob));
|
||||
}
|
||||
|
||||
log.debug("IOB pred for AS=" + DecimalFormatter.to2Decimal(lastAutosensResult.ratio) + ": " + IobCobCalculatorPlugin.getPlugin().iobArrayToString(iobPredArray));
|
||||
|
||||
IobTotal[] iobPredArray2 = IobCobCalculatorPlugin.getPlugin().calculateIobArrayForSMB(new AutosensResult(), SMBDefaults.exercise_mode, SMBDefaults.half_basal_exercise_target, isTempTarget);
|
||||
|
||||
for (IobTotal i : iobPredArray2) {
|
||||
iobPred.add(i.setColor(R.color.iobPred));
|
||||
maxIobValueFound = Math.max(maxIobValueFound, Math.abs(i.iob));
|
||||
}
|
||||
|
||||
log.debug("IOB pred for AS=" + DecimalFormatter.to2Decimal(1) + ": " + IobCobCalculatorPlugin.getPlugin().iobArrayToString(iobPredArray2));
|
||||
|
||||
DataPointWithLabelInterface[] iobp = new DataPointWithLabelInterface[iobPred.size()];
|
||||
iobp = iobPred.toArray(iobp);
|
||||
addSeries(new PointsWithLabelGraphSeries<>(iobp));
|
||||
|
||||
|
||||
if (useForScale) {
|
||||
maxY = maxIobValueFound;
|
||||
minY = -maxIobValueFound;
|
||||
|
|
|
@ -79,7 +79,8 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
|||
EXERCISE,
|
||||
GENERAL,
|
||||
GENERALWITHDURATION,
|
||||
COBFAILOVER
|
||||
COBFAILOVER,
|
||||
IOBPREDICTION
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -206,6 +207,11 @@ public class PointsWithLabelGraphSeries<E extends DataPointWithLabelInterface> e
|
|||
mPaint.setStyle(Paint.Style.FILL);
|
||||
mPaint.setStrokeWidth(0);
|
||||
canvas.drawCircle(endX, endY, value.getSize() * scaledPxSize, mPaint);
|
||||
} else if (value.getShape() == Shape.BG || value.getShape() == Shape.IOBPREDICTION) {
|
||||
mPaint.setColor(value.getColor());
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
mPaint.setStrokeWidth(0);
|
||||
canvas.drawCircle(endX, endY, value.getSize() * scaledPxSize, mPaint);
|
||||
} else if (value.getShape() == Shape.PREDICTION) {
|
||||
mPaint.setColor(value.getColor());
|
||||
mPaint.setStyle(Paint.Style.FILL);
|
||||
|
|
|
@ -39,6 +39,7 @@ import info.nightscout.androidaps.plugins.sensitivity.SensitivityOref1Plugin;
|
|||
import info.nightscout.androidaps.plugins.treatments.Treatment;
|
||||
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.DecimalFormatter;
|
||||
import info.nightscout.androidaps.utils.T;
|
||||
|
||||
import static info.nightscout.androidaps.utils.DateUtil.now;
|
||||
|
@ -342,6 +343,12 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
}
|
||||
}
|
||||
|
||||
public IobTotal calculateFromTreatmentsAndTempsSynchronized(long time, AutosensResult lastAutosensResult, boolean exercise_mode, int half_basal_exercise_target, boolean isTempTarget) {
|
||||
synchronized (dataLock) {
|
||||
return calculateFromTreatmentsAndTemps(time, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget);
|
||||
}
|
||||
}
|
||||
|
||||
public IobTotal calculateFromTreatmentsAndTemps(long time, Profile profile) {
|
||||
long now = System.currentTimeMillis();
|
||||
time = roundUpTime(time);
|
||||
|
@ -352,7 +359,7 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
//log.debug(">>> calculateFromTreatmentsAndTemps Cache miss " + new Date(time).toLocaleString());
|
||||
}
|
||||
IobTotal bolusIob = TreatmentsPlugin.getPlugin().getCalculationToTimeTreatments(time).round();
|
||||
IobTotal basalIob = TreatmentsPlugin.getPlugin().getCalculationToTimeTempBasals(time, profile, true, now).round();
|
||||
IobTotal basalIob = TreatmentsPlugin.getPlugin().getCalculationToTimeTempBasals(time, true, now).round();
|
||||
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginType.APS)) {
|
||||
// Add expected zero temp basal for next 240 mins
|
||||
IobTotal basalIobWithZeroTemp = basalIob.copy();
|
||||
|
@ -375,6 +382,32 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
return iobTotal;
|
||||
}
|
||||
|
||||
public IobTotal calculateFromTreatmentsAndTemps(long time, AutosensResult lastAutosensResult, boolean exercise_mode, int half_basal_exercise_target, boolean isTempTarget) {
|
||||
long now = DateUtil.now();
|
||||
|
||||
IobTotal bolusIob = TreatmentsPlugin.getPlugin().getCalculationToTimeTreatments(time).round();
|
||||
IobTotal basalIob = TreatmentsPlugin.getPlugin().getCalculationToTimeTempBasals(time, now, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget).round();
|
||||
if (OpenAPSSMBPlugin.getPlugin().isEnabled(PluginType.APS)) {
|
||||
// Add expected zero temp basal for next 240 mins
|
||||
IobTotal basalIobWithZeroTemp = basalIob.copy();
|
||||
TemporaryBasal t = new TemporaryBasal()
|
||||
.date(now + 60 * 1000L)
|
||||
.duration(240)
|
||||
.absolute(0);
|
||||
if (t.date < time) {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile(t.date);
|
||||
if (profile != null) {
|
||||
IobTotal calc = t.iobCalc(time, profile, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget);
|
||||
basalIobWithZeroTemp.plus(calc);
|
||||
}
|
||||
}
|
||||
|
||||
basalIob.iobWithZeroTemp = IobTotal.combine(bolusIob, basalIobWithZeroTemp).round();
|
||||
}
|
||||
|
||||
return IobTotal.combine(bolusIob, basalIob).round();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Long findPreviousTimeFromBucketedData(long time) {
|
||||
if (bucketed_data == null)
|
||||
|
@ -534,22 +567,32 @@ public class IobCobCalculatorPlugin extends PluginBase {
|
|||
return array;
|
||||
}
|
||||
|
||||
public IobTotal[] calculateIobArrayForSMB(Profile profile) {
|
||||
public IobTotal[] calculateIobArrayForSMB(AutosensResult lastAutosensResult, boolean exercise_mode, int half_basal_exercise_target, boolean isTempTarget) {
|
||||
// predict IOB out to DIA plus 30m
|
||||
long time = System.currentTimeMillis();
|
||||
time = roundUpTime(time);
|
||||
long now = DateUtil.now();
|
||||
int len = (4 * 60) / 5;
|
||||
IobTotal[] array = new IobTotal[len];
|
||||
int pos = 0;
|
||||
for (int i = 0; i < len; i++) {
|
||||
long t = time + i * 5 * 60000;
|
||||
IobTotal iob = calculateFromTreatmentsAndTempsSynchronized(t, profile);
|
||||
long t = now + i * 5 * 60000;
|
||||
IobTotal iob = calculateFromTreatmentsAndTempsSynchronized(t, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget);
|
||||
array[pos] = iob;
|
||||
pos++;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
public String iobArrayToString(IobTotal[] array) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("[");
|
||||
for (IobTotal i : array) {
|
||||
sb.append(DecimalFormatter.to2Decimal(i.iob));
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append("]");
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public AutosensResult detectSensitivityWithLock(long fromTime, long toTime) {
|
||||
synchronized (dataLock) {
|
||||
return ConfigBuilderPlugin.getPlugin().getActiveSensitivity().detectSensitivity(this, fromTime, toTime);
|
||||
|
|
|
@ -48,6 +48,7 @@ import info.nightscout.androidaps.plugins.general.overview.dialogs.ErrorHelperAc
|
|||
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification;
|
||||
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensData;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin;
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityAAPSPlugin;
|
||||
import info.nightscout.androidaps.plugins.sensitivity.SensitivityWeightedAveragePlugin;
|
||||
|
@ -369,11 +370,11 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
}
|
||||
|
||||
@Override
|
||||
public IobTotal getCalculationToTimeTempBasals(long time, Profile profile) {
|
||||
return getCalculationToTimeTempBasals(time, profile, false, 0);
|
||||
public IobTotal getCalculationToTimeTempBasals(long time) {
|
||||
return getCalculationToTimeTempBasals(time, false, 0);
|
||||
}
|
||||
|
||||
public IobTotal getCalculationToTimeTempBasals(long time, Profile profile, boolean truncate, long truncateTime) {
|
||||
public IobTotal getCalculationToTimeTempBasals(long time, boolean truncate, long truncateTime) {
|
||||
IobTotal total = new IobTotal(time);
|
||||
|
||||
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
|
||||
|
@ -385,6 +386,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
TemporaryBasal t = tempBasals.get(pos);
|
||||
if (t.date > time) continue;
|
||||
IobTotal calc;
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile(t.date);
|
||||
if (profile == null) continue;
|
||||
if (truncate && t.end() > truncateTime) {
|
||||
TemporaryBasal dummyTemp = new TemporaryBasal();
|
||||
dummyTemp.copyFrom(t);
|
||||
|
@ -404,6 +407,8 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
ExtendedBolus e = extendedBoluses.get(pos);
|
||||
if (e.date > time) continue;
|
||||
IobTotal calc;
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile(e.date);
|
||||
if (profile == null) continue;
|
||||
if (truncate && e.end() > truncateTime) {
|
||||
ExtendedBolus dummyExt = new ExtendedBolus();
|
||||
dummyExt.copyFrom(e);
|
||||
|
@ -425,11 +430,65 @@ public class TreatmentsPlugin extends PluginBase implements TreatmentsInterface
|
|||
return total;
|
||||
}
|
||||
|
||||
public IobTotal getCalculationToTimeTempBasals(long time, long truncateTime, AutosensResult lastAutosensResult, boolean exercise_mode, int half_basal_exercise_target, boolean isTempTarget) {
|
||||
IobTotal total = new IobTotal(time);
|
||||
|
||||
InsulinInterface insulinInterface = ConfigBuilderPlugin.getPlugin().getActiveInsulin();
|
||||
if (insulinInterface == null)
|
||||
return total;
|
||||
|
||||
synchronized (tempBasals) {
|
||||
for (int pos = 0; pos < tempBasals.size(); pos++) {
|
||||
TemporaryBasal t = tempBasals.get(pos);
|
||||
if (t.date > time) continue;
|
||||
IobTotal calc;
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile(t.date);
|
||||
if (profile == null) continue;
|
||||
if (t.end() > truncateTime) {
|
||||
TemporaryBasal dummyTemp = new TemporaryBasal();
|
||||
dummyTemp.copyFrom(t);
|
||||
dummyTemp.cutEndTo(truncateTime);
|
||||
calc = dummyTemp.iobCalc(time, profile, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget);
|
||||
} else {
|
||||
calc = t.iobCalc(time, profile, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget);
|
||||
}
|
||||
//log.debug("BasalIOB " + new Date(time) + " >>> " + calc.basaliob);
|
||||
total.plus(calc);
|
||||
}
|
||||
}
|
||||
if (ConfigBuilderPlugin.getPlugin().getActivePump().isFakingTempsByExtendedBoluses()) {
|
||||
IobTotal totalExt = new IobTotal(time);
|
||||
synchronized (extendedBoluses) {
|
||||
for (int pos = 0; pos < extendedBoluses.size(); pos++) {
|
||||
ExtendedBolus e = extendedBoluses.get(pos);
|
||||
if (e.date > time) continue;
|
||||
IobTotal calc;
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile(e.date);
|
||||
if (profile == null) continue;
|
||||
if (e.end() > truncateTime) {
|
||||
ExtendedBolus dummyExt = new ExtendedBolus();
|
||||
dummyExt.copyFrom(e);
|
||||
dummyExt.cutEndTo(truncateTime);
|
||||
calc = dummyExt.iobCalc(time, profile, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget);
|
||||
} else {
|
||||
calc = e.iobCalc(time, profile, lastAutosensResult, exercise_mode, half_basal_exercise_target, isTempTarget);
|
||||
}
|
||||
totalExt.plus(calc);
|
||||
}
|
||||
}
|
||||
// Convert to basal iob
|
||||
totalExt.basaliob = totalExt.iob;
|
||||
totalExt.iob = 0d;
|
||||
totalExt.netbasalinsulin = totalExt.extendedBolusInsulin;
|
||||
totalExt.hightempinsulin = totalExt.extendedBolusInsulin;
|
||||
total.plus(totalExt);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateTotalIOBTempBasals() {
|
||||
Profile profile = ProfileFunctions.getInstance().getProfile();
|
||||
if (profile != null)
|
||||
lastTempBasalsCalculation = getCalculationToTimeTempBasals(DateUtil.now(), profile);
|
||||
lastTempBasalsCalculation = getCalculationToTimeTempBasals(DateUtil.now());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
|
|
@ -3,7 +3,9 @@
|
|||
<color name="prediction">#ff00ff</color>
|
||||
<color name="basal">#00ffff</color>
|
||||
<color name="iob">#1e88e5</color>
|
||||
<color name="iobPred">#00d2d2</color>
|
||||
<color name="bolus">#1ea3e5</color>
|
||||
<color name="iobPredAS">#1ea3e5</color>
|
||||
<color name="cob">#FFFB8C00</color>
|
||||
<color name="carbs">#FFFB8C00</color>
|
||||
<color name="uam">#c9bd60</color>
|
||||
|
|
Loading…
Reference in a new issue