Enable DynISF, fallback to SMB with no tdd data, new objective to enable DynISF
This commit is contained in:
parent
f870fbc618
commit
8d05588f11
17 changed files with 145 additions and 66 deletions
|
@ -11,8 +11,8 @@ import info.nightscout.androidaps.insight.database.InsightDatabaseDao
|
|||
import info.nightscout.androidaps.insight.database.InsightDbHelper
|
||||
import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.implementation.iob.GlucoseStatusProviderImpl
|
||||
import info.nightscout.interfaces.ApsMode
|
||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||
import info.nightscout.interfaces.constraints.Constraint
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
|
@ -29,6 +29,7 @@ import info.nightscout.interfaces.pump.PumpSync
|
|||
import info.nightscout.interfaces.pump.TemporaryBasalStorage
|
||||
import info.nightscout.interfaces.pump.defs.PumpDescription
|
||||
import info.nightscout.interfaces.queue.CommandQueue
|
||||
import info.nightscout.interfaces.stats.TddCalculator
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.HardLimits
|
||||
import info.nightscout.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
|
||||
|
@ -75,6 +76,7 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
@Mock lateinit var danaHistoryDatabase: DanaHistoryDatabase
|
||||
@Mock lateinit var insightDatabase: InsightDatabase
|
||||
@Mock lateinit var bgQualityCheck: BgQualityCheck
|
||||
@Mock lateinit var tddCalculator: TddCalculator
|
||||
|
||||
private lateinit var hardLimits: HardLimits
|
||||
private lateinit var danaPump: DanaPump
|
||||
|
@ -190,7 +192,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
dateUtil,
|
||||
repository,
|
||||
glucoseStatusProvider,
|
||||
bgQualityCheck
|
||||
bgQualityCheck,
|
||||
tddCalculator
|
||||
)
|
||||
openAPSSMBDynamicISFPlugin =
|
||||
OpenAPSSMBDynamicISFPlugin(
|
||||
|
@ -209,8 +212,8 @@ class ConstraintsCheckerTest : TestBaseWithProfile() {
|
|||
dateUtil,
|
||||
repository,
|
||||
glucoseStatusProvider,
|
||||
config,
|
||||
bgQualityCheck
|
||||
bgQualityCheck,
|
||||
tddCalculator
|
||||
)
|
||||
openAPSAMAPlugin =
|
||||
OpenAPSAMAPlugin(
|
||||
|
|
|
@ -15,6 +15,7 @@ import info.nightscout.interfaces.plugin.ActivePlugin
|
|||
import info.nightscout.interfaces.plugin.PluginType
|
||||
import info.nightscout.interfaces.profiling.Profiler
|
||||
import info.nightscout.interfaces.pump.defs.PumpDescription
|
||||
import info.nightscout.interfaces.stats.TddCalculator
|
||||
import info.nightscout.interfaces.ui.UiInteraction
|
||||
import info.nightscout.interfaces.utils.HardLimits
|
||||
import info.nightscout.plugins.aps.openAPSAMA.OpenAPSAMAPlugin
|
||||
|
@ -41,6 +42,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
@Mock lateinit var glucoseStatusProvider: GlucoseStatusProvider
|
||||
@Mock lateinit var bgQualityCheck: BgQualityCheck
|
||||
@Mock lateinit var uiInteraction: UiInteraction
|
||||
@Mock lateinit var tddCalculator: TddCalculator
|
||||
|
||||
private lateinit var hardLimits: HardLimits
|
||||
private lateinit var safetyPlugin: SafetyPlugin
|
||||
|
@ -84,7 +86,7 @@ class SafetyPluginTest : TestBaseWithProfile() {
|
|||
)
|
||||
openAPSSMBPlugin = OpenAPSSMBPlugin(
|
||||
injector, aapsLogger, rxBus, constraintChecker, rh, profileFunction, context, activePlugin, iobCobCalculator, hardLimits, profiler, sp,
|
||||
dateUtil, repository, glucoseStatusProvider, bgQualityCheck
|
||||
dateUtil, repository, glucoseStatusProvider, bgQualityCheck, tddCalculator
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,12 @@ interface DetermineBasalAdapter {
|
|||
microBolusAllowed: Boolean = false,
|
||||
uamAllowed: Boolean = false,
|
||||
advancedFiltering: Boolean = false,
|
||||
flatBGsDetected: Boolean = false
|
||||
flatBGsDetected: Boolean = false,
|
||||
tdd1D: Double?,
|
||||
tdd7D: Double?,
|
||||
tddLast24H: Double?,
|
||||
tddLast4H: Double?,
|
||||
tddLast8to4H: Double?
|
||||
)
|
||||
|
||||
operator fun invoke(): APSResult?
|
||||
|
|
|
@ -21,6 +21,7 @@ interface Constraints {
|
|||
fun isLgsAllowed(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isAutosensModeEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isSMBModeEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isDynIsfModeEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isUAMEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isAdvancedFilteringEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
fun isSuperBolusEnabled(value: Constraint<Boolean> = Constraint(true)): Constraint<Boolean> = value
|
||||
|
|
|
@ -13,6 +13,7 @@ interface Objectives {
|
|||
const val AUTOSENS_OBJECTIVE = 7
|
||||
const val SMB_OBJECTIVE = 8
|
||||
const val AUTO_OBJECTIVE = 9
|
||||
const val DYN_ISF_OBJECTIVE = 10
|
||||
}
|
||||
|
||||
fun isAccomplished(index: Int): Boolean
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.plugins.aps.openAPSAMA
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.plugins.aps.APSResultObject
|
||||
import info.nightscout.core.extensions.convertedToAbsolute
|
||||
import info.nightscout.core.extensions.getPassedDurationToTimeInMinutes
|
||||
import info.nightscout.core.extensions.plannedRemainingMinutes
|
||||
|
@ -15,6 +14,7 @@ import info.nightscout.interfaces.iob.IobTotal
|
|||
import info.nightscout.interfaces.iob.MealData
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.plugins.aps.APSResultObject
|
||||
import info.nightscout.plugins.aps.R
|
||||
import info.nightscout.plugins.aps.logger.LoggerCallback
|
||||
import info.nightscout.plugins.aps.utils.ScriptReader
|
||||
|
@ -162,7 +162,12 @@ class DetermineBasalAdapterAMAJS internal constructor(scriptReader: ScriptReader
|
|||
microBolusAllowed: Boolean,
|
||||
uamAllowed: Boolean,
|
||||
advancedFiltering: Boolean,
|
||||
flatBGsDetected: Boolean
|
||||
flatBGsDetected: Boolean,
|
||||
tdd1D: Double?,
|
||||
tdd7D: Double?,
|
||||
tddLast24H: Double?,
|
||||
tddLast4H: Double?,
|
||||
tddLast8to4H: Double?
|
||||
) {
|
||||
this.profile = JSONObject()
|
||||
this.profile.put("max_iob", maxIob)
|
||||
|
|
|
@ -181,7 +181,12 @@ class OpenAPSAMAPlugin @Inject constructor(
|
|||
determineBasalAdapterAMAJS.setData(
|
||||
profile, maxIob, maxBasal, minBg, maxBg, targetBg, activePlugin.activePump.baseBasalRate, iobArray, glucoseStatus, mealData,
|
||||
lastAutosensResult.ratio,
|
||||
isTempTarget
|
||||
isTempTarget,
|
||||
tdd1D = null,
|
||||
tdd7D = null,
|
||||
tddLast4H = null,
|
||||
tddLast8to4H = null,
|
||||
tddLast24H = null,
|
||||
)
|
||||
} catch (e: JSONException) {
|
||||
fabricPrivacy.logException(e)
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package info.nightscout.plugins.aps.openAPSSMB
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.plugins.aps.APSResultObject
|
||||
import info.nightscout.core.extensions.convertedToAbsolute
|
||||
import info.nightscout.core.extensions.getPassedDurationToTimeInMinutes
|
||||
import info.nightscout.core.extensions.plannedRemainingMinutes
|
||||
|
@ -16,6 +15,7 @@ import info.nightscout.interfaces.iob.MealData
|
|||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.plugins.aps.APSResultObject
|
||||
import info.nightscout.plugins.aps.R
|
||||
import info.nightscout.plugins.aps.logger.LoggerCallback
|
||||
import info.nightscout.plugins.aps.utils.ScriptReader
|
||||
|
@ -174,7 +174,12 @@ class DetermineBasalAdapterSMBJS internal constructor(private val scriptReader:
|
|||
microBolusAllowed: Boolean,
|
||||
uamAllowed: Boolean,
|
||||
advancedFiltering: Boolean,
|
||||
flatBGsDetected: Boolean
|
||||
flatBGsDetected: Boolean,
|
||||
tdd1D: Double?,
|
||||
tdd7D: Double?,
|
||||
tddLast24H: Double?,
|
||||
tddLast4H: Double?,
|
||||
tddLast8to4H: Double?
|
||||
) {
|
||||
val pump = activePlugin.activePump
|
||||
val pumpBolusStep = pump.pumpDescription.bolusStep
|
||||
|
|
|
@ -25,6 +25,7 @@ import info.nightscout.interfaces.plugin.PluginType
|
|||
import info.nightscout.interfaces.profile.Profile
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.profiling.Profiler
|
||||
import info.nightscout.interfaces.stats.TddCalculator
|
||||
import info.nightscout.interfaces.utils.HardLimits
|
||||
import info.nightscout.interfaces.utils.Round
|
||||
import info.nightscout.plugins.aps.R
|
||||
|
@ -57,7 +58,8 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
private val dateUtil: DateUtil,
|
||||
private val repository: AppRepository,
|
||||
private val glucoseStatusProvider: GlucoseStatusProvider,
|
||||
private val bgQualityCheck: BgQualityCheck
|
||||
private val bgQualityCheck: BgQualityCheck,
|
||||
private val tddCalculator: TddCalculator
|
||||
) : PluginBase(
|
||||
PluginDescription()
|
||||
.mainType(PluginType.APS)
|
||||
|
@ -71,6 +73,14 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
aapsLogger, rh, injector
|
||||
), APS, Constraints {
|
||||
|
||||
// DynamicISF specific
|
||||
var tdd1D : Double? = null
|
||||
var tdd7D : Double? = null
|
||||
var tddLast24H : Double? = null
|
||||
var tddLast4H : Double? = null
|
||||
var tddLast8to4H : Double? = null
|
||||
var dynIsfEnabled : Constraint<Boolean> = Constraint(false)
|
||||
|
||||
// last values
|
||||
override var lastAPSRun: Long = 0
|
||||
override var lastAPSResult: DetermineBasalResultSMB? = null
|
||||
|
@ -193,11 +203,24 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
constraintChecker.isUAMEnabled(it)
|
||||
inputConstraints.copyReasons(it)
|
||||
}
|
||||
dynIsfEnabled = Constraint(true).also {
|
||||
constraintChecker.isDynIsfModeEnabled(it)
|
||||
inputConstraints.copyReasons(it)
|
||||
}
|
||||
val flatBGsDetected = bgQualityCheck.state == BgQualityCheck.State.FLAT
|
||||
profiler.log(LTag.APS, "detectSensitivityAndCarbAbsorption()", startPart)
|
||||
profiler.log(LTag.APS, "SMB data gathering", start)
|
||||
start = System.currentTimeMillis()
|
||||
|
||||
// DynamicISF specific
|
||||
// without these values DynISF doesn't work properly
|
||||
// Current implementation is fallback to SMB if TDD history is not available. Thus calculated here
|
||||
tdd1D = tddCalculator.averageTDD(tddCalculator.calculate(1, allowMissingDays = false))?.totalAmount
|
||||
tdd7D = tddCalculator.averageTDD(tddCalculator.calculate(7, allowMissingDays = false))?.totalAmount
|
||||
tddLast24H = tddCalculator.calculateDaily(-24, 0)?.totalAmount
|
||||
tddLast4H = tddCalculator.calculateDaily(-4, 0)?.totalAmount
|
||||
tddLast8to4H = tddCalculator.calculateDaily(-8, -4)?.totalAmount
|
||||
|
||||
provideDetermineBasalAdapter().also { determineBasalAdapterSMBJS ->
|
||||
determineBasalAdapterSMBJS.setData(
|
||||
profile, maxIob, maxBasal, minBg, maxBg, targetBg,
|
||||
|
@ -210,7 +233,12 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
smbAllowed.value(),
|
||||
uam.value(),
|
||||
advancedFiltering.value(),
|
||||
flatBGsDetected
|
||||
flatBGsDetected,
|
||||
tdd1D = tdd1D,
|
||||
tdd7D = tdd7D,
|
||||
tddLast24H = tddLast24H,
|
||||
tddLast4H = tddLast4H,
|
||||
tddLast8to4H = tddLast8to4H
|
||||
)
|
||||
val now = System.currentTimeMillis()
|
||||
val determineBasalResultSMB = determineBasalAdapterSMBJS.invoke()
|
||||
|
@ -243,7 +271,7 @@ class OpenAPSSMBPlugin @Inject constructor(
|
|||
|
||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
||||
if (isEnabled()) {
|
||||
val maxIobPref: Double = sp.getDouble(info.nightscout.plugins.aps.R.string.key_openapssmb_max_iob, 3.0)
|
||||
val maxIobPref: Double = sp.getDouble(R.string.key_openapssmb_max_iob, 3.0)
|
||||
maxIob.setIfSmaller(aapsLogger, maxIobPref, rh.gs(R.string.limiting_iob, maxIobPref, rh.gs(R.string.maxvalueinpreferences)), this)
|
||||
maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobSMB(), rh.gs(R.string.limiting_iob, hardLimits.maxIobSMB(), rh.gs(R.string.hardlimit)), this)
|
||||
}
|
||||
|
|
|
@ -14,7 +14,6 @@ import info.nightscout.interfaces.iob.MealData
|
|||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.Profile
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.stats.TddCalculator
|
||||
import info.nightscout.interfaces.utils.Round
|
||||
import info.nightscout.plugins.aps.R
|
||||
import info.nightscout.plugins.aps.logger.LoggerCallback
|
||||
|
@ -38,6 +37,7 @@ import org.mozilla.javascript.Undefined
|
|||
import java.io.IOException
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.security.InvalidParameterException
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.ln
|
||||
|
||||
|
@ -48,7 +48,6 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
|
|||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var iobCobCalculator: IobCobCalculator
|
||||
@Inject lateinit var activePlugin: ActivePlugin
|
||||
@Inject lateinit var tddCalculator: TddCalculator
|
||||
|
||||
private var profile = JSONObject()
|
||||
private var mGlucoseStatus = JSONObject()
|
||||
|
@ -176,8 +175,19 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
|
|||
microBolusAllowed: Boolean,
|
||||
uamAllowed: Boolean,
|
||||
advancedFiltering: Boolean,
|
||||
flatBGsDetected: Boolean
|
||||
flatBGsDetected: Boolean,
|
||||
tdd1D: Double?,
|
||||
tdd7D: Double?,
|
||||
tddLast24H: Double?,
|
||||
tddLast4H: Double?,
|
||||
tddLast8to4H: Double?
|
||||
) {
|
||||
tdd1D ?: throw InvalidParameterException()
|
||||
tdd7D ?: throw InvalidParameterException()
|
||||
tddLast24H ?: throw InvalidParameterException()
|
||||
tddLast4H ?: throw InvalidParameterException()
|
||||
tddLast8to4H ?: throw InvalidParameterException()
|
||||
|
||||
val pump = activePlugin.activePump
|
||||
val pumpBolusStep = pump.pumpDescription.bolusStep
|
||||
this.profile.put("max_iob", maxIob)
|
||||
|
@ -262,12 +272,6 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
|
|||
this.mealData.put("lastBolusTime", mealData.lastBolusTime)
|
||||
this.mealData.put("lastCarbTime", mealData.lastCarbTime)
|
||||
|
||||
val tdd1D = tddCalculator.averageTDD(tddCalculator.calculate(1, allowMissingDays = false))?.totalAmount
|
||||
val tdd7D = tddCalculator.averageTDD(tddCalculator.calculate(7, allowMissingDays = false))?.totalAmount
|
||||
val tddLast24H = tddCalculator.calculateDaily(-24, 0)?.totalAmount
|
||||
val tddLast4H = tddCalculator.calculateDaily(-4, 0)?.totalAmount
|
||||
val tddLast8to4H = tddCalculator.calculateDaily(-8, -4)?.totalAmount
|
||||
|
||||
val insulin = activePlugin.activeInsulin
|
||||
val insulinDivisor = when {
|
||||
insulin.peak > 65 -> 55 // lyumjev peak: 45
|
||||
|
@ -275,34 +279,19 @@ class DetermineBasalAdapterSMBDynamicISFJS internal constructor(private val scri
|
|||
else -> 75 // rapid peak: 75
|
||||
}
|
||||
|
||||
var tdd: Double? = null
|
||||
var variableSensitivity: Double
|
||||
if (tddLast24H != null && tddLast4H != null && tddLast8to4H != null) {
|
||||
val tddWeightedFromLast8H = ((1.4 * tddLast4H) + (0.6 * tddLast8to4H)) * 3
|
||||
// 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 + "; ");
|
||||
val tddWeightedFromLast8H = ((1.4 * tddLast4H) + (0.6 * tddLast8to4H)) * 3
|
||||
var tdd = (tddWeightedFromLast8H * 0.33) + (tdd7D * 0.34) + (tdd1D * 0.33)
|
||||
val dynISFadjust = SafeParse.stringToDouble(sp.getString(R.string.key_DynISFAdjust, "100")) / 100.0
|
||||
tdd *= dynISFadjust
|
||||
|
||||
tdd =
|
||||
if (tdd1D != null && tdd7D != null) (tddWeightedFromLast8H * 0.33) + (tdd7D * 0.34) + (tdd1D * 0.33)
|
||||
else tddWeightedFromLast8H
|
||||
// console.log("TDD = " + TDD + " using average of 7-day, 1-day and weighted 8hr average");
|
||||
|
||||
val dynISFadjust = SafeParse.stringToDouble(sp.getString(R.string.key_DynISFAdjust, "100")) / 100.0
|
||||
tdd *= dynISFadjust
|
||||
|
||||
variableSensitivity = 1800 / (tdd * (ln((glucoseStatus.glucose / insulinDivisor) + 1)))
|
||||
variableSensitivity = Round.roundTo(variableSensitivity, 0.1)
|
||||
} else {
|
||||
variableSensitivity = profile.getIsfMgdl()
|
||||
}
|
||||
val variableSensitivity = Round.roundTo(1800 / (tdd * (ln((glucoseStatus.glucose / insulinDivisor) + 1))), 0.1)
|
||||
|
||||
this.profile.put("variable_sens", variableSensitivity)
|
||||
this.profile.put("insulinDivisor", insulinDivisor)
|
||||
tdd?.let { this.profile.put("TDD", tdd) }
|
||||
this.profile.put("TDD", tdd)
|
||||
|
||||
|
||||
if (sp.getBoolean(R.string.key_adjust_sensitivity, false) && tdd7D != null && tddLast24H != null)
|
||||
if (sp.getBoolean(R.string.key_adjust_sensitivity, false))
|
||||
autosensData.put("ratio", tddLast24H / tdd7D)
|
||||
else
|
||||
autosensData.put("ratio", 1.0)
|
||||
|
|
|
@ -4,7 +4,6 @@ import android.content.Context
|
|||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.annotations.OpenForTesting
|
||||
import info.nightscout.database.impl.AppRepository
|
||||
import info.nightscout.interfaces.Config
|
||||
import info.nightscout.interfaces.aps.DetermineBasalAdapter
|
||||
import info.nightscout.interfaces.bgQualityCheck.BgQualityCheck
|
||||
import info.nightscout.interfaces.constraints.Constraints
|
||||
|
@ -13,8 +12,10 @@ import info.nightscout.interfaces.iob.IobCobCalculator
|
|||
import info.nightscout.interfaces.plugin.ActivePlugin
|
||||
import info.nightscout.interfaces.profile.ProfileFunction
|
||||
import info.nightscout.interfaces.profiling.Profiler
|
||||
import info.nightscout.interfaces.stats.TddCalculator
|
||||
import info.nightscout.interfaces.utils.HardLimits
|
||||
import info.nightscout.plugins.aps.R
|
||||
import info.nightscout.plugins.aps.openAPSSMB.DetermineBasalAdapterSMBJS
|
||||
import info.nightscout.plugins.aps.openAPSSMB.OpenAPSSMBPlugin
|
||||
import info.nightscout.plugins.aps.utils.ScriptReader
|
||||
import info.nightscout.rx.bus.RxBus
|
||||
|
@ -43,8 +44,8 @@ class OpenAPSSMBDynamicISFPlugin @Inject constructor(
|
|||
dateUtil: DateUtil,
|
||||
repository: AppRepository,
|
||||
glucoseStatusProvider: GlucoseStatusProvider,
|
||||
private val config: Config,
|
||||
private val bgQualityCheck: BgQualityCheck
|
||||
bgQualityCheck: BgQualityCheck,
|
||||
tddCalculator: TddCalculator
|
||||
) : OpenAPSSMBPlugin(
|
||||
injector,
|
||||
aapsLogger,
|
||||
|
@ -61,7 +62,8 @@ class OpenAPSSMBDynamicISFPlugin @Inject constructor(
|
|||
dateUtil,
|
||||
repository,
|
||||
glucoseStatusProvider,
|
||||
bgQualityCheck
|
||||
bgQualityCheck,
|
||||
tddCalculator
|
||||
) {
|
||||
|
||||
init {
|
||||
|
@ -71,10 +73,11 @@ class OpenAPSSMBDynamicISFPlugin @Inject constructor(
|
|||
.shortName(R.string.dynisf_shortname)
|
||||
.preferencesId(R.xml.pref_openapssmbdynamicisf)
|
||||
.setDefault(false)
|
||||
.showInList(config.isEngineeringMode() && config.isDev())
|
||||
}
|
||||
|
||||
override fun specialEnableCondition(): Boolean = config.isEngineeringMode() && config.isDev()
|
||||
|
||||
override fun provideDetermineBasalAdapter(): DetermineBasalAdapter = DetermineBasalAdapterSMBDynamicISFJS(ScriptReader(context), injector)
|
||||
// If there is no TDD data fallback to SMB as ISF calculation may be really off
|
||||
override fun provideDetermineBasalAdapter(): DetermineBasalAdapter =
|
||||
if (tdd1D == null || tdd7D == null || tddLast4H == null || tddLast8to4H == null || tddLast24H == null || !dynIsfEnabled.value())
|
||||
DetermineBasalAdapterSMBJS(ScriptReader(context), injector)
|
||||
else DetermineBasalAdapterSMBDynamicISFJS(ScriptReader(context), injector)
|
||||
}
|
|
@ -60,6 +60,16 @@ class ConstraintsImpl @Inject constructor(private val activePlugin: ActivePlugin
|
|||
return value
|
||||
}
|
||||
|
||||
override fun isDynIsfModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
val constraint = p as Constraints
|
||||
if (!p.isEnabled()) continue
|
||||
constraint.isDynIsfModeEnabled(value)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
override fun isUAMEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
val constraintsPlugins = activePlugin.getSpecificPluginsListByInterface(Constraints::class.java)
|
||||
for (p in constraintsPlugins) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import info.nightscout.plugins.constraints.objectives.objectives.Objective
|
|||
import info.nightscout.plugins.constraints.objectives.objectives.Objective0
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective1
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective10
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective11
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective2
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective3
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective4
|
||||
|
@ -36,4 +37,5 @@ abstract class ObjectivesModule {
|
|||
@ContributesAndroidInjector abstract fun objective7Injector(): Objective7
|
||||
@ContributesAndroidInjector abstract fun objective9Injector(): Objective9
|
||||
@ContributesAndroidInjector abstract fun objective10Injector(): Objective10
|
||||
@ContributesAndroidInjector abstract fun objective11Injector(): Objective11
|
||||
}
|
|
@ -7,6 +7,7 @@ import info.nightscout.interfaces.constraints.Constraints
|
|||
import info.nightscout.interfaces.constraints.Objectives
|
||||
import info.nightscout.interfaces.constraints.Objectives.Companion.AUTOSENS_OBJECTIVE
|
||||
import info.nightscout.interfaces.constraints.Objectives.Companion.AUTO_OBJECTIVE
|
||||
import info.nightscout.interfaces.constraints.Objectives.Companion.DYN_ISF_OBJECTIVE
|
||||
import info.nightscout.interfaces.constraints.Objectives.Companion.FIRST_OBJECTIVE
|
||||
import info.nightscout.interfaces.constraints.Objectives.Companion.MAXBASAL_OBJECTIVE
|
||||
import info.nightscout.interfaces.constraints.Objectives.Companion.MAXIOB_ZERO_CL_OBJECTIVE
|
||||
|
@ -20,6 +21,7 @@ import info.nightscout.plugins.constraints.objectives.objectives.Objective
|
|||
import info.nightscout.plugins.constraints.objectives.objectives.Objective0
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective1
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective10
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective11
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective2
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective3
|
||||
import info.nightscout.plugins.constraints.objectives.objectives.Objective4
|
||||
|
@ -76,6 +78,7 @@ class ObjectivesPlugin @Inject constructor(
|
|||
objectives.add(Objective7(injector))
|
||||
objectives.add(Objective9(injector))
|
||||
objectives.add(Objective10(injector))
|
||||
objectives.add(Objective11(injector))
|
||||
// edit companion object if you remove/add Objective
|
||||
}
|
||||
|
||||
|
@ -137,6 +140,12 @@ class ObjectivesPlugin @Inject constructor(
|
|||
return value
|
||||
}
|
||||
|
||||
override fun isDynIsfModeEnabled(value: Constraint<Boolean>): Constraint<Boolean> {
|
||||
if (!objectives[DYN_ISF_OBJECTIVE].isStarted)
|
||||
value.set(aapsLogger, false, rh.gs(R.string.objectivenotstarted, DYN_ISF_OBJECTIVE + 1), this)
|
||||
return value
|
||||
}
|
||||
|
||||
override fun applyMaxIOBConstraints(maxIob: Constraint<Double>): Constraint<Double> {
|
||||
if (objectives[MAXIOB_ZERO_CL_OBJECTIVE].isStarted && !objectives[MAXIOB_ZERO_CL_OBJECTIVE].isAccomplished)
|
||||
maxIob.set(aapsLogger, 0.0, rh.gs(R.string.objectivenotfinished, MAXIOB_ZERO_CL_OBJECTIVE + 1), this)
|
||||
|
|
|
@ -46,6 +46,7 @@ abstract class Objective(injector: HasAndroidInjector, spName: String, @StringRe
|
|||
}
|
||||
|
||||
init {
|
||||
@Suppress("LeakingThis")
|
||||
injector.androidInjector().inject(this)
|
||||
this.spName = spName
|
||||
this.objective = objective
|
||||
|
@ -70,10 +71,10 @@ abstract class Objective(injector: HasAndroidInjector, spName: String, @StringRe
|
|||
val isStarted: Boolean
|
||||
get() = startedOn != 0L
|
||||
|
||||
open fun specialActionEnabled(): Boolean {
|
||||
return true
|
||||
}
|
||||
@Suppress("unused")
|
||||
open fun specialActionEnabled(): Boolean = true
|
||||
|
||||
@Suppress("unused")
|
||||
open fun specialAction(activity: FragmentActivity, input: String) {}
|
||||
|
||||
abstract inner class Task(var objective: Objective, @StringRes val task: Int) {
|
||||
|
@ -157,7 +158,7 @@ abstract class Objective(injector: HasAndroidInjector, spName: String, @StringRe
|
|||
|
||||
inner class Option internal constructor(@StringRes var option: Int, var isCorrect: Boolean) {
|
||||
|
||||
var cb: CheckBox? = null // TODO: change it, this will block releasing memory
|
||||
private var cb: CheckBox? = null // TODO: change it, this will block releasing memory
|
||||
|
||||
fun generate(context: Context): CheckBox {
|
||||
cb = CheckBox(context)
|
||||
|
@ -184,13 +185,5 @@ abstract class Objective(injector: HasAndroidInjector, spName: String, @StringRe
|
|||
}
|
||||
}
|
||||
|
||||
inner class Learned internal constructor(@StringRes var learned: Int) {
|
||||
|
||||
fun generate(context: Context): TextView {
|
||||
val textView = TextView(context)
|
||||
textView.setText(learned)
|
||||
textView.setLinkTextColor(rh.gac(context, com.google.android.material.R.attr.colorSecondary))
|
||||
return textView
|
||||
}
|
||||
}
|
||||
inner class Learned internal constructor(@StringRes var learned: Int)
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package info.nightscout.plugins.constraints.objectives.objectives
|
||||
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.plugins.constraints.R
|
||||
import info.nightscout.shared.utils.T
|
||||
|
||||
class Objective11(injector: HasAndroidInjector) : Objective(injector, "dyn_isf", R.string.objectives_dyn_isf_objective, R.string.objectives_dyn_isf_gate) {
|
||||
|
||||
init {
|
||||
tasks.add(
|
||||
MinimumDurationTask(this, T.days(28).msecs())
|
||||
.learned(Learned(R.string.objectives_dyn_isf_learned))
|
||||
)
|
||||
}
|
||||
}
|
|
@ -28,6 +28,9 @@
|
|||
<string name="objectives_smb_objective">Enabling additional features for daytime use, such as SMB</string>
|
||||
<string name="objectives_smb_gate">You must read the wiki and raise maxIOB to get SMBs working fine! A good start is maxIOB=average mealbolus + 3 x max daily basal</string>
|
||||
<string name="objectives_smb_learned">Using SMB is your goal. Oref1 algorithm was designed to help you with your boluses as well. You should not give full bolus for your food but only part of it and let AAPS give you the rest if needed. This way you have more space for miscalculated carbs. Did you know that you can set a percentage of bolus calculator result to reduce the size of bolus?</string>
|
||||
<string name="objectives_dyn_isf_objective">Enabling additional features for daytime use, such as Dynamic sensitivity plugin</string>
|
||||
<string name="objectives_dyn_isf_gate">Make sure SMB is working well. Enable DynamicISF plugin and determine correct strangeness specific to your body. It\'s safer to start with lower value than 100%.</string>
|
||||
<string name="objectives_dyn_isf_learned">Dynamic sensitivity plugin is based on idea that total insulin income and current glycemia affects actual sensitivity. DynamicISF plugin can adjust ISF passed to the algorithm for you.</string>
|
||||
<string name="objectives_auto_objective">Enabling automation</string>
|
||||
<string name="objectives_auto_gate">Read the docs on how automation works. Set up your first simple rules. Instead of action let AAPS display only notification. When you are sure automation is triggered at the right time replace notification by real action. (https://wiki.aaps.app/en/latest/Usage/Automation.html)</string>
|
||||
<string name="objectives_auto_learned">Automation can be a good servant but a bad master. Don\'t overuse it. Do not try to replace underlying algorithm. Test the rule with message only before use. It depends on order.</string>
|
||||
|
|
Loading…
Reference in a new issue