Implemented proper activation and deactivation screens

This commit is contained in:
jbr7rr 2023-06-25 10:21:47 +02:00
parent 3ffb78a7e8
commit 895cf54a17
40 changed files with 1307 additions and 220 deletions

View file

@ -8,4 +8,5 @@ interface Medtrum {
fun loadEvents(): PumpEnactResult // events history to build treatments from fun loadEvents(): PumpEnactResult // events history to build treatments from
fun setUserOptions(): PumpEnactResult // set user settings fun setUserOptions(): PumpEnactResult // set user settings
fun clearAlarms(): PumpEnactResult // clear alarms fun clearAlarms(): PumpEnactResult // clear alarms
fun deactivate(): PumpEnactResult // deactivate patch
} }

View file

@ -29,6 +29,7 @@ abstract class Command(
START_PUMP, START_PUMP,
STOP_PUMP, STOP_PUMP,
CLEAR_ALARMS, // so far only Medtrum specific CLEAR_ALARMS, // so far only Medtrum specific
DEACTIVATE, // so far only Medtrum specific
INSIGHT_SET_TBR_OVER_ALARM, // insight only INSIGHT_SET_TBR_OVER_ALARM, // insight only
CUSTOM_COMMAND CUSTOM_COMMAND
} }

View file

@ -32,6 +32,7 @@ interface CommandQueue {
fun loadTDDs(callback: Callback?): Boolean fun loadTDDs(callback: Callback?): Boolean
fun loadEvents(callback: Callback?): Boolean fun loadEvents(callback: Callback?): Boolean
fun clearAlarms(callback: Callback?): Boolean fun clearAlarms(callback: Callback?): Boolean
fun deactivate(callback: Callback?): Boolean
fun customCommand(customCommand: CustomCommand, callback: Callback?): Boolean fun customCommand(customCommand: CustomCommand, callback: Callback?): Boolean
fun isCustomCommandRunning(customCommandType: Class<out CustomCommand>): Boolean fun isCustomCommandRunning(customCommandType: Class<out CustomCommand>): Boolean
fun isCustomCommandInQueue(customCommandType: Class<out CustomCommand>): Boolean fun isCustomCommandInQueue(customCommandType: Class<out CustomCommand>): Boolean

View file

@ -394,6 +394,7 @@
<string name="extended_bolus_u_min">EXTENDED BOLUS %1$.2f U %2$d min</string> <string name="extended_bolus_u_min">EXTENDED BOLUS %1$.2f U %2$d min</string>
<string name="load_events">LOAD EVENTS</string> <string name="load_events">LOAD EVENTS</string>
<string name="clear_alarms">CLEAR_ALARMS</string> <string name="clear_alarms">CLEAR_ALARMS</string>
<string name="deactivate">DEACTIVATE</string>
<string name="load_history">LOAD HISTORY %1$d</string> <string name="load_history">LOAD HISTORY %1$d</string>
<string name="load_tdds">LOAD TDDs</string> <string name="load_tdds">LOAD TDDs</string>
<string name="set_profile">SET PROFILE</string> <string name="set_profile">SET PROFILE</string>

View file

@ -16,6 +16,7 @@ import info.nightscout.implementation.queue.commands.CommandCancelExtendedBolus
import info.nightscout.implementation.queue.commands.CommandCancelTempBasal import info.nightscout.implementation.queue.commands.CommandCancelTempBasal
import info.nightscout.implementation.queue.commands.CommandClearAlarms import info.nightscout.implementation.queue.commands.CommandClearAlarms
import info.nightscout.implementation.queue.commands.CommandCustomCommand import info.nightscout.implementation.queue.commands.CommandCustomCommand
import info.nightscout.implementation.queue.commands.CommandDeactivate
import info.nightscout.implementation.queue.commands.CommandExtendedBolus import info.nightscout.implementation.queue.commands.CommandExtendedBolus
import info.nightscout.implementation.queue.commands.CommandInsightSetTBROverNotification import info.nightscout.implementation.queue.commands.CommandInsightSetTBROverNotification
import info.nightscout.implementation.queue.commands.CommandLoadEvents import info.nightscout.implementation.queue.commands.CommandLoadEvents
@ -34,6 +35,7 @@ abstract class CommandQueueModule {
@ContributesAndroidInjector abstract fun commandInsightSetTBROverNotificationInjector(): CommandInsightSetTBROverNotification @ContributesAndroidInjector abstract fun commandInsightSetTBROverNotificationInjector(): CommandInsightSetTBROverNotification
@ContributesAndroidInjector abstract fun commandLoadEventsInjector(): CommandLoadEvents @ContributesAndroidInjector abstract fun commandLoadEventsInjector(): CommandLoadEvents
@ContributesAndroidInjector abstract fun commandClearAlarmsInjector(): CommandClearAlarms @ContributesAndroidInjector abstract fun commandClearAlarmsInjector(): CommandClearAlarms
@ContributesAndroidInjector abstract fun commandDeactivateInjector(): CommandDeactivate
@ContributesAndroidInjector abstract fun commandLoadHistoryInjector(): CommandLoadHistory @ContributesAndroidInjector abstract fun commandLoadHistoryInjector(): CommandLoadHistory
@ContributesAndroidInjector abstract fun commandLoadTDDsInjector(): CommandLoadTDDs @ContributesAndroidInjector abstract fun commandLoadTDDsInjector(): CommandLoadTDDs
@ContributesAndroidInjector abstract fun commandReadStatusInjector(): CommandReadStatus @ContributesAndroidInjector abstract fun commandReadStatusInjector(): CommandReadStatus

View file

@ -24,6 +24,7 @@ import info.nightscout.implementation.queue.commands.CommandCancelExtendedBolus
import info.nightscout.implementation.queue.commands.CommandCancelTempBasal import info.nightscout.implementation.queue.commands.CommandCancelTempBasal
import info.nightscout.implementation.queue.commands.CommandClearAlarms import info.nightscout.implementation.queue.commands.CommandClearAlarms
import info.nightscout.implementation.queue.commands.CommandCustomCommand import info.nightscout.implementation.queue.commands.CommandCustomCommand
import info.nightscout.implementation.queue.commands.CommandDeactivate
import info.nightscout.implementation.queue.commands.CommandExtendedBolus import info.nightscout.implementation.queue.commands.CommandExtendedBolus
import info.nightscout.implementation.queue.commands.CommandInsightSetTBROverNotification import info.nightscout.implementation.queue.commands.CommandInsightSetTBROverNotification
import info.nightscout.implementation.queue.commands.CommandLoadEvents import info.nightscout.implementation.queue.commands.CommandLoadEvents
@ -550,6 +551,19 @@ class CommandQueueImplementation @Inject constructor(
return true return true
} }
override fun deactivate(callback: Callback?): Boolean {
if (isRunning(CommandType.DEACTIVATE)) {
callback?.result(executingNowError())?.run()
return false
}
// remove all unfinished
removeAll(CommandType.DEACTIVATE)
// add new command to queue
add(CommandDeactivate(injector, callback))
notifyAboutNewCommand()
return true
}
override fun customCommand(customCommand: CustomCommand, callback: Callback?): Boolean { override fun customCommand(customCommand: CustomCommand, callback: Callback?): Boolean {
if (isCustomCommandInQueue(customCommand.javaClass)) { if (isCustomCommandInQueue(customCommand.javaClass)) {
callback?.result(executingNowError())?.run() callback?.result(executingNowError())?.run()

View file

@ -31,7 +31,7 @@ class CommandClearAlarms(
override fun status(): String = rh.gs(info.nightscout.core.ui.R.string.clear_alarms) override fun status(): String = rh.gs(info.nightscout.core.ui.R.string.clear_alarms)
override fun log(): String = "CLEAR ALAMRS" override fun log(): String = "CLEAR ALARMS"
override fun cancel() { override fun cancel() {
aapsLogger.debug(LTag.PUMPQUEUE, "Result cancel") aapsLogger.debug(LTag.PUMPQUEUE, "Result cancel")
callback?.result(PumpEnactResult(injector).success(false).comment(info.nightscout.core.ui.R.string.connectiontimedout))?.run() callback?.result(PumpEnactResult(injector).success(false).comment(info.nightscout.core.ui.R.string.connectiontimedout))?.run()

View file

@ -0,0 +1,39 @@
package info.nightscout.implementation.queue.commands
import dagger.android.HasAndroidInjector
import info.nightscout.interfaces.plugin.ActivePlugin
import info.nightscout.interfaces.pump.Dana
import info.nightscout.interfaces.pump.Diaconn
import info.nightscout.interfaces.pump.Medtrum
import info.nightscout.interfaces.pump.PumpEnactResult
import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.queue.Command
import info.nightscout.rx.logging.LTag
import javax.inject.Inject
class CommandDeactivate(
injector: HasAndroidInjector,
callback: Callback?
) : Command(injector, CommandType.DEACTIVATE, callback) {
@Inject lateinit var activePlugin: ActivePlugin
override fun execute() {
val pump = activePlugin.activePump
if (pump is Medtrum) {
val medtrumPump = pump as Medtrum
val r = medtrumPump.deactivate()
aapsLogger.debug(LTag.PUMPQUEUE, "Result success: ${r.success} enacted: ${r.enacted}")
callback?.result(r)?.run()
}
}
override fun status(): String = rh.gs(info.nightscout.core.ui.R.string.deactivate)
override fun log(): String = "DEACTIVATE"
override fun cancel() {
aapsLogger.debug(LTag.PUMPQUEUE, "Result cancel")
callback?.result(PumpEnactResult(injector).success(false).comment(info.nightscout.core.ui.R.string.connectiontimedout))?.run()
}
}

View file

@ -243,6 +243,10 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
commandQueue.clearAlarms(null) commandQueue.clearAlarms(null)
Assertions.assertEquals(5, commandQueue.size()) Assertions.assertEquals(5, commandQueue.size())
// add deactivate
commandQueue.deactivate(null)
Assertions.assertEquals(6, commandQueue.size())
commandQueue.clear() commandQueue.clear()
commandQueue.tempBasalAbsolute(0.0, 30, true, validProfile, PumpSync.TemporaryBasalType.NORMAL, null) commandQueue.tempBasalAbsolute(0.0, 30, true, validProfile, PumpSync.TemporaryBasalType.NORMAL, null)
commandQueue.pickup() commandQueue.pickup()
@ -375,6 +379,22 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
Assertions.assertEquals(1, commandQueue.size()) Assertions.assertEquals(1, commandQueue.size())
} }
@Test
fun isDeactivateCommandInQueue() {
// given
Assertions.assertEquals(0, commandQueue.size())
// when
commandQueue.deactivate(null)
// then
Assertions.assertTrue(commandQueue.isLastScheduled(Command.CommandType.DEACTIVATE))
Assertions.assertEquals(1, commandQueue.size())
// next should be ignored
commandQueue.deactivate(null)
Assertions.assertEquals(1, commandQueue.size())
}
@Test @Test
fun isLoadTDDsCommandInQueue() { fun isLoadTDDsCommandInQueue() {
// given // given

View file

@ -82,7 +82,7 @@ import kotlin.math.round
PluginDescription() PluginDescription()
.mainType(PluginType.PUMP) .mainType(PluginType.PUMP)
.fragmentClass(MedtrumOverviewFragment::class.java.name) .fragmentClass(MedtrumOverviewFragment::class.java.name)
.pluginIcon(info.nightscout.core.ui.R.drawable.ic_eopatch2_128) // TODO .pluginIcon(info.nightscout.core.ui.R.drawable.ic_generic_icon) // TODO
.pluginName(R.string.medtrum) .pluginName(R.string.medtrum)
.shortName(R.string.medtrum_pump_shortname) .shortName(R.string.medtrum_pump_shortname)
.preferencesId(R.xml.pref_medtrum_pump) .preferencesId(R.xml.pref_medtrum_pump)
@ -442,4 +442,14 @@ import kotlin.math.round
val connectionOK = medtrumService?.clearAlarms() ?: false val connectionOK = medtrumService?.clearAlarms() ?: false
return PumpEnactResult(injector).success(connectionOK) return PumpEnactResult(injector).success(connectionOK)
} }
override fun deactivate(): PumpEnactResult {
// if (!isInitialized()) {
// val result = PumpEnactResult(injector).success(false)
// result.comment = "pump not initialized"
// return result
// }
val connectionOK = medtrumService?.deactivatePatch() ?: false
return PumpEnactResult(injector).success(connectionOK)
}
} }

View file

@ -3,13 +3,17 @@ package info.nightscout.pump.medtrum.code
enum class PatchStep { enum class PatchStep {
START_DEACTIVATION, START_DEACTIVATION,
DEACTIVATE, DEACTIVATE,
FORCE_DEACTIVATION,
DEACTIVATION_COMPLETE, DEACTIVATION_COMPLETE,
PREPARE_PATCH, PREPARE_PATCH,
PREPARE_PATCH_CONNECT,
PRIME, PRIME,
PRIMING,
PRIME_COMPLETE,
ATTACH_PATCH, ATTACH_PATCH,
ACTIVATE, ACTIVATE,
ACTIVATE_COMPLETE,
ERROR,
CANCEL, CANCEL,
COMPLETE, COMPLETE;
BACK_TO_HOME,
FINISH;
} }

View file

@ -112,7 +112,7 @@ class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(bolusStartTime, bolusNormalDelivered) val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(bolusStartTime, bolusNormalDelivered)
var newRecord = false var newRecord = false
if (detailedBolusInfo != null) { if (detailedBolusInfo != null) {
val success = pumpSync.syncBolusWithTempId( val syncOk = pumpSync.syncBolusWithTempId(
timestamp = bolusStartTime, timestamp = bolusStartTime,
amount = bolusNormalDelivered, amount = bolusNormalDelivered,
temporaryId = detailedBolusInfo.timestamp, temporaryId = detailedBolusInfo.timestamp,
@ -121,7 +121,7 @@ class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int
pumpType = medtrumPump.pumpType(), pumpType = medtrumPump.pumpType(),
pumpSerial = medtrumPump.pumpSN.toString(radix = 16) pumpSerial = medtrumPump.pumpSN.toString(radix = 16)
) )
if (success == false) { if (syncOk == false) {
aapsLogger.warn(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BOLUS_RECORD: Failed to sync bolus with tempId: ${detailedBolusInfo.timestamp}") aapsLogger.warn(LTag.PUMPCOMM, "GetRecordPacket HandleResponse: BOLUS_RECORD: Failed to sync bolus with tempId: ${detailedBolusInfo.timestamp}")
// detailedInfo can be from another similar record. Reinsert // detailedInfo can be from another similar record. Reinsert
detailedBolusInfoStorage.add(detailedBolusInfo) detailedBolusInfoStorage.add(detailedBolusInfo)

View file

@ -7,13 +7,18 @@ import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.android.ContributesAndroidInjector import dagger.android.ContributesAndroidInjector
import dagger.multibindings.IntoMap import dagger.multibindings.IntoMap
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumActivateFragment
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumAttachPatchFragment
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumDeactivatePatchFragment
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumPreparePatchFragment
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumPrimeFragment
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumStartDeactivationFragment
import info.nightscout.pump.medtrum.services.MedtrumService import info.nightscout.pump.medtrum.services.MedtrumService
import info.nightscout.pump.medtrum.ui.MedtrumActivateCompleteFragment
import info.nightscout.pump.medtrum.ui.MedtrumActivateFragment
import info.nightscout.pump.medtrum.ui.MedtrumAttachPatchFragment
import info.nightscout.pump.medtrum.ui.MedtrumDeactivatePatchFragment
import info.nightscout.pump.medtrum.ui.MedtrumDeactivationCompleteFragment
import info.nightscout.pump.medtrum.ui.MedtrumPreparePatchConnectFragment
import info.nightscout.pump.medtrum.ui.MedtrumPreparePatchFragment
import info.nightscout.pump.medtrum.ui.MedtrumPrimeCompleteFragment
import info.nightscout.pump.medtrum.ui.MedtrumPrimeFragment
import info.nightscout.pump.medtrum.ui.MedtrumPrimingFragment
import info.nightscout.pump.medtrum.ui.MedtrumStartDeactivationFragment
import info.nightscout.pump.medtrum.ui.MedtrumActivity import info.nightscout.pump.medtrum.ui.MedtrumActivity
import info.nightscout.pump.medtrum.ui.MedtrumOverviewFragment import info.nightscout.pump.medtrum.ui.MedtrumOverviewFragment
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumOverviewViewModel import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumOverviewViewModel
@ -60,14 +65,30 @@ abstract class MedtrumModule {
@ContributesAndroidInjector @ContributesAndroidInjector
internal abstract fun contributesDeactivatePatchFragment(): MedtrumDeactivatePatchFragment internal abstract fun contributesDeactivatePatchFragment(): MedtrumDeactivatePatchFragment
@FragmentScope
@ContributesAndroidInjector
internal abstract fun contributesDeactivationCompleteFragment(): MedtrumDeactivationCompleteFragment
@FragmentScope @FragmentScope
@ContributesAndroidInjector @ContributesAndroidInjector
internal abstract fun contributesPreparePatchFragment(): MedtrumPreparePatchFragment internal abstract fun contributesPreparePatchFragment(): MedtrumPreparePatchFragment
@FragmentScope
@ContributesAndroidInjector
internal abstract fun contributesPreparePatchConnectFragment(): MedtrumPreparePatchConnectFragment
@FragmentScope @FragmentScope
@ContributesAndroidInjector @ContributesAndroidInjector
internal abstract fun contributesPrimeFragment(): MedtrumPrimeFragment internal abstract fun contributesPrimeFragment(): MedtrumPrimeFragment
@FragmentScope
@ContributesAndroidInjector
internal abstract fun contributesPrimeCompleteFragment(): MedtrumPrimeCompleteFragment
@FragmentScope
@ContributesAndroidInjector
internal abstract fun contributesPrimingFragment(): MedtrumPrimingFragment
@FragmentScope @FragmentScope
@ContributesAndroidInjector @ContributesAndroidInjector
internal abstract fun contributesAttachPatchFragment(): MedtrumAttachPatchFragment internal abstract fun contributesAttachPatchFragment(): MedtrumAttachPatchFragment
@ -76,6 +97,10 @@ abstract class MedtrumModule {
@ContributesAndroidInjector @ContributesAndroidInjector
internal abstract fun contributesActivateFragment(): MedtrumActivateFragment internal abstract fun contributesActivateFragment(): MedtrumActivateFragment
@FragmentScope
@ContributesAndroidInjector
internal abstract fun contributesActivateCompleteFragment(): MedtrumActivateCompleteFragment
// ACTIVITIES // ACTIVITIES
@ContributesAndroidInjector @ContributesAndroidInjector
abstract fun contributesMedtrumActivity(): MedtrumActivity abstract fun contributesMedtrumActivity(): MedtrumActivity

View file

@ -414,12 +414,6 @@ class MedtrumService : DaggerService(), BLECommCallback {
// Map the pump state to a notification // Map the pump state to a notification
when (state) { when (state) {
MedtrumPumpState.NONE, MedtrumPumpState.NONE,
MedtrumPumpState.IDLE,
MedtrumPumpState.FILLED,
MedtrumPumpState.PRIMING,
MedtrumPumpState.PRIMED,
MedtrumPumpState.EJECTING,
MedtrumPumpState.EJECTED,
MedtrumPumpState.STOPPED -> { MedtrumPumpState.STOPPED -> {
rxBus.send(EventDismissNotification(Notification.PUMP_ERROR)) rxBus.send(EventDismissNotification(Notification.PUMP_ERROR))
rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED)) rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED))
@ -432,6 +426,18 @@ class MedtrumService : DaggerService(), BLECommCallback {
medtrumPump.clearAlarmState() medtrumPump.clearAlarmState()
} }
MedtrumPumpState.IDLE,
MedtrumPumpState.FILLED,
MedtrumPumpState.PRIMING,
MedtrumPumpState.PRIMED,
MedtrumPumpState.EJECTING,
MedtrumPumpState.EJECTED -> {
rxBus.send(EventDismissNotification(Notification.PUMP_ERROR))
rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED))
medtrumPump.setFakeTBRIfNeeded()
medtrumPump.clearAlarmState()
}
MedtrumPumpState.ACTIVE, MedtrumPumpState.ACTIVE,
MedtrumPumpState.ACTIVE_ALT -> { MedtrumPumpState.ACTIVE_ALT -> {
rxBus.send(EventDismissNotification(Notification.PATCH_NOT_ACTIVE)) rxBus.send(EventDismissNotification(Notification.PATCH_NOT_ACTIVE))
@ -599,7 +605,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
} }
fun onSendMessageError(reason: String) { fun onSendMessageError(reason: String) {
aapsLogger.debug(LTag.PUMPCOMM, "onSendMessageError: " + this.toString() + "reason: $reason") aapsLogger.warn(LTag.PUMPCOMM, "onSendMessageError: " + this.toString() + "reason: $reason")
responseHandled = true responseHandled = true
responseSuccess = false responseSuccess = false
} }

View file

@ -0,0 +1,53 @@
package info.nightscout.pump.medtrum.ui
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import info.nightscout.core.ui.toast.ToastUtils
import info.nightscout.pump.medtrum.R
import info.nightscout.pump.medtrum.code.PatchStep
import info.nightscout.pump.medtrum.databinding.FragmentMedtrumActivateBinding
import info.nightscout.pump.medtrum.databinding.FragmentMedtrumActivateCompleteBinding
import info.nightscout.pump.medtrum.ui.MedtrumBaseFragment
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import javax.inject.Inject
class MedtrumActivateCompleteFragment : MedtrumBaseFragment<FragmentMedtrumActivateCompleteBinding>() {
@Inject lateinit var aapsLogger: AAPSLogger
companion object {
fun newInstance(): MedtrumActivateCompleteFragment = MedtrumActivateCompleteFragment()
}
override fun getLayoutId(): Int = R.layout.fragment_medtrum_activate_complete
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.apply {
viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java)
viewModel?.apply {
setupStep.observe(viewLifecycleOwner) {
when (it) {
MedtrumViewModel.SetupStep.INITIAL,
MedtrumViewModel.SetupStep.PRIMED -> Unit // Nothing to do here, previous state
MedtrumViewModel.SetupStep.ACTIVATED -> btnPositive.visibility = View.VISIBLE
MedtrumViewModel.SetupStep.ERROR -> {
ToastUtils.errorToast(requireContext(), "Error Activating") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL)
}
else -> {
ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message
aapsLogger.error(LTag.PUMP, "Unexpected state: $it")
}
}
}
}
}
}
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.pump.eopatch.ui package info.nightscout.pump.medtrum.ui
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
@ -11,11 +11,13 @@ import info.nightscout.pump.medtrum.ui.MedtrumBaseFragment
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import javax.inject.Inject import javax.inject.Inject
class MedtrumActivateFragment : MedtrumBaseFragment<FragmentMedtrumActivateBinding>() { class MedtrumActivateFragment : MedtrumBaseFragment<FragmentMedtrumActivateBinding>() {
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rh: ResourceHelper
companion object { companion object {
@ -31,16 +33,20 @@ class MedtrumActivateFragment : MedtrumBaseFragment<FragmentMedtrumActivateBindi
viewModel?.apply { viewModel?.apply {
setupStep.observe(viewLifecycleOwner) { setupStep.observe(viewLifecycleOwner) {
when (it) { when (it) {
MedtrumViewModel.SetupStep.INITIAL,
MedtrumViewModel.SetupStep.PRIMED -> Unit // Nothing to do here, previous state MedtrumViewModel.SetupStep.PRIMED -> Unit // Nothing to do here, previous state
MedtrumViewModel.SetupStep.ACTIVATED -> btnPositive.visibility = View.VISIBLE MedtrumViewModel.SetupStep.ACTIVATED -> moveStep(PatchStep.ACTIVATE_COMPLETE)
MedtrumViewModel.SetupStep.ERROR -> { MedtrumViewModel.SetupStep.ERROR -> {
ToastUtils.errorToast(requireContext(), "Error Activating") // TODO: String resource and show error message moveStep(PatchStep.ERROR)
moveStep(PatchStep.CANCEL) updateSetupStep(MedtrumViewModel.SetupStep.PRIMED) // Reset setup step
binding.textActivatingPump.text = rh.gs(R.string.activating_error)
binding.btnPositive.visibility = View.VISIBLE
} }
else -> { else -> {
ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message ToastUtils.errorToast(requireContext(), "Unexpected state: $it")
moveStep(PatchStep.CANCEL) aapsLogger.error(LTag.PUMP, "Unexpected state: $it")
} }
} }
} }

View file

@ -3,21 +3,29 @@ package info.nightscout.pump.medtrum.ui
import android.app.Dialog import android.app.Dialog
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.ActivityInfo
import android.media.MediaPlayer import android.media.MediaPlayer
import android.media.RingtoneManager import android.media.RingtoneManager
import android.os.Bundle import android.os.Bundle
import android.view.MotionEvent import android.view.MotionEvent
import android.view.WindowManager
import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.ViewModelProvider
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumActivateFragment import info.nightscout.pump.medtrum.ui.MedtrumActivateCompleteFragment
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumAttachPatchFragment import info.nightscout.pump.medtrum.ui.MedtrumActivateFragment
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumDeactivatePatchFragment import info.nightscout.pump.medtrum.ui.MedtrumAttachPatchFragment
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumPreparePatchFragment import info.nightscout.pump.medtrum.ui.MedtrumDeactivatePatchFragment
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumPrimeFragment import info.nightscout.pump.medtrum.ui.MedtrumDeactivationCompleteFragment
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumStartDeactivationFragment import info.nightscout.pump.medtrum.ui.MedtrumPreparePatchConnectFragment
import info.nightscout.pump.medtrum.ui.MedtrumPreparePatchFragment
import info.nightscout.pump.medtrum.ui.MedtrumPrimeCompleteFragment
import info.nightscout.pump.medtrum.ui.MedtrumPrimeFragment
import info.nightscout.pump.medtrum.ui.MedtrumPrimingFragment
import info.nightscout.pump.medtrum.ui.MedtrumStartDeactivationFragment
import info.nightscout.core.utils.extensions.safeGetSerializableExtra import info.nightscout.core.utils.extensions.safeGetSerializableExtra
import info.nightscout.pump.medtrum.R import info.nightscout.pump.medtrum.R
import info.nightscout.pump.medtrum.code.PatchStep import info.nightscout.pump.medtrum.code.PatchStep
import info.nightscout.pump.medtrum.comm.enums.MedtrumPumpState
import info.nightscout.pump.medtrum.databinding.ActivityMedtrumBinding import info.nightscout.pump.medtrum.databinding.ActivityMedtrumBinding
import info.nightscout.pump.medtrum.extension.replaceFragmentInActivity import info.nightscout.pump.medtrum.extension.replaceFragmentInActivity
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
@ -36,6 +44,8 @@ class MedtrumActivity : MedtrumBaseActivity<ActivityMedtrumBinding>() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
binding.apply { binding.apply {
viewModel = ViewModelProvider(this@MedtrumActivity, viewModelFactory).get(MedtrumViewModel::class.java) viewModel = ViewModelProvider(this@MedtrumActivity, viewModelFactory).get(MedtrumViewModel::class.java)
@ -45,15 +55,33 @@ class MedtrumActivity : MedtrumBaseActivity<ActivityMedtrumBinding>() {
patchStep.observe(this@MedtrumActivity) { patchStep.observe(this@MedtrumActivity) {
when (it) { when (it) {
PatchStep.PREPARE_PATCH -> setupViewFragment(MedtrumPreparePatchFragment.newInstance()) PatchStep.PREPARE_PATCH -> setupViewFragment(MedtrumPreparePatchFragment.newInstance())
PatchStep.PREPARE_PATCH_CONNECT -> setupViewFragment(MedtrumPreparePatchConnectFragment.newInstance())
PatchStep.PRIME -> setupViewFragment(MedtrumPrimeFragment.newInstance()) PatchStep.PRIME -> setupViewFragment(MedtrumPrimeFragment.newInstance())
PatchStep.PRIMING -> setupViewFragment(MedtrumPrimingFragment.newInstance())
PatchStep.PRIME_COMPLETE -> setupViewFragment(MedtrumPrimeCompleteFragment.newInstance())
PatchStep.ATTACH_PATCH -> setupViewFragment(MedtrumAttachPatchFragment.newInstance()) PatchStep.ATTACH_PATCH -> setupViewFragment(MedtrumAttachPatchFragment.newInstance())
PatchStep.ACTIVATE -> setupViewFragment(MedtrumActivateFragment.newInstance()) PatchStep.ACTIVATE -> setupViewFragment(MedtrumActivateFragment.newInstance())
PatchStep.COMPLETE -> this@MedtrumActivity.finish() // TODO proper finish PatchStep.ACTIVATE_COMPLETE -> setupViewFragment(MedtrumActivateCompleteFragment.newInstance())
PatchStep.CANCEL -> this@MedtrumActivity.finish() PatchStep.COMPLETE -> this@MedtrumActivity.finish()
PatchStep.ERROR -> Unit // Do nothing, let activity handle this
PatchStep.CANCEL -> {
if (setupStep.value !in listOf(MedtrumViewModel.SetupStep.ACTIVATED, MedtrumViewModel.SetupStep.START_DEACTIVATION, MedtrumViewModel.SetupStep.STOPPED)) {
resetPumpState()
}
this@MedtrumActivity.finish()
}
PatchStep.START_DEACTIVATION -> setupViewFragment(MedtrumStartDeactivationFragment.newInstance()) PatchStep.START_DEACTIVATION -> setupViewFragment(MedtrumStartDeactivationFragment.newInstance())
PatchStep.DEACTIVATE -> setupViewFragment(MedtrumDeactivatePatchFragment.newInstance()) PatchStep.DEACTIVATE -> setupViewFragment(MedtrumDeactivatePatchFragment.newInstance())
PatchStep.DEACTIVATION_COMPLETE -> this@MedtrumActivity.finish() // TODO proper finish
else -> Unit PatchStep.FORCE_DEACTIVATION -> {
medtrumPump.pumpState = MedtrumPumpState.STOPPED
moveStep(PatchStep.DEACTIVATION_COMPLETE)
}
PatchStep.DEACTIVATION_COMPLETE -> setupViewFragment(MedtrumDeactivationCompleteFragment.newInstance())
null -> Unit
} }
} }
} }
@ -69,10 +97,12 @@ class MedtrumActivity : MedtrumBaseActivity<ActivityMedtrumBinding>() {
binding.viewModel?.apply { binding.viewModel?.apply {
intent?.run { intent?.run {
val step = intent.safeGetSerializableExtra(EXTRA_START_PATCH_STEP, PatchStep::class.java) val step = intent.safeGetSerializableExtra(EXTRA_START_PATCH_STEP, PatchStep::class.java)
if (step != null) {
initializePatchStep(step) initializePatchStep(step)
} }
} }
} }
}
override fun onDestroy() { override fun onDestroy() {
super.onDestroy() super.onDestroy()

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.pump.eopatch.ui package info.nightscout.pump.medtrum.ui
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
@ -32,14 +32,16 @@ class MedtrumAttachPatchFragment : MedtrumBaseFragment<FragmentMedtrumAttachPatc
viewModel?.apply { viewModel?.apply {
setupStep.observe(viewLifecycleOwner) { setupStep.observe(viewLifecycleOwner) {
when (it) { when (it) {
MedtrumViewModel.SetupStep.INITIAL,
MedtrumViewModel.SetupStep.PRIMED -> Unit // Nothing to do here, previous state MedtrumViewModel.SetupStep.PRIMED -> Unit // Nothing to do here, previous state
MedtrumViewModel.SetupStep.ERROR -> { MedtrumViewModel.SetupStep.ERROR -> {
ToastUtils.errorToast(requireContext(), "Error attach patch") // TODO: String resource and show error message ToastUtils.errorToast(requireContext(), "Error attach patch") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL) moveStep(PatchStep.CANCEL)
} }
else -> { else -> {
ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL) aapsLogger.error(LTag.PUMP, "Unexpected state: $it")
} }
} }
} }

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.pump.eopatch.ui package info.nightscout.pump.medtrum.ui
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
@ -11,11 +11,13 @@ import info.nightscout.pump.medtrum.ui.MedtrumBaseFragment
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import javax.inject.Inject import javax.inject.Inject
class MedtrumDeactivatePatchFragment : MedtrumBaseFragment<FragmentMedtrumDeactivatePatchBinding>() { class MedtrumDeactivatePatchFragment : MedtrumBaseFragment<FragmentMedtrumDeactivatePatchBinding>() {
@Inject lateinit var aapsLogger: AAPSLogger @Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rh: ResourceHelper
companion object { companion object {
@ -32,11 +34,16 @@ class MedtrumDeactivatePatchFragment : MedtrumBaseFragment<FragmentMedtrumDeacti
viewModel?.apply { viewModel?.apply {
setupStep.observe(viewLifecycleOwner) { setupStep.observe(viewLifecycleOwner) {
when (it) { when (it) {
MedtrumViewModel.SetupStep.STOPPED -> btnPositive.visibility = View.VISIBLE MedtrumViewModel.SetupStep.STOPPED -> {
moveStep(PatchStep.DEACTIVATION_COMPLETE)
}
MedtrumViewModel.SetupStep.ERROR -> { MedtrumViewModel.SetupStep.ERROR -> {
ToastUtils.errorToast(requireContext(), "Error deactivate") // TODO: String resource and show error message moveStep(PatchStep.ERROR)
moveStep(PatchStep.CANCEL) updateSetupStep(MedtrumViewModel.SetupStep.START_DEACTIVATION) // Reset setup step
binding.textDeactivatingPump.text = rh.gs(R.string.deactivating_error)
binding.btnNegative.visibility = View.VISIBLE
binding.btnPositive.visibility = View.VISIBLE
} }
else -> Unit // Nothing to do here else -> Unit // Nothing to do here

View file

@ -0,0 +1,37 @@
package info.nightscout.pump.medtrum.ui
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import info.nightscout.core.ui.toast.ToastUtils
import info.nightscout.pump.medtrum.R
import info.nightscout.pump.medtrum.code.PatchStep
import info.nightscout.pump.medtrum.databinding.FragmentMedtrumDeactivationCompleteBinding
import info.nightscout.pump.medtrum.ui.MedtrumBaseFragment
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import javax.inject.Inject
class MedtrumDeactivationCompleteFragment : MedtrumBaseFragment<FragmentMedtrumDeactivationCompleteBinding>() {
@Inject lateinit var aapsLogger: AAPSLogger
companion object {
fun newInstance(): MedtrumDeactivationCompleteFragment = MedtrumDeactivationCompleteFragment()
}
override fun getLayoutId(): Int = R.layout.fragment_medtrum_deactivation_complete
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
aapsLogger.debug(LTag.PUMP, "MedtrumStartDeactivationFragment onViewCreated")
binding.apply {
viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java)
viewModel?.apply {
// Nothing to do here (yet)
}
}
}
}

View file

@ -0,0 +1,51 @@
package info.nightscout.pump.medtrum.ui
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import info.nightscout.core.ui.toast.ToastUtils
import info.nightscout.pump.medtrum.R
import info.nightscout.pump.medtrum.code.PatchStep
import info.nightscout.pump.medtrum.databinding.FragmentMedtrumPreparePatchConnectBinding
import info.nightscout.pump.medtrum.ui.MedtrumBaseFragment
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import javax.inject.Inject
class MedtrumPreparePatchConnectFragment : MedtrumBaseFragment<FragmentMedtrumPreparePatchConnectBinding>() {
@Inject lateinit var aapsLogger: AAPSLogger
companion object {
fun newInstance(): MedtrumPreparePatchConnectFragment = MedtrumPreparePatchConnectFragment()
}
override fun getLayoutId(): Int = R.layout.fragment_medtrum_prepare_patch_connect
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
aapsLogger.debug(LTag.PUMP, "MedtrumPreparePatchFragment onViewCreated")
binding.apply {
viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java)
viewModel?.apply {
setupStep.observe(viewLifecycleOwner) {
when (it) {
MedtrumViewModel.SetupStep.INITIAL -> btnPositive.visibility = View.GONE
// TODO: Confirmation dialog
MedtrumViewModel.SetupStep.FILLED -> btnPositive.visibility = View.VISIBLE
MedtrumViewModel.SetupStep.ERROR -> {
ToastUtils.errorToast(requireContext(), "Error preparing patch") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL)
}
else -> Unit
}
}
preparePatchConnect()
}
}
}
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.pump.eopatch.ui package info.nightscout.pump.medtrum.ui
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
@ -30,23 +30,6 @@ class MedtrumPreparePatchFragment : MedtrumBaseFragment<FragmentMedtrumPreparePa
binding.apply { binding.apply {
viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java) viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java)
viewModel?.apply { viewModel?.apply {
setupStep.observe(viewLifecycleOwner) {
when (it) {
MedtrumViewModel.SetupStep.INITIAL -> btnPositive.visibility = View.GONE
// TODO: Confirmation dialog
MedtrumViewModel.SetupStep.FILLED -> btnPositive.visibility = View.VISIBLE
MedtrumViewModel.SetupStep.ERROR -> {
ToastUtils.errorToast(requireContext(), "Error preparing patch") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL)
}
else -> {
ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL)
}
}
}
preparePatch() preparePatch()
} }
} }

View file

@ -0,0 +1,50 @@
package info.nightscout.pump.medtrum.ui
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import info.nightscout.core.ui.toast.ToastUtils
import info.nightscout.pump.medtrum.R
import info.nightscout.pump.medtrum.code.PatchStep
import info.nightscout.pump.medtrum.databinding.FragmentMedtrumPrimeCompleteBinding
import info.nightscout.pump.medtrum.ui.MedtrumBaseFragment
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import javax.inject.Inject
class MedtrumPrimeCompleteFragment : MedtrumBaseFragment<FragmentMedtrumPrimeCompleteBinding>() {
@Inject lateinit var aapsLogger: AAPSLogger
companion object {
fun newInstance(): MedtrumPrimeCompleteFragment = MedtrumPrimeCompleteFragment()
}
override fun getLayoutId(): Int = R.layout.fragment_medtrum_prime_complete
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.apply {
viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java)
viewModel?.apply {
setupStep.observe(viewLifecycleOwner) {
when (it) {
MedtrumViewModel.SetupStep.INITIAL,
MedtrumViewModel.SetupStep.PRIMED -> Unit // Nothing to do here, previous state
MedtrumViewModel.SetupStep.ERROR -> {
ToastUtils.errorToast(requireContext(), "Error priming") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL)
}
else -> {
ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message
aapsLogger.error(LTag.PUMP, "Unexpected state: $it")
}
}
}
}
}
}
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.pump.eopatch.ui package info.nightscout.pump.medtrum.ui
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
@ -31,8 +31,8 @@ class MedtrumPrimeFragment : MedtrumBaseFragment<FragmentMedtrumPrimeBinding>()
viewModel?.apply { viewModel?.apply {
setupStep.observe(viewLifecycleOwner) { setupStep.observe(viewLifecycleOwner) {
when (it) { when (it) {
MedtrumViewModel.SetupStep.INITIAL,
MedtrumViewModel.SetupStep.FILLED -> Unit // Nothing to do here, previous state MedtrumViewModel.SetupStep.FILLED -> Unit // Nothing to do here, previous state
MedtrumViewModel.SetupStep.PRIMED -> btnPositive.visibility = View.VISIBLE
MedtrumViewModel.SetupStep.ERROR -> { MedtrumViewModel.SetupStep.ERROR -> {
ToastUtils.errorToast(requireContext(), "Error priming") // TODO: String resource and show error message ToastUtils.errorToast(requireContext(), "Error priming") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL) moveStep(PatchStep.CANCEL)
@ -40,11 +40,10 @@ class MedtrumPrimeFragment : MedtrumBaseFragment<FragmentMedtrumPrimeBinding>()
else -> { else -> {
ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL) aapsLogger.error(LTag.PUMP, "Unexpected state: $it")
} }
} }
} }
startPrime()
} }
} }
} }

View file

@ -0,0 +1,57 @@
package info.nightscout.pump.medtrum.ui
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import info.nightscout.core.ui.toast.ToastUtils
import info.nightscout.pump.medtrum.R
import info.nightscout.pump.medtrum.code.PatchStep
import info.nightscout.pump.medtrum.databinding.FragmentMedtrumPrimingBinding
import info.nightscout.pump.medtrum.ui.MedtrumBaseFragment
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.shared.interfaces.ResourceHelper
import javax.inject.Inject
class MedtrumPrimingFragment : MedtrumBaseFragment<FragmentMedtrumPrimingBinding>() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rh: ResourceHelper
companion object {
fun newInstance(): MedtrumPrimingFragment = MedtrumPrimingFragment()
}
override fun getLayoutId(): Int = R.layout.fragment_medtrum_priming
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.apply {
viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java)
viewModel?.apply {
setupStep.observe(viewLifecycleOwner) {
when (it) {
MedtrumViewModel.SetupStep.INITIAL,
MedtrumViewModel.SetupStep.FILLED -> Unit // Nothing to do here, previous state
MedtrumViewModel.SetupStep.PRIMED -> moveStep(PatchStep.PRIME_COMPLETE)
MedtrumViewModel.SetupStep.ERROR -> {
moveStep(PatchStep.ERROR)
updateSetupStep(MedtrumViewModel.SetupStep.FILLED) // Reset setup step
binding.textWaitForPriming.text = rh.gs(R.string.priming_error)
binding.btnPositive.visibility = View.VISIBLE
}
else -> {
ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message
aapsLogger.error(LTag.PUMP, "Unexpected state: $it")
}
}
}
startPrime()
}
}
}
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.pump.eopatch.ui package info.nightscout.pump.medtrum.ui
import android.os.Bundle import android.os.Bundle
import android.view.View import android.view.View
@ -30,19 +30,7 @@ class MedtrumStartDeactivationFragment : MedtrumBaseFragment<FragmentMedtrumStar
binding.apply { binding.apply {
viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java) viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java)
viewModel?.apply { viewModel?.apply {
setupStep.observe(viewLifecycleOwner) { updateSetupStep(MedtrumViewModel.SetupStep.START_DEACTIVATION)
when (it) {
MedtrumViewModel.SetupStep.READY_DEACTIVATE -> btnPositive.visibility = View.VISIBLE
MedtrumViewModel.SetupStep.ERROR -> {
ToastUtils.errorToast(requireContext(), "Error deactivate") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL)
}
else -> Unit // Nothing to do here
}
}
startDeactivation()
} }
} }
} }

View file

@ -29,14 +29,4 @@ abstract class BaseViewModel<N : MedtrumBaseNavigator> : ViewModel() {
fun finish() = navigator?.finish() fun finish() = navigator?.finish()
fun Disposable.addTo() = apply { compositeDisposable.add(this) } fun Disposable.addTo() = apply { compositeDisposable.add(this) }
fun convertToPatchStep(pumpState: MedtrumPumpState) = when (pumpState) {
MedtrumPumpState.NONE, MedtrumPumpState.IDLE -> PatchStep.PREPARE_PATCH
MedtrumPumpState.FILLED -> PatchStep.PREPARE_PATCH
MedtrumPumpState.PRIMING -> PatchStep.PRIME
MedtrumPumpState.PRIMED, MedtrumPumpState.EJECTED -> PatchStep.ATTACH_PATCH
MedtrumPumpState.ACTIVE, MedtrumPumpState.ACTIVE_ALT -> PatchStep.COMPLETE
MedtrumPumpState.STOPPED -> PatchStep.DEACTIVATION_COMPLETE
else -> PatchStep.CANCEL
}
} }

View file

@ -3,6 +3,8 @@ package info.nightscout.pump.medtrum.ui.viewmodel
import androidx.lifecycle.LiveData import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import info.nightscout.core.utils.fabric.FabricPrivacy import info.nightscout.core.utils.fabric.FabricPrivacy
import info.nightscout.interfaces.queue.Callback
import info.nightscout.interfaces.queue.CommandQueue
import info.nightscout.pump.medtrum.MedtrumPlugin import info.nightscout.pump.medtrum.MedtrumPlugin
import info.nightscout.pump.medtrum.MedtrumPump import info.nightscout.pump.medtrum.MedtrumPump
import info.nightscout.pump.medtrum.R import info.nightscout.pump.medtrum.R
@ -35,7 +37,8 @@ class MedtrumViewModel @Inject constructor(
private val aapsSchedulers: AapsSchedulers, private val aapsSchedulers: AapsSchedulers,
private val fabricPrivacy: FabricPrivacy, private val fabricPrivacy: FabricPrivacy,
private val medtrumPlugin: MedtrumPlugin, private val medtrumPlugin: MedtrumPlugin,
private val medtrumPump: MedtrumPump, private val commandQueue: CommandQueue,
val medtrumPump: MedtrumPump,
private val sp: SP private val sp: SP
) : BaseViewModel<MedtrumBaseNavigator>() { ) : BaseViewModel<MedtrumBaseNavigator>() {
@ -55,25 +58,43 @@ class MedtrumViewModel @Inject constructor(
get() = _eventHandler get() = _eventHandler
private var mInitPatchStep: PatchStep? = null private var mInitPatchStep: PatchStep? = null
private var connectRetryCounter = 0
init { init {
// TODO destroy scope
scope.launch { scope.launch {
medtrumPump.connectionStateFlow.collect { state -> medtrumPump.connectionStateFlow.collect { state ->
aapsLogger.debug(LTag.PUMP, "MedtrumViewModel connectionStateFlow: $state") aapsLogger.debug(LTag.PUMP, "MedtrumViewModel connectionStateFlow: $state")
if (patchStep.value != null) { if (patchStep.value != null) {
when (state) { when (state) {
ConnectionState.CONNECTED -> { ConnectionState.CONNECTED -> {
if (patchStep.value == PatchStep.START_DEACTIVATION) {
updateSetupStep(SetupStep.READY_DEACTIVATE)
}
medtrumPump.lastConnection = System.currentTimeMillis() medtrumPump.lastConnection = System.currentTimeMillis()
} }
ConnectionState.DISCONNECTED -> { ConnectionState.DISCONNECTED -> { // TODO: This is getting ridiciolous, refactor
if (patchStep.value != PatchStep.DEACTIVATION_COMPLETE && patchStep.value != PatchStep.COMPLETE && patchStep.value != PatchStep.CANCEL) { if (patchStep.value != PatchStep.START_DEACTIVATION
&& patchStep.value != PatchStep.DEACTIVATE
&& patchStep.value != PatchStep.FORCE_DEACTIVATION
&& patchStep.value != PatchStep.DEACTIVATION_COMPLETE
&& patchStep.value != PatchStep.ACTIVATE_COMPLETE
&& patchStep.value != PatchStep.CANCEL
&& patchStep.value != PatchStep.ERROR
&& patchStep.value != PatchStep.PREPARE_PATCH
&& patchStep.value != PatchStep.PREPARE_PATCH_CONNECT
) {
medtrumService?.connect("Try reconnect from viewModel") medtrumService?.connect("Try reconnect from viewModel")
} }
if (patchStep.value == PatchStep.PREPARE_PATCH_CONNECT) {
// We are disconnected during prepare patch connect, this means we failed to connect (wrong session token?)
// Retry 3 times, then give up
if (connectRetryCounter < 3) {
connectRetryCounter++
aapsLogger.info(LTag.PUMP, "preparePatchConnect: retry $connectRetryCounter")
medtrumService?.connect("Try reconnect from viewModel")
} else {
aapsLogger.info(LTag.PUMP, "preparePatchConnect: failed to connect")
updateSetupStep(SetupStep.ERROR)
}
}
} }
ConnectionState.CONNECTING -> { ConnectionState.CONNECTING -> {
@ -132,21 +153,30 @@ class MedtrumViewModel @Inject constructor(
if (oldPatchStep != newPatchStep) { if (oldPatchStep != newPatchStep) {
when (newPatchStep) { when (newPatchStep) {
PatchStep.CANCEL -> { PatchStep.CANCEL -> {
if (medtrumService?.isConnected == true || medtrumService?.isConnecting == true) medtrumService?.disconnect("Cancel") else { // TODO: Are you sure?
} // TODO: Dont disconnect when deactivating
// TODO: For DEACTIVATE STATE we might want to move to force cancel screen medtrumService?.disconnect("Cancel")
if (oldPatchStep == PatchStep.START_DEACTIVATION || oldPatchStep == PatchStep.DEACTIVATE) {
// What to do here?
}
} }
PatchStep.COMPLETE -> { PatchStep.COMPLETE -> {
if (medtrumService?.isConnected == true || medtrumService?.isConnecting == true) medtrumService?.disconnect("Complete") else { medtrumService?.disconnect("Complete")
}
} }
PatchStep.DEACTIVATION_COMPLETE -> { PatchStep.START_DEACTIVATION,
if (medtrumService?.isConnected == true || medtrumService?.isConnecting == true) medtrumService?.disconnect("DeactivationComplete") else { PatchStep.DEACTIVATE,
PatchStep.FORCE_DEACTIVATION,
PatchStep.DEACTIVATION_COMPLETE,
PatchStep.PREPARE_PATCH -> {
// Do nothing, deactivation uses commandQueue to control connection
}
PatchStep.PREPARE_PATCH_CONNECT -> {
// Make sure we are disconnected, else dont move step
if (medtrumService?.isConnected == true) {
// TODO, replace with error message
aapsLogger.info(LTag.PUMP, "moveStep: connected, not moving step")
return
} else {
} }
} }
@ -166,29 +196,31 @@ class MedtrumViewModel @Inject constructor(
aapsLogger.info(LTag.PUMP, "moveStep: $oldPatchStep -> $newPatchStep") aapsLogger.info(LTag.PUMP, "moveStep: $oldPatchStep -> $newPatchStep")
} }
fun initializePatchStep(step: PatchStep?) { fun initializePatchStep(step: PatchStep) {
mInitPatchStep = prepareStep(step) mInitPatchStep = prepareStep(step)
} }
fun preparePatch() { fun preparePatch() {
// Make sure patch step is updated when already filled medtrumService?.disconnect("PreparePatch")
// TODO: Maybe a nicer solution for this
if (medtrumPump.pumpState == MedtrumPumpState.FILLED) {
updateSetupStep(SetupStep.FILLED)
} }
// New session, generate new session token, only do this when not connected
fun preparePatchConnect() {
scope.launch {
if (medtrumService?.isConnected == false) { if (medtrumService?.isConnected == false) {
aapsLogger.info(LTag.PUMP, "preparePatch: new session") aapsLogger.info(LTag.PUMP, "preparePatch: new session")
// New session, generate new session token, only do this when not connected
medtrumPump.patchSessionToken = Crypt().generateRandomToken() medtrumPump.patchSessionToken = Crypt().generateRandomToken()
// Connect to pump // Connect to pump
medtrumService?.connect("PreparePatch") medtrumService?.connect("PreparePatch")
} else { } else {
aapsLogger.error(LTag.PUMP, "preparePatch: Already connected when trying to prepare patch") aapsLogger.error(LTag.PUMP, "preparePatch: Already connected when trying to prepare patch")
// Do nothing here, continue with old key and connection // Do nothing, we are already connected
}
} }
} }
fun startPrime() { fun startPrime() {
scope.launch {
if (medtrumPump.pumpState == MedtrumPumpState.PRIMING) { if (medtrumPump.pumpState == MedtrumPumpState.PRIMING) {
aapsLogger.info(LTag.PUMP, "startPrime: already priming!") aapsLogger.info(LTag.PUMP, "startPrime: already priming!")
} else { } else {
@ -200,8 +232,10 @@ class MedtrumViewModel @Inject constructor(
} }
} }
} }
}
fun startActivate() { fun startActivate() {
scope.launch {
if (medtrumService?.startActivate() == true) { if (medtrumService?.startActivate() == true) {
aapsLogger.info(LTag.PUMP, "startActivate: success!") aapsLogger.info(LTag.PUMP, "startActivate: success!")
} else { } else {
@ -209,58 +243,61 @@ class MedtrumViewModel @Inject constructor(
updateSetupStep(SetupStep.ERROR) updateSetupStep(SetupStep.ERROR)
} }
} }
fun startDeactivation() {
// Start connecting if needed
if (medtrumService?.isConnected == true) {
updateSetupStep(SetupStep.READY_DEACTIVATE)
} else if (medtrumService?.isConnecting != true) {
medtrumService?.connect("StartDeactivation")
}
// TODO: Also start timer to check if connection is made, if timed out show force forget patch
} }
fun deactivatePatch() { fun deactivatePatch() {
if (medtrumService?.deactivatePatch() == true) { commandQueue.deactivate(object : Callback() {
aapsLogger.info(LTag.PUMP, "deactivatePatch: success!") override fun run() {
if (this.result.success) {
// Do nothing, state change will handle this
} else { } else {
aapsLogger.info(LTag.PUMP, "deactivatePatch: failure!")
// TODO: State to force forget the patch or try again
updateSetupStep(SetupStep.ERROR) updateSetupStep(SetupStep.ERROR)
} }
} }
})
}
private fun prepareStep(step: PatchStep?): PatchStep { fun resetPumpState() {
(step ?: convertToPatchStep(medtrumPump.pumpState)).let { newStep -> medtrumPump.pumpState = MedtrumPumpState.NONE
when (newStep) { }
private fun prepareStep(newStep: PatchStep): PatchStep {
val stringResId = when (newStep) {
PatchStep.PREPARE_PATCH -> R.string.step_prepare_patch PatchStep.PREPARE_PATCH -> R.string.step_prepare_patch
PatchStep.PREPARE_PATCH_CONNECT -> R.string.step_prepare_patch_connect
PatchStep.PRIME -> R.string.step_prime PatchStep.PRIME -> R.string.step_prime
PatchStep.PRIMING -> R.string.step_priming
PatchStep.PRIME_COMPLETE -> R.string.step_priming_complete
PatchStep.ATTACH_PATCH -> R.string.step_attach PatchStep.ATTACH_PATCH -> R.string.step_attach
PatchStep.ACTIVATE -> R.string.step_activate PatchStep.ACTIVATE -> R.string.step_activate
PatchStep.COMPLETE -> R.string.step_complete PatchStep.ACTIVATE_COMPLETE -> R.string.step_activate_complete
PatchStep.START_DEACTIVATION, PatchStep.DEACTIVATE -> R.string.step_deactivate PatchStep.START_DEACTIVATION -> R.string.step_deactivate
PatchStep.DEACTIVATION_COMPLETE -> R.string.step_complete PatchStep.DEACTIVATE -> R.string.step_deactivating
else -> _title.value PatchStep.DEACTIVATION_COMPLETE -> R.string.step_deactivate_complete
}.let { PatchStep.COMPLETE,
aapsLogger.info(LTag.PUMP, "prepareStep: title before cond: $it") PatchStep.FORCE_DEACTIVATION,
if (_title.value != it) { PatchStep.ERROR,
aapsLogger.info(LTag.PUMP, "prepareStep: title: $it") PatchStep.CANCEL -> _title.value
_title.postValue(it)
} }
val currentTitle = _title.value
aapsLogger.info(LTag.PUMP, "prepareStep: title before cond: $stringResId")
if (currentTitle != stringResId) {
aapsLogger.info(LTag.PUMP, "prepareStep: title: $stringResId")
_title.postValue(stringResId)
} }
patchStep.postValue(newStep) patchStep.postValue(newStep)
return newStep return newStep
} }
}
enum class SetupStep { INITIAL, FILLED, PRIMED, ACTIVATED, ERROR, START_DEACTIVATION, STOPPED, READY_DEACTIVATE enum class SetupStep { INITIAL, FILLED, PRIMED, ACTIVATED, ERROR, START_DEACTIVATION, STOPPED
} }
val setupStep = MutableLiveData<SetupStep>() val setupStep = MutableLiveData<SetupStep>()
private fun updateSetupStep(newSetupStep: SetupStep) { fun updateSetupStep(newSetupStep: SetupStep) {
aapsLogger.info(LTag.PUMP, "curSetupStep: ${setupStep.value}, newSetupStep: $newSetupStep") aapsLogger.info(LTag.PUMP, "curSetupStep: ${setupStep.value}, newSetupStep: $newSetupStep")
setupStep.postValue(newSetupStep) setupStep.postValue(newSetupStep)
} }

View file

@ -25,6 +25,20 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity"> tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_activating_pump"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/activating_pump"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button" android:id="@+id/layout_button"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -49,14 +63,15 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:contentDescription="@string/string_start_complete" android:contentDescription="@string/retry"
android:text="@string/string_start_complete" android:text="@string/retry"
android:visibility="gone" android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative" app:layout_constraintStart_toEndOf="@id/btn_negative"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.COMPLETE)}" app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.ACTIVATE)}"
tools:visibility="visible" /> tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="info.nightscout.pump.medtrum.code.PatchStep" />
<variable
name="viewModel"
type="info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:fillViewport="true"
android:scrollbars="none">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_activating_complete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@{@string/activating_complete(viewModel.medtrumPump.reservoir)}"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_press_OK_to_return"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/press_OK_to_return"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_activating_complete" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/btn_positive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:contentDescription="@string/ok"
android:text="@string/ok"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/parent"
app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.COMPLETE)}" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>

View file

@ -25,6 +25,35 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity"> tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_remove_safety"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/remove_safety_lock"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_press_next"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/press_next"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_remove_safety" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button" android:id="@+id/layout_button"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -49,8 +78,8 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:contentDescription="@string/string_start_activate" android:contentDescription="@string/next"
android:text="@string/string_start_activate" android:text="@string/next"
android:visibility="visible" android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative" app:layout_constraintStart_toEndOf="@id/btn_negative"

View file

@ -25,6 +25,20 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity"> tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_deactivating_pump"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/deactivating_pump"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button" android:id="@+id/layout_button"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -39,23 +53,25 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:contentDescription="@string/cancel" android:contentDescription="@string/cancel"
android:text="@string/cancel" android:text="@string/cancel"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="@id/btn_positive" app:layout_constraintEnd_toStartOf="@id/btn_positive"
app:layout_constraintStart_toStartOf="parent" app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.CANCEL)}" /> app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.CANCEL)}"
tools:visibility="visible" />
<Button <Button
android:id="@+id/btn_positive" android:id="@+id/btn_positive"
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:contentDescription="@string/string_start_complete" android:contentDescription="@string/next"
android:text="@string/string_start_complete" android:text="@string/next"
android:visibility="gone" android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative" app:layout_constraintStart_toEndOf="@id/btn_negative"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.DEACTIVATION_COMPLETE)}" app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.FORCE_DEACTIVATION)}"
tools:visibility="visible" /> tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="info.nightscout.pump.medtrum.code.PatchStep" />
<variable
name="viewModel"
type="info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:fillViewport="true"
android:scrollbars="none">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_remove_base_discard_patch"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/remove_base_discard_patch"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_press_next_or_OK"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/press_next_or_OK"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_remove_base_discard_patch" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/btn_negative"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:contentDescription="@string/ok"
android:text="@string/ok"
app:layout_constraintEnd_toStartOf="@id/btn_positive"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.COMPLETE)}" />
<Button
android:id="@+id/btn_positive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/next"
android:text="@string/next"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative"
app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.PREPARE_PATCH)}" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>

View file

@ -25,6 +25,50 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity"> tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_serial_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@{@string/base_serial(viewModel.medtrumPump.pumpSN)}"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_no_active_patch"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/patch_begin_activation"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_serial_number" />
<TextView
android:id="@+id/text_no_active_patch_note"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="40dp"
android:gravity="center"
android:text="@string/patch_not_active_note"
android:textColor="@color/red"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/layout_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button" android:id="@+id/layout_button"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -33,6 +77,7 @@
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"> app:layout_constraintStart_toStartOf="parent">
<Button <Button
android:id="@+id/btn_negative" android:id="@+id/btn_negative"
android:layout_width="0dp" android:layout_width="0dp"
@ -49,14 +94,12 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:contentDescription="@string/string_start_prime" android:contentDescription="@string/next"
android:text="@string/string_start_prime" android:text="@string/next"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative" app:layout_constraintStart_toEndOf="@id/btn_negative"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.PRIME)}" app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.PREPARE_PATCH_CONNECT)}" />
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="info.nightscout.pump.medtrum.code.PatchStep" />
<variable
name="viewModel"
type="info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:fillViewport="true"
android:scrollbars="none">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_connect_pump_base"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/connect_pump_base"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_note_min_70"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/note_min_70_units"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_connect_pump_base" />
<TextView
android:id="@+id/do_not_attach"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="40dp"
android:gravity="center"
android:text="@string/do_not_attach_to_body"
android:textColor="@color/red"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/layout_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/btn_negative"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:contentDescription="@string/cancel"
android:text="@string/cancel"
app:layout_constraintEnd_toStartOf="@id/btn_positive"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.CANCEL)}" />
<Button
android:id="@+id/btn_positive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/next"
android:text="@string/next"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative"
app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.PRIME)}"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>

View file

@ -25,6 +25,37 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity"> tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_half_press_needle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/half_press_needle"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/do_not_attach"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="40dp"
android:gravity="center"
android:text="@string/do_not_attach_to_body"
android:textColor="@color/red"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/layout_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button" android:id="@+id/layout_button"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -49,13 +80,13 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:contentDescription="@string/string_next" android:contentDescription="@string/next"
android:text="@string/string_next" android:text="@string/next"
android:visibility="gone" android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative" app:layout_constraintStart_toEndOf="@id/btn_negative"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.ATTACH_PATCH)}" app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.PRIMING)}"
tools:visibility="visible" /> tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -0,0 +1,97 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="info.nightscout.pump.medtrum.code.PatchStep" />
<variable
name="viewModel"
type="info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:fillViewport="true"
android:scrollbars="none">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_press_next"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/press_next"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/do_not_attach"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="40dp"
android:gravity="center"
android:text="@string/do_not_attach_to_body"
android:textColor="@color/red"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/layout_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/btn_negative"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:contentDescription="@string/cancel"
android:text="@string/cancel"
app:layout_constraintEnd_toStartOf="@id/btn_positive"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.CANCEL)}" />
<Button
android:id="@+id/btn_positive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/next"
android:text="@string/next"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative"
app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.ATTACH_PATCH)}"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>

