diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt
index 92afb1141e..ee18a17818 100644
--- a/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt
+++ b/app/src/main/java/info/nightscout/androidaps/dialogs/WizardDialog.kt
@@ -27,14 +27,10 @@ import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.bus.RxBus
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
-import info.nightscout.androidaps.utils.DateUtil
-import info.nightscout.androidaps.utils.DecimalFormatter
-import info.nightscout.androidaps.utils.FabricPrivacy
-import info.nightscout.androidaps.utils.SafeParse
-import info.nightscout.androidaps.utils.ToastUtils
import info.nightscout.androidaps.extensions.toVisibility
import info.nightscout.androidaps.extensions.valueToUnits
import info.nightscout.androidaps.interfaces.*
+import info.nightscout.androidaps.utils.*
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.rx.AapsSchedulers
import info.nightscout.androidaps.utils.sharedPreferences.SP
@@ -63,6 +59,9 @@ class WizardDialog : DaggerDialogFragment() {
@Inject lateinit var dateUtil: DateUtil
private var wizard: BolusWizard? = null
+ private var calculatedPercentage = 100.0
+ private var calculatedCorrection = 0.0
+ private var correctionPercent = false
//one shot guards
private var okClicked: Boolean = false
@@ -134,12 +133,22 @@ class WizardDialog : DaggerDialogFragment() {
binding.carbsInput.setParams(savedInstanceState?.getDouble("carbs_input")
?: 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, binding.ok, textWatcher)
val bolusStep = activePlugin.activePump.pumpDescription.bolusStep
- binding.correctionInput.setParams(savedInstanceState?.getDouble("correction_input")
- ?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), false, binding.ok, textWatcher)
+
+ if (correctionPercent) {
+ calculatedPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble()
+ binding.correctionInput.setParams(calculatedPercentage, 10.0, 200.0, 1.0, DecimalFormat("0"), false, binding.ok, textWatcher)
+ binding.correctionInput.value = calculatedPercentage
+ binding.correctionUnit.text = "%"
+ } else {
+ binding.correctionInput.setParams(
+ savedInstanceState?.getDouble("correction_input")
+ ?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), false, binding.ok, textWatcher)
+ binding.correctionUnit.text = rh.gs(R.string.insulin_unit_shortname)
+ }
binding.carbTimeInput.setParams(savedInstanceState?.getDouble("carb_time_input")
?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, binding.ok, timeTextWatcher)
initDialog()
-
+ calculatedPercentage = sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble()
binding.percentUsed.text = rh.gs(R.string.format_percent, sp.getInt(R.string.key_boluswizard_percentage, 100))
// ok button
binding.ok.setOnClickListener {
@@ -176,6 +185,21 @@ class WizardDialog : DaggerDialogFragment() {
binding.resulttable.visibility = isChecked.toVisibility()
}
}
+
+ binding.correctionPercent.setOnCheckedChangeListener {_, isChecked ->
+ run {
+ sp.putBoolean(rh.gs(R.string.key_wizard_correction_percent), isChecked)
+ binding.correctionUnit.text = if (isChecked) "%" else rh.gs(R.string.insulin_unit_shortname)
+ correctionPercent = binding.correctionPercent.isChecked
+ if (correctionPercent)
+ binding.correctionInput.setParams(calculatedPercentage.toDouble(), 10.0, 200.0, 1.0, DecimalFormat("0"), false, binding.ok, textWatcher)
+ else
+ binding.correctionInput.setParams(savedInstanceState?.getDouble("correction_input")
+ ?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), false, binding.ok, textWatcher)
+ binding.correctionInput.value = if (correctionPercent) calculatedPercentage.toDouble() else calculatedCorrection
+ }
+
+ }
// profile spinner
binding.profile.onItemSelectedListener = object : OnItemSelectedListener {
override fun onNothingSelected(parent: AdapterView<*>?) {
@@ -228,11 +252,14 @@ class WizardDialog : DaggerDialogFragment() {
private fun saveCheckedStates() {
sp.putBoolean(R.string.key_wizard_include_cob, binding.cobcheckbox.isChecked)
sp.putBoolean(R.string.key_wizard_include_trend_bg, binding.bgtrendcheckbox.isChecked)
+ sp.putBoolean(R.string.key_wizard_correction_percent, binding.correctionPercent.isChecked)
}
private fun loadCheckedStates() {
binding.bgtrendcheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_trend_bg, false)
binding.cobcheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_cob, false)
+ correctionPercent = sp.getBoolean(R.string.key_wizard_correction_percent,false)
+ binding.correctionPercent.isChecked = correctionPercent
}
private fun valueToUnitsToString(value: Double, units: String): String =
@@ -273,7 +300,7 @@ class WizardDialog : DaggerDialogFragment() {
calculateInsulin()
- binding.percentUsed.visibility = (sp.getInt(R.string.key_boluswizard_percentage, 100) != 100).toVisibility()
+ binding.percentUsed.visibility = (sp.getInt(R.string.key_boluswizard_percentage, 100) != 100 || correctionPercent).toVisibility()
}
private fun calculateInsulin() {
@@ -291,9 +318,16 @@ class WizardDialog : DaggerDialogFragment() {
if (specificProfile == null) return
// Entered values
+ val usePercentage = binding.correctionPercent.isChecked
var bg = SafeParse.stringToDouble(binding.bgInput.text)
val carbs = SafeParse.stringToInt(binding.carbsInput.text)
- val correction = SafeParse.stringToDouble(binding.correctionInput.text)
+ val correction = if (usePercentage) 0.0 else SafeParse.stringToDouble(binding.correctionInput.text)
+ val percentageCorrection = if (usePercentage) {
+ if (Round.roundTo(calculatedPercentage,1.0) == SafeParse.stringToDouble(binding.correctionInput.text))
+ calculatedPercentage
+ else
+ SafeParse.stringToDouble(binding.correctionInput.text)
+ } else sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble()
val carbsAfterConstraint = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value()
if (abs(carbs - carbsAfterConstraint) > 0.01) {
binding.carbsInput.value = 0.0
@@ -314,8 +348,7 @@ class WizardDialog : DaggerDialogFragment() {
val carbTime = SafeParse.stringToInt(binding.carbTimeInput.text)
- wizard = BolusWizard(injector).doCalc(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction,
- sp.getInt(R.string.key_boluswizard_percentage, 100),
+ wizard = BolusWizard(injector).doCalc(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction, sp.getInt(R.string.key_boluswizard_percentage, 100),
binding.bgcheckbox.isChecked,
binding.cobcheckbox.isChecked,
binding.bolusiobcheckbox.isChecked,
@@ -324,7 +357,11 @@ class WizardDialog : DaggerDialogFragment() {
binding.ttcheckbox.isChecked,
binding.bgtrendcheckbox.isChecked,
binding.alarm.isChecked,
- binding.notes.text.toString(), carbTime)
+ binding.notes.text.toString(),
+ carbTime,
+ usePercentage = usePercentage,
+ totalPercentage = percentageCorrection
+ )
wizard?.let { wizard ->
binding.bg.text = String.format(rh.gs(R.string.format_bg_isf), valueToUnitsToString(Profile.toMgdl(bg, profileFunction.getUnits()), profileFunction.getUnits().asText), wizard.sens)
@@ -370,6 +407,9 @@ class WizardDialog : DaggerDialogFragment() {
binding.total.text = rh.gs(R.string.missing_carbs, wizard.carbsEquivalent.toInt())
binding.ok.visibility = View.INVISIBLE
}
+ binding.percentUsed.text = rh.gs(R.string.format_percent, wizard.percentageCorrection)
+ calculatedPercentage = wizard.calculatedPercentage
+ calculatedCorrection = wizard.calculatedCorrection
}
}
diff --git a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt
index 74950918f5..c9443e17b6 100644
--- a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt
+++ b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt
@@ -36,6 +36,8 @@ import io.reactivex.rxkotlin.plusAssign
import java.util.*
import javax.inject.Inject
import kotlin.math.abs
+import kotlin.math.max
+import kotlin.math.min
class BolusWizard @Inject constructor(
val injector: HasAndroidInjector
@@ -105,6 +107,10 @@ class BolusWizard @Inject constructor(
private set
var insulinAfterConstraints: Double = 0.0
private set
+ var calculatedPercentage: Double = 100.0
+ private set
+ var calculatedCorrection: Double = 0.0
+ private set
// Input
lateinit var profile: Profile
@@ -114,7 +120,8 @@ class BolusWizard @Inject constructor(
var cob: Double = 0.0
var bg: Double = 0.0
private var correction: Double = 0.0
- private var percentageCorrection: Int = 0
+ var percentageCorrection: Int = 100
+ private var totalPercentage: Double = 100.0
private var useBg: Boolean = false
private var useCob: Boolean = false
private var includeBolusIOB: Boolean = false
@@ -126,6 +133,7 @@ class BolusWizard @Inject constructor(
var notes: String = ""
private var carbTime: Int = 0
private var quickWizard: Boolean = true
+ var usePercentage: Boolean = false
fun doCalc(profile: Profile,
profileName: String,
@@ -145,6 +153,8 @@ class BolusWizard @Inject constructor(
useAlarm: Boolean,
notes: String = "",
carbTime: Int = 0,
+ usePercentage: Boolean = false,
+ totalPercentage: Double = 100.0,
quickWizard: Boolean = false
): BolusWizard {
@@ -167,6 +177,8 @@ class BolusWizard @Inject constructor(
this.notes = notes
this.carbTime = carbTime
this.quickWizard = quickWizard
+ this.usePercentage = usePercentage
+ this.totalPercentage = totalPercentage
// Insulin from BG
sens = Profile.fromMgdlToUnits(profile.getIsfMgdl(), profileFunction.getUnits())
@@ -208,7 +220,7 @@ class BolusWizard @Inject constructor(
insulinFromBasalIOB = if (includeBasalIOB) -basalIob.basaliob else 0.0
// Insulin from correction
- insulinFromCorrection = correction
+ insulinFromCorrection = if (usePercentage) 0.0 else correction
// Insulin from superbolus for 2h. Get basal rate now and after 1h
if (useSuperBolus) {
@@ -221,15 +233,23 @@ class BolusWizard @Inject constructor(
// Total
calculatedTotalInsulin = insulinFromBG + insulinFromTrend + insulinFromCarbs + insulinFromBolusIOB + insulinFromBasalIOB + insulinFromCorrection + insulinFromSuperBolus + insulinFromCOB
+ var percentage = if (usePercentage) totalPercentage else percentageCorrection.toDouble()
+
// Percentage adjustment
totalBeforePercentageAdjustment = calculatedTotalInsulin
- if (calculatedTotalInsulin > 0) {
- calculatedTotalInsulin = calculatedTotalInsulin * percentageCorrection / 100.0
- }
-
- if (calculatedTotalInsulin < 0) {
+ if (calculatedTotalInsulin >= 0) {
+ calculatedTotalInsulin = calculatedTotalInsulin * percentage / 100.0
+ if (usePercentage)
+ calcCorrectionWithConstraints()
+ else
+ calcPercentageWithConstraints()
+ if (usePercentage) //Should be updated after calcCorrectionWithConstraints and calcPercentageWithConstraints to have correct synthesis in WizardInfo
+ this.percentageCorrection = Round.roundTo(totalPercentage, 1.0).toInt()
+ } else {
carbsEquivalent = (-calculatedTotalInsulin) * ic
calculatedTotalInsulin = 0.0
+ calculatedPercentage = percentageCorrection.toDouble()
+ calculatedCorrection = 0.0
}
val bolusStep = activePlugin.activePump.pumpDescription.bolusStep
@@ -441,4 +461,21 @@ class BolusWizard @Inject constructor(
}
})
}
+
+ private fun calcPercentageWithConstraints() {
+ calculatedPercentage = 100.0
+ if (totalBeforePercentageAdjustment != insulinFromCorrection)
+ calculatedPercentage = calculatedTotalInsulin/(totalBeforePercentageAdjustment-insulinFromCorrection)*100
+ calculatedPercentage = max(calculatedPercentage, 10.0)
+ calculatedPercentage = min(calculatedPercentage,250.0)
+ }
+
+ private fun calcCorrectionWithConstraints() {
+ val bolusStep = activePlugin.activePump.pumpDescription.bolusStep
+ calculatedCorrection = Round.roundTo(totalBeforePercentageAdjustment * totalPercentage / percentageCorrection - totalBeforePercentageAdjustment, bolusStep)
+ //Apply constraints
+ calculatedCorrection = min(constraintChecker.getMaxBolusAllowed().value(), calculatedCorrection)
+ calculatedCorrection = max(-constraintChecker.getMaxBolusAllowed().value(), calculatedCorrection)
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/res/layout/dialog_wizard.xml b/app/src/main/res/layout/dialog_wizard.xml
index ce32053308..635ff30447 100644
--- a/app/src/main/res/layout/dialog_wizard.xml
+++ b/app/src/main/res/layout/dialog_wizard.xml
@@ -118,14 +118,42 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
-
+ android:orientation="horizontal">
+
+
+
+
+
+
+
+
+
+
+
Units
Do you want to switch profile and discard changes made to current profile?
wizard_calculation_visible
+ wizard_correction_percent
Clear finished
Clear started
Do you want reset objective start? You may lose your progress.