This commit is contained in:
Milos Kozak 2021-03-07 19:26:08 +01:00
parent 658f565cf2
commit bcfa449ec8
16 changed files with 109 additions and 133 deletions

View file

@ -34,6 +34,7 @@ import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.extensions.valueToUnits
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP

View file

@ -18,6 +18,7 @@ import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.db.CareportalEvent
import info.nightscout.androidaps.db.Source
import info.nightscout.androidaps.events.EventAcceptOpenLoopChange
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.events.EventNewBG
import info.nightscout.androidaps.events.EventTempTargetChange
import info.nightscout.androidaps.interfaces.*
@ -33,10 +34,9 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSUpload
import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification
import info.nightscout.androidaps.plugins.general.overview.events.EventNewNotification
import info.nightscout.androidaps.plugins.general.overview.notifications.Notification
import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAction
import info.nightscout.androidaps.plugins.general.wear.events.EventWearInitiateAction
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
import info.nightscout.androidaps.events.EventAutosensCalculationFinished
import info.nightscout.androidaps.plugins.general.wear.events.EventWearConfirmAction
import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.queue.Callback
@ -76,8 +76,7 @@ open class LoopPlugin @Inject constructor(
private val receiverStatusStore: ReceiverStatusStore,
private val fabricPrivacy: FabricPrivacy,
private val nsUpload: NSUpload,
private val databaseHelper: DatabaseHelperInterface,
private val hardLimits: HardLimits
private val databaseHelper: DatabaseHelperInterface
) : PluginBase(PluginDescription()
.mainType(PluginType.LOOP)
.fragmentClass(LoopFragment::class.java.name)
@ -198,7 +197,7 @@ open class LoopPlugin @Inject constructor(
val apsMode = sp.getString(R.string.key_aps_mode, "open")
val pump = activePlugin.activePump
var isLGS = false
if (!isSuspended && !pump.isSuspended()) if (closedLoopEnabled.value()) if (maxIobAllowed == hardLimits.MAXIOB_LGS || apsMode == "lgs") isLGS = true
if (!isSuspended && !pump.isSuspended()) if (closedLoopEnabled.value()) if (maxIobAllowed == HardLimits.MAX_IOB_LGS || apsMode == "lgs") isLGS = true
return isLGS
}

View file

@ -113,20 +113,20 @@ open class OpenAPSAMAPlugin @Inject constructor(
val maxIob = constraintChecker.getMaxIOBAllowed().also { maxIOBAllowedConstraint ->
inputConstraints.copyReasons(maxIOBAllowedConstraint)
}.value()
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetLowMgdl, 0.1), R.string.profile_low_target, hardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble())
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetHighMgdl, 0.1), R.string.profile_high_target, hardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble())
var targetBg = hardLimits.verifyHardLimits(profile.targetMgdl, R.string.temp_target_value, hardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble())
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetLowMgdl, 0.1), R.string.profile_low_target, HardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble())
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetHighMgdl, 0.1), R.string.profile_high_target, HardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble())
var targetBg = hardLimits.verifyHardLimits(profile.targetMgdl, R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble())
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.checkOnlyHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return
if (!hardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return
if (!hardLimits.checkOnlyHardLimits(profile.isfMgdl, R.string.profile_sensitivity_value, hardLimits.MINISF, hardLimits.MAXISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.isfMgdl, R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.maxDailyBasal, R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return
if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
startPart = System.currentTimeMillis()

View file

@ -119,20 +119,20 @@ open class OpenAPSSMBPlugin @Inject constructor(
inputConstraints.copyReasons(maxIOBAllowedConstraint)
}.value()
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetLowMgdl, 0.1), R.string.profile_low_target, hardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble())
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetHighMgdl, 0.1), R.string.profile_high_target, hardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble())
var targetBg = hardLimits.verifyHardLimits(profile.targetMgdl, R.string.temp_target_value, hardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble())
var minBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetLowMgdl, 0.1), R.string.profile_low_target, HardLimits.VERY_HARD_LIMIT_MIN_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MIN_BG[1].toDouble())
var maxBg = hardLimits.verifyHardLimits(Round.roundTo(profile.targetHighMgdl, 0.1), R.string.profile_high_target, HardLimits.VERY_HARD_LIMIT_MAX_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_MAX_BG[1].toDouble())
var targetBg = hardLimits.verifyHardLimits(profile.targetMgdl, R.string.temp_target_value, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble())
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.checkOnlyHardLimits(profile.dia, R.string.profile_dia, hardLimits.minDia(), hardLimits.maxDia())) return
if (!hardLimits.checkOnlyHardLimits(profile.getIcTimeFromMidnight(Profile.secondsFromMidnight()), R.string.profile_carbs_ratio_value, hardLimits.minIC(), hardLimits.maxIC())) return
if (!hardLimits.checkOnlyHardLimits(profile.isfMgdl, R.string.profile_sensitivity_value, hardLimits.MINISF, hardLimits.MAXISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.isfMgdl, R.string.profile_sensitivity_value, HardLimits.MIN_ISF, HardLimits.MAX_ISF)) return
if (!hardLimits.checkOnlyHardLimits(profile.maxDailyBasal, R.string.profile_max_daily_basal_value, 0.02, hardLimits.maxBasal())) return
if (!hardLimits.checkOnlyHardLimits(pump.baseBasalRate, R.string.current_basal_value, 0.01, hardLimits.maxBasal())) return
startPart = System.currentTimeMillis()

View file

@ -188,7 +188,7 @@ class SafetyPlugin @Inject constructor(
maxIob.setIfSmaller(aapsLogger, maxIobPref, String.format(resourceHelper.gs(R.string.limitingiob), maxIobPref, resourceHelper.gs(R.string.maxvalueinpreferences)), this)
if (openAPSAMAPlugin.isEnabled(PluginType.APS)) maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobAMA(), String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.maxIobAMA(), resourceHelper.gs(R.string.hardlimit)), this)
if (openAPSSMBPlugin.isEnabled(PluginType.APS)) maxIob.setIfSmaller(aapsLogger, hardLimits.maxIobSMB(), String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.maxIobSMB(), resourceHelper.gs(R.string.hardlimit)), this)
if (apsMode == "lgs") maxIob.setIfSmaller(aapsLogger, hardLimits.MAXIOB_LGS, String.format(resourceHelper.gs(R.string.limitingiob), hardLimits.MAXIOB_LGS, resourceHelper.gs(R.string.lowglucosesuspend)), this)
if (apsMode == "lgs") maxIob.setIfSmaller(aapsLogger, HardLimits.MAX_IOB_LGS, String.format(resourceHelper.gs(R.string.limitingiob), HardLimits.MAX_IOB_LGS, resourceHelper.gs(R.string.lowglucosesuspend)), this)
return maxIob
}
}

View file

@ -62,6 +62,8 @@ import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.buildHelper.BuildHelper
import info.nightscout.androidaps.utils.extensions.directionToIcon
import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.extensions.valueToUnits
import info.nightscout.androidaps.utils.extensions.valueToUnitsString
import info.nightscout.androidaps.utils.protection.ProtectionCheck
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers

View file

@ -22,7 +22,7 @@ import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.resources.IconsProvider
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.valueToUnitsString
import info.nightscout.androidaps.utils.extensions.valueToUnitsString
import io.reactivex.disposables.CompositeDisposable
import javax.inject.Inject
import javax.inject.Singleton

View file

@ -41,6 +41,7 @@ import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.receivers.BundleStore
import info.nightscout.androidaps.receivers.DataReceiver
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.extensions.valueToUnitsString
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP

View file

