Bolus advisor
This commit is contained in:
parent
4238e9cab3
commit
c8f7dae2c8
17 changed files with 602 additions and 310 deletions
|
@ -18,6 +18,7 @@ import info.nightscout.androidaps.Constants
|
|||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.data.Profile
|
||||
import info.nightscout.androidaps.databinding.DialogWizardBinding
|
||||
import info.nightscout.androidaps.db.BgReading
|
||||
import info.nightscout.androidaps.interfaces.ActivePluginProvider
|
||||
import info.nightscout.androidaps.interfaces.Constraint
|
||||
|
@ -39,7 +40,6 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP
|
|||
import info.nightscout.androidaps.utils.wizard.BolusWizard
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import kotlinx.android.synthetic.main.dialog_wizard.*
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
|
@ -72,8 +72,23 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
}
|
||||
}
|
||||
|
||||
private val timeTextWatcher = object : TextWatcher {
|
||||
override fun afterTextChanged(s: Editable) {}
|
||||
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
|
||||
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||
calculateInsulin()
|
||||
binding.alarm.isChecked = binding.carbTimeInput.value > 0
|
||||
}
|
||||
}
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
|
||||
private var _binding: DialogWizardBinding? = null
|
||||
|
||||
// This property is only valid between onCreateView and
|
||||
// onDestroyView.
|
||||
private val binding get() = _binding!!
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
dialog?.window?.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||
|
@ -81,49 +96,50 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
|
||||
override fun onSaveInstanceState(savedInstanceState: Bundle) {
|
||||
super.onSaveInstanceState(savedInstanceState)
|
||||
savedInstanceState.putDouble("treatments_wizard_bg_input", treatments_wizard_bg_input.value)
|
||||
savedInstanceState.putDouble("treatments_wizard_carbs_input", treatments_wizard_carbs_input.value)
|
||||
savedInstanceState.putDouble("treatments_wizard_correction_input", treatments_wizard_correction_input.value)
|
||||
savedInstanceState.putDouble("treatments_wizard_carb_time_input", treatments_wizard_carb_time_input.value)
|
||||
savedInstanceState.putDouble("bg_input", binding.bgInput.value)
|
||||
savedInstanceState.putDouble("carbs_input", binding.carbsInput.value)
|
||||
savedInstanceState.putDouble("correction_input", binding.correctionInput.value)
|
||||
savedInstanceState.putDouble("carb_time_input", binding.carbTimeInput.value)
|
||||
}
|
||||
|
||||
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?): View? {
|
||||
savedInstanceState: Bundle?): View {
|
||||
dialog?.window?.requestFeature(Window.FEATURE_NO_TITLE)
|
||||
dialog?.window?.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN)
|
||||
isCancelable = true
|
||||
dialog?.setCanceledOnTouchOutside(false)
|
||||
|
||||
return inflater.inflate(R.layout.dialog_wizard, container, false)
|
||||
_binding = DialogWizardBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
loadCheckedStates()
|
||||
processCobCheckBox()
|
||||
treatments_wizard_sbcheckbox.visibility = sp.getBoolean(R.string.key_usesuperbolus, false).toVisibility()
|
||||
treatments_wizard_notes_layout.visibility = sp.getBoolean(R.string.key_show_notes_entry_dialogs, false).toVisibility()
|
||||
binding.sbcheckbox.visibility = sp.getBoolean(R.string.key_usesuperbolus, false).toVisibility()
|
||||
binding.notesLayout.visibility = sp.getBoolean(R.string.key_show_notes_entry_dialogs, false).toVisibility()
|
||||
|
||||
val maxCarbs = constraintChecker.getMaxCarbsAllowed().value()
|
||||
val maxCorrection = constraintChecker.getMaxBolusAllowed().value()
|
||||
|
||||
if (profileFunction.getUnits() == Constants.MGDL)
|
||||
treatments_wizard_bg_input.setParams(savedInstanceState?.getDouble("treatments_wizard_bg_input")
|
||||
?: 0.0, 0.0, 500.0, 1.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||
binding.bgInput.setParams(savedInstanceState?.getDouble("bg_input")
|
||||
?: 0.0, 0.0, 500.0, 1.0, DecimalFormat("0"), false, binding.ok, timeTextWatcher)
|
||||
else
|
||||
treatments_wizard_bg_input.setParams(savedInstanceState?.getDouble("treatments_wizard_bg_input")
|
||||
?: 0.0, 0.0, 30.0, 0.1, DecimalFormat("0.0"), false, ok, textWatcher)
|
||||
treatments_wizard_carbs_input.setParams(savedInstanceState?.getDouble("treatments_wizard_carbs_input")
|
||||
?: 0.0, 0.0, maxCarbs.toDouble(), 1.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||
binding.bgInput.setParams(savedInstanceState?.getDouble("bg_input")
|
||||
?: 0.0, 0.0, 30.0, 0.1, DecimalFormat("0.0"), false, binding.ok, textWatcher)
|
||||
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
|
||||
treatments_wizard_correction_input.setParams(savedInstanceState?.getDouble("treatments_wizard_correction_input")
|
||||
?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), false, ok, textWatcher)
|
||||
treatments_wizard_carb_time_input.setParams(savedInstanceState?.getDouble("treatments_wizard_carb_time_input")
|
||||
?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, ok, textWatcher)
|
||||
binding.correctionInput.setParams(savedInstanceState?.getDouble("correction_input")
|
||||
?: 0.0, -maxCorrection, maxCorrection, bolusStep, DecimalFormatter.pumpSupportedBolusFormat(activePlugin.activePump), false, binding.ok, textWatcher)
|
||||
binding.carbTimeInput.setParams(savedInstanceState?.getDouble("carb_time_input")
|
||||
?: 0.0, -60.0, 60.0, 5.0, DecimalFormat("0"), false, binding.ok, timeTextWatcher)
|
||||
initDialog()
|
||||
|
||||
treatments_wizard_percent_used.text = resourceHelper.gs(R.string.format_percent, sp.getInt(R.string.key_boluswizard_percentage, 100))
|
||||
binding.percentUsed.text = resourceHelper.gs(R.string.format_percent, sp.getInt(R.string.key_boluswizard_percentage, 100))
|
||||
// ok button
|
||||
ok.setOnClickListener {
|
||||
binding.ok.setOnClickListener {
|
||||
if (okClicked) {
|
||||
aapsLogger.debug(LTag.UI, "guarding: ok already clicked")
|
||||
} else {
|
||||
|
@ -136,37 +152,37 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
dismiss()
|
||||
}
|
||||
// cancel button
|
||||
cancel.setOnClickListener { dismiss() }
|
||||
binding.cancel.setOnClickListener { dismiss() }
|
||||
// checkboxes
|
||||
treatments_wizard_bgcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_ttcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_cobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_basaliobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_bolusiobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_bgtrendcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
treatments_wizard_sbcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.bgcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.ttcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.cobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.basaliobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.bolusiobcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.bgtrendcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
binding.sbcheckbox.setOnCheckedChangeListener(::onCheckedChanged)
|
||||
|
||||
val showCalc = sp.getBoolean(R.string.key_wizard_calculation_visible, false)
|
||||
treatments_wizard_delimiter.visibility = showCalc.toVisibility()
|
||||
treatments_wizard_resulttable.visibility = showCalc.toVisibility()
|
||||
treatments_wizard_calculationcheckbox.isChecked = showCalc
|
||||
treatments_wizard_calculationcheckbox.setOnCheckedChangeListener { _, isChecked ->
|
||||
binding.delimiter.visibility = showCalc.toVisibility()
|
||||
binding.resulttable.visibility = showCalc.toVisibility()
|
||||
binding.calculationcheckbox.isChecked = showCalc
|
||||
binding.calculationcheckbox.setOnCheckedChangeListener { _, isChecked ->
|
||||
run {
|
||||
sp.putBoolean(resourceHelper.gs(R.string.key_wizard_calculation_visible), isChecked)
|
||||
treatments_wizard_delimiter.visibility = isChecked.toVisibility()
|
||||
treatments_wizard_resulttable.visibility = isChecked.toVisibility()
|
||||
binding.delimiter.visibility = isChecked.toVisibility()
|
||||
binding.resulttable.visibility = isChecked.toVisibility()
|
||||
}
|
||||
}
|
||||
// profile spinner
|
||||
treatments_wizard_profile.onItemSelectedListener = object : OnItemSelectedListener {
|
||||
binding.profile.onItemSelectedListener = object : OnItemSelectedListener {
|
||||
override fun onNothingSelected(parent: AdapterView<*>?) {
|
||||
ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.noprofileselected))
|
||||
ok.visibility = View.GONE
|
||||
binding.ok.visibility = View.GONE
|
||||
}
|
||||
|
||||
override fun onItemSelected(parent: AdapterView<*>?, view: View?, position: Int, id: Long) {
|
||||
calculateInsulin()
|
||||
ok.visibility = View.VISIBLE
|
||||
binding.ok.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
// bus
|
||||
|
@ -183,36 +199,37 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
disposable.clear()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
private fun onCheckedChanged(buttonView: CompoundButton, @Suppress("UNUSED_PARAMETER") state: Boolean) {
|
||||
saveCheckedStates()
|
||||
treatments_wizard_ttcheckbox.isEnabled = treatments_wizard_bgcheckbox.isChecked && treatmentsPlugin.tempTargetFromHistory != null
|
||||
if (buttonView.id == treatments_wizard_cobcheckbox.id)
|
||||
binding.ttcheckbox.isEnabled = binding.bgcheckbox.isChecked && treatmentsPlugin.tempTargetFromHistory != null
|
||||
if (buttonView.id == binding.cobcheckbox.id)
|
||||
processCobCheckBox()
|
||||
calculateInsulin()
|
||||
}
|
||||
|
||||
private fun processCobCheckBox() {
|
||||
if (treatments_wizard_cobcheckbox.isChecked) {
|
||||
treatments_wizard_bolusiobcheckbox.isEnabled = false
|
||||
treatments_wizard_basaliobcheckbox.isEnabled = false
|
||||
treatments_wizard_bolusiobcheckbox.isChecked = true
|
||||
treatments_wizard_basaliobcheckbox.isChecked = true
|
||||
if (binding.cobcheckbox.isChecked) {
|
||||
binding.bolusiobcheckbox.isEnabled = false
|
||||
binding.basaliobcheckbox.isEnabled = false
|
||||
binding.bolusiobcheckbox.isChecked = true
|
||||
binding.basaliobcheckbox.isChecked = true
|
||||
} else {
|
||||
treatments_wizard_bolusiobcheckbox.isEnabled = true
|
||||
treatments_wizard_basaliobcheckbox.isEnabled = true
|
||||
binding.bolusiobcheckbox.isEnabled = true
|
||||
binding.basaliobcheckbox.isEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun saveCheckedStates() {
|
||||
sp.putBoolean(resourceHelper.gs(R.string.key_wizard_include_cob), treatments_wizard_cobcheckbox.isChecked)
|
||||
sp.putBoolean(resourceHelper.gs(R.string.key_wizard_include_trend_bg), treatments_wizard_bgtrendcheckbox.isChecked)
|
||||
sp.putBoolean(R.string.key_wizard_include_cob, binding.cobcheckbox.isChecked)
|
||||
sp.putBoolean(R.string.key_wizard_include_trend_bg, binding.bgtrendcheckbox.isChecked)
|
||||
}
|
||||
|
||||
private fun loadCheckedStates() {
|
||||
treatments_wizard_bgtrendcheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_trend_bg, false)
|
||||
treatments_wizard_cobcheckbox.isChecked = sp.getBoolean(R.string.key_wizard_include_cob, false)
|
||||
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)
|
||||
}
|
||||
|
||||
private fun initDialog() {
|
||||
|
@ -230,25 +247,25 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
profileList.add(0, resourceHelper.gs(R.string.active))
|
||||
context?.let { context ->
|
||||
val adapter = ArrayAdapter(context, R.layout.spinner_centered, profileList)
|
||||
treatments_wizard_profile.adapter = adapter
|
||||
binding.profile.adapter = adapter
|
||||
} ?: return
|
||||
|
||||
val units = profileFunction.getUnits()
|
||||
treatments_wizard_bgunits.text = units
|
||||
binding.bgunits.text = units
|
||||
if (units == Constants.MGDL)
|
||||
treatments_wizard_bg_input.setStep(1.0)
|
||||
binding.bgInput.setStep(1.0)
|
||||
else
|
||||
treatments_wizard_bg_input.setStep(0.1)
|
||||
binding.bgInput.setStep(0.1)
|
||||
|
||||
// Set BG if not old
|
||||
val lastBg = iobCobCalculatorPlugin.actualBg()
|
||||
|
||||
if (lastBg != null) {
|
||||
treatments_wizard_bg_input.value = lastBg.valueToUnits(units)
|
||||
binding.bgInput.value = lastBg.valueToUnits(units)
|
||||
} else {
|
||||
treatments_wizard_bg_input.value = 0.0
|
||||
binding.bgInput.value = 0.0
|
||||
}
|
||||
treatments_wizard_ttcheckbox.isEnabled = treatmentsPlugin.tempTargetFromHistory != null
|
||||
binding.ttcheckbox.isEnabled = treatmentsPlugin.tempTargetFromHistory != null
|
||||
|
||||
// IOB calculation
|
||||
treatmentsPlugin.updateTotalIOBTreatments()
|
||||
|
@ -256,19 +273,19 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
treatmentsPlugin.updateTotalIOBTempBasals()
|
||||
val basalIob = treatmentsPlugin.lastCalculationTempBasals.round()
|
||||
|
||||
treatments_wizard_bolusiobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, -bolusIob.iob)
|
||||
treatments_wizard_basaliobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, -basalIob.basaliob)
|
||||
binding.bolusiobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, -bolusIob.iob)
|
||||
binding.basaliobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, -basalIob.basaliob)
|
||||
|
||||
calculateInsulin()
|
||||
|
||||
treatments_wizard_percent_used.visibility = (sp.getInt(R.string.key_boluswizard_percentage, 100) != 100).toVisibility()
|
||||
binding.percentUsed.visibility = (sp.getInt(R.string.key_boluswizard_percentage, 100) != 100).toVisibility()
|
||||
}
|
||||
|
||||
private fun calculateInsulin() {
|
||||
val profileStore = activePlugin.activeProfileInterface.profile
|
||||
if (treatments_wizard_profile?.selectedItem == null || profileStore == null)
|
||||
if (binding.profile.selectedItem == null || profileStore == null)
|
||||
return // not initialized yet
|
||||
var profileName = treatments_wizard_profile.selectedItem.toString()
|
||||
var profileName = binding.profile.selectedItem.toString()
|
||||
val specificProfile: Profile?
|
||||
if (profileName == resourceHelper.gs(R.string.active)) {
|
||||
specificProfile = profileFunction.getProfile()
|
||||
|
@ -279,82 +296,83 @@ class WizardDialog : DaggerDialogFragment() {
|
|||
if (specificProfile == null) return
|
||||
|
||||
// Entered values
|
||||
var bg = SafeParse.stringToDouble(treatments_wizard_bg_input.text)
|
||||
val carbs = SafeParse.stringToInt(treatments_wizard_carbs_input.text)
|
||||
val correction = SafeParse.stringToDouble(treatments_wizard_correction_input.text)
|
||||
var bg = SafeParse.stringToDouble(binding.bgInput.text)
|
||||
val carbs = SafeParse.stringToInt(binding.carbsInput.text)
|
||||
val correction = SafeParse.stringToDouble(binding.correctionInput.text)
|
||||
val carbsAfterConstraint = constraintChecker.applyCarbsConstraints(Constraint(carbs)).value()
|
||||
if (abs(carbs - carbsAfterConstraint) > 0.01) {
|
||||
treatments_wizard_carbs_input.value = 0.0
|
||||
binding.carbsInput.value = 0.0
|
||||
ToastUtils.showToastInUiThread(mainApp, resourceHelper.gs(R.string.carbsconstraintapplied))
|
||||
return
|
||||
}
|
||||
|
||||
bg = if (treatments_wizard_bgcheckbox.isChecked) bg else 0.0
|
||||
val tempTarget = if (treatments_wizard_ttcheckbox.isChecked) treatmentsPlugin.tempTargetFromHistory else null
|
||||
bg = if (binding.bgcheckbox.isChecked) bg else 0.0
|
||||
val tempTarget = if (binding.ttcheckbox.isChecked) treatmentsPlugin.tempTargetFromHistory else null
|
||||
|
||||
// COB
|
||||
var cob = 0.0
|
||||
if (treatments_wizard_cobcheckbox.isChecked) {
|
||||
if (binding.cobcheckbox.isChecked) {
|
||||
val cobInfo = iobCobCalculatorPlugin.getCobInfo(false, "Wizard COB")
|
||||
cobInfo.displayCob?.let { cob = it }
|
||||
}
|
||||
|
||||
val carbTime = SafeParse.stringToInt(treatments_wizard_carb_time_input.text)
|
||||
val carbTime = SafeParse.stringToInt(binding.carbTimeInput.text)
|
||||
|
||||
wizard = BolusWizard(mainApp).doCalc(specificProfile, profileName, tempTarget, carbsAfterConstraint, cob, bg, correction,
|
||||
sp.getInt(R.string.key_boluswizard_percentage, 100).toDouble(),
|
||||
treatments_wizard_bgcheckbox.isChecked,
|
||||
treatments_wizard_cobcheckbox.isChecked,
|
||||
treatments_wizard_bolusiobcheckbox.isChecked,
|
||||
treatments_wizard_basaliobcheckbox.isChecked,
|
||||
treatments_wizard_sbcheckbox.isChecked,
|
||||
treatments_wizard_ttcheckbox.isChecked,
|
||||
treatments_wizard_bgtrendcheckbox.isChecked,
|
||||
treatment_wizard_notes.text.toString(), carbTime)
|
||||
binding.bgcheckbox.isChecked,
|
||||
binding.cobcheckbox.isChecked,
|
||||
binding.bolusiobcheckbox.isChecked,
|
||||
binding.basaliobcheckbox.isChecked,
|
||||
binding.sbcheckbox.isChecked,
|
||||
binding.ttcheckbox.isChecked,
|
||||
binding.bgtrendcheckbox.isChecked,
|
||||
binding.alarm.isChecked,
|
||||
binding.notes.text.toString(), carbTime)
|
||||
|
||||
wizard?.let { wizard ->
|
||||
treatments_wizard_bg.text = String.format(resourceHelper.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, profileFunction.getUnits())).valueToUnitsToString(profileFunction.getUnits()), wizard.sens)
|
||||
treatments_wizard_bginsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBG)
|
||||
binding.bg.text = String.format(resourceHelper.gs(R.string.format_bg_isf), BgReading().value(Profile.toMgdl(bg, profileFunction.getUnits())).valueToUnitsToString(profileFunction.getUnits()), wizard.sens)
|
||||
binding.bginsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBG)
|
||||
|
||||
treatments_wizard_carbs.text = String.format(resourceHelper.gs(R.string.format_carbs_ic), carbs.toDouble(), wizard.ic)
|
||||
treatments_wizard_carbsinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromCarbs)
|
||||
binding.carbs.text = String.format(resourceHelper.gs(R.string.format_carbs_ic), carbs.toDouble(), wizard.ic)
|
||||
binding.carbsinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromCarbs)
|
||||
|
||||
treatments_wizard_bolusiobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBolusIOB)
|
||||
treatments_wizard_basaliobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBasalsIOB)
|
||||
binding.bolusiobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBolusIOB)
|
||||
binding.basaliobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromBasalIOB)
|
||||
|
||||
treatments_wizard_correctioninsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromCorrection)
|
||||
binding.correctioninsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromCorrection)
|
||||
|
||||
// Superbolus
|
||||
treatments_wizard_sb.text = if (treatments_wizard_sbcheckbox.isChecked) resourceHelper.gs(R.string.twohours) else ""
|
||||
treatments_wizard_sbinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromSuperBolus)
|
||||
binding.sb.text = if (binding.sbcheckbox.isChecked) resourceHelper.gs(R.string.twohours) else ""
|
||||
binding.sbinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromSuperBolus)
|
||||
|
||||
// Trend
|
||||
if (treatments_wizard_bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) {
|
||||
treatments_wizard_bgtrend.text = ((if (wizard.trend > 0) "+" else "")
|
||||
if (binding.bgtrendcheckbox.isChecked && wizard.glucoseStatus != null) {
|
||||
binding.bgtrend.text = ((if (wizard.trend > 0) "+" else "")
|
||||
+ Profile.toUnitsString(wizard.trend * 3, wizard.trend * 3 / Constants.MMOLL_TO_MGDL, profileFunction.getUnits())
|
||||
+ " " + profileFunction.getUnits())
|
||||
} else {
|
||||
treatments_wizard_bgtrend.text = ""
|
||||
binding.bgtrend.text = ""
|
||||
}
|
||||
treatments_wizard_bgtrendinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromTrend)
|
||||
binding.bgtrendinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromTrend)
|
||||
|
||||
// COB
|
||||
if (treatments_wizard_cobcheckbox.isChecked) {
|
||||
treatments_wizard_cob.text = String.format(resourceHelper.gs(R.string.format_cob_ic), cob, wizard.ic)
|
||||
treatments_wizard_cobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromCOB)
|
||||
if (binding.cobcheckbox.isChecked) {
|
||||
binding.cob.text = String.format(resourceHelper.gs(R.string.format_cob_ic), cob, wizard.ic)
|
||||
binding.cobinsulin.text = resourceHelper.gs(R.string.formatinsulinunits, wizard.insulinFromCOB)
|
||||
} else {
|
||||
treatments_wizard_cob.text = ""
|
||||
treatments_wizard_cobinsulin.text = ""
|
||||
binding.cob.text = ""
|
||||
binding.cobinsulin.text = ""
|
||||
}
|
||||
|
||||
if (wizard.calculatedTotalInsulin > 0.0 || carbsAfterConstraint > 0.0) {
|
||||
val insulinText = if (wizard.calculatedTotalInsulin > 0.0) resourceHelper.gs(R.string.formatinsulinunits, wizard.calculatedTotalInsulin) else ""
|
||||
val carbsText = if (carbsAfterConstraint > 0.0) resourceHelper.gs(R.string.format_carbs, carbsAfterConstraint) else ""
|
||||
treatments_wizard_total.text = resourceHelper.gs(R.string.result_insulin_carbs, insulinText, carbsText)
|
||||
ok.visibility = View.VISIBLE
|
||||
binding.total.text = resourceHelper.gs(R.string.result_insulin_carbs, insulinText, carbsText)
|
||||
binding.ok.visibility = View.VISIBLE
|
||||
} else {
|
||||
treatments_wizard_total.text = resourceHelper.gs(R.string.missing_carbs, wizard.carbsEquivalent.toInt())
|
||||
ok.visibility = View.INVISIBLE
|
||||
binding.total.text = resourceHelper.gs(R.string.missing_carbs, wizard.carbsEquivalent.toInt())
|
||||
binding.ok.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,8 @@ import androidx.annotation.DrawableRes
|
|||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import dagger.android.HasAndroidInjector
|
||||
import dagger.android.support.DaggerFragment
|
||||
import info.nightscout.androidaps.MainApp
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.databinding.AutomationEventItemBinding
|
||||
import info.nightscout.androidaps.databinding.AutomationFragmentBinding
|
||||
|
@ -46,7 +46,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
|
|||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var fabricPrivacy: FabricPrivacy
|
||||
@Inject lateinit var automationPlugin: AutomationPlugin
|
||||
@Inject lateinit var mainApp: MainApp
|
||||
@Inject lateinit var injector: HasAndroidInjector
|
||||
|
||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||
private lateinit var eventListAdapter: EventListAdapter
|
||||
|
@ -76,7 +76,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
|
|||
binding.fabAddEvent.setOnClickListener {
|
||||
val dialog = EditEventDialog()
|
||||
val args = Bundle()
|
||||
args.putString("event", AutomationEvent(mainApp).toJSON())
|
||||
args.putString("event", AutomationEvent(injector).toJSON())
|
||||
args.putInt("position", -1) // New event
|
||||
dialog.arguments = args
|
||||
dialog.show(childFragmentManager, "EditEventDialog")
|
||||
|
@ -159,7 +159,7 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
|
|||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val event = automationPlugin.automationEvents[position]
|
||||
val event = automationPlugin.at(position)
|
||||
holder.binding.eventTitle.text = event.title
|
||||
holder.binding.enabled.isChecked = event.isEnabled
|
||||
holder.binding.enabled.isEnabled = !event.readOnly
|
||||
|
@ -190,15 +190,14 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
|
|||
rxBus.send(EventAutomationDataChanged())
|
||||
}
|
||||
// edit event
|
||||
if (!event.readOnly)
|
||||
holder.binding.rootLayout.setOnClickListener {
|
||||
val dialog = EditEventDialog()
|
||||
val args = Bundle()
|
||||
args.putString("event", event.toJSON())
|
||||
args.putInt("position", position)
|
||||
dialog.arguments = args
|
||||
dialog.show(childFragmentManager, "EditEventDialog")
|
||||
}
|
||||
holder.binding.rootLayout.setOnClickListener {
|
||||
val dialog = EditEventDialog()
|
||||
val args = Bundle()
|
||||
args.putString("event", event.toJSON())
|
||||
args.putInt("position", position)
|
||||
dialog.arguments = args
|
||||
dialog.show(childFragmentManager, "EditEventDialog")
|
||||
}
|
||||
// Start a drag whenever the handle view it touched
|
||||
holder.binding.iconSort.setOnTouchListener { v: View, motionEvent: MotionEvent ->
|
||||
if (motionEvent.action == MotionEvent.ACTION_DOWN) {
|
||||
|
@ -209,36 +208,33 @@ class AutomationFragment : DaggerFragment(), OnStartDragListener {
|
|||
}
|
||||
// remove event
|
||||
holder.binding.iconTrash.setOnClickListener {
|
||||
showConfirmation(requireContext(), resourceHelper.gs(R.string.removerecord) + " " + automationPlugin.automationEvents[position].title,
|
||||
showConfirmation(requireContext(), resourceHelper.gs(R.string.removerecord) + " " + automationPlugin.at(position).title,
|
||||
Runnable {
|
||||
automationPlugin.automationEvents.removeAt(position)
|
||||
automationPlugin.removeAt(position)
|
||||
notifyItemRemoved(position)
|
||||
rxBus.send(EventAutomationDataChanged())
|
||||
rxBus.send(EventAutomationUpdateGui())
|
||||
}, Runnable {
|
||||
rxBus.send(EventAutomationUpdateGui())
|
||||
})
|
||||
}
|
||||
holder.binding.iconTrash.visibility = (!event.readOnly).toVisibility()
|
||||
holder.binding.aapsLogo.visibility = (event.systemAction).toVisibility()
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = automationPlugin.automationEvents.size
|
||||
override fun getItemCount(): Int = automationPlugin.size()
|
||||
|
||||
override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
|
||||
Collections.swap(automationPlugin.automationEvents, fromPosition, toPosition)
|
||||
automationPlugin.swap(fromPosition, toPosition)
|
||||
notifyItemMoved(fromPosition, toPosition)
|
||||
rxBus.send(EventAutomationDataChanged())
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onItemDismiss(position: Int) {
|
||||
activity?.let { activity ->
|
||||
showConfirmation(activity, resourceHelper.gs(R.string.removerecord) + " " + automationPlugin.automationEvents[position].title,
|
||||
showConfirmation(activity, resourceHelper.gs(R.string.removerecord) + " " + automationPlugin.at(position).title,
|
||||
Runnable {
|
||||
automationPlugin.automationEvents.removeAt(position)
|
||||
automationPlugin.removeAt(position)
|
||||
notifyItemRemoved(position)
|
||||
rxBus.send(EventAutomationDataChanged())
|
||||
rxBus.send(EventAutomationUpdateGui())
|
||||
}, Runnable { rxBus.send(EventAutomationUpdateGui()) })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,8 +39,10 @@ import io.reactivex.schedulers.Schedulers
|
|||
import org.json.JSONArray
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
import kotlin.collections.ArrayList
|
||||
|
||||
@Singleton
|
||||
class AutomationPlugin @Inject constructor(
|
||||
|
@ -69,7 +71,7 @@ class AutomationPlugin @Inject constructor(
|
|||
|
||||
private val keyAutomationEvents = "AUTOMATION_EVENTS"
|
||||
|
||||
val automationEvents = ArrayList<AutomationEvent>()
|
||||
private val automationEvents = ArrayList<AutomationEvent>()
|
||||
var executionLog: MutableList<String> = ArrayList()
|
||||
var btConnects: MutableList<EventBTChange> = ArrayList()
|
||||
|
||||
|
@ -77,6 +79,7 @@ class AutomationPlugin @Inject constructor(
|
|||
private lateinit var refreshLoop: Runnable
|
||||
|
||||
companion object {
|
||||
|
||||
const val event = "{\"title\":\"Low\",\"enabled\":true,\"trigger\":\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector\\\",\\\"data\\\":{\\\"connectorType\\\":\\\"AND\\\",\\\"triggerList\\\":[\\\"{\\\\\\\"type\\\\\\\":\\\\\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerBg\\\\\\\",\\\\\\\"data\\\\\\\":{\\\\\\\"bg\\\\\\\":4,\\\\\\\"comparator\\\\\\\":\\\\\\\"IS_LESSER\\\\\\\",\\\\\\\"units\\\\\\\":\\\\\\\"mmol\\\\\\\"}}\\\",\\\"{\\\\\\\"type\\\\\\\":\\\\\\\"info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDelta\\\\\\\",\\\\\\\"data\\\\\\\":{\\\\\\\"value\\\\\\\":-0.1,\\\\\\\"units\\\\\\\":\\\\\\\"mmol\\\\\\\",\\\\\\\"deltaType\\\\\\\":\\\\\\\"DELTA\\\\\\\",\\\\\\\"comparator\\\\\\\":\\\\\\\"IS_LESSER\\\\\\\"}}\\\"]}}\",\"actions\":[\"{\\\"type\\\":\\\"info.nightscout.androidaps.plugins.general.automation.actions.ActionStartTempTarget\\\",\\\"data\\\":{\\\"value\\\":8,\\\"units\\\":\\\"mmol\\\",\\\"durationInMinutes\\\":60}}\"]}"
|
||||
}
|
||||
|
||||
|
@ -184,42 +187,46 @@ class AutomationPlugin @Inject constructor(
|
|||
|
||||
@Synchronized
|
||||
private fun processActions() {
|
||||
var userEventsEnabled = true
|
||||
if (loopPlugin.isSuspended || !loopPlugin.isEnabled()) {
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Loop deactivated")
|
||||
executionLog.add(resourceHelper.gs(R.string.smscommunicator_loopisdisabled))
|
||||
return
|
||||
userEventsEnabled = false
|
||||
}
|
||||
val enabled = constraintChecker.isAutomationEnabled()
|
||||
if (!enabled.value()) {
|
||||
executionLog.add(enabled.getMostLimitedReasons(aapsLogger))
|
||||
return
|
||||
userEventsEnabled = false
|
||||
}
|
||||
|
||||
aapsLogger.debug(LTag.AUTOMATION, "processActions")
|
||||
for (event in automationEvents) {
|
||||
if (event.isEnabled && event.shouldRun() && event.trigger.shouldRun() && event.getPreconditions().shouldRun()) {
|
||||
val actions = event.actions
|
||||
for (action in actions) {
|
||||
action.doAction(object : Callback() {
|
||||
override fun run() {
|
||||
val sb = StringBuilder()
|
||||
sb.append(dateUtil.timeString(DateUtil.now()))
|
||||
sb.append(" ")
|
||||
sb.append(if (result.success) "☺" else "▼")
|
||||
sb.append(" <b>")
|
||||
sb.append(event.title)
|
||||
sb.append(":</b> ")
|
||||
sb.append(action.shortDescription())
|
||||
sb.append(": ")
|
||||
sb.append(result.comment)
|
||||
executionLog.add(sb.toString())
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Executed: $sb")
|
||||
rxBus.send(EventAutomationUpdateGui())
|
||||
}
|
||||
})
|
||||
if (event.systemAction || userEventsEnabled) {
|
||||
val actions = event.actions
|
||||
for (action in actions) {
|
||||
action.doAction(object : Callback() {
|
||||
override fun run() {
|
||||
val sb = StringBuilder()
|
||||
sb.append(dateUtil.timeString(DateUtil.now()))
|
||||
sb.append(" ")
|
||||
sb.append(if (result.success) "☺" else "▼")
|
||||
sb.append(" <b>")
|
||||
sb.append(event.title)
|
||||
sb.append(":</b> ")
|
||||
sb.append(action.shortDescription())
|
||||
sb.append(": ")
|
||||
sb.append(result.comment)
|
||||
executionLog.add(sb.toString())
|
||||
aapsLogger.debug(LTag.AUTOMATION, "Executed: $sb")
|
||||
rxBus.send(EventAutomationUpdateGui())
|
||||
}
|
||||
})
|
||||
}
|
||||
SystemClock.sleep(1100)
|
||||
event.lastRun = DateUtil.now()
|
||||
if (event.autoRemove) automationEvents.remove(event)
|
||||
}
|
||||
SystemClock.sleep(1100)
|
||||
event.lastRun = DateUtil.now()
|
||||
}
|
||||
}
|
||||
// we cannot detect connected BT devices
|
||||
|
@ -231,6 +238,38 @@ class AutomationPlugin @Inject constructor(
|
|||
storeToSP() // save last run time
|
||||
}
|
||||
|
||||
fun add(event: AutomationEvent) {
|
||||
automationEvents.add(event)
|
||||
rxBus.send(EventAutomationDataChanged())
|
||||
}
|
||||
|
||||
fun addIfNotExists(event: AutomationEvent) {
|
||||
for (e in automationEvents) {
|
||||
if (event.title == e.title) return
|
||||
}
|
||||
automationEvents.add(event)
|
||||
rxBus.send(EventAutomationDataChanged())
|
||||
}
|
||||
|
||||
fun set(event: AutomationEvent, index: Int) {
|
||||
automationEvents[index] = event
|
||||
rxBus.send(EventAutomationDataChanged())
|
||||
}
|
||||
|
||||
fun removeAt(index: Int) {
|
||||
automationEvents.removeAt(index)
|
||||
rxBus.send(EventAutomationDataChanged())
|
||||
}
|
||||
|
||||
fun at(index: Int) = automationEvents[index]
|
||||
|
||||
fun size() = automationEvents.size
|
||||
|
||||
fun swap(fromPosition: Int, toPosition: Int) {
|
||||
Collections.swap(automationEvents, fromPosition, toPosition)
|
||||
rxBus.send(EventAutomationDataChanged())
|
||||
}
|
||||
|
||||
fun getActionDummyObjects(): List<Action> {
|
||||
return listOf(
|
||||
//ActionLoopDisable(injector),
|
||||
|
|
|
@ -33,6 +33,9 @@ class ActionAlarm(injector: HasAndroidInjector) : Action(injector) {
|
|||
|
||||
var text = InputString(injector)
|
||||
|
||||
constructor(injector: HasAndroidInjector, text: String) : this(injector) {
|
||||
this.text = InputString(injector, text)
|
||||
}
|
||||
override fun friendlyName(): Int = R.string.alarm
|
||||
override fun shortDescription(): String = resourceHelper.gs(R.string.alarm_message, text.value)
|
||||
@DrawableRes override fun icon(): Int = R.drawable.ic_access_alarm_24dp
|
||||
|
|
|
@ -26,6 +26,7 @@ import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerCon
|
|||
import info.nightscout.androidaps.utils.FabricPrivacy
|
||||
import info.nightscout.androidaps.utils.ToastUtils
|
||||
import info.nightscout.androidaps.utils.extensions.plusAssign
|
||||
import info.nightscout.androidaps.utils.extensions.toVisibility
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
import javax.inject.Inject
|
||||
|
@ -66,9 +67,13 @@ class EditEventDialog : DialogFragmentWithDate() {
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.okcancel.ok.visibility = (!event.readOnly).toVisibility()
|
||||
|
||||
binding.inputEventTitle.setText(event.title)
|
||||
binding.inputEventTitle.isFocusable = false
|
||||
binding.triggerDescription.text = event.trigger.friendlyDescription()
|
||||
|
||||
binding.editTrigger.visibility = (!event.readOnly).toVisibility()
|
||||
binding.editTrigger.setOnClickListener {
|
||||
val args = Bundle()
|
||||
args.putString("trigger", event.trigger.toJSON())
|
||||
|
@ -82,6 +87,7 @@ class EditEventDialog : DialogFragmentWithDate() {
|
|||
binding.actionListView.layoutManager = LinearLayoutManager(context)
|
||||
binding.actionListView.adapter = actionListAdapter
|
||||
|
||||
binding.addAction.visibility = (!event.readOnly).toVisibility()
|
||||
binding.addAction.setOnClickListener { ChooseActionDialog().show(childFragmentManager, "ChooseActionDialog") }
|
||||
|
||||
showPreconditions()
|
||||
|
@ -140,9 +146,9 @@ class EditEventDialog : DialogFragmentWithDate() {
|
|||
}
|
||||
// store
|
||||
if (position == -1)
|
||||
automationPlugin.automationEvents.add(event)
|
||||
automationPlugin.add(event)
|
||||
else
|
||||
automationPlugin.automationEvents[position] = event
|
||||
automationPlugin.set(event, position)
|
||||
|
||||
rxBus.send(EventAutomationDataChanged())
|
||||
return true
|
||||
|
@ -189,20 +195,24 @@ class EditEventDialog : DialogFragmentWithDate() {
|
|||
inner class ViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||
|
||||
fun bind(action: Action, recyclerView: RecyclerView.Adapter<ViewHolder>, position: Int) {
|
||||
view.findViewById<LinearLayout>(R.id.automation_layoutText).setOnClickListener {
|
||||
if (action.hasDialog()) {
|
||||
val args = Bundle()
|
||||
args.putInt("actionPosition", position)
|
||||
args.putString("action", action.toJSON())
|
||||
val dialog = EditActionDialog()
|
||||
dialog.arguments = args
|
||||
dialog.show(childFragmentManager, "EditActionDialog")
|
||||
if (!event.readOnly)
|
||||
view.findViewById<LinearLayout>(R.id.automation_layoutText).setOnClickListener {
|
||||
if (action.hasDialog()) {
|
||||
val args = Bundle()
|
||||
args.putInt("actionPosition", position)
|
||||
args.putString("action", action.toJSON())
|
||||
val dialog = EditActionDialog()
|
||||
dialog.arguments = args
|
||||
dialog.show(childFragmentManager, "EditActionDialog")
|
||||
}
|
||||
}
|
||||
view.findViewById<ImageView>(R.id.automation_iconTrash).run {
|
||||
visibility = (!event.readOnly).toVisibility()
|
||||
setOnClickListener {
|
||||
event.actions.remove(action)
|
||||
recyclerView.notifyDataSetChanged()
|
||||
rxBus.send(EventAutomationUpdateGui())
|
||||
}
|
||||
}
|
||||
view.findViewById<ImageView>(R.id.automation_iconTrash).setOnClickListener {
|
||||
event.actions.remove(action)
|
||||
recyclerView.notifyDataSetChanged()
|
||||
rxBus.send(EventAutomationUpdateGui())
|
||||
}
|
||||
view.findViewById<ImageView>(R.id.automation_action_image).setImageResource(action.icon())
|
||||
view.findViewById<TextView>(R.id.automation_viewActionTitle).text = action.shortDescription()
|
||||
|
|
|
@ -35,6 +35,12 @@ class TriggerDelta(injector: HasAndroidInjector) : Trigger(injector) {
|
|||
else InputDelta(injector, 0.0, (-MGDL_MAX), MGDL_MAX, 1.0, DecimalFormat("1"), DeltaType.DELTA)
|
||||
}
|
||||
|
||||
constructor(injector: HasAndroidInjector, inputDelta: InputDelta, units: String, comparator: Comparator.Compare) : this(injector) {
|
||||
this.units = units
|
||||
this.delta = inputDelta
|
||||
this.comparator.value = comparator
|
||||
}
|
||||
|
||||
private constructor(injector: HasAndroidInjector, triggerDelta: TriggerDelta) : this(injector) {
|
||||
units = triggerDelta.units
|
||||
delta = InputDelta(injector, triggerDelta.delta)
|
||||
|
|
|
@ -195,7 +195,7 @@ class ActionStringHandler @Inject constructor(
|
|||
val formatInt = DecimalFormat("0")
|
||||
val bolusWizard = BolusWizard(injector).doCalc(profile, profileName, activePlugin.activeTreatments.tempTargetFromHistory,
|
||||
carbsAfterConstraints, cobInfo.displayCob!!, bgReading!!.valueToUnits(profileFunction.getUnits()),
|
||||
0.0, percentage.toDouble(), useBG, useCOB, useBolusIOB, useBasalIOB, false, useTT, useTrend)
|
||||
0.0, percentage.toDouble(), useBG, useCOB, useBolusIOB, useBasalIOB, false, useTT, useTrend, false)
|
||||
if (Math.abs(bolusWizard.insulinAfterConstraints - bolusWizard.calculatedTotalInsulin) >= 0.01) {
|
||||
sendError("Insulin constraint violation!" +
|
||||
"\nCannot deliver " + format.format(bolusWizard.calculatedTotalInsulin) + "!")
|
||||
|
@ -215,7 +215,7 @@ class ActionStringHandler @Inject constructor(
|
|||
if (useCOB) rMessage += "\nFrom" + formatInt.format(cobInfo.displayCob) + "g COB : " + format.format(bolusWizard.insulinFromCOB) + "U"
|
||||
if (useBG) rMessage += "\nFrom BG: " + format.format(bolusWizard.insulinFromBG) + "U"
|
||||
if (useBolusIOB) rMessage += "\nBolus IOB: " + format.format(bolusWizard.insulinFromBolusIOB) + "U"
|
||||
if (useBasalIOB) rMessage += "\nBasal IOB: " + format.format(bolusWizard.insulinFromBasalsIOB) + "U"
|
||||
if (useBasalIOB) rMessage += "\nBasal IOB: " + format.format(bolusWizard.insulinFromBasalIOB) + "U"
|
||||
if (useTrend) rMessage += "\nFrom 15' trend: " + format.format(bolusWizard.insulinFromTrend) + "U"
|
||||
if (percentage != 100) {
|
||||
rMessage += "\nPercentage: " + format.format(bolusWizard.totalBeforePercentageAdjustment) + "U * " + percentage + "% -> ~" + format.format(bolusWizard.calculatedTotalInsulin) + "U"
|
||||
|
|
|
@ -6,6 +6,7 @@ import android.text.Spanned
|
|||
import com.google.common.base.Joiner
|
||||
import dagger.android.HasAndroidInjector
|
||||
import info.nightscout.androidaps.Config
|
||||
import info.nightscout.androidaps.Constants
|
||||
import info.nightscout.androidaps.R
|
||||
import info.nightscout.androidaps.activities.ErrorHelperActivity
|
||||
import info.nightscout.androidaps.data.DetailedBolusInfo
|
||||
|
@ -20,6 +21,15 @@ import info.nightscout.androidaps.logging.LTag
|
|||
import info.nightscout.androidaps.plugins.aps.loop.LoopPlugin
|
||||
import info.nightscout.androidaps.plugins.bus.RxBusWrapper
|
||||
import info.nightscout.androidaps.plugins.configBuilder.ConstraintChecker
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationEvent
|
||||
import info.nightscout.androidaps.plugins.general.automation.AutomationPlugin
|
||||
import info.nightscout.androidaps.plugins.general.automation.actions.ActionAlarm
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.Comparator
|
||||
import info.nightscout.androidaps.plugins.general.automation.elements.InputDelta
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerBg
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerConnector
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerDelta
|
||||
import info.nightscout.androidaps.plugins.general.automation.triggers.TriggerTime
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.GlucoseStatus
|
||||
import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin
|
||||
import info.nightscout.androidaps.queue.Callback
|
||||
|
@ -30,8 +40,10 @@ import info.nightscout.androidaps.utils.T
|
|||
import info.nightscout.androidaps.utils.alertDialogs.OKDialog
|
||||
import info.nightscout.androidaps.utils.extensions.formatColor
|
||||
import info.nightscout.androidaps.utils.resources.ResourceHelper
|
||||
import info.nightscout.androidaps.utils.sharedPreferences.SP
|
||||
import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.text.DecimalFormat
|
||||
import java.util.*
|
||||
import javax.inject.Inject
|
||||
import kotlin.math.abs
|
||||
|
@ -43,13 +55,15 @@ class BolusWizard @Inject constructor(
|
|||
@Inject lateinit var aapsLogger: AAPSLogger
|
||||
@Inject lateinit var resourceHelper: ResourceHelper
|
||||
@Inject lateinit var rxBus: RxBusWrapper
|
||||
@Inject lateinit var sp: SP
|
||||
@Inject lateinit var profileFunction: ProfileFunction
|
||||
@Inject lateinit var constraintChecker: ConstraintChecker
|
||||
@Inject lateinit var context: Context
|
||||
@Inject lateinit var activePlugin: ActivePluginProvider
|
||||
@Inject lateinit var commandQueue: CommandQueueProvider
|
||||
@Inject lateinit var loopPlugin: LoopPlugin
|
||||
@Inject lateinit var iobCobCalculatorPlugin: IobCobCalculatorPlugin
|
||||
@Inject lateinit var automationPlugin: AutomationPlugin
|
||||
@Inject lateinit var dateUtil: DateUtil
|
||||
@Inject lateinit var config: Config
|
||||
|
||||
init {
|
||||
|
@ -72,7 +86,7 @@ class BolusWizard @Inject constructor(
|
|||
private set
|
||||
var insulinFromBolusIOB = 0.0
|
||||
private set
|
||||
var insulinFromBasalsIOB = 0.0
|
||||
var insulinFromBasalIOB = 0.0
|
||||
private set
|
||||
var insulinFromCorrection = 0.0
|
||||
private set
|
||||
|
@ -104,7 +118,7 @@ class BolusWizard @Inject constructor(
|
|||
var carbs: Int = 0
|
||||
var cob: Double = 0.0
|
||||
var bg: Double = 0.0
|
||||
var correction: Double = 0.0
|
||||
private var correction: Double = 0.0
|
||||
private var percentageCorrection: Double = 0.0
|
||||
private var useBg: Boolean = false
|
||||
private var useCob: Boolean = false
|
||||
|
@ -113,8 +127,9 @@ class BolusWizard @Inject constructor(
|
|||
private var useSuperBolus: Boolean = false
|
||||
private var useTT: Boolean = false
|
||||
private var useTrend: Boolean = false
|
||||
private var useAlarm = false
|
||||
var notes: String = ""
|
||||
var carbTime: Int = 0
|
||||
private var carbTime: Int = 0
|
||||
|
||||
@JvmOverloads
|
||||
fun doCalc(profile: Profile,
|
||||
|
@ -132,6 +147,7 @@ class BolusWizard @Inject constructor(
|
|||
useSuperBolus: Boolean,
|
||||
useTT: Boolean,
|
||||
useTrend: Boolean,
|
||||
useAlarm: Boolean,
|
||||
notes: String = "",
|
||||
carbTime: Int = 0
|
||||
): BolusWizard {
|
||||
|
@ -151,6 +167,7 @@ class BolusWizard @Inject constructor(
|
|||
this.useSuperBolus = useSuperBolus
|
||||
this.useTT = useTT
|
||||
this.useTrend = useTrend
|
||||
this.useAlarm = useAlarm
|
||||
this.notes = notes
|
||||
this.carbTime = carbTime
|
||||
|
||||
|
@ -193,7 +210,7 @@ class BolusWizard @Inject constructor(
|
|||
val basalIob = activePlugin.activeTreatments.lastCalculationTempBasals.round()
|
||||
|
||||
insulinFromBolusIOB = if (includeBolusIOB) -bolusIob.iob else 0.0
|
||||
insulinFromBasalsIOB = if (includeBasalIOB) -basalIob.basaliob else 0.0
|
||||
insulinFromBasalIOB = if (includeBasalIOB) -basalIob.basaliob else 0.0
|
||||
|
||||
// Insulin from correction
|
||||
insulinFromCorrection = correction
|
||||
|
@ -207,7 +224,7 @@ class BolusWizard @Inject constructor(
|
|||
}
|
||||
|
||||
// Total
|
||||
calculatedTotalInsulin = insulinFromBG + insulinFromTrend + insulinFromCarbs + insulinFromBolusIOB + insulinFromBasalsIOB + insulinFromCorrection + insulinFromSuperBolus + insulinFromCOB
|
||||
calculatedTotalInsulin = insulinFromBG + insulinFromTrend + insulinFromCarbs + insulinFromBolusIOB + insulinFromBasalIOB + insulinFromCorrection + insulinFromSuperBolus + insulinFromCOB
|
||||
|
||||
// Percentage adjustment
|
||||
totalBeforePercentageAdjustment = calculatedTotalInsulin
|
||||
|
@ -229,6 +246,7 @@ class BolusWizard @Inject constructor(
|
|||
return this
|
||||
}
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
private fun nsJSON(): JSONObject {
|
||||
val bolusCalcJSON = JSONObject()
|
||||
try {
|
||||
|
@ -239,9 +257,9 @@ class BolusWizard @Inject constructor(
|
|||
bolusCalcJSON.put("targetBGHigh", targetBGHigh)
|
||||
bolusCalcJSON.put("isf", sens)
|
||||
bolusCalcJSON.put("ic", ic)
|
||||
bolusCalcJSON.put("iob", -(insulinFromBolusIOB + insulinFromBasalsIOB))
|
||||
bolusCalcJSON.put("iob", -(insulinFromBolusIOB + insulinFromBasalIOB))
|
||||
bolusCalcJSON.put("bolusiob", insulinFromBolusIOB)
|
||||
bolusCalcJSON.put("basaliob", insulinFromBasalsIOB)
|
||||
bolusCalcJSON.put("basaliob", insulinFromBasalIOB)
|
||||
bolusCalcJSON.put("bolusiobused", includeBolusIOB)
|
||||
bolusCalcJSON.put("basaliobused", includeBasalIOB)
|
||||
bolusCalcJSON.put("bg", bg)
|
||||
|
@ -270,14 +288,14 @@ class BolusWizard @Inject constructor(
|
|||
return bolusCalcJSON
|
||||
}
|
||||
|
||||
private fun confirmMessageAfterConstraints(pump: PumpInterface): Spanned {
|
||||
private fun confirmMessageAfterConstraints(advisor: Boolean): Spanned {
|
||||
|
||||
val actions: LinkedList<String> = LinkedList()
|
||||
if (insulinAfterConstraints > 0) {
|
||||
val pct = if (percentageCorrection != 100.0) " (" + percentageCorrection.toInt() + "%)" else ""
|
||||
actions.add(resourceHelper.gs(R.string.bolus) + ": " + resourceHelper.gs(R.string.formatinsulinunits, insulinAfterConstraints).formatColor(resourceHelper, R.color.bolus) + pct)
|
||||
}
|
||||
if (carbs > 0) {
|
||||
if (carbs > 0 && !advisor) {
|
||||
var timeShift = ""
|
||||
if (carbTime > 0) {
|
||||
timeShift += " (+" + resourceHelper.gs(R.string.mins, carbTime) + ")"
|
||||
|
@ -287,23 +305,24 @@ class BolusWizard @Inject constructor(
|
|||
actions.add(resourceHelper.gs(R.string.carbs) + ": " + resourceHelper.gs(R.string.format_carbs, carbs).formatColor(resourceHelper, R.color.carbs) + timeShift)
|
||||
}
|
||||
if (insulinFromCOB > 0) {
|
||||
actions.add(resourceHelper.gs(R.string.cobvsiob) + ": " + resourceHelper.gs(R.string.formatsignedinsulinunits, insulinFromBolusIOB + insulinFromBasalsIOB + insulinFromCOB + insulinFromBG).formatColor(resourceHelper, R.color.cobAlert))
|
||||
actions.add(resourceHelper.gs(R.string.cobvsiob) + ": " + resourceHelper.gs(R.string.formatsignedinsulinunits, insulinFromBolusIOB + insulinFromBasalIOB + insulinFromCOB + insulinFromBG).formatColor(resourceHelper, R.color.cobAlert))
|
||||
val absorptionRate = iobCobCalculatorPlugin.slowAbsorptionPercentage(60)
|
||||
if (absorptionRate > .25)
|
||||
actions.add(resourceHelper.gs(R.string.slowabsorptiondetected, resourceHelper.gc(R.color.cobAlert), (absorptionRate * 100).toInt()))
|
||||
}
|
||||
if (abs(insulinAfterConstraints - calculatedTotalInsulin) > pump.pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
|
||||
actions.add(resourceHelper.gs(R.string.bolusconstraintappliedwarn, calculatedTotalInsulin, insulinAfterConstraints).formatColor(resourceHelper, R.color.warning))
|
||||
if (config.NSCLIENT)
|
||||
if (abs(insulinAfterConstraints - calculatedTotalInsulin) > activePlugin.activePump.pumpDescription.pumpType.determineCorrectBolusStepSize(insulinAfterConstraints))
|
||||
actions.add(resourceHelper.gs(R.string.bolusconstraintappliedwarn, calculatedTotalInsulin, insulinAfterConstraints).formatColor(resourceHelper, R.color.warning))
|
||||
if (config.NSCLIENT && insulinAfterConstraints > 0)
|
||||
actions.add(resourceHelper.gs(R.string.bolusrecordedonly).formatColor(resourceHelper, R.color.warning))
|
||||
if (useAlarm && !advisor && carbs > 0 && carbTime > 0)
|
||||
actions.add(resourceHelper.gs(R.string.alarminxmin, carbTime).formatColor(resourceHelper, R.color.info))
|
||||
if (advisor)
|
||||
actions.add(resourceHelper.gs(R.string.advisoralarm).formatColor(resourceHelper, R.color.info))
|
||||
|
||||
return HtmlHelper.fromHtml(Joiner.on("<br/>").join(actions))
|
||||
}
|
||||
|
||||
fun confirmAndExecute(context: Context) {
|
||||
val profile = profileFunction.getProfile() ?: return
|
||||
val pump = activePlugin.activePump
|
||||
|
||||
fun confirmAndExecute(ctx: Context) {
|
||||
if (calculatedTotalInsulin > 0.0 || carbs > 0.0) {
|
||||
if (accepted) {
|
||||
aapsLogger.debug(LTag.UI, "guarding: already accepted")
|
||||
|
@ -311,76 +330,174 @@ class BolusWizard @Inject constructor(
|
|||
}
|
||||
accepted = true
|
||||
|
||||
val confirmMessage = confirmMessageAfterConstraints(pump)
|
||||
if (sp.getBoolean(R.string.key_usebolusadvisor, false) && Profile.toMgdl(bg, profile.units) > 180 && carbs > 0 && carbTime >= 0)
|
||||
OKDialog.showYesNoCancel(ctx, resourceHelper.gs(R.string.bolusadvisor), resourceHelper.gs(R.string.bolusadvisormessage),
|
||||
{ bolusAdvisorProcessing(ctx) },
|
||||
{ commonProcessing(ctx) }
|
||||
)
|
||||
else
|
||||
commonProcessing(ctx)
|
||||
}
|
||||
}
|
||||
|
||||
OKDialog.showConfirmation(context, resourceHelper.gs(R.string.boluswizard), confirmMessage, Runnable {
|
||||
if (insulinAfterConstraints > 0 || carbs > 0) {
|
||||
if (useSuperBolus) {
|
||||
aapsLogger.debug("USER ENTRY: SUPERBOLUS TBR")
|
||||
if (loopPlugin.isEnabled(PluginType.LOOP)) {
|
||||
loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000)
|
||||
rxBus.send(EventRefreshOverview("WizardDialog"))
|
||||
private fun bolusAdvisorProcessing(ctx: Context) {
|
||||
val confirmMessage = confirmMessageAfterConstraints(advisor = true)
|
||||
OKDialog.showConfirmation(ctx, resourceHelper.gs(R.string.boluswizard), confirmMessage, {
|
||||
DetailedBolusInfo().apply {
|
||||
eventType = CareportalEvent.CORRECTIONBOLUS
|
||||
insulin = insulinAfterConstraints
|
||||
carbs = 0.0
|
||||
context = ctx
|
||||
glucose = bg
|
||||
glucoseType = "Manual"
|
||||
carbTime = 0
|
||||
boluscalc = nsJSON()
|
||||
source = Source.USER
|
||||
notes = this@BolusWizard.notes
|
||||
aapsLogger.debug("USER ENTRY: BOLUS ADVISOR insulin $insulinAfterConstraints")
|
||||
if (insulin > 0) {
|
||||
commandQueue.bolus(this, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(ctx, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.treatmentdeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
ctx.startActivity(i)
|
||||
} else
|
||||
scheduleEatReminder()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
|
||||
commandQueue.tempBasalAbsolute(0.0, 120, true, profile, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(context, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.tempbasaldeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(i)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
private fun commonProcessing(ctx: Context) {
|
||||
val profile = profileFunction.getProfile() ?: return
|
||||
val pump = activePlugin.activePump
|
||||
|
||||
commandQueue.tempBasalPercent(0, 120, true, profile, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(context, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.tempbasaldeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(i)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
val confirmMessage = confirmMessageAfterConstraints(advisor = false)
|
||||
OKDialog.showConfirmation(ctx, resourceHelper.gs(R.string.boluswizard), confirmMessage, {
|
||||
if (insulinAfterConstraints > 0 || carbs > 0) {
|
||||
if (useSuperBolus) {
|
||||
aapsLogger.debug("USER ENTRY: SUPERBOLUS TBR")
|
||||
if (loopPlugin.isEnabled(PluginType.LOOP)) {
|
||||
loopPlugin.superBolusTo(System.currentTimeMillis() + 2 * 60L * 60 * 1000)
|
||||
rxBus.send(EventRefreshOverview("WizardDialog"))
|
||||
}
|
||||
val detailedBolusInfo = DetailedBolusInfo()
|
||||
detailedBolusInfo.eventType = CareportalEvent.BOLUSWIZARD
|
||||
detailedBolusInfo.insulin = insulinAfterConstraints
|
||||
detailedBolusInfo.carbs = carbs.toDouble()
|
||||
detailedBolusInfo.context = context
|
||||
detailedBolusInfo.glucose = bg
|
||||
detailedBolusInfo.glucoseType = "Manual"
|
||||
detailedBolusInfo.carbTime = carbTime
|
||||
detailedBolusInfo.boluscalc = nsJSON()
|
||||
detailedBolusInfo.source = Source.USER
|
||||
detailedBolusInfo.notes = notes
|
||||
aapsLogger.debug("USER ENTRY: BOLUS insulin $insulinAfterConstraints carbs: $carbs")
|
||||
if (detailedBolusInfo.insulin > 0 || pump.pumpDescription.storesCarbInfo) {
|
||||
commandQueue.bolus(detailedBolusInfo, object : Callback() {
|
||||
|
||||
if (pump.pumpDescription.tempBasalStyle == PumpDescription.ABSOLUTE) {
|
||||
commandQueue.tempBasalAbsolute(0.0, 120, true, profile, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(context, ErrorHelperActivity::class.java)
|
||||
val i = Intent(ctx, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.treatmentdeliveryerror))
|
||||
i.putExtra("title", resourceHelper.gs(R.string.tempbasaldeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
context.startActivity(i)
|
||||
ctx.startActivity(i)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
activePlugin.activeTreatments.addToHistoryTreatment(detailedBolusInfo, false)
|
||||
|
||||
commandQueue.tempBasalPercent(0, 120, true, profile, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(ctx, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.tempbasaldeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
ctx.startActivity(i)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
DetailedBolusInfo().apply {
|
||||
eventType = CareportalEvent.BOLUSWIZARD
|
||||
insulin = insulinAfterConstraints
|
||||
carbs = this@BolusWizard.carbs.toDouble()
|
||||
context = ctx
|
||||
glucose = bg
|
||||
glucoseType = "Manual"
|
||||
carbTime = this@BolusWizard.carbTime
|
||||
boluscalc = nsJSON()
|
||||
source = Source.USER
|
||||
notes = this@BolusWizard.notes
|
||||
aapsLogger.debug("USER ENTRY: BOLUS WIZARD insulin $insulinAfterConstraints carbs: $carbs")
|
||||
if (insulin > 0 || pump.pumpDescription.storesCarbInfo) {
|
||||
commandQueue.bolus(this, object : Callback() {
|
||||
override fun run() {
|
||||
if (!result.success) {
|
||||
val i = Intent(ctx, ErrorHelperActivity::class.java)
|
||||
i.putExtra("soundid", R.raw.boluserror)
|
||||
i.putExtra("status", result.comment)
|
||||
i.putExtra("title", resourceHelper.gs(R.string.treatmentdeliveryerror))
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
|
||||
ctx.startActivity(i)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
activePlugin.activeTreatments.addToHistoryTreatment(this, false)
|
||||
}
|
||||
}
|
||||
if (useAlarm && carbs > 0 && carbTime > 0) {
|
||||
scheduleReminder(dateUtil._now() + T.mins(carbTime.toLong()).msecs())
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun scheduleEatReminder() {
|
||||
val event = AutomationEvent(injector).apply {
|
||||
title = resourceHelper.gs(R.string.bolusadvisor)
|
||||
readOnly = true
|
||||
systemAction = true
|
||||
autoRemove = true
|
||||
trigger = TriggerConnector(injector, TriggerConnector.Type.OR).apply {
|
||||
|
||||
// Bg under 180 mgdl and dropping by 15 mgdl
|
||||
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
|
||||
list.add(TriggerBg(injector, 180.0, Constants.MGDL, Comparator.Compare.IS_LESSER))
|
||||
list.add(TriggerDelta(injector, InputDelta(injector, -15.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
|
||||
list.add(TriggerDelta(injector, InputDelta(injector, -8.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
|
||||
})
|
||||
// Bg under 160 mgdl and dropping by 9 mgdl
|
||||
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
|
||||
list.add(TriggerBg(injector, 160.0, Constants.MGDL, Comparator.Compare.IS_LESSER))
|
||||
list.add(TriggerDelta(injector, InputDelta(injector, -9.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
|
||||
list.add(TriggerDelta(injector, InputDelta(injector, -5.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
|
||||
})
|
||||
// Bg under 145 mgdl and dropping
|
||||
list.add(TriggerConnector(injector, TriggerConnector.Type.AND).apply {
|
||||
list.add(TriggerBg(injector, 145.0, Constants.MGDL, Comparator.Compare.IS_LESSER))
|
||||
list.add(TriggerDelta(injector, InputDelta(injector, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.DELTA), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
|
||||
list.add(TriggerDelta(injector, InputDelta(injector, 0.0, -360.0, 360.0, 1.0, DecimalFormat("0"), InputDelta.DeltaType.SHORT_AVERAGE), Constants.MGDL, Comparator.Compare.IS_EQUAL_OR_LESSER))
|
||||
})
|
||||
}
|
||||
actions.add(ActionAlarm(injector, resourceHelper.gs(R.string.time_to_eat)))
|
||||
}
|
||||
|
||||
automationPlugin.addIfNotExists(event)
|
||||
}
|
||||
|
||||
private fun scheduleReminder(time: Long) {
|
||||
val event = AutomationEvent(injector).apply {
|
||||
title = resourceHelper.gs(R.string.timetoeat)
|
||||
readOnly = true
|
||||
systemAction = true
|
||||
autoRemove = true
|
||||
trigger = TriggerConnector(injector, TriggerConnector.Type.AND).apply {
|
||||
list.add(TriggerTime(injector, time))
|
||||
}
|
||||
actions.add(ActionAlarm(injector, resourceHelper.gs(R.string.timetoeat)))
|
||||
}
|
||||
|
||||
automationPlugin.addIfNotExists(event)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -117,7 +117,7 @@ class QuickWizardEntry @Inject constructor(private val injector: HasAndroidInjec
|
|||
trend = true
|
||||
}
|
||||
val percentage = sp.getDouble(R.string.key_boluswizard_percentage, 100.0)
|
||||
return BolusWizard(injector).doCalc(profile, profileName, tempTarget, carbs(), cob, bg, 0.0, percentage, true, useCOB() == YES, bolusIOB, basalIOB, superBolus, useTempTarget() == YES, trend, "QuickWizard")
|
||||
return BolusWizard(injector).doCalc(profile, profileName, tempTarget, carbs(), cob, bg, 0.0, percentage, true, useCOB() == YES, bolusIOB, basalIOB, superBolus, useTempTarget() == YES, trend, false, "QuickWizard")
|
||||
}
|
||||
|
||||
fun buttonText(): String = safeGetString(storage, "buttonText", "")
|
||||
|
|
|
@ -51,8 +51,8 @@
|
|||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:id="@+id/inputEventTitle"
|
||||
|
@ -163,7 +163,9 @@
|
|||
android:layout_marginTop="10dp"
|
||||
android:layout_marginBottom="10dp" />
|
||||
|
||||
<include layout="@layout/okcancel" />
|
||||
<include
|
||||
android:id="@+id/okcancel"
|
||||
layout="@layout/okcancel" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/rootLayout"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -8,59 +8,79 @@
|
|||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:background="@color/ribbonDefault"
|
||||
android:padding="8dp">
|
||||
android:clickable="true"
|
||||
android:focusable="true">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/enabled"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true" />
|
||||
app:layout_constraintBottom_toTopOf="@+id/iconLayout"
|
||||
app:layout_constraintEnd_toStartOf="@+id/aapsLogo"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/aapsLogo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="5dp"
|
||||
android:contentDescription="@string/remove_label"
|
||||
android:scaleX="0.9"
|
||||
android:scaleY="0.9"
|
||||
android:src="@drawable/ic_notif_aaps"
|
||||
app:layout_constraintBottom_toTopOf="@+id/iconLayout"
|
||||
app:layout_constraintEnd_toStartOf="@+id/eventTitle"
|
||||
app:layout_constraintStart_toEndOf="@+id/enabled"
|
||||
app:layout_constraintTop_toTopOf="@+id/enabled" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/eventTitle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignTop="@+id/enabled"
|
||||
android:layout_alignBottom="@+id/enabled"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_toStartOf="@+id/iconTrash"
|
||||
android:layout_toEndOf="@id/enabled"
|
||||
android:text="Title"
|
||||
android:textAlignment="viewStart"
|
||||
android:textStyle="bold" />
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintBottom_toTopOf="@+id/iconLayout"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconTrash"
|
||||
app:layout_constraintStart_toEndOf="@+id/aapsLogo"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iconTrash"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_toStartOf="@+id/iconSort"
|
||||
android:contentDescription="@string/remove_label"
|
||||
android:orientation="horizontal"
|
||||
android:src="@drawable/ic_trash_outline" />
|
||||
android:src="@drawable/ic_trash_outline"
|
||||
app:layout_constraintBottom_toTopOf="@+id/iconLayout"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconSort"
|
||||
app:layout_constraintStart_toEndOf="@+id/eventTitle"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/iconSort"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:contentDescription="@string/reorder_label"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toTopOf="@+id/iconLayout"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconTrash"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_reorder_gray_24dp" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/iconLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/enabled"
|
||||
android:orientation="horizontal" />
|
||||
android:layout_marginStart="16dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/iconSort" />
|
||||
|
||||
|
||||
</RelativeLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -49,9 +49,9 @@
|
|||
android:padding="5dp" />
|
||||
|
||||
<TableLayout
|
||||
android:paddingEnd="5dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:paddingEnd="5dp">
|
||||
|
||||
<TableRow
|
||||
android:layout_width="match_parent"
|
||||
|
@ -67,12 +67,12 @@
|
|||
android:textStyle="bold" />
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.NumberPicker
|
||||
android:id="@+id/treatments_wizard_bg_input"
|
||||
android:id="@+id/bg_input"
|
||||
android:layout_width="130dp"
|
||||
android:layout_height="40dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_bgunits"
|
||||
android:id="@+id/bgunits"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
|
@ -97,7 +97,7 @@
|
|||
android:textStyle="bold" />
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.NumberPicker
|
||||
android:id="@+id/treatments_wizard_carbs_input"
|
||||
android:id="@+id/carbs_input"
|
||||
android:layout_width="130dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
@ -128,7 +128,7 @@
|
|||
android:textStyle="bold" />
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.NumberPicker
|
||||
android:id="@+id/treatments_wizard_correction_input"
|
||||
android:id="@+id/correction_input"
|
||||
android:layout_width="130dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
@ -148,17 +148,43 @@
|
|||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:padding="10dp"
|
||||
android:text="@string/careportal_newnstreatment_carbtime_label"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textStyle="bold" />
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="10dp"
|
||||
android:text="@string/careportal_newnstreatment_carbtime_label"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"/>
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:src="@drawable/ic_access_alarm_24dp" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/alarm"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:checked="false"
|
||||
android:padding="5dp" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<info.nightscout.androidaps.utils.ui.NumberPicker
|
||||
android:id="@+id/treatments_wizard_carb_time_input"
|
||||
android:id="@+id/carb_time_input"
|
||||
android:layout_width="130dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_gravity="center_horizontal" />
|
||||
|
@ -191,7 +217,7 @@
|
|||
android:textStyle="bold" />
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/treatments_wizard_profile"
|
||||
android:id="@+id/profile"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
|
@ -199,13 +225,13 @@
|
|||
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/treatments_wizard_sbcheckbox"
|
||||
android:id="@+id/sbcheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_marginStart="10dp"
|
||||
android:padding="5dp"
|
||||
android:checked="false"
|
||||
android:padding="5dp"
|
||||
android:text="@string/superbolus" />
|
||||
|
||||
</LinearLayout>
|
||||
|
@ -217,7 +243,7 @@
|
|||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_total"
|
||||
android:id="@+id/total"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@drawable/background_darkgray"
|
||||
|
@ -227,7 +253,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_percent_used"
|
||||
android:id="@+id/percent_used"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
|
@ -241,7 +267,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/treatments_wizard_notes_layout"
|
||||
android:id="@+id/notes_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
@ -250,14 +276,14 @@
|
|||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:labelFor="@+id/treatment_wizard_notes"
|
||||
android:labelFor="@+id/notes"
|
||||
android:padding="10dp"
|
||||
android:text="@string/careportal_newnstreatment_notes_label"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/treatment_wizard_notes"
|
||||
android:id="@+id/notes"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
|
@ -279,7 +305,7 @@
|
|||
android:padding="5dp">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/treatments_wizard_calculationcheckbox"
|
||||
android:id="@+id/calculationcheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
|
@ -288,8 +314,8 @@
|
|||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:contentDescription="@string/show_calculation"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:contentDescription="@string/show_calculation"
|
||||
app:srcCompat="@drawable/ic_visibility" />
|
||||
|
||||
<Button
|
||||
|
@ -312,7 +338,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<View
|
||||
android:id="@+id/treatments_wizard_delimiter"
|
||||
android:id="@+id/delimiter"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="2dip"
|
||||
android:layout_marginStart="20dp"
|
||||
|
@ -321,7 +347,7 @@
|
|||
android:background="@color/listdelimiter" />
|
||||
|
||||
<TableLayout
|
||||
android:id="@+id/treatments_wizard_resulttable"
|
||||
android:id="@+id/resulttable"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="5dp">
|
||||
|
@ -331,7 +357,7 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/treatments_wizard_bgcheckbox"
|
||||
android:id="@+id/bgcheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp"
|
||||
|
@ -350,7 +376,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/treatments_wizard_ttcheckbox"
|
||||
android:id="@+id/ttcheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp"
|
||||
|
@ -366,7 +392,7 @@
|
|||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_bg"
|
||||
android:id="@+id/bg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
|
@ -374,7 +400,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_bginsulin"
|
||||
android:id="@+id/bginsulin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="50dp"
|
||||
|
@ -388,7 +414,7 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/treatments_wizard_bgtrendcheckbox"
|
||||
android:id="@+id/bgtrendcheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp"
|
||||
|
@ -402,7 +428,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_bgtrend"
|
||||
android:id="@+id/bgtrend"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
|
@ -410,7 +436,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_bgtrendinsulin"
|
||||
android:id="@+id/bgtrendinsulin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="50dp"
|
||||
|
@ -424,7 +450,7 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/treatments_wizard_cobcheckbox"
|
||||
android:id="@+id/cobcheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp"
|
||||
|
@ -438,7 +464,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_cob"
|
||||
android:id="@+id/cob"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
|
@ -446,7 +472,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_cobinsulin"
|
||||
android:id="@+id/cobinsulin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="50dp"
|
||||
|
@ -460,7 +486,7 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/treatments_wizard_bolusiobcheckbox"
|
||||
android:id="@+id/bolusiobcheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp"
|
||||
|
@ -481,7 +507,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_bolusiobinsulin"
|
||||
android:id="@+id/bolusiobinsulin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="50dp"
|
||||
|
@ -495,7 +521,7 @@
|
|||
android:layout_height="match_parent">
|
||||
|
||||
<CheckBox
|
||||
android:id="@+id/treatments_wizard_basaliobcheckbox"
|
||||
android:id="@+id/basaliobcheckbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="32dp"
|
||||
|
@ -516,7 +542,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_basaliobinsulin"
|
||||
android:id="@+id/basaliobinsulin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="50dp"
|
||||
|
@ -542,7 +568,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_carbs"
|
||||
android:id="@+id/carbs"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
|
@ -550,7 +576,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_carbsinsulin"
|
||||
android:id="@+id/carbsinsulin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="50dp"
|
||||
|
@ -576,7 +602,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_sb"
|
||||
android:id="@+id/sb"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
|
@ -584,7 +610,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_sbinsulin"
|
||||
android:id="@+id/sbinsulin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="50dp"
|
||||
|
@ -617,7 +643,7 @@
|
|||
android:textAppearance="?android:attr/textAppearanceSmall" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/treatments_wizard_correctioninsulin"
|
||||
android:id="@+id/correctioninsulin"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:width="50dp"
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
<color name="basebasal">#C83F51B5</color>
|
||||
<color name="graphgrid">#757575</color>
|
||||
<color name="warning">#ff1a1a</color>
|
||||
<color name="info">#77dd77</color>
|
||||
<color name="error_background">#66FC0000</color>
|
||||
<color name="ok_background">#323232</color>
|
||||
|
||||
|
|
|
@ -680,8 +680,6 @@
|
|||
<string name="overview_editquickwizard_usebasaliob">Basal IOB calculation</string>
|
||||
<string name="overview_editquickwizard_usetrend">Trend calculation</string>
|
||||
<string name="overview_editquickwizard_usesuperbolus">Superbolus calculation</string>
|
||||
<string name="yes">Yes</string>
|
||||
<string name="no">No</string>
|
||||
<string name="positiveonly">Positive only</string>
|
||||
<string name="negativeonly">Negative only</string>
|
||||
<string name="overview_editquickwizard_usecob">COB calculation</string>
|
||||
|
@ -1425,5 +1423,14 @@
|
|||
<string name="key_smscommunicator_report_pump_ureachable" translatable="false">smscommunicator_report_pump_ureachable</string>
|
||||
<string name="smscommunicator_report_pump_ureachable_summary">Send SMS if unreachable pump event is triggered</string>
|
||||
<string name="smscommunicator_pump_ureachable">Report pump ureachable</string>
|
||||
<string name="advisoralarm">Run alarm when is time to eat</string>
|
||||
<string name="alarminxmin">Run alarm in %1$d min</string>
|
||||
<string name="bolusadvisor">Bolus advisor</string>
|
||||
<string name="bolusadvisormessage">You have high glycemia. Instead of eating now it\'s recommended to wait for better glycemia. Do you want to do a correction bolus now and remind you when it\'s time to eat? In this case no carbs will be recorded and you must use wizard again when we remind you.</string>
|
||||
<string name="key_usebolusadvisor" translatable="false">use_bolus_advisor</string>
|
||||
<string name="enablebolusadvisor">Enable bolus advisor</string>
|
||||
<string name="enablebolusadvisor_summary">Use reminder to start eating instead of wizard during high glycemia</string>
|
||||
<string name="time_to_eat">Time to eat!\nRun Bolus wizard and do calculation again.</string>
|
||||
<string name="timetoeat">Time to eat</string>
|
||||
|
||||
</resources>
|
||||
|
|
|
@ -489,6 +489,18 @@
|
|||
validate:minNumber="10"
|
||||
validate:testType="numericRange" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="true"
|
||||
android:key="@string/key_usebolusadvisor"
|
||||
android:summary="@string/enablebolusadvisor_summary"
|
||||
android:title="@string/enablebolusadvisor" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_usebolusadvisor"
|
||||
android:summary="@string/enablebolusadvisor_summary"
|
||||
android:title="@string/enablebolusadvisor" />
|
||||
|
||||
<SwitchPreference
|
||||
android:defaultValue="false"
|
||||
android:key="@string/key_usesuperbolus"
|
||||
|
|
|
@ -10,6 +10,7 @@ import info.nightscout.androidaps.core.R
|
|||
import info.nightscout.androidaps.utils.extensions.runOnUiThread
|
||||
|
||||
object OKDialog {
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
fun show(context: Context, title: String, message: String, runnable: Runnable? = null) {
|
||||
var okClicked = false
|
||||
|
@ -217,4 +218,36 @@ object OKDialog {
|
|||
.show()
|
||||
.setCanceledOnTouchOutside(false)
|
||||
}
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
fun showYesNoCancel(context: Context, title: String, message: String, yes: Runnable?, no: Runnable? = null) {
|
||||
var okClicked = false
|
||||
AlertDialogHelper.Builder(context)
|
||||
.setMessage(message)
|
||||
.setCustomTitle(AlertDialogHelper.buildCustomTitle(context, title))
|
||||
.setPositiveButton(R.string.yes) { dialog: DialogInterface, _: Int ->
|
||||
if (okClicked) return@setPositiveButton
|
||||
else {
|
||||
okClicked = true
|
||||
dialog.dismiss()
|
||||
SystemClock.sleep(100)
|
||||
runOnUiThread(yes)
|
||||
}
|
||||
}
|
||||
.setNegativeButton(R.string.no) { dialog: DialogInterface, _: Int ->
|
||||
if (okClicked) return@setNegativeButton
|
||||
else {
|
||||
okClicked = true
|
||||
dialog.dismiss()
|
||||
SystemClock.sleep(100)
|
||||
runOnUiThread(no)
|
||||
}
|
||||
}
|
||||
.setNeutralButton(R.string.cancel) { dialog: DialogInterface, _: Int ->
|
||||
dialog.dismiss()
|
||||
}
|
||||
.show()
|
||||
.setCanceledOnTouchOutside(false)
|
||||
}
|
||||
|
||||
}
|
|
@ -95,6 +95,8 @@
|
|||
<string name="btwatchdog_title">BT Watchdog</string>
|
||||
<string name="btwatchdog_summary">Switches off the phone\'s bluetooth for one second if no connection to the pump is possible. This may help on some phones where the bluetooth stack freezes.</string>
|
||||
<string name="pairing">Pairing</string>
|
||||
<string name="yes">Yes</string>
|
||||
<string name="no">No</string>
|
||||
|
||||
<!-- Constraints-->
|
||||
<string name="limitingbasalratio">Limiting max basal rate to %1$.2f U/h because of %2$s</string>
|
||||
|
|
Loading…
Reference in a new issue