Merge pull request #1832 from nightscout/tim2000s_dev

Dynamic ISF update to model cleaned
This commit is contained in:
Milos Kozak 2022-06-17 11:56:51 +02:00 committed by GitHub
commit 67b4eaee70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 93 additions and 75 deletions

View file

@ -218,7 +218,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
//********************************************************************************* //*********************************************************************************
console.error("---------------------------------------------------------"); console.error("---------------------------------------------------------");
console.error( " Dynamic ISF version Beta 1.5 "); console.error( " Dynamic ISF version Beta 1.6.4 ");
console.error("---------------------------------------------------------"); console.error("---------------------------------------------------------");
@ -247,39 +247,50 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
/*var tdd_pump_now = meal_data.TDDPUMP; /*var tdd_pump_now = meal_data.TDDPUMP;
var tdd_pump = ( tdd_pump_now / (now / 24));*/ var tdd_pump = ( tdd_pump_now / (now / 24));*/
var TDD = (tdd7 * 0.4) + (tdd_pump * 0.6); //var TDD = (tdd7 * 0.4) + (tdd_pump * 0.6);
console.error("Pump extrapolated TDD = "+tdd_pump+"; "); var tdd1 = meal_data.TDDAIMI1;
//if (tdd7 > 0){ var tdd_4 = meal_data.TDDLast4;
if ( tdd_pump > tdd7 && now < 5 || now < 7 && TDD < ( 0.8 * tdd7 ) ){ var tdd8to4 = meal_data.TDD4to8;
TDD = ( 0.8 * tdd7 ); var tdd_last8_wt = ( ( ( 1.4 * tdd_4) + ( 0.6 * tdd8to4) ) * 3 );
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; "; console.error("Rolling 8 hours weight average: "+tdd_last8_wt+"; ");
console.error("1-day average TDD is: "+tdd1+"; ");
console.error("7-day average TDD is: " +tdd7+ "; ");
//TDD = ( tdd_last8_wt * 0.6) + ( tdd7 * 0.4 );
var TDD = ( tdd_last8_wt * 0.33 ) + ( tdd7 * 0.34 ) + (tdd1 * 0.33);
console.log("TDD = " +TDD+ " using average of 7-day, 1-day and weighted 8hr average");
//var ins_val = 75;
var insulin = profile.insulinType;
console.log("Insulin Peak = "+profile.insulinPeak+"; ");
//console.log("Initial insulin value for ISF: "+ins_val+"; ");
//console.log("Current value for insulin: "+insulin+"; ");
var ins_val;
if (profile.insulinPeak > 65) { // lyumjev peak: 45
ins_val = 55;
} else if (profile.insulinPeak > 50 ){ // ultra rapid peak: 55
ins_val = 65;
} else {
ins_val = 75; // rapid peak: 75
} }
console.log("For "+profile.insulinType+" (insulin peak: "+profile.insulinPeak+") divisor is: "+ins_val+"; ");
else if (tdd_pump > (1.75 * tdd7)){ console.log("Insulin value for ISF based on profile: "+ins_val+"; ");
TDD = tdd7;
console.error("TDD set to TDD7 due to high pump usage reported. TDD = "+TDD+"; ");
rT.reason += "TDD set to TDD7 due to high pump usage reported. TDD = "+TDD+"; ";
}
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 = " +TDD+ " based on standard pump 60/tdd7 40 split; ");
rT.reason += "TDD: " +TDD+ " based on standard pump 60/tdd7 40 split; ";
}
var dynISFadjust = profile.DynISFAdjust; var dynISFadjust = profile.DynISFAdjust;
var dynISFadjust = ( dynISFadjust / 100 ); dynISFadjust = ( dynISFadjust / 100 );
var TDD = (dynISFadjust * TDD); TDD = ( dynISFadjust * TDD );
var variable_sens = (277700 / ( TDD * bg));
var variable_sens = 1800 / ( TDD * (Math.log(( bg / ins_val ) + 1 ) ) );
variable_sens = round(variable_sens,1); variable_sens = round(variable_sens,1);
if (dynISFadjust > 1 ) { if (dynISFadjust > 1 ) {
console.log("TDD adjustment factor is: " +dynISFadjust+"; "); console.log("TDD adjustment factor is: " +dynISFadjust+"; ");
console.log("TDD adjusted to "+TDD+" using adjustment factor of "+dynISFadjust+"; "); console.log("TDD adjusted to "+TDD+" using adjustment factor of "+dynISFadjust+"; ");
@ -314,7 +325,7 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
console.log("ISF from "+variable_sens+" to "+sens+ "due to temp target; "); console.log("ISF from "+variable_sens+" to "+sens+ "due to temp target; ");
} }
else { else {
sensitivityRatio = ( tdd_24 / tdd7 ); sensitivityRatio = ( meal_data.TDD24 / tdd7 );
} }
if (sensitivityRatio > 1) { if (sensitivityRatio > 1) {
sensitivityRatio = Math.min(sensitivityRatio, profile.autosens_max); sensitivityRatio = Math.min(sensitivityRatio, profile.autosens_max);
@ -501,8 +512,14 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
return rT; return rT;
} }
// min_bg of 90 -> threshold of 65, 100 -> 70 110 -> 75, and 130 -> 85 // min_bg of 90 -> threshold of 65, 100 -> 70 110 -> 75, and 130 -> 85, or if specified by user, take that value
var lgsThreshold = profile.lgsThreshold;
var threshold = min_bg - 0.5*(min_bg-40); var threshold = min_bg - 0.5*(min_bg-40);
var oldThreshold = threshold;
if (lgsThreshold >= 65 && lgsThreshold <= 120 && lgsThreshold > threshold) {
threshold = lgsThreshold;
}
console.error("Threshold set from " + convert_bg(oldThreshold, profile) + " to " + convert_bg(threshold, profile) + "; ");
//console.error(reservoir_data); //console.error(reservoir_data);
@ -808,23 +825,26 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
console.log("EventualBG is" +eventualBG+" ;"); console.log("EventualBG is" +eventualBG+" ;");
if (bg > target_bg && glucose_status.delta < 3 && glucose_status.delta > -3 && glucose_status.short_avgdelta > -3 && glucose_status.short_avgdelta < 3 && eventualBG > target_bg && eventualBG < bg ) { if (bg > target_bg && glucose_status.delta < 3 && glucose_status.delta > -3 && glucose_status.short_avgdelta > -3 && glucose_status.short_avgdelta < 3 && eventualBG > target_bg && eventualBG < bg ) {
var future_sens = ( 277700 / (TDD * ((eventualBG * 0.5) + (bg * 0.5) ) ) ); var future_sens = ( 1800 / (Math.log((((eventualBG * 0.5) + (bg * 0.5))/ins_val)+1)*TDD));
//var future_sens_old = ( 277700 / (TDD * ((bg * 0.5) + (eventualBG * 0.5 ))));
console.log("Future state sensitivity is " +future_sens+" based on eventual and current bg due to flat glucose level above target"); console.log("Future state sensitivity is " +future_sens+" based on eventual and current bg due to flat glucose level above target");
rT.reason += "Dosing sensitivity: " +future_sens+" using eventual BG;"; rT.reason += "Dosing sensitivity: " +future_sens+" using eventual BG;";
} }
else if( glucose_status.delta > 0 && eventualBG > target_bg ) { else if( glucose_status.delta > 0 && eventualBG > target_bg ) {
var future_sens = ( 277700 / (TDD * bg) ); var future_sens = ( 1800 / (Math.log((bg/ins_val)+1)*TDD));
//var future_sens_old = ( 277700 / (TDD * bg));
console.log("Future state sensitivity is " +future_sens+" using current bg due to small delta or variation"); console.log("Future state sensitivity is " +future_sens+" using current bg due to small delta or variation");
rT.reason += "Dosing sensitivity: " +future_sens+" using current BG;"; rT.reason += "Dosing sensitivity: " +future_sens+" using current BG;";
} }
else { else {
var future_sens = ( 277700 / (TDD * eventualBG) ); var future_sens = ( 1800 / (Math.log((eventualBG/ins_val)+1)*TDD));
//var future_sens_old = ( 277700 / (TDD * eventualBG));
console.log("Future state sensitivity is " +future_sens+" based on eventual bg due to -ve delta"); 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;"; rT.reason += "Dosing sensitivity: " +future_sens+" using eventual BG;";
} }
var future_sens = round(future_sens,1); future_sens = round(future_sens,1);

View file

@ -192,6 +192,11 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
this.profile.put("sens", profile.getIsfMgdl()) this.profile.put("sens", profile.getIsfMgdl())
this.profile.put("max_daily_safety_multiplier", sp.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3)) this.profile.put("max_daily_safety_multiplier", sp.getInt(R.string.key_openapsama_max_daily_safety_multiplier, 3))
this.profile.put("current_basal_safety_multiplier", sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0)) this.profile.put("current_basal_safety_multiplier", sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0))
this.profile.put("lgsThreshold", Profile.toMgdl(sp.getDouble(R.string.key_lgs_threshold, 65.0)))
val insulin = activePlugin.activeInsulin
val insulinType = insulin.friendlyName
val insulinPeak = insulin.peak
//mProfile.put("high_temptarget_raises_sensitivity", SP.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity)); //mProfile.put("high_temptarget_raises_sensitivity", SP.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity));
this.profile.put("high_temptarget_raises_sensitivity", sp.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity)) this.profile.put("high_temptarget_raises_sensitivity", sp.getBoolean(R.string.key_high_temptarget_raises_sensitivity, SMBDefaults.high_temptarget_raises_sensitivity))
@ -222,7 +227,9 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
this.profile.put("enableSMB_after_carbs", smbEnabled && sp.getBoolean(R.string.key_enableSMB_after_carbs, false) && advancedFiltering) this.profile.put("enableSMB_after_carbs", smbEnabled && sp.getBoolean(R.string.key_enableSMB_after_carbs, false) && advancedFiltering)
this.profile.put("maxSMBBasalMinutes", sp.getInt(R.string.key_smbmaxminutes, SMBDefaults.maxSMBBasalMinutes)) this.profile.put("maxSMBBasalMinutes", sp.getInt(R.string.key_smbmaxminutes, SMBDefaults.maxSMBBasalMinutes))
this.profile.put("maxUAMSMBBasalMinutes", sp.getInt(R.string.key_uamsmbmaxminutes, SMBDefaults.maxUAMSMBBasalMinutes)) this.profile.put("maxUAMSMBBasalMinutes", sp.getInt(R.string.key_uamsmbmaxminutes, SMBDefaults.maxUAMSMBBasalMinutes))
this.profile.put("DynISFAdjust", SafeParse.stringToDouble(sp.getString(R.string.key_DynISFAdjust,"100"))) this.profile.put("DynISFAdjust", SafeParse.stringToDouble(sp.getString(R.string.key_DynISFAdjust, "100")))
this.profile.put("insulinType", insulinType)
this.profile.put("insulinPeak", insulinPeak)
this.profile.put("maxUAMSMBBasalMinutes", sp.getInt(R.string.key_uamsmbmaxminutes, SMBDefaults.maxUAMSMBBasalMinutes)) this.profile.put("maxUAMSMBBasalMinutes", sp.getInt(R.string.key_uamsmbmaxminutes, SMBDefaults.maxUAMSMBBasalMinutes))
//set the min SMB amount to be the amount set by the pump. //set the min SMB amount to be the amount set by the pump.
this.profile.put("bolus_increment", pumpBolusStep) this.profile.put("bolus_increment", pumpBolusStep)
@ -263,9 +270,13 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
this.mealData.put("lastBolusTime", mealData.lastBolusTime) this.mealData.put("lastBolusTime", mealData.lastBolusTime)
this.mealData.put("lastCarbTime", mealData.lastCarbTime) this.mealData.put("lastCarbTime", mealData.lastCarbTime)
this.mealData.put("TDDAIMI1", tddCalculator.averageTDD(tddCalculator.calculate(1))?.totalAmount)
this.mealData.put("TDDAIMI7", tddCalculator.averageTDD(tddCalculator.calculate(7))?.totalAmount) this.mealData.put("TDDAIMI7", tddCalculator.averageTDD(tddCalculator.calculate(7))?.totalAmount)
this.mealData.put("TDDPUMP", tddCalculator.calculateDaily().totalAmount) this.mealData.put("TDDLast4", tddCalculator.calculateDaily(-4, 0).totalAmount)
this.mealData.put("TDDLast24", tddCalculator.calculate24Daily().totalAmount) this.mealData.put("TDD4to8", tddCalculator.calculateDaily(-8, -4).totalAmount)
this.mealData.put("TDD24", tddCalculator.calculateDaily(-24, 0).totalAmount)
if (constraintChecker.isAutosensModeEnabled().value()) { if (constraintChecker.isAutosensModeEnabled().value()) {
autosensData.put("ratio", autosensDataRatio) autosensData.put("ratio", autosensDataRatio)

View file

@ -99,41 +99,9 @@ class TddCalculator @Inject constructor(
return result return result
} }
fun calculateDaily(): TotalDailyDose { fun calculateDaily(startHours: Long, endHours: Long): TotalDailyDose {
val startTime = MidnightTime.calc(dateUtil.now()) val startTime = dateUtil.now() + T.hours(hour = startHours).msecs()
val endTime = dateUtil.now() val endTime = dateUtil.now() + T.hours(hour = endHours).msecs()
val tdd = TotalDailyDose(timestamp = startTime)
//val result = TotalDailyDose()
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
.filter { it.type != Bolus.Type.PRIMING }
.forEach { t ->
tdd.bolusAmount += t.amount
}
repository.getCarbsDataFromTimeToTimeExpanded(startTime, endTime, true).blockingGet().forEach { t ->
tdd.carbs += t.amount
}
val calculationStep = T.mins(5).msecs()
for (t in startTime until endTime step calculationStep) {
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
}
}
tdd.totalAmount = tdd.bolusAmount + tdd.basalAmount
aapsLogger.debug(LTag.CORE, tdd.toString())
return tdd
}
fun calculate24Daily(): TotalDailyDose {
val startTime = dateUtil.now() - T.hours(hour = 24).msecs()
val endTime = dateUtil.now()
val tdd = TotalDailyDose(timestamp = startTime) val tdd = TotalDailyDose(timestamp = startTime)
repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet() repository.getBolusesDataFromTimeToTime(startTime, endTime, true).blockingGet()
.filter { it.type != Bolus.Type.PRIMING } .filter { it.type != Bolus.Type.PRIMING }

View file

@ -58,6 +58,7 @@
<string name="treatmentssafety_title">Treatments safety</string> <string name="treatmentssafety_title">Treatments safety</string>
<string name="treatmentssafety_maxbolus_title">Max allowed bolus [U]</string> <string name="treatmentssafety_maxbolus_title">Max allowed bolus [U]</string>
<string name="treatmentssafety_maxcarbs_title">Max allowed carbs [g]</string> <string name="treatmentssafety_maxcarbs_title">Max allowed carbs [g]</string>
<string name="treatmentssafety_lgsThreshold_title">BG level below which low glucose suspend occurs</string>
<string name="nav_preferences_plugin">%1$s Preferences</string> <string name="nav_preferences_plugin">%1$s Preferences</string>
<string name="nav_preferences">Preferences</string> <string name="nav_preferences">Preferences</string>
<string name="nav_refreshtreatments">Refresh treatments from NS</string> <string name="nav_refreshtreatments">Refresh treatments from NS</string>
@ -163,6 +164,9 @@
<string name="closedloop">Closed Loop</string> <string name="closedloop">Closed Loop</string>
<string name="openloop">Open Loop</string> <string name="openloop">Open Loop</string>
<string name="lowglucosesuspend">Low Glucose Suspend</string> <string name="lowglucosesuspend">Low Glucose Suspend</string>
<string name="rapidacting">Humalog/Novolog</string>
<string name="Fiasp">Fiasp</string>
<string name="Lyumjev">Lyumjev</string>
<string name="disabledloop">Loop Disabled</string> <string name="disabledloop">Loop Disabled</string>
<string name="openloop_newsuggestion">New suggestion available</string> <string name="openloop_newsuggestion">New suggestion available</string>
<string name="carbssuggestion">Carbs Suggestion</string> <string name="carbssuggestion">Carbs Suggestion</string>
@ -701,6 +705,7 @@
<string name="smb_frequency_exceeded">A bolus was delivered within the last 3 minutes, skipping SMB</string> <string name="smb_frequency_exceeded">A bolus was delivered within the last 3 minutes, skipping SMB</string>
<string name="basal_set_correctly">Basal set correctly</string> <string name="basal_set_correctly">Basal set correctly</string>
<string name="key_treatmentssafety_maxbolus" translatable="false">treatmentssafety_maxbolus</string> <string name="key_treatmentssafety_maxbolus" translatable="false">treatmentssafety_maxbolus</string>
<string name="key_lgs_threshold" translatable="false">lgsThreshold</string>
<string name="limitingextendedbolus">Limiting extended bolus to %1$.1f U because of %2$s</string> <string name="limitingextendedbolus">Limiting extended bolus to %1$.1f U because of %2$s</string>
<string name="limitingcarbs">Limiting carbs to %1$d g because of %2$s</string> <string name="limitingcarbs">Limiting carbs to %1$d g because of %2$s</string>
<string name="limitingiob">Limiting IOB to %1$.1f U because of %2$s</string> <string name="limitingiob">Limiting IOB to %1$.1f U because of %2$s</string>
@ -720,6 +725,7 @@
<string name="openapssmb_maxiob_summary">This value is called Max IOB in OpenAPS context\nOpenAPS will not add more insulin if current IOB is greater than this value</string> <string name="openapssmb_maxiob_summary">This value is called Max IOB in OpenAPS context\nOpenAPS will not add more insulin if current IOB is greater than this value</string>
<string name="absorption_cutoff_title">Meal max absorption time [h]</string> <string name="absorption_cutoff_title">Meal max absorption time [h]</string>
<string name="absorption_cutoff_summary">Time at which any meal is considered absorbed. Remaining carbs will be cut off.</string> <string name="absorption_cutoff_summary">Time at which any meal is considered absorbed. Remaining carbs will be cut off.</string>
<string name="treatmentssafety_lgsThreshold_summary">BG value below which insulin is suspended. Default value uses standard target model. User can set value between 60mg/dl (3.3mmol/l) and 100mg/dl(5.5mmol/l). Values below 65/3.6 result in use of default model</string>
<string name="overview_show_notes_field_in_dialogs_title">Show notes field in treatment dialogs</string> <string name="overview_show_notes_field_in_dialogs_title">Show notes field in treatment dialogs</string>
<string name="title_activity_setup_wizard" translatable="false">SetupWizardActivity</string> <string name="title_activity_setup_wizard" translatable="false">SetupWizardActivity</string>
<string name="next_button">Next</string> <string name="next_button">Next</string>

View file

@ -39,6 +39,16 @@
validate:floatminNumber="1" validate:floatminNumber="1"
validate:testType="floatNumericRange" /> validate:testType="floatNumericRange" />
<info.nightscout.androidaps.utils.textValidator.ValidatingEditTextPreference
android:defaultValue="65"
android:inputType="numberDecimal"
android:dialogMessage="@string/treatmentssafety_lgsThreshold_summary"
android:key="@string/key_lgs_threshold"
android:title="@string/treatmentssafety_lgsThreshold_title"
validate:floatmaxNumber="120"
validate:floatminNumber="65"
validate:testType="bgRange" />
<SwitchPreference <SwitchPreference
android:defaultValue="false" android:defaultValue="false"
android:key="openapsama_useautosens" android:key="openapsama_useautosens"

View file

@ -188,6 +188,9 @@ interface Profile {
if (isMmol(anyBg)) toUnitsString(anyBg * Constants.MMOLL_TO_MGDL, anyBg, profileFunction.getUnits()) if (isMmol(anyBg)) toUnitsString(anyBg * Constants.MMOLL_TO_MGDL, anyBg, profileFunction.getUnits())
else toUnitsString(anyBg, anyBg * Constants.MGDL_TO_MMOLL, profileFunction.getUnits()) else toUnitsString(anyBg, anyBg * Constants.MGDL_TO_MMOLL, profileFunction.getUnits())
fun toMgdl(value: Double): Double =
if (isMgdl(value)) value else value * Constants.MMOLL_TO_MGDL
fun toMgdl(value: Double, units: GlucoseUnit): Double = fun toMgdl(value: Double, units: GlucoseUnit): Double =
if (units == GlucoseUnit.MGDL) value else value * Constants.MMOLL_TO_MGDL if (units == GlucoseUnit.MGDL) value else value * Constants.MMOLL_TO_MGDL