AutoISF -> separate plugin
This commit is contained in:
parent
e32515a369
commit
8a19267a39
17 changed files with 1809 additions and 218 deletions
|
@ -277,56 +277,16 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
|||
|
||||
var profile_sens = round(profile.sens,1)
|
||||
var sens = profile.sens;
|
||||
|
||||
var now = new Date().getHours();
|
||||
if (now < 1){
|
||||
now = 1;}
|
||||
else {
|
||||
console.error("Time now is "+now+"; ");
|
||||
}
|
||||
if (meal_data.TDDAIMI7){
|
||||
var tdd7 = meal_data.TDDAIMI7;
|
||||
}
|
||||
else{
|
||||
var tdd7 = ((basal * 12)*100)/21;
|
||||
}
|
||||
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;
|
||||
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);
|
||||
}
|
||||
//console.log(" (autosens ratio "+sensitivityRatio+")");
|
||||
}
|
||||
|
||||
console.error("; CR:",profile.carb_ratio);
|
||||
|
||||
// compare currenttemp to iob_data.lastTemp and cancel temp if they don't match
|
||||
|
@ -740,20 +700,6 @@ 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 || eventualBG > target_bg && glucose_status.delta < 0 ) {
|
||||
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);
|
||||
|
@ -974,33 +920,30 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
|||
rT.reason += ", but Min. Delta " + minDelta.toFixed(2) + " > Exp. Delta " + convert_bg(expectedDelta, profile);
|
||||
}
|
||||
if (currenttemp.duration > 15 && (round_basal(basal, profile) === round_basal(currenttemp.rate, profile))) {
|
||||
rT.reason += ", temp " + currenttemp.rate + " ~ req " + round(basal, 2) + "U/hr. ";
|
||||
rT.reason += ", temp " + currenttemp.rate + " ~ req " + basal + "U/hr. ";
|
||||
return rT;
|
||||
} else {
|
||||
rT.reason += "; setting current basal of " + round(basal, 2) + " as temp. ";
|
||||
rT.reason += "; setting current basal of " + basal + " as temp. ";
|
||||
return tempBasalFunctions.setTempBasal(basal, 30, profile, rT, currenttemp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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);
|
||||
// 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);
|
||||
|
||||
// if required temp < existing temp basal
|
||||
var insulinScheduled = currenttemp.duration * (currenttemp.rate - basal) / 60;
|
||||
|
@ -1049,10 +992,10 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
|||
rT.reason += "Eventual BG " + convert_bg(eventualBG, profile) + " > " + convert_bg(min_bg, profile) + " but Min. Delta " + minDelta.toFixed(2) + " < Exp. Delta " + convert_bg(expectedDelta, profile);
|
||||
}
|
||||
if (currenttemp.duration > 15 && (round_basal(basal, profile) === round_basal(currenttemp.rate, profile))) {
|
||||
rT.reason += ", temp " + currenttemp.rate + " ~ req " + round(basal, 2) + "U/hr. ";
|
||||
rT.reason += ", temp " + currenttemp.rate + " ~ req " + basal + "U/hr. ";
|
||||
return rT;
|
||||
} else {
|
||||
rT.reason += "; setting current basal of " + round(basal, 2) + " as temp. ";
|
||||
rT.reason += "; setting current basal of " + basal + " as temp. ";
|
||||
return tempBasalFunctions.setTempBasal(basal, 30, profile, rT, currenttemp);
|
||||
}
|
||||
}
|
||||
|
@ -1063,10 +1006,10 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
|||
if (! (microBolusAllowed && enableSMB )) {
|
||||
rT.reason += convert_bg(eventualBG, profile)+"-"+convert_bg(minPredBG, profile)+" in range: no temp required";
|
||||
if (currenttemp.duration > 15 && (round_basal(basal, profile) === round_basal(currenttemp.rate, profile))) {
|
||||
rT.reason += ", temp " + currenttemp.rate + " ~ req " + round(basal, 2) + "U/hr. ";
|
||||
rT.reason += ", temp " + currenttemp.rate + " ~ req " + basal + "U/hr. ";
|
||||
return rT;
|
||||
} else {
|
||||
rT.reason += "; setting current basal of " + round(basal, 2) + " as temp. ";
|
||||
rT.reason += "; setting current basal of " + basal + " as temp. ";
|
||||
return tempBasalFunctions.setTempBasal(basal, 30, profile, rT, currenttemp);
|
||||
}
|
||||
}
|
||||
|
@ -1080,22 +1023,22 @@ var determine_basal = function determine_basal(glucose_status, currenttemp, iob_
|
|||
if (iob_data.iob > max_iob) {
|
||||
rT.reason += "IOB " + round(iob_data.iob,2) + " > max_iob " + max_iob;
|
||||
if (currenttemp.duration > 15 && (round_basal(basal, profile) === round_basal(currenttemp.rate, profile))) {
|
||||
rT.reason += ", temp " + currenttemp.rate + " ~ req " + round(basal, 2) + "U/hr. ";
|
||||
rT.reason += ", temp " + currenttemp.rate + " ~ req " + basal + "U/hr. ";
|
||||
return rT;
|
||||
} else {
|
||||
rT.reason += "; setting current basal of " + round(basal, 2) + " as temp. ";
|
||||
rT.reason += "; setting current basal of " + basal + " as temp. ";
|
||||
return tempBasalFunctions.setTempBasal(basal, 30, profile, rT, currenttemp);
|
||||
}
|
||||
} 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) / 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;
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
|
||||
// rate required to deliver insulinReq more insulin over 30m:
|
||||
rate = basal + (2 * insulinReq);
|
||||
|
|
1224
app/src/main/assets/OpenAPSSMBAutoISF/determine-basal.js
Normal file
1224
app/src/main/assets/OpenAPSSMBAutoISF/determine-basal.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -7,6 +7,7 @@ import info.nightscout.androidaps.plugins.aps.openAPSAMA.DetermineBasalAdapterAM
|
|||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.DetermineBasalResultAMA
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalAdapterSMBJS
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalResultSMB
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMBAutoISF.DetermineBasalAdapterSMBAutoISFJS
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobOref1Thread
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobThread
|
||||
|
||||
|
@ -19,6 +20,7 @@ abstract class APSModule {
|
|||
@ContributesAndroidInjector abstract fun determineBasalResultAMAInjector(): DetermineBasalResultAMA
|
||||
@ContributesAndroidInjector abstract fun determineBasalAdapterAMAJSInjector(): DetermineBasalAdapterAMAJS
|
||||
@ContributesAndroidInjector abstract fun determineBasalAdapterSMBJSInjector(): DetermineBasalAdapterSMBJS
|
||||
@ContributesAndroidInjector abstract fun determineBasalAdapterSMBAutoISFJSInjector(): DetermineBasalAdapterSMBAutoISFJS
|
||||
@ContributesAndroidInjector abstract fun iobCobThreadInjector(): IobCobThread
|
||||
@ContributesAndroidInjector abstract fun iobCobOref1ThreadInjector(): IobCobOref1Thread
|
||||
}
|
|
@ -14,6 +14,7 @@ import info.nightscout.androidaps.plugin.general.openhumans.OpenHumansUploader
|
|||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMBAutoISF.OpenAPSSMBAutoISFPlugin
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConfigBuilderPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.bgQualityCheck.BgQualityCheckPlugin
|
||||
import info.nightscout.androidaps.plugins.constraints.dstHelper.DstHelperPlugin
|
||||
|
@ -212,6 +213,12 @@ abstract class PluginsModule {
|
|||
@IntKey(220)
|
||||
abstract fun bindOpenAPSSMBPlugin(plugin: OpenAPSSMBPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@APS
|
||||
@IntoMap
|
||||
@IntKey(222)
|
||||
abstract fun bindOpenAPSSMBAutoISFPlugin(plugin: OpenAPSSMBAutoISFPlugin): PluginBase
|
||||
|
||||
@Binds
|
||||
@AllConfigs
|
||||
@IntoMap
|
||||
|
|
|
@ -7,6 +7,7 @@ import info.nightscout.androidaps.data.MealData
|
|||
import info.nightscout.androidaps.extensions.convertedToAbsolute
|
||||
import info.nightscout.androidaps.extensions.getPassedDurationToTimeInMinutes
|
||||
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
|
||||
import info.nightscout.androidaps.interfaces.DetermineBasalAdapterInterface
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
|
@ -14,6 +15,7 @@ import info.nightscout.androidaps.interfaces.ProfileFunction
|
|||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback
|
||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult
|
||||
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
|
@ -30,7 +32,7 @@ import java.nio.charset.StandardCharsets
|
|||
import javax.inject.Inject
|
||||
import kotlin.math.min
|
||||
|
||||
class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader, injector: HasAndroidInjector) {
|
||||
class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader, injector: HasAndroidInjector) : DetermineBasalAdapterInterface {
|
||||
|
||||
private val injector: HasAndroidInjector
|
||||
|
||||
|
@ -48,21 +50,15 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader
|
|||
private var currentTemp = JSONObject()
|
||||
private var autosensData = JSONObject()
|
||||
|
||||
var currentTempParam: String? = null
|
||||
private set
|
||||
var iobDataParam: String? = null
|
||||
private set
|
||||
var glucoseStatusParam: String? = null
|
||||
private set
|
||||
var profileParam: String? = null
|
||||
private set
|
||||
var mealDataParam: String? = null
|
||||
private set
|
||||
var scriptDebug = ""
|
||||
private set
|
||||
override var currentTempParam: String? = null
|
||||
override var iobDataParam: String? = null
|
||||
override var glucoseStatusParam: String? = null
|
||||
override var profileParam: String? = null
|
||||
override var mealDataParam: String? = null
|
||||
override var scriptDebug = ""
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
operator fun invoke(): DetermineBasalResultAMA? {
|
||||
override operator fun invoke(): APSResult? {
|
||||
aapsLogger.debug(LTag.APS, ">>> Invoking determine_basal <<<")
|
||||
aapsLogger.debug(LTag.APS, "Glucose status: " + glucoseStatus.toString().also { glucoseStatusParam = it })
|
||||
aapsLogger.debug(LTag.APS, "IOB data: " + iobData.toString().also { iobDataParam = it })
|
||||
|
@ -143,18 +139,25 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader
|
|||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
@Throws(JSONException::class) fun setData(profile: Profile,
|
||||
maxIob: Double,
|
||||
maxBasal: Double,
|
||||
minBg: Double,
|
||||
maxBg: Double,
|
||||
targetBg: Double,
|
||||
basalRate: Double,
|
||||
iobArray: Array<IobTotal>,
|
||||
glucoseStatus: GlucoseStatus,
|
||||
mealData: MealData,
|
||||
autosensDataRatio: Double,
|
||||
tempTargetSet: Boolean) {
|
||||
@Throws(JSONException::class)
|
||||
override fun setData(
|
||||
profile: Profile,
|
||||
maxIob: Double,
|
||||
maxBasal: Double,
|
||||
minBg: Double,
|
||||
maxBg: Double,
|
||||
targetBg: Double,
|
||||
basalRate: Double,
|
||||
iobArray: Array<IobTotal>,
|
||||
glucoseStatus: GlucoseStatus,
|
||||
mealData: MealData,
|
||||
autosensDataRatio: Double,
|
||||
tempTargetSet: Boolean,
|
||||
microBolusAllowed: Boolean,
|
||||
uamAllowed: Boolean,
|
||||
advancedFiltering: Boolean,
|
||||
isSaveCgmSource: Boolean
|
||||
) {
|
||||
this.profile = JSONObject()
|
||||
this.profile.put("max_iob", maxIob)
|
||||
this.profile.put("dia", min(profile.dia, 3.0))
|
||||
|
|
|
@ -96,7 +96,7 @@ class OpenAPSAMAFragment : DaggerFragment() {
|
|||
binding.result.text = jsonFormatter.format(lastAPSResult.json)
|
||||
binding.request.text = lastAPSResult.toSpanned()
|
||||
}
|
||||
openAPSAMAPlugin.lastDetermineBasalAdapterAMAJS?.let { determineBasalAdapterAMAJS ->
|
||||
openAPSAMAPlugin.lastDetermineBasalAdapter?.let { determineBasalAdapterAMAJS ->
|
||||
binding.glucosestatus.text = jsonFormatter.format(determineBasalAdapterAMAJS.glucoseStatusParam)
|
||||
binding.currenttemp.text = jsonFormatter.format(determineBasalAdapterAMAJS.currentTempParam)
|
||||
try {
|
||||
|
|
|
@ -60,8 +60,8 @@ class OpenAPSAMAPlugin @Inject constructor(
|
|||
// last values
|
||||
override var lastAPSRun: Long = 0
|
||||
override var lastAPSResult: DetermineBasalResultAMA? = null
|
||||
var lastDetermineBasalAdapterAMAJS: DetermineBasalAdapterAMAJS? = null
|
||||
var lastAutosensResult: AutosensResult = AutosensResult()
|
||||
override var lastDetermineBasalAdapter: DetermineBasalAdapterInterface? = null
|
||||
override var lastAutosensResult: AutosensResult = AutosensResult()
|
||||
|
||||
override fun specialEnableCondition(): Boolean {
|
||||
return try {
|
||||
|
@ -158,7 +158,7 @@ class OpenAPSAMAPlugin @Inject constructor(
|
|||
// Fix bug determine basal
|
||||
if (determineBasalResultAMA == null) {
|
||||
aapsLogger.error(LTag.APS, "SMB calculation returned null")
|
||||
lastDetermineBasalAdapterAMAJS = null
|
||||
lastDetermineBasalAdapter = null
|
||||
lastAPSResult = null
|
||||
lastAPSRun = 0
|
||||
} else {
|
||||
|
@ -167,8 +167,8 @@ class OpenAPSAMAPlugin @Inject constructor(
|
|||
val now = System.currentTimeMillis()
|
||||
determineBasalResultAMA.json?.put("timestamp", dateUtil.toISOString(now))
|
||||
determineBasalResultAMA.inputConstraints = inputConstraints
|
||||
lastDetermineBasalAdapterAMAJS = determineBasalAdapterAMAJS
|
||||
lastAPSResult = determineBasalResultAMA
|
||||
lastDetermineBasalAdapter = determineBasalAdapterAMAJS
|
||||
lastAPSResult = determineBasalResultAMA as DetermineBasalResultAMA
|
||||
lastAPSRun = now
|
||||
}
|
||||
rxBus.send(EventOpenAPSUpdateGui())
|
||||
|
|
|
@ -4,27 +4,19 @@ 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
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback
|
||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult
|
||||
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
|
||||
|
@ -36,7 +28,7 @@ import java.lang.reflect.InvocationTargetException
|
|||
import java.nio.charset.StandardCharsets
|
||||
import javax.inject.Inject
|
||||
|
||||
class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader: ScriptReader, private val injector: HasAndroidInjector) {
|
||||
class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader: ScriptReader, private val injector: HasAndroidInjector) : DetermineBasalAdapterInterface {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
|
@ -45,10 +37,6 @@ 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()
|
||||
|
@ -60,26 +48,16 @@ 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
|
||||
private set
|
||||
var glucoseStatusParam: String? = null
|
||||
private set
|
||||
var profileParam: String? = null
|
||||
private set
|
||||
var mealDataParam: String? = null
|
||||
private set
|
||||
var scriptDebug = ""
|
||||
private set
|
||||
override var currentTempParam: String? = null
|
||||
override var iobDataParam: String? = null
|
||||
override var glucoseStatusParam: String? = null
|
||||
override var profileParam: String? = null
|
||||
override var mealDataParam: String? = null
|
||||
override var scriptDebug = ""
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
operator fun invoke(): DetermineBasalResultSMB? {
|
||||
override operator fun invoke(): APSResult? {
|
||||
aapsLogger.debug(LTag.APS, ">>> Invoking determine_basal <<<")
|
||||
aapsLogger.debug(LTag.APS, "Glucose status: " + mGlucoseStatus.toString().also { glucoseStatusParam = it })
|
||||
aapsLogger.debug(LTag.APS, "IOB data: " + iobData.toString().also { iobDataParam = it })
|
||||
|
@ -169,22 +147,24 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
|
|||
return determineBasalResultSMB
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection") fun setData(profile: Profile,
|
||||
maxIob: Double,
|
||||
maxBasal: Double,
|
||||
minBg: Double,
|
||||
maxBg: Double,
|
||||
targetBg: Double,
|
||||
basalRate: Double,
|
||||
iobArray: Array<IobTotal>,
|
||||
glucoseStatus: GlucoseStatus,
|
||||
mealData: MealData,
|
||||
autosensDataRatio: Double,
|
||||
tempTargetSet: Boolean,
|
||||
microBolusAllowed: Boolean,
|
||||
uamAllowed: Boolean,
|
||||
advancedFiltering: Boolean,
|
||||
isSaveCgmSource: Boolean
|
||||
@Suppress("SpellCheckingInspection")
|
||||
override fun setData(
|
||||
profile: Profile,
|
||||
maxIob: Double,
|
||||
maxBasal: Double,
|
||||
minBg: Double,
|
||||
maxBg: Double,
|
||||
targetBg: Double,
|
||||
basalRate: Double,
|
||||
iobArray: Array<IobTotal>,
|
||||
glucoseStatus: GlucoseStatus,
|
||||
mealData: MealData,
|
||||
autosensDataRatio: Double,
|
||||
tempTargetSet: Boolean,
|
||||
microBolusAllowed: Boolean,
|
||||
uamAllowed: Boolean,
|
||||
advancedFiltering: Boolean,
|
||||
isSaveCgmSource: Boolean
|
||||
) {
|
||||
val pump = activePlugin.activePump
|
||||
val pumpBolusStep = pump.pumpDescription.bolusStep
|
||||
|
@ -255,7 +235,6 @@ 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)
|
||||
|
@ -264,13 +243,7 @@ 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("TDDAIMI7", tddAIMI!!.averageTDD(tddAIMI!!.calculate(7)).totalAmount)
|
||||
this.mealData.put("TDDPUMP", tddAIMI!!.calculateDaily().totalAmount)
|
||||
|
||||
if (constraintChecker.isAutosensModeEnabled().value()) {
|
||||
autosensData.put("ratio", autosensDataRatio)
|
||||
} else {
|
||||
|
|
|
@ -9,8 +9,7 @@ import android.view.ViewGroup
|
|||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.databinding.OpenapsamaFragmentBinding
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui
|
||||
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateResultGui
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
|
@ -19,6 +18,8 @@ import info.nightscout.androidaps.utils.FabricPrivacy
|
|||
import info.nightscout.androidaps.utils.JSONFormatter
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import io.reactivex.rxkotlin.plusAssign
|
||||
import org.json.JSONArray
|
||||
|
@ -34,7 +35,7 @@ class OpenAPSSMBFragment : DaggerFragment() {
|
|||
@Inject lateinit var rxBus: RxBus
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var openAPSSMBPlugin: OpenAPSSMBPlugin
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var jsonFormatter: JSONFormatter
|
||||
|
||||
|
@ -44,8 +45,7 @@ class OpenAPSSMBFragment : DaggerFragment() {
|
|||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View {
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
|
||||
_binding = OpenapsamaFragmentBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ class OpenAPSSMBFragment : DaggerFragment() {
|
|||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.run.setOnClickListener {
|
||||
openAPSSMBPlugin.invoke("OpenAPSSMB button", false)
|
||||
activePlugin.activeAPS.invoke("OpenAPSSMB button", false)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,11 +92,12 @@ class OpenAPSSMBFragment : DaggerFragment() {
|
|||
@Synchronized
|
||||
fun updateGUI() {
|
||||
if (_binding == null) return
|
||||
val openAPSSMBPlugin = activePlugin.activeAPS
|
||||
openAPSSMBPlugin.lastAPSResult?.let { lastAPSResult ->
|
||||
binding.result.text = jsonFormatter.format(lastAPSResult.json)
|
||||
binding.request.text = lastAPSResult.toSpanned()
|
||||
}
|
||||
openAPSSMBPlugin.lastDetermineBasalAdapterSMBJS?.let { determineBasalAdapterSMBJS ->
|
||||
openAPSSMBPlugin.lastDetermineBasalAdapter?.let { determineBasalAdapterSMBJS ->
|
||||
binding.glucosestatus.text = jsonFormatter.format(determineBasalAdapterSMBJS.glucoseStatusParam)
|
||||
binding.currenttemp.text = jsonFormatter.format(determineBasalAdapterSMBJS.currentTempParam)
|
||||
try {
|
||||
|
|
|
@ -10,8 +10,6 @@ import info.nightscout.androidaps.database.AppRepository
|
|||
import info.nightscout.androidaps.database.ValueWrapper
|
||||
import info.nightscout.androidaps.extensions.target
|
||||
import info.nightscout.androidaps.interfaces.*
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateGui
|
||||
import info.nightscout.androidaps.plugins.aps.events.EventOpenAPSUpdateResultGui
|
||||
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader
|
||||
|
@ -24,6 +22,8 @@ import info.nightscout.androidaps.utils.HardLimits
|
|||
import info.nightscout.androidaps.utils.Profiler
|
||||
import info.nightscout.androidaps.utils.Round
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
@ -37,7 +37,7 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
private val constraintChecker: ConstraintChecker,
|
||||
rh: ResourceHelper,
|
||||
private val profileFunction: ProfileFunction,
|
||||
private val context: Context,
|
||||
val context: Context,
|
||||
private val activePlugin: ActivePlugin,
|
||||
private val iobCobCalculator: IobCobCalculator,
|
||||
private val hardLimits: HardLimits,
|
||||
|
@ -46,23 +46,24 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
private val dateUtil: DateUtil,
|
||||
private val repository: AppRepository,
|
||||
private val glucoseStatusProvider: GlucoseStatusProvider
|
||||
) : PluginBase(PluginDescription()
|
||||
.mainType(PluginType.APS)
|
||||
.fragmentClass(OpenAPSSMBFragment::class.java.name)
|
||||
.pluginIcon(R.drawable.ic_generic_icon)
|
||||
.pluginName(R.string.openapssmb)
|
||||
.shortName(R.string.smb_shortname)
|
||||
.preferencesId(R.xml.pref_openapssmb)
|
||||
.description(R.string.description_smb)
|
||||
.setDefault(),
|
||||
) : PluginBase(
|
||||
PluginDescription()
|
||||
.mainType(PluginType.APS)
|
||||
.fragmentClass(OpenAPSSMBFragment::class.java.name)
|
||||
.pluginIcon(R.drawable.ic_generic_icon)
|
||||
.pluginName(R.string.openapssmb)
|
||||
.shortName(R.string.smb_shortname)
|
||||
.preferencesId(R.xml.pref_openapssmb)
|
||||
.description(R.string.description_smb)
|
||||
.setDefault(),
|
||||
aapsLogger, rh, injector
|
||||
), APS, Constraints {
|
||||
|
||||
// last values
|
||||
override var lastAPSRun: Long = 0
|
||||
override var lastAPSResult: DetermineBasalResultSMB? = null
|
||||
var lastDetermineBasalAdapterSMBJS: DetermineBasalAdapterSMBJS? = null
|
||||
var lastAutosensResult = AutosensResult()
|
||||
override var lastDetermineBasalAdapter: DetermineBasalAdapterInterface? = null
|
||||
override var lastAutosensResult = AutosensResult()
|
||||
|
||||
override fun specialEnableCondition(): Boolean {
|
||||
return try {
|
||||
|
@ -120,15 +121,34 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
}.value()
|
||||
|
||||
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.getTargetLowMgdl(), 0.1), R.string.profile_low_target, HardLimits.VERY_HARD_LIMIT_MIN_BG[0], HardLimits.VERY_HARD_LIMIT_MIN_BG[1])
|
||||
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.getTargetHighMgdl(), 0.1), R.string.profile_high_target, HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1])
|
||||
var maxBg =
|
||||
hardLimits.verifyHardLimits(Round.roundTo(profile.getTargetHighMgdl(), 0.1), R.string.profile_high_target, HardLimits.VERY_HARD_LIMIT_MAX_BG[0], HardLimits.VERY_HARD_LIMIT_MAX_BG[1])
|
||||
var targetBg = hardLimits.verifyHardLimits(profile.getTargetMgdl(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0], HardLimits.VERY_HARD_LIMIT_TARGET_BG[1])
|
||||
var isTempTarget = false
|
||||
val tempTarget = repository.getTemporaryTargetActiveAt(dateUtil.now()).blockingGet()
|
||||
if (tempTarget is ValueWrapper.Existing) {
|
||||
isTempTarget = true
|
||||
minBg = hardLimits.verifyHardLimits(tempTarget.value.lowTarget, R.string.temp_target_low_target, HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1].toDouble())
|
||||
maxBg = hardLimits.verifyHardLimits(tempTarget.value.highTarget, R.string.temp_target_high_target, HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1].toDouble())
|
||||
targetBg = hardLimits.verifyHardLimits(tempTarget.value.target(), R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1].toDouble())
|
||||
minBg =
|
||||
hardLimits.verifyHardLimits(
|
||||
tempTarget.value.lowTarget,
|
||||
R.string.temp_target_low_target,
|
||||
HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0].toDouble(),
|
||||
HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1].toDouble()
|
||||
)
|
||||
maxBg =
|
||||
hardLimits.verifyHardLimits(
|
||||
tempTarget.value.highTarget,
|
||||
R.string.temp_target_high_target,
|
||||
HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0].toDouble(),
|
||||
HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1].toDouble()
|
||||
)
|
||||
targetBg =
|
||||
hardLimits.verifyHardLimits(
|
||||
tempTarget.value.target(),
|
||||
R.string.temp_target_value,
|
||||
HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[0].toDouble(),
|
||||
HardLimits.VERY_HARD_LIMIT_TEMP_TARGET_BG[1].toDouble()
|
||||
)
|
||||
}
|
||||
if (!hardLimits.checkHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return
|
||||
if (!hardLimits.checkHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return
|
||||
|
@ -165,8 +185,9 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
profiler.log(LTag.APS, "SMB data gathering", start)
|
||||
start = System.currentTimeMillis()
|
||||
|
||||
DetermineBasalAdapterSMBJS(ScriptReader(context), injector).also { determineBasalAdapterSMBJS ->
|
||||
determineBasalAdapterSMBJS.setData(profile, maxIob, maxBasal, minBg, maxBg, targetBg,
|
||||
provideDetermineBasalAdapter().also { determineBasalAdapterSMBJS ->
|
||||
determineBasalAdapterSMBJS.setData(
|
||||
profile, maxIob, maxBasal, minBg, maxBg, targetBg,
|
||||
activePlugin.activePump.baseBasalRate,
|
||||
iobArray,
|
||||
glucoseStatus,
|
||||
|
@ -176,24 +197,26 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
smbAllowed.value(),
|
||||
uam.value(),
|
||||
advancedFiltering.value(),
|
||||
activePlugin.activeBgSource.javaClass.simpleName == "DexcomPlugin")
|
||||
activePlugin.activeBgSource.javaClass.simpleName == "DexcomPlugin"
|
||||
)
|
||||
val now = System.currentTimeMillis()
|
||||
val determineBasalResultSMB = determineBasalAdapterSMBJS.invoke()
|
||||
profiler.log(LTag.APS, "SMB calculation", start)
|
||||
if (determineBasalResultSMB == null) {
|
||||
aapsLogger.error(LTag.APS, "SMB calculation returned null")
|
||||
lastDetermineBasalAdapterSMBJS = null
|
||||
lastDetermineBasalAdapter = null
|
||||
lastAPSResult = null
|
||||
lastAPSRun = 0
|
||||
} else {
|
||||
// TODO still needed with oref1?
|
||||
// Fix bug determine basal
|
||||
if (determineBasalResultSMB.rate == 0.0 && determineBasalResultSMB.duration == 0 && iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now()) == null) determineBasalResultSMB.tempBasalRequested = false
|
||||
if (determineBasalResultSMB.rate == 0.0 && determineBasalResultSMB.duration == 0 && iobCobCalculator.getTempBasalIncludingConvertedExtended(dateUtil.now()) == null) determineBasalResultSMB.tempBasalRequested =
|
||||
false
|
||||
determineBasalResultSMB.iob = iobArray[0]
|
||||
determineBasalResultSMB.json?.put("timestamp", dateUtil.toISOString(now))
|
||||
determineBasalResultSMB.inputConstraints = inputConstraints
|
||||
lastDetermineBasalAdapterSMBJS = determineBasalAdapterSMBJS
|
||||
lastAPSResult = determineBasalResultSMB
|
||||
lastDetermineBasalAdapter = determineBasalAdapterSMBJS
|
||||
lastAPSResult = determineBasalResultSMB as DetermineBasalResultSMB
|
||||
lastAPSRun = now
|
||||
}
|
||||
}
|
||||
|
@ -204,4 +227,6 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
value.set(aapsLogger, false)
|
||||
return value
|
||||
}
|
||||
|
||||
fun provideDetermineBasalAdapter(): DetermineBasalAdapterInterface = DetermineBasalAdapterSMBJS(ScriptReader(context), injector)
|
||||
}
|
|
@ -0,0 +1,298 @@
|
|||
package info.nightscout.androidaps.plugins.aps.openAPSSMBAutoISF
|
||||
|
||||
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.extensions.convertedToAbsolute
|
||||
import info.nightscout.androidaps.extensions.getPassedDurationToTimeInMinutes
|
||||
import info.nightscout.androidaps.extensions.plannedRemainingMinutes
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.GlucoseUnit
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.interfaces.Profile
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.aps.logger.LoggerCallback
|
||||
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader
|
||||
import info.nightscout.androidaps.interfaces.DetermineBasalAdapterInterface
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.DetermineBasalResultSMB
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.SMBDefaults
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.stats.TddCalculator
|
||||
import info.nightscout.shared.SafeParse
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.logging.LTag
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import org.mozilla.javascript.*
|
||||
import org.mozilla.javascript.Function
|
||||
import java.io.IOException
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.nio.charset.StandardCharsets
|
||||
import javax.inject.Inject
|
||||
|
||||
class DetermineBasalAdapterSMBAutoISFJS internal constructor(private val scriptReader: ScriptReader, private val injector: HasAndroidInjector) : DetermineBasalAdapterInterface {
|
||||
|
||||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var rh: ResourceHelper
|
||||
@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 tddCalculator: TddCalculator
|
||||
|
||||
private var profile = JSONObject()
|
||||
private var mGlucoseStatus = JSONObject()
|
||||
private var iobData: JSONArray? = null
|
||||
private var mealData = JSONObject()
|
||||
private var currentTemp = JSONObject()
|
||||
private var autosensData = JSONObject()
|
||||
private var microBolusAllowed = false
|
||||
private var smbAlwaysAllowed = false
|
||||
private var currentTime: Long = 0
|
||||
private var saveCgmSource = false
|
||||
private var lastBolusNormalTime: Long = 0
|
||||
|
||||
override var currentTempParam: String? = null
|
||||
override var iobDataParam: String? = null
|
||||
override var glucoseStatusParam: String? = null
|
||||
override var profileParam: String? = null
|
||||
override var mealDataParam: String? = null
|
||||
override var scriptDebug = ""
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
override operator fun invoke(): DetermineBasalResultSMB? {
|
||||
aapsLogger.debug(LTag.APS, ">>> Invoking determine_basal <<<")
|
||||
aapsLogger.debug(LTag.APS, "Glucose status: " + mGlucoseStatus.toString().also { glucoseStatusParam = it })
|
||||
aapsLogger.debug(LTag.APS, "IOB data: " + iobData.toString().also { iobDataParam = it })
|
||||
aapsLogger.debug(LTag.APS, "Current temp: " + currentTemp.toString().also { currentTempParam = it })
|
||||
aapsLogger.debug(LTag.APS, "Profile: " + profile.toString().also { profileParam = it })
|
||||
aapsLogger.debug(LTag.APS, "Meal data: " + mealData.toString().also { mealDataParam = it })
|
||||
aapsLogger.debug(LTag.APS, "Autosens data: $autosensData")
|
||||
aapsLogger.debug(LTag.APS, "Reservoir data: " + "undefined")
|
||||
aapsLogger.debug(LTag.APS, "MicroBolusAllowed: $microBolusAllowed")
|
||||
aapsLogger.debug(LTag.APS, "SMBAlwaysAllowed: $smbAlwaysAllowed")
|
||||
aapsLogger.debug(LTag.APS, "CurrentTime: $currentTime")
|
||||
aapsLogger.debug(LTag.APS, "isSaveCgmSource: $saveCgmSource")
|
||||
var determineBasalResultSMB: DetermineBasalResultSMB? = null
|
||||
val rhino = Context.enter()
|
||||
val scope: Scriptable = rhino.initStandardObjects()
|
||||
// Turn off optimization to make Rhino Android compatible
|
||||
rhino.optimizationLevel = -1
|
||||
try {
|
||||
|
||||
//register logger callback for console.log and console.error
|
||||
ScriptableObject.defineClass(scope, LoggerCallback::class.java)
|
||||
val myLogger = rhino.newObject(scope, "LoggerCallback", null)
|
||||
scope.put("console2", scope, myLogger)
|
||||
rhino.evaluateString(scope, readFile("OpenAPSAMA/loggerhelper.js"), "JavaScript", 0, null)
|
||||
|
||||
//set module parent
|
||||
rhino.evaluateString(scope, "var module = {\"parent\":Boolean(1)};", "JavaScript", 0, null)
|
||||
rhino.evaluateString(scope, "var round_basal = function round_basal(basal, profile) { return basal; };", "JavaScript", 0, null)
|
||||
rhino.evaluateString(scope, "require = function() {return round_basal;};", "JavaScript", 0, null)
|
||||
|
||||
//generate functions "determine_basal" and "setTempBasal"
|
||||
rhino.evaluateString(scope, readFile("OpenAPSSMBAutoISF/determine-basal.js"), "JavaScript", 0, null)
|
||||
rhino.evaluateString(scope, readFile("OpenAPSSMB/basal-set-temp.js"), "setTempBasal.js", 0, null)
|
||||
val determineBasalObj = scope["determine_basal", scope]
|
||||
val setTempBasalFunctionsObj = scope["tempBasalFunctions", scope]
|
||||
|
||||
//call determine-basal
|
||||
if (determineBasalObj is Function && setTempBasalFunctionsObj is NativeObject) {
|
||||
|
||||
//prepare parameters
|
||||
val params = arrayOf(
|
||||
makeParam(mGlucoseStatus, rhino, scope),
|
||||
makeParam(currentTemp, rhino, scope),
|
||||
makeParamArray(iobData, rhino, scope),
|
||||
makeParam(profile, rhino, scope),
|
||||
makeParam(autosensData, rhino, scope),
|
||||
makeParam(mealData, rhino, scope),
|
||||
setTempBasalFunctionsObj,
|
||||
java.lang.Boolean.valueOf(microBolusAllowed),
|
||||
makeParam(null, rhino, scope), // reservoir data as undefined
|
||||
java.lang.Long.valueOf(currentTime),
|
||||
java.lang.Boolean.valueOf(saveCgmSource)
|
||||
)
|
||||
val jsResult = determineBasalObj.call(rhino, scope, scope, params) as NativeObject
|
||||
scriptDebug = LoggerCallback.scriptDebug
|
||||
|
||||
// Parse the jsResult object to a JSON-String
|
||||
val result = NativeJSON.stringify(rhino, scope, jsResult, null, null).toString()
|
||||
aapsLogger.debug(LTag.APS, "Result: $result")
|
||||
try {
|
||||
val resultJson = JSONObject(result)
|
||||
determineBasalResultSMB = DetermineBasalResultSMB(injector, resultJson)
|
||||
} catch (e: JSONException) {
|
||||
aapsLogger.error(LTag.APS, "Unhandled exception", e)
|
||||
}
|
||||
} else {
|
||||
aapsLogger.error(LTag.APS, "Problem loading JS Functions")
|
||||
}
|
||||
} catch (e: IOException) {
|
||||
aapsLogger.error(LTag.APS, "IOException")
|
||||
} catch (e: RhinoException) {
|
||||
aapsLogger.error(LTag.APS, "RhinoException: (" + e.lineNumber() + "," + e.columnNumber() + ") " + e.toString())
|
||||
} catch (e: IllegalAccessException) {
|
||||
aapsLogger.error(LTag.APS, e.toString())
|
||||
} catch (e: InstantiationException) {
|
||||
aapsLogger.error(LTag.APS, e.toString())
|
||||
} catch (e: InvocationTargetException) {
|
||||
aapsLogger.error(LTag.APS, e.toString())
|
||||
} finally {
|
||||
Context.exit()
|
||||
}
|
||||
glucoseStatusParam = mGlucoseStatus.toString()
|
||||
iobDataParam = iobData.toString()
|
||||
currentTempParam = currentTemp.toString()
|
||||
profileParam = profile.toString()
|
||||
mealDataParam = mealData.toString()
|
||||
return determineBasalResultSMB
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
override fun setData(
|
||||
profile: Profile,
|
||||
maxIob: Double,
|
||||
maxBasal: Double,
|
||||
minBg: Double,
|
||||
maxBg: Double,
|
||||
targetBg: Double,
|
||||
basalRate: Double,
|
||||
iobArray: Array<IobTotal>,
|
||||
glucoseStatus: GlucoseStatus,
|
||||
mealData: MealData,
|
||||
autosensDataRatio: Double,
|
||||
tempTargetSet: Boolean,
|
||||
microBolusAllowed: Boolean,
|
||||
uamAllowed: Boolean,
|
||||
advancedFiltering: Boolean,
|
||||
isSaveCgmSource: Boolean
|
||||
) {
|
||||
val pump = activePlugin.activePump
|
||||
val pumpBolusStep = pump.pumpDescription.bolusStep
|
||||
this.profile.put("max_iob", maxIob)
|
||||
//mProfile.put("dia", profile.getDia());
|
||||
this.profile.put("type", "current")
|
||||
this.profile.put("max_daily_basal", profile.getMaxDailyBasal())
|
||||
this.profile.put("max_basal", maxBasal)
|
||||
this.profile.put("min_bg", minBg)
|
||||
this.profile.put("max_bg", maxBg)
|
||||
this.profile.put("target_bg", targetBg)
|
||||
this.profile.put("carb_ratio", profile.getIc())
|
||||
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("current_basal_safety_multiplier", sp.getDouble(R.string.key_openapsama_current_basal_safety_multiplier, 4.0))
|
||||
|
||||
//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", false)
|
||||
//mProfile.put("low_temptarget_lowers_sensitivity", SP.getBoolean(R.string.key_low_temptarget_lowers_sensitivity, SMBDefaults.low_temptarget_lowers_sensitivity));
|
||||
this.profile.put("low_temptarget_lowers_sensitivity", false)
|
||||
this.profile.put("sensitivity_raises_target", sp.getBoolean(R.string.key_sensitivity_raises_target, SMBDefaults.sensitivity_raises_target))
|
||||
this.profile.put("resistance_lowers_target", sp.getBoolean(R.string.key_resistance_lowers_target, SMBDefaults.resistance_lowers_target))
|
||||
this.profile.put("adv_target_adjustments", SMBDefaults.adv_target_adjustments)
|
||||
this.profile.put("exercise_mode", SMBDefaults.exercise_mode)
|
||||
this.profile.put("half_basal_exercise_target", SMBDefaults.half_basal_exercise_target)
|
||||
this.profile.put("maxCOB", SMBDefaults.maxCOB)
|
||||
this.profile.put("skip_neutral_temps", pump.setNeutralTempAtFullHour())
|
||||
// min_5m_carbimpact is not used within SMB determinebasal
|
||||
//if (mealData.usedMinCarbsImpact > 0) {
|
||||
// mProfile.put("min_5m_carbimpact", mealData.usedMinCarbsImpact);
|
||||
//} else {
|
||||
// mProfile.put("min_5m_carbimpact", SP.getDouble(R.string.key_openapsama_min_5m_carbimpact, SMBDefaults.min_5m_carbimpact));
|
||||
//}
|
||||
this.profile.put("remainingCarbsCap", SMBDefaults.remainingCarbsCap)
|
||||
this.profile.put("enableUAM", uamAllowed)
|
||||
this.profile.put("A52_risk_enable", SMBDefaults.A52_risk_enable)
|
||||
val smbEnabled = sp.getBoolean(R.string.key_use_smb, false)
|
||||
this.profile.put("SMBInterval", sp.getInt(R.string.key_smbinterval, SMBDefaults.SMBInterval))
|
||||
this.profile.put("enableSMB_with_COB", smbEnabled && sp.getBoolean(R.string.key_enableSMB_with_COB, false))
|
||||
this.profile.put("enableSMB_with_temptarget", smbEnabled && sp.getBoolean(R.string.key_enableSMB_with_temptarget, false))
|
||||
this.profile.put("allowSMB_with_high_temptarget", smbEnabled && sp.getBoolean(R.string.key_allowSMB_with_high_temptarget, false))
|
||||
this.profile.put("enableSMB_always", smbEnabled && sp.getBoolean(R.string.key_enableSMB_always, 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("maxUAMSMBBasalMinutes", sp.getInt(R.string.key_uamsmbmaxminutes, SMBDefaults.maxUAMSMBBasalMinutes))
|
||||
//set the min SMB amount to be the amount set by the pump.
|
||||
this.profile.put("bolus_increment", pumpBolusStep)
|
||||
this.profile.put("carbsReqThreshold", sp.getInt(R.string.key_carbsReqThreshold, SMBDefaults.carbsReqThreshold))
|
||||
this.profile.put("current_basal", basalRate)
|
||||
this.profile.put("temptargetSet", tempTargetSet)
|
||||
this.profile.put("autosens_max", SafeParse.stringToDouble(sp.getString(R.string.key_openapsama_autosens_max, "1.2")))
|
||||
if (profileFunction.getUnits() == GlucoseUnit.MMOL) {
|
||||
this.profile.put("out_units", "mmol/L")
|
||||
}
|
||||
val now = System.currentTimeMillis()
|
||||
val tb = iobCobCalculator.getTempBasalIncludingConvertedExtended(now)
|
||||
currentTemp.put("temp", "absolute")
|
||||
currentTemp.put("duration", tb?.plannedRemainingMinutes ?: 0)
|
||||
currentTemp.put("rate", tb?.convertedToAbsolute(now, profile) ?: 0.0)
|
||||
// as we have non default temps longer than 30 mintues
|
||||
if (tb != null) currentTemp.put("minutesrunning", tb.getPassedDurationToTimeInMinutes(now))
|
||||
|
||||
iobData = iobCobCalculator.convertToJSONArray(iobArray)
|
||||
mGlucoseStatus.put("glucose", glucoseStatus.glucose)
|
||||
mGlucoseStatus.put("noise", glucoseStatus.noise)
|
||||
if (sp.getBoolean(R.string.key_always_use_shortavg, false)) {
|
||||
mGlucoseStatus.put("delta", glucoseStatus.shortAvgDelta)
|
||||
} else {
|
||||
mGlucoseStatus.put("delta", glucoseStatus.delta)
|
||||
}
|
||||
|
||||
mGlucoseStatus.put("short_avgdelta", glucoseStatus.shortAvgDelta)
|
||||
mGlucoseStatus.put("long_avgdelta", glucoseStatus.longAvgDelta)
|
||||
mGlucoseStatus.put("date", glucoseStatus.date)
|
||||
this.mealData.put("carbs", mealData.carbs)
|
||||
this.mealData.put("mealCOB", mealData.mealCOB)
|
||||
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)
|
||||
|
||||
this.mealData.put("TDDAIMI7", tddCalculator.averageTDD(tddCalculator.calculate(7)).totalAmount)
|
||||
this.mealData.put("TDDPUMP", tddCalculator.calculateDaily().totalAmount)
|
||||
|
||||
if (constraintChecker.isAutosensModeEnabled().value()) {
|
||||
autosensData.put("ratio", autosensDataRatio)
|
||||
} else {
|
||||
autosensData.put("ratio", 1.0)
|
||||
}
|
||||
this.microBolusAllowed = microBolusAllowed
|
||||
smbAlwaysAllowed = advancedFiltering
|
||||
currentTime = now
|
||||
saveCgmSource = isSaveCgmSource
|
||||
}
|
||||
|
||||
private fun makeParam(jsonObject: JSONObject?, rhino: Context, scope: Scriptable): Any {
|
||||
return if (jsonObject == null) Undefined.instance
|
||||
else NativeJSON.parse(rhino, scope, jsonObject.toString()) { _: Context?, _: Scriptable?, _: Scriptable?, objects: Array<Any?> -> objects[1] }
|
||||
}
|
||||
|
||||
private fun makeParamArray(jsonArray: JSONArray?, rhino: Context, scope: Scriptable): Any {
|
||||
return NativeJSON.parse(rhino, scope, jsonArray.toString()) { _: Context?, _: Scriptable?, _: Scriptable?, objects: Array<Any?> -> objects[1] }
|
||||
}
|
||||
|
||||
@Throws(IOException::class) private fun readFile(filename: String): String {
|
||||
val bytes = scriptReader.readFile(filename)
|
||||
var string = String(bytes, StandardCharsets.UTF_8)
|
||||
if (string.startsWith("#!/usr/bin/env node")) {
|
||||
string = string.substring(20)
|
||||
}
|
||||
return string
|
||||
}
|
||||
|
||||
init {
|
||||
injector.androidInjector().inject(this)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,74 @@
|
|||
package info.nightscout.androidaps.plugins.aps.openAPSSMBAutoISF
|
||||
|
||||
import android.content.Context
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.androidaps.database.AppRepository
|
||||
import info.nightscout.androidaps.interfaces.ActivePlugin
|
||||
import info.nightscout.androidaps.interfaces.IobCobCalculator
|
||||
import info.nightscout.androidaps.interfaces.ProfileFunction
|
||||
import info.nightscout.androidaps.plugins.aps.loop.ScriptReader
|
||||
import info.nightscout.androidaps.interfaces.DetermineBasalAdapterInterface
|
||||
import info.nightscout.androidaps.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||
import info.nightscout.androidaps.plugins.bus.RxBus
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatusProvider
|
||||
import info.nightscout.androidaps.utils.DateUtil
|
||||
import info.nightscout.androidaps.utils.HardLimits
|
||||
import info.nightscout.androidaps.utils.Profiler
|
||||
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.shared.logging.AAPSLogger
|
||||
import info.nightscout.shared.sharedPreferences.SP
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
@OpenForTesting
|
||||
@Singleton
|
||||
class OpenAPSSMBAutoISFPlugin @Inject constructor(
|
||||
injector: HasAndroidInjector,
|
||||
aapsLogger: AAPSLogger,
|
||||
rxBus: RxBus,
|
||||
constraintChecker: ConstraintChecker,
|
||||
rh: ResourceHelper,
|
||||
profileFunction: ProfileFunction,
|
||||
context: Context,
|
||||
activePlugin: ActivePlugin,
|
||||
iobCobCalculator: IobCobCalculator,
|
||||
hardLimits: HardLimits,
|
||||
profiler: Profiler,
|
||||
sp: SP,
|
||||
dateUtil: DateUtil,
|
||||
repository: AppRepository,
|
||||
glucoseStatusProvider: GlucoseStatusProvider,
|
||||
private val buildHelper: BuildHelper
|
||||
) : OpenAPSSMBPlugin(
|
||||
injector,
|
||||
aapsLogger,
|
||||
rxBus,
|
||||
constraintChecker,
|
||||
rh,
|
||||
profileFunction,
|
||||
context,
|
||||
activePlugin,
|
||||
iobCobCalculator,
|
||||
hardLimits,
|
||||
profiler,
|
||||
sp,
|
||||
dateUtil,
|
||||
repository,
|
||||
glucoseStatusProvider
|
||||
) {
|
||||
|
||||
init {
|
||||
pluginDescription
|
||||
.pluginName(R.string.openapssmbautoisf)
|
||||
.description(R.string.description_smb_auto_isf)
|
||||
.setDefault(false)
|
||||
}
|
||||
|
||||
override fun specialEnableCondition(): Boolean = buildHelper.isEngineeringMode() && buildHelper.isDev()
|
||||
|
||||
override fun provideDetermineBasalAdapter(): DetermineBasalAdapterInterface = DetermineBasalAdapterSMBAutoISFJS(ScriptReader(context), injector)
|
||||
}
|
|
@ -96,7 +96,6 @@ class TddCalculator @Inject constructor(
|
|||
//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)
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
<string name="description_ns_client">Synchronizes your data with Nightscout</string>
|
||||
<string name="description_ama">State of the algorithm in 2017</string>
|
||||
<string name="description_smb">Most recent algorithm for advanced users</string>
|
||||
<string name="description_smb_auto_isf">Most recent algorithm for advanced users with automatic ISF</string>
|
||||
<string name="description_overview">Displays the current state of your loop and buttons for most common actions</string>
|
||||
<string name="description_persistent_notification">Shows an ongoing notification with a short overview of what your loop is doing</string>
|
||||
<string name="description_profile_local">Define a profile which is available offline.</string>
|
||||
|
@ -535,6 +536,7 @@
|
|||
<string name="ns_localbroadcasts">Enable broadcasts to other apps (like xDrip+). Do not enable if you have more than one instance of AAPS or NSClient installed!</string>
|
||||
<string name="ns_localbroadcasts_title">Enable local Broadcasts.</string>
|
||||
<string name="openapssmb">OpenAPS SMB</string>
|
||||
<string name="openapssmbautoisf">OpenAPS SMB Auto ISF</string>
|
||||
<string name="key_use_smb" translatable="false">use_smb</string>
|
||||
<string name="key_use_uam" translatable="false">use_uam</string>
|
||||
<string name="key_smb_enable_carbs_suggestions_threshold" translatable="false">smb_enable_carbs_suggestions_threshold</string>
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package info.nightscout.androidaps.interfaces
|
||||
|
||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.AutosensResult
|
||||
|
||||
interface APS {
|
||||
|
||||
val lastAPSResult: APSResult?
|
||||
val lastAPSRun: Long
|
||||
var lastDetermineBasalAdapter: DetermineBasalAdapterInterface?
|
||||
var lastAutosensResult: AutosensResult
|
||||
|
||||
operator fun invoke(initiator: String, tempBasalFallback: Boolean)
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
package info.nightscout.androidaps.interfaces
|
||||
|
||||
import info.nightscout.androidaps.data.IobTotal
|
||||
import info.nightscout.androidaps.data.MealData
|
||||
import info.nightscout.androidaps.plugins.aps.loop.APSResult
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
|
||||
interface DetermineBasalAdapterInterface {
|
||||
|
||||
var currentTempParam: String?
|
||||
var iobDataParam: String?
|
||||
var glucoseStatusParam: String?
|
||||
var profileParam: String?
|
||||
var mealDataParam: String?
|
||||
var scriptDebug: String
|
||||
|
||||
fun setData(profile: Profile,
|
||||
maxIob: Double,
|
||||
maxBasal: Double,
|
||||
minBg: Double,
|
||||
maxBg: Double,
|
||||
targetBg: Double,
|
||||
basalRate: Double,
|
||||
iobArray: Array<IobTotal>,
|
||||
glucoseStatus: GlucoseStatus,
|
||||
mealData: MealData,
|
||||
autosensDataRatio: Double,
|
||||
tempTargetSet: Boolean,
|
||||
microBolusAllowed: Boolean = false,
|
||||
uamAllowed: Boolean = false,
|
||||
advancedFiltering: Boolean = false,
|
||||
isSaveCgmSource: Boolean = false
|
||||
) {}
|
||||
|
||||
operator fun invoke(): APSResult?
|
||||
}
|
|
@ -35,5 +35,5 @@ class PluginDescription {
|
|||
fun enableByDefault(enableByDefault: Boolean): PluginDescription = this.also { it.enableByDefault = enableByDefault }
|
||||
fun visibleByDefault(visibleByDefault: Boolean): PluginDescription = this.also { it.visibleByDefault = visibleByDefault }
|
||||
fun description(description: Int): PluginDescription = this.also { it.description = description }
|
||||
fun setDefault(): PluginDescription = this.also { it.defaultPlugin = true }
|
||||
fun setDefault(value: Boolean = true): PluginDescription = this.also { it.defaultPlugin = value }
|
||||
}
|
Loading…
Reference in a new issue