Add selector to allow correction in percentage
This commit is contained in:
parent
a83eb1c456
commit
88b2a8d0d7
4 changed files with 132 additions and 25 deletions
|
@ -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")
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
}
|
|
@ -118,6 +118,13 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_weight="1"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
@ -127,6 +134,27 @@
|
|||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textStyle="bold" />
|
||||
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:text=" %"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/correction_percent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:padding="2dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.NumberPicker
|
||||
android:id="@+id/correction_input"
|
||||
android:layout_width="130dp"
|
||||
|
@ -134,6 +162,7 @@
|
|||
android:layout_gravity="center_horizontal" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/correction_unit"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
|
|
|
@ -934,6 +934,7 @@
|
|||
<string name="unitsnosemicolon">Units</string>
|
||||
<string name="doyouwantswitchprofile">Do you want to switch profile and discard changes made to current profile?</string>
|
||||
<string name="key_wizard_calculation_visible" translatable="false">wizard_calculation_visible</string>
|
||||
<string name="key_wizard_correction_percent" translatable="false">wizard_correction_percent</string>
|
||||
<string name="objectives_button_unfinish">Clear finished</string>
|
||||
<string name="objectives_button_unstart">Clear started</string>
|
||||
<string name="doyouwantresetstart">Do you want reset objective start? You may lose your progress.</string>
|
||||
|
|
Loading…
Reference in a new issue