AutosensData -> kt
This commit is contained in:
parent
ae466e51d0
commit
38738018ef
|
@ -646,9 +646,9 @@ class OverviewData @Inject constructor(
|
|||
maxCobValueFound = max(maxCobValueFound, cob.toDouble())
|
||||
lastCob = cob
|
||||
}
|
||||
if (autosensData.failoverToMinAbsorbtionRate) {
|
||||
autosensData.setScale(cobScale)
|
||||
autosensData.setChartTime(time)
|
||||
if (autosensData.failOverToMinAbsorptionRate) {
|
||||
autosensData.scale = cobScale
|
||||
autosensData.chartTime = time
|
||||
minFailOverActiveList.add(autosensData)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -209,12 +209,12 @@ class IobCobOref1Thread internal constructor(
|
|||
// figure out how many carbs that represents
|
||||
// but always assume at least 3mg/dL/5m (default) absorption per active treatment
|
||||
val ci = max(deviation, totalMinCarbsImpact)
|
||||
if (ci != deviation) autosensData.failoverToMinAbsorbtionRate = true
|
||||
if (ci != deviation) autosensData.failOverToMinAbsorptionRate = true
|
||||
autosensData.absorbed = ci * profile.getIc(bgTime) / sens
|
||||
// and add that to the running total carbsAbsorbed
|
||||
autosensData.cob = max(previous.cob - autosensData.absorbed, 0.0)
|
||||
autosensData.mealCarbs = previous.mealCarbs
|
||||
autosensData.substractAbosorbedCarbs()
|
||||
autosensData.deductAbsorbedCarbs()
|
||||
autosensData.usedMinCarbsImpact = totalMinCarbsImpact
|
||||
autosensData.absorbing = previous.absorbing
|
||||
autosensData.mealStartCounter = previous.mealStartCounter
|
||||
|
|
|
@ -10,7 +10,6 @@ import info.nightscout.androidaps.database.AppRepository
|
|||
import info.nightscout.androidaps.events.Event
|
||||
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.PluginType
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
|
@ -218,11 +217,11 @@ class IobCobThread @Inject internal constructor(
|
|||
// figure out how many carbs that represents
|
||||
// but always assume at least 3mg/dL/5m (default) absorption per active treatment
|
||||
val ci = max(deviation, totalMinCarbsImpact)
|
||||
if (ci != deviation) autosensData.failoverToMinAbsorbtionRate = true
|
||||
if (ci != deviation) autosensData.failOverToMinAbsorptionRate = true
|
||||
autosensData.absorbed = ci * profile.getIc(bgTime) / sens
|
||||
// and add that to the running total carbsAbsorbed
|
||||
autosensData.cob = max(previous.cob - autosensData.absorbed, 0.0)
|
||||
autosensData.substractAbosorbedCarbs()
|
||||
autosensData.deductAbsorbedCarbs()
|
||||
autosensData.usedMinCarbsImpact = totalMinCarbsImpact
|
||||
}
|
||||
val isAAPSOrWeighted = sensitivityAAPSPlugin.isEnabled() || sensitivityWeightedAveragePlugin.isEnabled()
|
||||
|
|
|
@ -347,7 +347,7 @@ class AutosensDataStore {
|
|||
synchronized(dataLock) {
|
||||
var i = autosensDataTable.size() - 1
|
||||
while (i >= 0 && count < valuesToProcess) {
|
||||
if (autosensDataTable.valueAt(i).failoverToMinAbsorbtionRate) sum++
|
||||
if (autosensDataTable.valueAt(i).failOverToMinAbsorptionRate) sum++
|
||||
count++
|
||||
i--
|
||||
}
|
||||
|
|
|
@ -1,203 +0,0 @@
|
|||
package info.nightscout.androidaps.plugins.iob.iobCobCalculator.data;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import dagger.android.HasAndroidInjector;
|
||||
import info.nightscout.androidaps.Constants;
|
||||
import info.nightscout.androidaps.core.R;
|
||||
import info.nightscout.androidaps.interfaces.Profile;
|
||||
import info.nightscout.androidaps.database.entities.Carbs;
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction;
|
||||
import info.nightscout.androidaps.logging.AAPSLogger;
|
||||
import info.nightscout.androidaps.logging.LTag;
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries;
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale;
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult;
|
||||
import info.nightscout.androidaps.utils.DateUtil;
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper;
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP;
|
||||
|
||||
public class AutosensData implements DataPointWithLabelInterface {
|
||||
|
||||
@Inject AAPSLogger aapsLogger;
|
||||
@Inject SP sp;
|
||||
@Inject ResourceHelper rh;
|
||||
@Inject ProfileFunction profileFunction;
|
||||
@Inject DateUtil dateUtil;
|
||||
|
||||
public AutosensData(HasAndroidInjector injector) {
|
||||
injector.androidInjector().inject(this);
|
||||
}
|
||||
|
||||
public void setChartTime(long chartTime) {
|
||||
this.chartTime = chartTime;
|
||||
}
|
||||
|
||||
public class CarbsInPast {
|
||||
long time;
|
||||
double carbs;
|
||||
public double min5minCarbImpact;
|
||||
double remaining;
|
||||
|
||||
public CarbsInPast(Carbs t, boolean isAAPSOrWeighted) {
|
||||
time = t.getTimestamp();
|
||||
carbs = t.getAmount();
|
||||
remaining = t.getAmount();
|
||||
Profile profile = profileFunction.getProfile(t.getTimestamp());
|
||||
if (isAAPSOrWeighted && profile != null) {
|
||||
double maxAbsorptionHours = sp.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||
double sens = profile.getIsfMgdl(t.getTimestamp());
|
||||
double ic = profile.getIc(t.getTimestamp());
|
||||
min5minCarbImpact = t.getAmount() / (maxAbsorptionHours * 60 / 5) * sens / ic;
|
||||
aapsLogger.debug(LTag.AUTOSENS, "Min 5m carbs impact for " + carbs + "g @" + dateUtil.dateAndTimeString(t.getTimestamp()) + " for " + maxAbsorptionHours + "h calculated to " + min5minCarbImpact + " ISF: " + sens + " IC: " + ic);
|
||||
} else {
|
||||
min5minCarbImpact = sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact);
|
||||
}
|
||||
}
|
||||
|
||||
CarbsInPast(CarbsInPast other) {
|
||||
this.time = other.time;
|
||||
this.carbs = other.carbs;
|
||||
this.min5minCarbImpact = other.min5minCarbImpact;
|
||||
this.remaining = other.remaining;
|
||||
}
|
||||
|
||||
@NonNull @Override
|
||||
public String toString() {
|
||||
return String.format(Locale.ENGLISH, "CarbsInPast: time: %s carbs: %.02f min5minCI: %.02f remaining: %.2f", dateUtil.dateAndTimeString(time), carbs, min5minCarbImpact, remaining);
|
||||
}
|
||||
}
|
||||
|
||||
public long time = 0L;
|
||||
public double bg = 0; // mgdl
|
||||
private long chartTime;
|
||||
public String pastSensitivity = "";
|
||||
public double deviation = 0d;
|
||||
public boolean validDeviation = false;
|
||||
public List<CarbsInPast> activeCarbsList = new ArrayList<>();
|
||||
public double absorbed = 0d;
|
||||
public double carbsFromBolus = 0d;
|
||||
public double cob = 0;
|
||||
public double bgi = 0d;
|
||||
public double delta = 0d;
|
||||
public double avgDelta = 0d;
|
||||
public double avgDeviation = 0d;
|
||||
|
||||
public AutosensResult autosensResult = new AutosensResult();
|
||||
public double slopeFromMaxDeviation = 0;
|
||||
public double slopeFromMinDeviation = 999;
|
||||
public double usedMinCarbsImpact = 0d;
|
||||
public boolean failoverToMinAbsorbtionRate = false;
|
||||
|
||||
// Oref1
|
||||
public boolean absorbing = false;
|
||||
public double mealCarbs = 0;
|
||||
public int mealStartCounter = 999;
|
||||
public String type = "";
|
||||
public boolean uam = false;
|
||||
public List<Double> extraDeviation = new ArrayList<>();
|
||||
|
||||
@NonNull @Override
|
||||
public String toString() {
|
||||
return String.format(Locale.ENGLISH, "AutosensData: %s pastSensitivity=%s delta=%.02f avgDelta=%.02f bgi=%.02f deviation=%.02f avgDeviation=%.02f absorbed=%.02f carbsFromBolus=%.02f cob=%.02f autosensRatio=%.02f slopeFromMaxDeviation=%.02f slopeFromMinDeviation=%.02f activeCarbsList=%s",
|
||||
dateUtil.dateAndTimeString(time), pastSensitivity, delta, avgDelta, bgi, deviation, avgDeviation, absorbed, carbsFromBolus, cob, autosensResult.getRatio(), slopeFromMaxDeviation, slopeFromMinDeviation, activeCarbsList.toString());
|
||||
}
|
||||
|
||||
public List<CarbsInPast> cloneCarbsList() {
|
||||
List<CarbsInPast> newActiveCarbsList = new ArrayList<>();
|
||||
|
||||
for (CarbsInPast c : activeCarbsList) {
|
||||
newActiveCarbsList.add(new CarbsInPast(c));
|
||||
}
|
||||
|
||||
return newActiveCarbsList;
|
||||
}
|
||||
|
||||
// remove carbs older than timeframe
|
||||
public void removeOldCarbs(long toTime, boolean isAAPSOrWeighted) {
|
||||
double maxAbsorptionHours;
|
||||
if (isAAPSOrWeighted) {
|
||||
maxAbsorptionHours = sp.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||
} else {
|
||||
maxAbsorptionHours = sp.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME);
|
||||
}
|
||||
for (int i = 0; i < activeCarbsList.size(); i++) {
|
||||
CarbsInPast c = activeCarbsList.get(i);
|
||||
if (c.time + maxAbsorptionHours * 60 * 60 * 1000L < toTime) {
|
||||
activeCarbsList.remove(i--);
|
||||
if (c.remaining > 0)
|
||||
cob -= c.remaining;
|
||||
aapsLogger.debug(LTag.AUTOSENS, "Removing carbs at " + dateUtil.dateAndTimeString(toTime) + " after " + maxAbsorptionHours + "h > " + c.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void substractAbosorbedCarbs() {
|
||||
double ac = absorbed;
|
||||
for (int i = 0; i < activeCarbsList.size() && ac > 0; i++) {
|
||||
CarbsInPast c = activeCarbsList.get(i);
|
||||
if (c.remaining > 0) {
|
||||
double sub = Math.min(ac, c.remaining);
|
||||
c.remaining -= sub;
|
||||
ac -= sub;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------- DataPointWithLabelInterface ------
|
||||
|
||||
private Scale scale;
|
||||
|
||||
public void setScale(Scale scale) {
|
||||
this.scale = scale;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getX() {
|
||||
return chartTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getY() {
|
||||
return scale.transform(cob);
|
||||
}
|
||||
|
||||
@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.COBFAILOVER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public float getSize() {
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getColor() {
|
||||
return rh.gc(R.color.cob);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
package info.nightscout.androidaps.plugins.iob.iobCobCalculator.data
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.core.R
|
||||
import info.nightscout.androidaps.database.entities.Carbs
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.DataPointWithLabelInterface
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.PointsWithLabelGraphSeries
|
||||
import info.nightscout.androidaps.plugins.general.overview.graphExtensions.Scale
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.min
|
||||
|
||||
class AutosensData(injector: HasAndroidInjector) : DataPointWithLabelInterface {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
|
||||
inner class CarbsInPast {
|
||||
|
||||
var time: Long
|
||||
var carbs: Double
|
||||
var min5minCarbImpact = 0.0
|
||||
var remaining: Double
|
||||
|
||||
constructor(t: Carbs, isAAPSOrWeighted: Boolean) {
|
||||
time = t.timestamp
|
||||
carbs = t.amount
|
||||
remaining = t.amount
|
||||
val profile = profileFunction.getProfile(t.timestamp)
|
||||
if (isAAPSOrWeighted && profile != null) {
|
||||
val maxAbsorptionHours = sp.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||
val sens = profile.getIsfMgdl(t.timestamp)
|
||||
val ic = profile.getIc(t.timestamp)
|
||||
min5minCarbImpact = t.amount / (maxAbsorptionHours * 60 / 5) * sens / ic
|
||||
aapsLogger.debug(
|
||||
LTag.AUTOSENS,
|
||||
"""Min 5m carbs impact for ${carbs}g @${dateUtil.dateAndTimeString(t.timestamp)} for ${maxAbsorptionHours}h calculated to $min5minCarbImpact ISF: $sens IC: $ic"""
|
||||
)
|
||||
} else {
|
||||
min5minCarbImpact = sp.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact)
|
||||
}
|
||||
}
|
||||
|
||||
internal constructor(other: CarbsInPast) {
|
||||
time = other.time
|
||||
carbs = other.carbs
|
||||
min5minCarbImpact = other.min5minCarbImpact
|
||||
remaining = other.remaining
|
||||
}
|
||||
|
||||
override fun toString(): String =
|
||||
String.format(Locale.ENGLISH, "CarbsInPast: time: %s carbs: %.02f min5minCI: %.02f remaining: %.2f", dateUtil.dateAndTimeString(time), carbs, min5minCarbImpact, remaining)
|
||||
}
|
||||
|
||||
var time = 0L
|
||||
var bg = 0.0 // mgdl
|
||||
var chartTime: Long = 0
|
||||
var pastSensitivity = ""
|
||||
var deviation = 0.0
|
||||
var validDeviation = false
|
||||
var activeCarbsList: MutableList<CarbsInPast> = ArrayList()
|
||||
var absorbed = 0.0
|
||||
var carbsFromBolus = 0.0
|
||||
var cob = 0.0
|
||||
var bgi = 0.0
|
||||
var delta = 0.0
|
||||
var avgDelta = 0.0
|
||||
var avgDeviation = 0.0
|
||||
var autosensResult = AutosensResult()
|
||||
var slopeFromMaxDeviation = 0.0
|
||||
var slopeFromMinDeviation = 999.0
|
||||
var usedMinCarbsImpact = 0.0
|
||||
var failOverToMinAbsorptionRate = false
|
||||
|
||||
// Oref1
|
||||
var absorbing = false
|
||||
var mealCarbs = 0.0
|
||||
var mealStartCounter = 999
|
||||
var type = ""
|
||||
var uam = false
|
||||
var extraDeviation: MutableList<Double> = ArrayList()
|
||||
override fun toString(): String {
|
||||
return String.format(
|
||||
Locale.ENGLISH,
|
||||
"AutosensData: %s pastSensitivity=%s delta=%.02f avgDelta=%.02f bgi=%.02f deviation=%.02f avgDeviation=%.02f absorbed=%.02f carbsFromBolus=%.02f cob=%.02f autosensRatio=%.02f slopeFromMaxDeviation=%.02f slopeFromMinDeviation=%.02f activeCarbsList=%s",
|
||||
dateUtil.dateAndTimeString(time),
|
||||
pastSensitivity,
|
||||
delta,
|
||||
avgDelta,
|
||||
bgi,
|
||||
deviation,
|
||||
avgDeviation,
|
||||
absorbed,
|
||||
carbsFromBolus,
|
||||
cob,
|
||||
autosensResult.ratio,
|
||||
slopeFromMaxDeviation,
|
||||
slopeFromMinDeviation,
|
||||
activeCarbsList.toString()
|
||||
)
|
||||
}
|
||||
|
||||
fun cloneCarbsList(): MutableList<CarbsInPast> {
|
||||
val newActiveCarbsList: MutableList<CarbsInPast> = ArrayList()
|
||||
for (c in activeCarbsList) {
|
||||
newActiveCarbsList.add(CarbsInPast(c))
|
||||
}
|
||||
return newActiveCarbsList
|
||||
}
|
||||
|
||||
// remove carbs older than timeframe
|
||||
fun removeOldCarbs(toTime: Long, isAAPSOrWeighted: Boolean) {
|
||||
val maxAbsorptionHours: Double =
|
||||
if (isAAPSOrWeighted) sp.getDouble(R.string.key_absorption_maxtime, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||
else sp.getDouble(R.string.key_absorption_cutoff, Constants.DEFAULT_MAX_ABSORPTION_TIME)
|
||||
var i = 0
|
||||
while (i < activeCarbsList.size) {
|
||||
val c = activeCarbsList[i]
|
||||
if (c.time + maxAbsorptionHours * 60 * 60 * 1000L < toTime) {
|
||||
activeCarbsList.removeAt(i--)
|
||||
if (c.remaining > 0) cob -= c.remaining
|
||||
aapsLogger.debug(LTag.AUTOSENS, "Removing carbs at " + dateUtil.dateAndTimeString(toTime) + " after " + maxAbsorptionHours + "h > " + c.toString())
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
fun deductAbsorbedCarbs() {
|
||||
var ac = absorbed
|
||||
var i = 0
|
||||
while (i < activeCarbsList.size && ac > 0) {
|
||||
val c = activeCarbsList[i]
|
||||
if (c.remaining > 0) {
|
||||
val sub = min(ac, c.remaining)
|
||||
c.remaining -= sub
|
||||
ac -= sub
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
// ------- DataPointWithLabelInterface ------
|
||||
var scale: Scale? = null
|
||||
|
||||
override fun getX(): Double = chartTime.toDouble()
|
||||
override fun getY(): Double = scale!!.transform(cob)
|
||||
|
||||
override fun setY(y: Double) {}
|
||||
override val label: String? = null
|
||||
override val duration = 0L
|
||||
override val shape = PointsWithLabelGraphSeries.Shape.COBFAILOVER
|
||||
override val size = 0.5f
|
||||
override val color get() = rh.gc(R.color.cob)
|
||||
|
||||
init {
|
||||
injector.androidInjector().inject(this)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue