diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index cb897b727c..42a8bc1042 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,6 +25,7 @@ + diff --git a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt index 59de46fc32..c2f0986820 100644 --- a/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt +++ b/app/src/main/java/info/nightscout/androidaps/dialogs/CarbsDialog.kt @@ -23,11 +23,7 @@ import info.nightscout.androidaps.plugins.general.nsclient.NSUpload import info.nightscout.androidaps.plugins.iob.iobCobCalculator.IobCobCalculatorPlugin import info.nightscout.androidaps.plugins.treatments.CarbsGenerator import info.nightscout.androidaps.plugins.treatments.TreatmentsPlugin -import info.nightscout.androidaps.utils.DateUtil -import info.nightscout.androidaps.utils.DecimalFormatter -import info.nightscout.androidaps.utils.DefaultValueHelper -import info.nightscout.androidaps.utils.HtmlHelper -import info.nightscout.androidaps.utils.ToastUtils +import info.nightscout.androidaps.utils.* import info.nightscout.androidaps.utils.alertDialogs.OKDialog import info.nightscout.androidaps.utils.extensions.formatColor import info.nightscout.androidaps.utils.resources.ResourceHelper @@ -48,6 +44,7 @@ class CarbsDialog : DialogFragmentWithDate() { @Inject lateinit var nsUpload: NSUpload @Inject lateinit var carbsGenerator: CarbsGenerator @Inject lateinit var uel: UserEntryLogger + @Inject lateinit var carbTimer: CarbTimer companion object { @@ -176,6 +173,7 @@ class CarbsDialog : DialogFragmentWithDate() { val hypoTT = defaultValueHelper.determineHypoTT() val actions: LinkedList = LinkedList() val unitLabel = if (units == Constants.MMOL) resourceHelper.gs(R.string.mmol) else resourceHelper.gs(R.string.mgdl) + val useAlarm = binding.alarmCheckBox.isChecked val activitySelected = binding.activityTt.isChecked if (activitySelected) @@ -192,6 +190,8 @@ class CarbsDialog : DialogFragmentWithDate() { val time = eventTime + timeOffset * 1000 * 60 if (timeOffset != 0) actions.add(resourceHelper.gs(R.string.time) + ": " + dateUtil.dateAndTimeString(time)) + if (useAlarm && carbs > 0 && timeOffset > 0) + actions.add(resourceHelper.gs(R.string.alarminxmin, timeOffset).formatColor(resourceHelper, R.color.info)) val duration = binding.duration.value.toInt() if (duration > 0) actions.add(resourceHelper.gs(R.string.duration) + ": " + duration + resourceHelper.gs(R.string.shorthour)) @@ -257,6 +257,9 @@ class CarbsDialog : DialogFragmentWithDate() { nsUpload.uploadEvent(CareportalEvent.NOTE, DateUtil.now() - 2000, resourceHelper.gs(R.string.generated_ecarbs_note, carbsAfterConstraints, duration, timeOffset)) } } + if (useAlarm && carbs > 0 && timeOffset > 0) { + carbTimer.scheduleReminder(dateUtil._now() + T.mins(timeOffset.toLong()).msecs()) + } }, null) } } else diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionAlarm.kt b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionAlarm.kt index c387e70f33..93411a1275 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionAlarm.kt +++ b/app/src/main/java/info/nightscout/androidaps/plugins/general/automation/actions/ActionAlarm.kt @@ -5,14 +5,16 @@ import android.widget.LinearLayout import androidx.annotation.DrawableRes import dagger.android.HasAndroidInjector import info.nightscout.androidaps.R -import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.data.PumpEnactResult import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.general.automation.elements.InputString import info.nightscout.androidaps.plugins.general.automation.elements.LabelWithElement import info.nightscout.androidaps.plugins.general.automation.elements.LayoutBuilder import info.nightscout.androidaps.queue.Callback +import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.JsonHelper +import info.nightscout.androidaps.utils.T +import info.nightscout.androidaps.utils.TimerUtil import info.nightscout.androidaps.utils.resources.ResourceHelper import org.json.JSONObject import javax.inject.Inject @@ -22,6 +24,7 @@ class ActionAlarm(injector: HasAndroidInjector) : Action(injector) { @Inject lateinit var resourceHelper: ResourceHelper @Inject lateinit var rxBus: RxBusWrapper @Inject lateinit var context: Context + @Inject lateinit var timerUtil: TimerUtil var text = InputString(injector) @@ -33,10 +36,11 @@ class ActionAlarm(injector: HasAndroidInjector) : Action(injector) { override fun shortDescription(): String = resourceHelper.gs(R.string.alarm_message, text.value) @DrawableRes override fun icon(): Int = R.drawable.ic_access_alarm_24dp - override fun isValid(): Boolean = text.value.isNotEmpty() + override fun isValid(): Boolean = true // empty alarm will show app name override fun doAction(callback: Callback) { - ErrorHelperActivity.runAlarm(context, text.value, resourceHelper.gs(R.string.alarm), R.raw.modern_alarm) + timerUtil.scheduleReminder(DateUtil.now() + T.secs(10L).msecs(), text.value.takeIf { it.isNotBlank() } + ?: resourceHelper.gs(R.string.app_name)) callback.result(PumpEnactResult(injector).success(true).comment(R.string.ok))?.run() } diff --git a/app/src/main/java/info/nightscout/androidaps/utils/CarbTimer.kt b/app/src/main/java/info/nightscout/androidaps/utils/CarbTimer.kt new file mode 100644 index 0000000000..c029b01af2 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/utils/CarbTimer.kt @@ -0,0 +1,63 @@ +package info.nightscout.androidaps.utils + +import dagger.android.HasAndroidInjector +import info.nightscout.androidaps.Constants +import info.nightscout.androidaps.R +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.utils.resources.ResourceHelper +import java.text.DecimalFormat +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class CarbTimer @Inject constructor( + private val injector: HasAndroidInjector, + private val resourceHelper: ResourceHelper, + private val automationPlugin: AutomationPlugin, + private val timerUtil: TimerUtil +) { + + fun scheduleReminder(time: Long, text: String? = null) = + timerUtil.scheduleReminder(time, text ?: resourceHelper.gs(R.string.timetoeat)) + + 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) + } + +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/utils/TimerUtil.kt b/app/src/main/java/info/nightscout/androidaps/utils/TimerUtil.kt new file mode 100644 index 0000000000..b62f00df54 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/utils/TimerUtil.kt @@ -0,0 +1,27 @@ +package info.nightscout.androidaps.utils + +import android.content.Context +import android.content.Intent +import android.provider.AlarmClock +import info.nightscout.androidaps.R +import info.nightscout.androidaps.utils.resources.ResourceHelper +import javax.inject.Inject +import javax.inject.Singleton + +@Singleton +class TimerUtil @Inject constructor( + private val context: Context, + private val resourceHelper: ResourceHelper, +) { + + fun scheduleReminder(time: Long, text: String? = null) { + Intent(AlarmClock.ACTION_SET_TIMER).apply { + val length: Int = ((time - DateUtil.now()) / 1000).toInt() + flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK + putExtra(AlarmClock.EXTRA_LENGTH, length) + putExtra(AlarmClock.EXTRA_SKIP_UI, true) + putExtra(AlarmClock.EXTRA_MESSAGE, text ?: resourceHelper.gs(R.string.app_name)) + context.startActivity(this) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt index e690ce4dba..37fccabd8c 100644 --- a/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt +++ b/app/src/main/java/info/nightscout/androidaps/utils/wizard/BolusWizard.kt @@ -6,7 +6,6 @@ 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 @@ -22,18 +21,10 @@ import info.nightscout.androidaps.logging.UserEntryLogger 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 +import info.nightscout.androidaps.utils.CarbTimer import info.nightscout.androidaps.utils.DateUtil import info.nightscout.androidaps.utils.HtmlHelper import info.nightscout.androidaps.utils.Round @@ -44,7 +35,6 @@ 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 @@ -63,10 +53,10 @@ class BolusWizard @Inject constructor( @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 @Inject lateinit var uel: UserEntryLogger + @Inject lateinit var carbTimer: CarbTimer init { injector.androidInjector().inject(this) @@ -363,7 +353,7 @@ class BolusWizard @Inject constructor( if (!result.success) { ErrorHelperActivity.runAlarm(ctx, result.comment, resourceHelper.gs(R.string.treatmentdeliveryerror), R.raw.boluserror) } else - scheduleEatReminder() + carbTimer.scheduleEatReminder() } }) } @@ -434,57 +424,9 @@ class BolusWizard @Inject constructor( } } if (useAlarm && carbs > 0 && carbTime > 0) { - scheduleReminder(dateUtil._now() + T.mins(carbTime.toLong()).msecs()) + carbTimer.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) - } -} +} \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_carbs.xml b/app/src/main/res/layout/dialog_carbs.xml index 66c58a61bf..f0f306c6ff 100644 --- a/app/src/main/res/layout/dialog_carbs.xml +++ b/app/src/main/res/layout/dialog_carbs.xml @@ -75,107 +75,160 @@ - + android:paddingEnd="5dp"> - + - + - + - + - + + - + - + - + - + + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + + + + + +