AutosensData -> kt

This commit is contained in:
Milos Kozak 2021-11-23 23:15:51 +01:00
parent ae466e51d0
commit 38738018ef
6 changed files with 178 additions and 212 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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