@ -36,6 +36,7 @@ import info.nightscout.androidaps.plugins.pump.insight.LocalInsightPlugin
import info.nightscout.androidaps.plugins.treatments.CarbsGenerator
import info.nightscout.androidaps.queue.Callback
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.extensions.valueToUnits
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
@ -52,6 +53,7 @@ import javax.inject.Singleton
import kotlin.math.abs
import kotlin.math.min
@Suppress("SpellCheckingInspection")
@Singleton
class ActionStringHandler @Inject constructor(
private val sp: SP,
@ -75,7 +77,6 @@ class ActionStringHandler @Inject constructor(
private val danaRv2Plugin: DanaRv2Plugin,
private val danaRSPlugin: DanaRSPlugin,
private val danaPump: DanaPump,
private val hardLimits: HardLimits,
private val carbsGenerator: CarbsGenerator,
private val dateUtil: DateUtil,
private val config: Config,
@ -84,7 +85,7 @@ class ActionStringHandler @Inject constructor(
private val nsUpload: NSUpload
) {
private val TIMEOUT = 65 * 1000
private val timeout = 65 * 1000
private var lastSentTimestamp: Long = 0
private var lastConfirmActionString: String? = null
private var lastBolusWizard: BolusWizard? = null
@ -113,14 +114,11 @@ class ActionStringHandler @Inject constructor(
// do the parsing and check constraints
val act = actionString.split("\\s+".toRegex()).toTypedArray()
if ("fillpreset" == act[0]) { ///////////////////////////////////// PRIME/FILL
val amount: Double = if ("1" == act[1]) {
sp.getDouble("fill_button1", 0.3)
} else if ("2" == act[1]) {
sp.getDouble("fill_button2", 0.0)
} else if ("3" == act[1]) {
sp.getDouble("fill_button3", 0.0)
} else {
return
val amount: Double = when {
"1" == act[1] -> sp.getDouble("fill_button1", 0.3)
"2" == act[1] -> sp.getDouble("fill_button2", 0.0)
"3" == act[1] -> sp.getDouble("fill_button3", 0.0)
else -> return
}
val insulinAfterConstraints = constraintChecker.applyBolusConstraints(Constraint(amount)).value()
rMessage += resourceHelper.gs(R.string.primefill) + ": " + insulinAfterConstraints + "U"
@ -160,11 +158,11 @@ class ActionStringHandler @Inject constructor(
low *= Constants.MMOLL_TO_MGDL
high *= Constants.MMOLL_TO_MGDL
}
if (low < hardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0] || low > hardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]) {
if (low < HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[0] || low > HardLimits.VERY_HARD_LIMIT_TEMP_MIN_BG[1]) {
sendError("Min-BG out of range!")
return
}
if (high < hardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0] || high > hardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]) {
if (high < HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[0] || high > HardLimits.VERY_HARD_LIMIT_TEMP_MAX_BG[1]) {
sendError("Max-BG out of range!")
return
}
@ -358,12 +356,11 @@ class ActionStringHandler @Inject constructor(
message += "Today: " + DecimalFormatter.to2Decimal(tdd) + "U " + (DecimalFormatter.to0Decimal(100 * tdd / refTDD) + "%") + "\n"
message += "\n"
}
var i = 0
var weighted03 = 0.0
var weighted05 = 0.0
var weighted07 = 0.0
historyList.reverse()
for (record in historyList) {
for ((i, record) in historyList.withIndex()) {
val tdd = record.getTotal()
if (i == 0) {
weighted03 = tdd
@ -374,7 +371,6 @@ class ActionStringHandler @Inject constructor(
weighted05 = weighted05 * 0.5 + tdd * 0.5
weighted03 = weighted03 * 0.7 + tdd * 0.3
}
i++
}
message += "weighted:\n"
message += "0.3: " + DecimalFormatter.to2Decimal(weighted03) + "U " + (DecimalFormatter.to0Decimal(100 * weighted03 / refTDD) + "%") + "\n"
@ -495,7 +491,7 @@ class ActionStringHandler @Inject constructor(
//Guard from old or duplicate confirmations
if (lastConfirmActionString == null) return
if (lastConfirmActionString != actionString) return
if (System.currentTimeMillis() - lastSentTimestamp > TIMEOUT) return
if (System.currentTimeMillis() - lastSentTimestamp > timeout) return
lastConfirmActionString = null
// do the parsing, check constraints and enact!
val act = actionString.split("\\s+".toRegex()).toTypedArray()
@ -578,7 +574,7 @@ class ActionStringHandler @Inject constructor(
lastConfirmActionString = rAction
return
}
//send profile to pumpe
//send profile to pump
activePlugin.activeTreatments.doProfileSwitch(0, percentage, timeshift)
}
@ -642,8 +638,8 @@ class ActionStringHandler @Inject constructor(
}
}
@Synchronized private fun sendError(errormessage: String) {
wearPlugin.requestActionConfirmation("ERROR", errormessage, "error")
@Synchronized private fun sendError(errorMessage: String) {
wearPlugin.requestActionConfirmation("ERROR", errorMessage, "error")
lastSentTimestamp = System.currentTimeMillis()
lastConfirmActionString = null
lastBolusWizard = null

View file

@ -56,8 +56,8 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin;
import info.nightscout.androidaps.receivers.ReceiverStatusStore;
import info.nightscout.androidaps.utils.DecimalFormatter;
import info.nightscout.androidaps.utils.DefaultValueHelper;
import info.nightscout.androidaps.utils.GlucoseValueUtilsKt;
import info.nightscout.androidaps.utils.ToastUtils;
import info.nightscout.androidaps.utils.extensions.GlucoseValueUtilsKt;
import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP;

View file

@ -21,10 +21,10 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper
import info.nightscout.androidaps.plugins.profile.local.events.EventLocalProfileChanged
import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import io.reactivex.rxkotlin.plusAssign
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import java.text.DecimalFormat
import javax.inject.Inject
@ -121,11 +121,11 @@ class LocalProfileFragment : DaggerFragment() {
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.ic, "IC", resourceHelper.gs(R.string.ic_label), currentProfile.ic, null, hardLimits.minIC(), hardLimits.maxIC(), 0.1, DecimalFormat("0.0"), save)
basalView = TimeListEdit(context, aapsLogger, dateUtil, view, R.id.basal, "BASAL", resourceHelper.gs(R.string.basal_label) + ": " + sumLabel(), currentProfile.basal, null, pumpDescription.basalMinimumRate, 10.0, 0.01, DecimalFormat("0.00"), save)
if (units == Constants.MGDL) {
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, hardLimits.MINISF, hardLimits.MAXISF, 1.0, DecimalFormat("0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, hardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), hardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, HardLimits.MIN_ISF, HardLimits.MAX_ISF, 1.0, DecimalFormat("0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), 1.0, DecimalFormat("0"), save)
} else {
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, Profile.fromMgdlToUnits(hardLimits.MINISF, Constants.MMOL), Profile.fromMgdlToUnits(hardLimits.MAXISF, Constants.MMOL), 0.1, DecimalFormat("0.0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, Profile.fromMgdlToUnits(hardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), Constants.MMOL), Profile.fromMgdlToUnits(hardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), Constants.MMOL), 0.1, DecimalFormat("0.0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.isf, "ISF", resourceHelper.gs(R.string.isf_label), currentProfile.isf, null, Profile.fromMgdlToUnits(HardLimits.MIN_ISF, Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.MAX_ISF, Constants.MMOL), 0.1, DecimalFormat("0.0"), save)
TimeListEdit(context, aapsLogger, dateUtil, view, R.id.target, "TARGET", resourceHelper.gs(R.string.target_label), currentProfile.targetLow, currentProfile.targetHigh, Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[0].toDouble(), Constants.MMOL), Profile.fromMgdlToUnits(HardLimits.VERY_HARD_LIMIT_TARGET_BG[1].toDouble(), Constants.MMOL), 0.1, DecimalFormat("0.0"), save)
}
// Spinner
@ -221,7 +221,7 @@ class LocalProfileFragment : DaggerFragment() {
disposable += rxBus
.toObservable(EventLocalProfileChanged::class.java)
.observeOn(aapsSchedulers.main)
.subscribe({ build() },fabricPrivacy::logException)
.subscribe({ build() }, fabricPrivacy::logException)
build()
}

View file

@ -25,9 +25,9 @@ import info.nightscout.androidaps.utils.T
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
import info.nightscout.androidaps.utils.extensions.directionToIcon
import info.nightscout.androidaps.utils.extensions.toVisibility
import info.nightscout.androidaps.utils.extensions.valueToUnitsString
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.valueToUnitsString
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.rxkotlin.plusAssign
import java.util.concurrent.TimeUnit

View file

@ -9,6 +9,8 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import javax.inject.Inject
import javax.inject.Singleton
import kotlin.math.max
import kotlin.math.min
@Singleton
class HardLimits @Inject constructor(
@ -20,12 +22,14 @@ class HardLimits @Inject constructor(
private val nsUpload: NSUpload
) {
val CHILD = 0
val TEENAGE = 1
val ADULT = 2
val RESISTANTADULT = 3
val PREGNANT = 4
val MAXBOLUS = doubleArrayOf(5.0, 10.0, 17.0, 25.0, 60.0)
companion object {
private const val CHILD = 0
private const val TEENAGE = 1
private const val ADULT = 2
private const val RESISTANT_ADULT = 3
private const val PREGNANT = 4
private val MAX_BOLUS = doubleArrayOf(5.0, 10.0, 17.0, 25.0, 60.0)
// Very Hard Limits Ranges
// First value is the Lowest and second value is the Highest a Limit can define
@ -37,81 +41,56 @@ class HardLimits @Inject constructor(
val VERY_HARD_LIMIT_TEMP_MIN_BG = intArrayOf(72, 180)
val VERY_HARD_LIMIT_TEMP_MAX_BG = intArrayOf(72, 270)
val VERY_HARD_LIMIT_TEMP_TARGET_BG = intArrayOf(72, 200)
val MINDIA = doubleArrayOf(5.0, 5.0, 5.0, 5.0, 5.0)
val MAXDIA = doubleArrayOf(7.0, 7.0, 7.0, 7.0, 10.0)
val MINIC = doubleArrayOf(2.0, 2.0, 2.0, 2.0, 0.3)
val MAXIC = doubleArrayOf(100.0, 100.0, 100.0, 100.0, 100.0)
val MINISF = 2.0 // mgdl
val MAXISF = 720.0 // mgdl
val MAXIOB_AMA = doubleArrayOf(3.0, 5.0, 7.0, 12.0, 25.0)
val MAXIOB_SMB = doubleArrayOf(3.0, 7.0, 12.0, 25.0, 40.0)
val MAXBASAL = doubleArrayOf(2.0, 5.0, 10.0, 12.0, 25.0)
val MIN_DIA = doubleArrayOf(5.0, 5.0, 5.0, 5.0, 5.0)
val MAX_DIA = doubleArrayOf(7.0, 7.0, 7.0, 7.0, 10.0)
val MIN_IC = doubleArrayOf(2.0, 2.0, 2.0, 2.0, 0.3)
val MAX_IC = doubleArrayOf(100.0, 100.0, 100.0, 100.0, 100.0)
const val MIN_ISF = 2.0 // mgdl
const val MAX_ISF = 720.0 // mgdl
val MAX_IOB_AMA = doubleArrayOf(3.0, 5.0, 7.0, 12.0, 25.0)
val MAX_IOB_SMB = doubleArrayOf(3.0, 7.0, 12.0, 25.0, 40.0)
val MAX_BASAL = doubleArrayOf(2.0, 5.0, 10.0, 12.0, 25.0)
//LGS Hard limits
//No IOB at all
val MAXIOB_LGS = 0.0
const val MAX_IOB_LGS = 0.0
private fun loadAge(): Int {
val sp_age = sp.getString(R.string.key_age, "")
val age: Int
age = if (sp_age == resourceHelper.gs(R.string.key_child)) CHILD
else if (sp_age == resourceHelper.gs(R.string.key_teenage)) TEENAGE
else if (sp_age == resourceHelper.gs(R.string.key_adult)) ADULT
else if (sp_age == resourceHelper.gs(R.string.key_resistantadult)) RESISTANTADULT
else if (sp_age == resourceHelper.gs(R.string.key_pregnant)) PREGNANT
else ADULT
return age
}
fun maxBolus(): Double {
return MAXBOLUS[loadAge()]
private fun loadAge(): Int = when (sp.getString(R.string.key_age, "")) {
resourceHelper.gs(R.string.key_child) -> CHILD
resourceHelper.gs(R.string.key_teenage) -> TEENAGE
resourceHelper.gs(R.string.key_adult) -> ADULT
resourceHelper.gs(R.string.key_resistantadult) -> RESISTANT_ADULT
resourceHelper.gs(R.string.key_pregnant) -> PREGNANT
else -> ADULT
}
fun maxIobAMA(): Double {
return MAXIOB_AMA[loadAge()]
}
fun maxIobSMB(): Double {
return MAXIOB_SMB[loadAge()]
}
fun maxBasal(): Double {
return MAXBASAL[loadAge()]
}
fun minDia(): Double {
return MINDIA[loadAge()]
}
fun maxDia(): Double {
return MAXDIA[loadAge()]
}
fun minIC(): Double {
return MINIC[loadAge()]
}
fun maxIC(): Double {
return MAXIC[loadAge()]
}
fun maxBolus(): Double = MAX_BOLUS[loadAge()]
fun maxIobAMA(): Double = MAX_IOB_AMA[loadAge()]
fun maxIobSMB(): Double = MAX_IOB_SMB[loadAge()]
fun maxBasal(): Double = MAX_BASAL[loadAge()]
fun minDia(): Double = MIN_DIA[loadAge()]
fun maxDia(): Double = MAX_DIA[loadAge()]
fun minIC(): Double = MIN_IC[loadAge()]
fun maxIC(): Double = MAX_IC[loadAge()]
// safety checks
fun checkOnlyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Boolean {
return value == verifyHardLimits(value, valueName, lowLimit, highLimit)
}
fun checkOnlyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Boolean =
value == verifyHardLimits(value, valueName, lowLimit, highLimit)
fun verifyHardLimits(value: Double, valueName: Int, lowLimit: Double, highLimit: Double): Double {
var newvalue = value
if (newvalue < lowLimit || newvalue > highLimit) {
newvalue = Math.max(newvalue, lowLimit)
newvalue = Math.min(newvalue, highLimit)
var newValue = value
if (newValue < lowLimit || newValue > highLimit) {
newValue = max(newValue, lowLimit)
newValue = min(newValue, highLimit)
var msg = String.format(resourceHelper.gs(R.string.valueoutofrange), resourceHelper.gs(valueName))
msg += ".\n"
msg += String.format(resourceHelper.gs(R.string.valuelimitedto), value, newvalue)
msg += String.format(resourceHelper.gs(R.string.valuelimitedto), value, newValue)
aapsLogger.error(msg)
nsUpload.uploadError(msg)
ToastUtils.showToastInUiThread(context, rxBus, msg, R.raw.error)
}
return newvalue
return newValue
}
}

View file

@ -1,7 +1,8 @@
package info.nightscout.androidaps.utils
package info.nightscout.androidaps.utils.extensions
import info.nightscout.androidaps.Constants
import info.nightscout.androidaps.database.entities.GlucoseValue
import info.nightscout.androidaps.utils.DecimalFormatter
fun GlucoseValue.valueToUnits(units: String): Double =
if (units == Constants.MGDL) value

View file

@ -15,8 +15,8 @@ import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.utils.DateUtil
import info.nightscout.androidaps.utils.JsonHelper.safeGetInt
import info.nightscout.androidaps.utils.JsonHelper.safeGetString
import info.nightscout.androidaps.utils.extensions.valueToUnits
import info.nightscout.androidaps.utils.sharedPreferences.SP
import info.nightscout.androidaps.utils.valueToUnits
import org.json.JSONException
import org.json.JSONObject
import java.util.*

View file

@ -16,7 +16,6 @@ import info.nightscout.androidaps.plugins.pump.virtual.VirtualPumpPlugin
import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin
import info.nightscout.androidaps.receivers.ReceiverStatusStore
import info.nightscout.androidaps.utils.FabricPrivacy
import info.nightscout.androidaps.utils.HardLimits
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import org.junit.Assert
@ -50,15 +49,13 @@ class LoopPluginTest : TestBase() {
@Mock lateinit var nsUpload: NSUpload
@Mock lateinit var notificationManager: NotificationManager
@Mock lateinit var databaseHelper: DatabaseHelperInterface
private lateinit var hardLimits: HardLimits
private lateinit var loopPlugin: LoopPlugin
val injector = HasAndroidInjector { AndroidInjector { } }
@Before fun prepareMock() {
hardLimits = HardLimits(aapsLogger, rxBus, sp, resourceHelper, context, nsUpload)
loopPlugin = LoopPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, Config(), constraintChecker, resourceHelper, profileFunction, context, commandQueue, activePlugin, treatmentsPlugin, virtualPumpPlugin, iobCobCalculatorPlugin, receiverStatusStore, fabricPrivacy, nsUpload, databaseHelper, hardLimits)
loopPlugin = LoopPlugin(injector, aapsLogger, aapsSchedulers, rxBus, sp, Config(), constraintChecker, resourceHelper, profileFunction, context, commandQueue, activePlugin, treatmentsPlugin, virtualPumpPlugin, iobCobCalculatorPlugin, receiverStatusStore, fabricPrivacy, nsUpload, databaseHelper)
`when`(activePlugin.activePump).thenReturn(virtualPumpPlugin)
`when`(context.getSystemService(Context.NOTIFICATION_SERVICE)).thenReturn(notificationManager)
}