View file

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="info.nightscout.pump.medtrum.code.PatchStep" />
<variable
name="viewModel"
type="info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel" />
</data>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="30dp"
android:layout_marginEnd="30dp"
android:fillViewport="true"
android:scrollbars="none">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_wait_for_priming"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/wait_for_priming"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="@+id/priming_progress"
style="@android:style/Widget.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="10dp"
android:layout_marginTop="48dp"
android:max="150"
android:progress="@{viewModel.medtrumPump.primeProgressFlow}"
app:layout_constraintTop_toBottomOf="@+id/text_wait_for_priming"
tools:layout_editor_absoluteX="0dp"
tools:progress="0" />
<TextView
android:id="@+id/do_not_attach"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginEnd="5dp"
android:layout_marginBottom="40dp"
android:gravity="center"
android:text="@string/do_not_attach_to_body"
android:textColor="@color/red"
android:textSize="16sp"
app:layout_constraintBottom_toTopOf="@+id/layout_button"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent" />
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/btn_negative"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:contentDescription="@string/cancel"
android:text="@string/cancel"
app:layout_constraintEnd_toStartOf="@id/btn_positive"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.CANCEL)}" />
<Button
android:id="@+id/btn_positive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/retry"
android:text="@string/retry"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative"
app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.PRIMING)}"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
</layout>

View file

@ -25,6 +25,34 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
tools:context=".ui.MedtrumActivity"> tools:context=".ui.MedtrumActivity">
<TextView
android:id="@+id/text_deactivate_sure"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="20dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/deactivate_sure"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/text_press_next_or_cancel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="5dp"
android:gravity="center"
android:text="@string/press_next_or_cancel"
android:textSize="16sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/text_deactivate_sure" />
<androidx.constraintlayout.widget.ConstraintLayout <androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_button" android:id="@+id/layout_button"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -49,14 +77,12 @@
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="6dp" android:layout_marginStart="6dp"
android:contentDescription="@string/string_start_deactivate" android:contentDescription="@string/next"
android:text="@string/string_start_deactivate" android:text="@string/next"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent" app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative" app:layout_constraintStart_toEndOf="@id/btn_negative"
app:layout_constraintTop_toTopOf="parent" app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.DEACTIVATE)}" app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.DEACTIVATE)}" />
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout> </androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -24,7 +24,7 @@
<string name="medtrum">Medtrum</string> <string name="medtrum">Medtrum</string>
<string name="medtrum_pump_shortname">MT</string> <string name="medtrum_pump_shortname">MT</string>
<string name="medtrum_pump_description">Medtrum Nano</string> <string name="medtrum_pump_description">Pump integration for Medtrum Nano</string>
<string name="medtrumpump_settings">Medtrum pump settings</string> <string name="medtrumpump_settings">Medtrum pump settings</string>
<string name="pump_error">Pump error: %1$s !! </string> <string name="pump_error">Pump error: %1$s !! </string>
<string name="pump_unsupported">Pump untested: %1$d! Please contact us at discord or github for support</string> <string name="pump_unsupported">Pump untested: %1$d! Please contact us at discord or github for support</string>
@ -76,19 +76,45 @@
<string name="alarm_no_calibration">No calibration</string> <string name="alarm_no_calibration">No calibration</string>
<!-- wizard--> <!-- wizard-->
<string name="string_change_patch">Discard/Change Patch</string> <!-- TODO check-->
<string name="string_next">Next</string>
<string name="string_start_prime">Start priming</string>
<string name="string_start_activate">Start activation</string>
<string name="string_start_complete">Complete</string> <string name="string_start_complete">Complete</string>
<string name="string_start_deactivate">Deactivate patch</string> <string name="string_start_deactivate">Deactivate patch</string>
<string name ="step_prepare_patch">Prepare patch</string> <string name ="step_prepare_patch">Activate Patch</string>
<string name ="step_prime">Priming</string> <string name ="step_prepare_patch_connect">Connect and Fill</string>
<string name ="step_attach">Attach patch</string> <string name ="step_prime">Prime</string>
<string name ="step_activate">Activation</string> <string name ="step_priming">Priming</string>
<string name ="step_complete">Complete</string> <string name ="step_priming_complete">Priming Complete</string>
<string name ="step_deactivate">Deactivation</string> <string name ="step_attach">Attach Patch</string>
<string name ="step_activate">Activating...</string>
<string name ="step_activate_complete">Activation Complete</string>
<string name ="step_deactivate">Deactivate Patch</string>
<string name ="step_deactivating">Deactivating...</string>
<string name ="step_deactivate_complete">Patch deactivated</string>
<string name="base_serial">Pump Base Serial: %1$X</string>
<string name="patch_begin_activation">No active patch. Press <b>Next</b> to begin the activation process.</string>
<string name="patch_not_active_note">Pump base should not be connected to the patch unil the next step!</string>
<string name="connect_pump_base">Connect pump base to a new patch, remove the residual air and fill with insulin, then press <b>Next</b>.</string>
<string name="note_min_70_units">Note: A minimum of 70 units is required for actvation.</string>
<string name="do_not_attach_to_body">Do not attach the patch to the body yet.</string>
<string name="half_press_needle">Half-press needle button. Then tap <b>Next</b> to start prime.</string>
<string name="wait_for_priming">Please wait for the priming to complete.</string>
<string name="priming_error">Failed to prime, press <b>Retry</b> to try again.</string>
<string name="press_next">Press <b>Next</b> to continue.</string>
<string name='attach_patch_to_body'>Remove the safety lock. Attach the pump to the body. Press the needle button.</string>
<string name="remove_safety_lock">Remove the safety lock. Attach the pump to the body. Press the needle button.</string>
<string name="activating_pump">Activating pump and settng initial basal rate. Please Wait.</string>
<string name="activating_error">Failed to activate, press <b>Retry</b> to try again.</string>
<string name="activating_complete">New patch activated. %.2f Units remaining.</string>
<string name="press_OK_to_return">Press <b>OK</b> to return to main screen.</string>
<string name="deactivate_sure">Are you sure that you want to deactivate the current patch?</string>
<string name="press_next_or_cancel">Press <b>Next</b> to deactivate or <b>Cancel</b> to return to main screen.</string>
<string name="deactivating_pump">Deactivating patch. Please Wait.</string>
<string name="deactivating_error">Failed to deactivate, press <b>Next</b> to forget patch.</string>
<string name="retract_needle">Retract needle. Remove patch from body.</string>
<string name="remove_base_discard_patch">Remove pump base and dispose of used patch appropriately.</string>
<string name="press_next_or_OK">Press <b>OK</b> to return to main screen. Press <b>Next</b> to start activation of new patch.</string>
<!-- settings--> <!-- settings-->
<string name="sn_input_title">Serial Number</string> <string name="sn_input_title">Serial Number</string>