Modified Master to replace profile sens with Chris Wilson's Dynamic ISF in OpenAPSSMB.
The rule of 277700 ISF using current BG is used for all predictions, while for dosing, if delta is =0 r positive, current bg is used, however, if delta is -ve, future bg is used.
This commit is contained in:
parent
34c4dc2a98
commit
f98175755e
3 changed files with 153 additions and 33 deletions
|
@ -277,16 +277,50 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
|||
|
||||
var profile_sens = round(profile.sens,1)
|
||||
var sens = profile.sens;
|
||||
if (typeof autosens_data !== 'undefined' && autosens_data) {
|
||||
sens = profile.sens / sensitivityRatio;
|
||||
sens = round(sens, 1);
|
||||
if (sens !== profile_sens) {
|
||||
console.log("ISF from "+profile_sens+" to "+sens);
|
||||
} else {
|
||||
console.log("ISF unchanged: "+sens);
|
||||
|
||||
var now = new Date().getHours();
|
||||
if (now < 1){
|
||||
now = 1;}
|
||||
else {
|
||||
console.error("Time now is "+now+"; ");
|
||||
}
|
||||
//console.log(" (autosens ratio "+sensitivityRatio+")");
|
||||
var tdd7 = meal_data.TDDAIMI7;
|
||||
var tdd_pump_now = meal_data.TDDPUMP;
|
||||
var tdd_pump = ( tdd_pump_now / (now / 24));
|
||||
var TDD = (tdd7 * 0.4) + (tdd_pump * 0.6);
|
||||
console.error("Pump extrapolated TDD = "+tdd_pump+"; ");
|
||||
//if (tdd7 > 0){
|
||||
if ( tdd_pump > tdd7 && now < 5 || now < 7 && TDD < ( 0.8 * tdd7 ) ){
|
||||
TDD = ( 0.8 * tdd7 );
|
||||
console.log("Excess or too low insulin from pump so TDD set to "+TDD+" based on 75% of TDD7; ");
|
||||
rT.reason += "TDD: " +TDD+ " due to low or high tdd from pump; ";
|
||||
}
|
||||
|
||||
else if (tdd_pump < (0.33 * tdd7)){
|
||||
TDD = (tdd7 * 0.25) + (tdd_pump * 0.75);
|
||||
console.error("TDD weighted to pump due to low insulin usage. TDD = "+TDD+"; ");
|
||||
rT.reason += "TDD weighted to pump due to low insulin usage. TDD = "+TDD+"; ";
|
||||
}
|
||||
|
||||
else {
|
||||
console.log("TDD 7 ="+tdd7+", TDD Pump ="+tdd_pump+" and TDD = "+TDD+";");
|
||||
rT.reason += "TDD: " +TDD+ " based on standard pump 60/tdd7 40 split; ";
|
||||
}
|
||||
|
||||
var variable_sens = (277700 / (TDD * bg));
|
||||
variable_sens = round(variable_sens,1);
|
||||
console.log("Current sensitivity for predictions is " +variable_sens+" based on current bg");
|
||||
|
||||
sens = variable_sens;
|
||||
if ( high_temptarget_raises_sensitivity && profile.temptargetSet && target_bg > normalTarget || profile.low_temptarget_lowers_sensitivity && profile.temptargetSet && target_bg < normalTarget ) {
|
||||
sens = sens / sensitivityRatio ;
|
||||
sens = round(sens, 1);
|
||||
console.log("ISF from "+variable_sens+" to "+sens+ "due to temp target; ");
|
||||
} else {
|
||||
sens = sens;
|
||||
sens = round(sens, 1);
|
||||
}
|
||||
|
||||
console.error("; CR:",profile.carb_ratio);
|
||||
|
||||
// compare currenttemp to iob_data.lastTemp and cancel temp if they don't match
|
||||
|
@ -700,6 +734,20 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
|||
|
||||
console.error("UAM Impact:",uci,"mg/dL per 5m; UAM Duration:",UAMduration,"hours");
|
||||
|
||||
console.log("EventualBG is" +eventualBG+" ;");
|
||||
|
||||
if( glucose_status.delta >= 0 || bg > 60 && glucose_status.delta < 2 && glucose_status.delta > -2 && glucose_status.short_avgdelta > -2 && glucose_status.short_avgdelta < 2 ) {
|
||||
var future_sens = ( 277700 / (TDD * bg) );
|
||||
console.log("Future state sensitivity is " +future_sens+" using current bg due to no COB & small delta or variation");
|
||||
rT.reason += "Dosing sensitivity: " +future_sens+" using current BG;";
|
||||
}
|
||||
else {
|
||||
var future_sens = ( 277700 / (TDD * eventualBG));
|
||||
console.log("Future state sensitivity is " +future_sens+" based on eventual bg due to -ve delta");
|
||||
rT.reason += "Dosing sensitivity: " +future_sens+" using eventual BG;";
|
||||
}
|
||||
var future_sens = round(future_sens,1);
|
||||
|
||||
|
||||
minIOBPredBG = Math.max(39,minIOBPredBG);
|
||||
minCOBPredBG = Math.max(39,minCOBPredBG);
|
||||
|
@ -928,22 +976,25 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
|||
}
|
||||
}
|
||||
|
||||
// calculate 30m low-temp required to get projected BG up to target
|
||||
// multiply by 2 to low-temp faster for increased hypo safety
|
||||
var insulinReq = 2 * Math.min(0, (eventualBG - target_bg) / sens);
|
||||
insulinReq = round( insulinReq , 2);
|
||||
// calculate naiveInsulinReq based on naive_eventualBG
|
||||
var naiveInsulinReq = Math.min(0, (naive_eventualBG - target_bg) / sens);
|
||||
naiveInsulinReq = round( naiveInsulinReq , 2);
|
||||
if (minDelta < 0 && minDelta > expectedDelta) {
|
||||
// if we're barely falling, newinsulinReq should be barely negative
|
||||
var newinsulinReq = round(( insulinReq * (minDelta / expectedDelta) ), 2);
|
||||
//console.error("Increasing insulinReq from " + insulinReq + " to " + newinsulinReq);
|
||||
insulinReq = newinsulinReq;
|
||||
}
|
||||
// rate required to deliver insulinReq less insulin over 30m:
|
||||
var rate = basal + (2 * insulinReq);
|
||||
rate = round_basal(rate, profile);
|
||||
|
||||
|
||||
// calculate 30m low-temp required to get projected BG up to target
|
||||
// multiply by 2 to low-temp faster for increased hypo safety
|
||||
|
||||
var insulinReq = 2 * Math.min(0, (eventualBG - target_bg) / future_sens);
|
||||
insulinReq = round( insulinReq , 2);
|
||||
// calculate naiveInsulinReq based on naive_eventualBG
|
||||
var naiveInsulinReq = Math.min(0, (naive_eventualBG - target_bg) / sens);
|
||||
naiveInsulinReq = round( naiveInsulinReq , 2);
|
||||
if (minDelta < 0 && minDelta > expectedDelta) {
|
||||
// if we're barely falling, newinsulinReq should be barely negative
|
||||
var newinsulinReq = round(( insulinReq * (minDelta / expectedDelta) ), 2);
|
||||
//console.error("Increasing insulinReq from " + insulinReq + " to " + newinsulinReq);
|
||||
insulinReq = newinsulinReq;
|
||||
}
|
||||
// rate required to deliver insulinReq less insulin over 30m:
|
||||
var rate = basal + (2 * insulinReq);
|
||||
rate = round_basal(rate, profile);
|
||||
|
||||
// if required temp < existing temp basal
|
||||
var insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60;
|
||||
|
@ -1031,14 +1082,14 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
|||
}
|
||||
} else { // otherwise, calculate 30m high-temp required to get projected BG down to target
|
||||
|
||||
// insulinReq is the additional insulin required to get minPredBG down to target_bg
|
||||
//console.error(minPredBG,eventualBG);
|
||||
insulinReq = round( (Math.min(minPredBG,eventualBG) - target_bg) / sens, 2);
|
||||
// if that would put us over max_iob, then reduce accordingly
|
||||
if (insulinReq > max_iob-iob_data.iob) {
|
||||
rT.reason += "max_iob " + max_iob + ", ";
|
||||
insulinReq = max_iob-iob_data.iob;
|
||||
}
|
||||
// insulinReq is the additional insulin required to get minPredBG down to target_bg
|
||||
//console.error(minPredBG,eventualBG);
|
||||
insulinReq = round( (Math.min(minPredBG,eventualBG) - target_bg) / future_sens, 2);
|
||||
// if that would put us over max_iob, then reduce accordingly
|
||||
if (insulinReq > max_iob-iob_data.iob) {
|
||||
rT.reason += "max_iob " + max_iob + ", ";
|
||||
insulinReq = max_iob-iob_data.iob;
|
||||
}
|
||||
|
||||
// rate required to deliver insulinReq more insulin over 30m:
|
||||
rate = basal + (2 * insulinReq);
|
||||
|
|
|
@ -4,6 +4,8 @@ import dagger.android.HasAndroidInjector
|
|||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.IobTotal
|
||||
import info.nightscout.androidaps.data.MealData
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.database.entities.Bolus
|
||||
import info.nightscout.androidaps.extensions.convertedToAbsolute
|
||||
import info.nightscout.androidaps.extensions.getPassedDurationToTimeInMinutes
|
||||
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
|
||||
|
@ -18,8 +20,11 @@ import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback
|
|||
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.shared.SafeParse
|
||||
import info.nightscout.androidaps.utils.T
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.stats.TddCalculator
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
|
@ -40,6 +45,10 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
|
|||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var repository: AppRepository
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
//@Inject lateinit var danaPump: DanaPump
|
||||
|
||||
|
||||
private var profile = JSONObject()
|
||||
private var mGlucoseStatus = JSONObject()
|
||||
|
@ -51,6 +60,11 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
|
|||
private var smbAlwaysAllowed = false
|
||||
private var currentTime: Long = 0
|
||||
private var saveCgmSource = false
|
||||
private var lastBolusNormalTime: Long = 0
|
||||
private val millsToThePast = T.hours(4).msecs()
|
||||
private var tddAIMI: TddCalculator? = null
|
||||
|
||||
|
||||
var currentTempParam: String? = null
|
||||
private set
|
||||
var iobDataParam: String? = null
|
||||
|
@ -241,6 +255,7 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
|
|||
} else {
|
||||
mGlucoseStatus.put("delta", glucoseStatus.delta)
|
||||
}
|
||||
|
||||
mGlucoseStatus.put("short_avgdelta", glucoseStatus.shortAvgDelta)
|
||||
mGlucoseStatus.put("long_avgdelta", glucoseStatus.longAvgDelta)
|
||||
mGlucoseStatus.put("date", glucoseStatus.date)
|
||||
|
@ -249,7 +264,13 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
|
|||
this.mealData.put("slopeFromMaxDeviation", mealData.slopeFromMaxDeviation)
|
||||
this.mealData.put("slopeFromMinDeviation", mealData.slopeFromMinDeviation)
|
||||
this.mealData.put("lastBolusTime", mealData.lastBolusTime)
|
||||
this.mealData.put("lastBolusNormalTime", lastBolusNormalTime)
|
||||
this.mealData.put("lastCarbTime", mealData.lastCarbTime)
|
||||
|
||||
tddAIMI = TddCalculator(aapsLogger,rh,activePlugin,profileFunction,dateUtil,iobCobCalculator, repository)
|
||||
this.mealData.put("TDD_AIMI7", tddAIMI!!.averageTDD(tddAIMI!!.calculate(7)).totalAmount)
|
||||
this.mealData.put("TDDPUMP", tddAIMI!!.calculateDaily().totalAmount)
|
||||
|
||||
if (constraintChecker.isAutosensModeEnabled().value()) {
|
||||
autosensData.put("ratio", autosensDataRatio)
|
||||
} else {
|
||||
|
|
|
@ -76,7 +76,55 @@ class TddCalculator @Inject constructor(
|
|||
return result
|
||||
}
|
||||
|
||||
private fun averageTDD(tdds: LongSparseArray<TotalDailyDose>): TotalDailyDose {
|
||||
fun calculateDaily():TotalDailyDose {
|
||||
val startTime = MidnightTime.calc(dateUtil.now() )
|
||||
val endTime = dateUtil.now()
|
||||
val tdd = TotalDailyDose(timestamp = startTime)
|
||||
//val result = TotalDailyDose()
|
||||
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
|
||||
.filter { it.type != Bolus.Type.PRIMING }
|
||||
.forEach { t ->
|
||||
//val midnight = MidnightTime.calc(t.timestamp)
|
||||
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
|
||||
tdd.bolusAmount += t.amount
|
||||
//result.put(midnight, tdd)
|
||||
}
|
||||
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
|
||||
//val midnight = MidnightTime.calc(t.timestamp)
|
||||
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
|
||||
tdd.carbs += t.amount
|
||||
//result.put(midnight, tdd)
|
||||
}
|
||||
val calculationStep = T.mins(5).msecs()
|
||||
val tempBasals = iobCobCalculator.getTempBasalIncludingConvertedExtendedForRange(startTime, endTime, calculationStep)
|
||||
for (t in startTime until endTime step calculationStep) {
|
||||
|
||||
//val midnight = MidnightTime.calc(t)
|
||||
//val tdd = result[midnight] ?: TotalDailyDose(timestamp = midnight)
|
||||
val tbr = iobCobCalculator.getTempBasalIncludingConvertedExtended(t)
|
||||
val profile = profileFunction.getProfile(t) ?: continue
|
||||
val absoluteRate = tbr?.convertedToAbsolute(t, profile) ?: profile.getBasal(t)
|
||||
tdd.basalAmount += absoluteRate / 60.0 * 5.0
|
||||
|
||||
if (!activePlugin.activePump.isFakingTempsByExtendedBoluses) {
|
||||
// they are not included in TBRs
|
||||
val eb = iobCobCalculator.getExtendedBolus(t)
|
||||
val absoluteEbRate = eb?.rate ?: 0.0
|
||||
tdd.bolusAmount += absoluteEbRate / 60.0 * 5.0
|
||||
}
|
||||
//result.put(midnight, tdd)
|
||||
}
|
||||
//for (i in 0 until tdd.size()) {
|
||||
//val tdd = result.valueAt(i)
|
||||
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
|
||||
//}
|
||||
|
||||
|
||||
aapsLogger.debug(LTag.CORE, tdd.toString())
|
||||
return tdd
|
||||
}
|
||||
|
||||
fun averageTDD(tdds: LongSparseArray<TotalDailyDose>): TotalDailyDose {
|
||||
val totalTdd = TotalDailyDose(timestamp = dateUtil.now())
|
||||
for (i in 0 until tdds.size()) {
|
||||
val tdd = tdds.valueAt(i)
|
||||
|
|
Loading…
Reference in a new issue