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 setUserOptions(): PumpEnactResult // set user settings
fun clearAlarms(): PumpEnactResult // clear alarms
fun deactivate(): PumpEnactResult // deactivate patch
}

View file

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

View file

@ -32,6 +32,7 @@ interface CommandQueue {
fun loadTDDs(callback: Callback?): Boolean
fun loadEvents(callback: Callback?): Boolean
fun clearAlarms(callback: Callback?): Boolean
fun deactivate(callback: Callback?): Boolean
fun customCommand(customCommand: CustomCommand, callback: Callback?): Boolean
fun isCustomCommandRunning(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="load_events">LOAD EVENTS</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_tdds">LOAD TDDs</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.CommandClearAlarms
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.CommandInsightSetTBROverNotification
import info.nightscout.implementation.queue.commands.CommandLoadEvents
@ -34,6 +35,7 @@ abstract class CommandQueueModule {
@ContributesAndroidInjector abstract fun commandInsightSetTBROverNotificationInjector(): CommandInsightSetTBROverNotification
@ContributesAndroidInjector abstract fun commandLoadEventsInjector(): CommandLoadEvents
@ContributesAndroidInjector abstract fun commandClearAlarmsInjector(): CommandClearAlarms
@ContributesAndroidInjector abstract fun commandDeactivateInjector(): CommandDeactivate
@ContributesAndroidInjector abstract fun commandLoadHistoryInjector(): CommandLoadHistory
@ContributesAndroidInjector abstract fun commandLoadTDDsInjector(): CommandLoadTDDs
@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.CommandClearAlarms
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.CommandInsightSetTBROverNotification
import info.nightscout.implementation.queue.commands.CommandLoadEvents
@ -550,6 +551,19 @@ class CommandQueueImplementation @Inject constructor(
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 {
if (isCustomCommandInQueue(customCommand.javaClass)) {
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 log(): String = "CLEAR ALAMRS"
override fun log(): String = "CLEAR ALARMS"
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

@ -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)
Assertions.assertEquals(5, commandQueue.size())
// add deactivate
commandQueue.deactivate(null)
Assertions.assertEquals(6, commandQueue.size())
commandQueue.clear()
commandQueue.tempBasalAbsolute(0.0, 30, true, validProfile, PumpSync.TemporaryBasalType.NORMAL, null)
commandQueue.pickup()
@ -375,6 +379,22 @@ class CommandQueueImplementationTest : TestBaseWithProfile() {
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
fun isLoadTDDsCommandInQueue() {
// given

View file

@ -82,7 +82,7 @@ import kotlin.math.round
PluginDescription()
.mainType(PluginType.PUMP)
.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)
.shortName(R.string.medtrum_pump_shortname)
.preferencesId(R.xml.pref_medtrum_pump)
@ -442,4 +442,14 @@ import kotlin.math.round
val connectionOK = medtrumService?.clearAlarms() ?: false
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 {
START_DEACTIVATION,
DEACTIVATE,
FORCE_DEACTIVATION,
DEACTIVATION_COMPLETE,
PREPARE_PATCH,
PREPARE_PATCH_CONNECT,
PRIME,
PRIMING,
PRIME_COMPLETE,
ATTACH_PATCH,
ACTIVATE,
ACTIVATE_COMPLETE,
ERROR,
CANCEL,
COMPLETE,
BACK_TO_HOME,
FINISH;
COMPLETE;
}

View file

@ -112,7 +112,7 @@ class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int
val detailedBolusInfo = detailedBolusInfoStorage.findDetailedBolusInfo(bolusStartTime, bolusNormalDelivered)
var newRecord = false
if (detailedBolusInfo != null) {
val success = pumpSync.syncBolusWithTempId(
val syncOk = pumpSync.syncBolusWithTempId(
timestamp = bolusStartTime,
amount = bolusNormalDelivered,
temporaryId = detailedBolusInfo.timestamp,
@ -121,7 +121,7 @@ class GetRecordPacket(injector: HasAndroidInjector, private val recordIndex: Int
pumpType = medtrumPump.pumpType(),
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}")
// detailedInfo can be from another similar record. Reinsert
detailedBolusInfoStorage.add(detailedBolusInfo)

View file

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

View file

@ -414,12 +414,6 @@ class MedtrumService : DaggerService(), BLECommCallback {
// Map the pump state to a notification
when (state) {
MedtrumPumpState.NONE,
MedtrumPumpState.IDLE,
MedtrumPumpState.FILLED,
MedtrumPumpState.PRIMING,
MedtrumPumpState.PRIMED,
MedtrumPumpState.EJECTING,
MedtrumPumpState.EJECTED,
MedtrumPumpState.STOPPED -> {
rxBus.send(EventDismissNotification(Notification.PUMP_ERROR))
rxBus.send(EventDismissNotification(Notification.PUMP_SUSPENDED))
@ -432,6 +426,18 @@ class MedtrumService : DaggerService(), BLECommCallback {
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_ALT -> {
rxBus.send(EventDismissNotification(Notification.PATCH_NOT_ACTIVE))
@ -599,7 +605,7 @@ class MedtrumService : DaggerService(), BLECommCallback {
}
fun onSendMessageError(reason: String) {
aapsLogger.debug(LTag.PUMPCOMM, "onSendMessageError: " + this.toString() + "reason: $reason")
aapsLogger.warn(LTag.PUMPCOMM, "onSendMessageError: " + this.toString() + "reason: $reason")
responseHandled = true
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.view.View
@ -11,11 +11,13 @@ 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 MedtrumActivateFragment : MedtrumBaseFragment<FragmentMedtrumActivateBinding>() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rh: ResourceHelper
companion object {
@ -31,16 +33,20 @@ class MedtrumActivateFragment : MedtrumBaseFragment<FragmentMedtrumActivateBindi
viewModel?.apply {
setupStep.observe(viewLifecycleOwner) {
when (it) {
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)
MedtrumViewModel.SetupStep.INITIAL,
MedtrumViewModel.SetupStep.PRIMED -> Unit // Nothing to do here, previous state
MedtrumViewModel.SetupStep.ACTIVATED -> moveStep(PatchStep.ACTIVATE_COMPLETE)
MedtrumViewModel.SetupStep.ERROR -> {
moveStep(PatchStep.ERROR)
updateSetupStep(MedtrumViewModel.SetupStep.PRIMED) // Reset setup step
binding.textActivatingPump.text = rh.gs(R.string.activating_error)
binding.btnPositive.visibility = View.VISIBLE
}
else -> {
ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL)
else -> {
ToastUtils.errorToast(requireContext(), "Unexpected state: $it")
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.content.Context
import android.content.Intent
import android.content.pm.ActivityInfo
import android.media.MediaPlayer
import android.media.RingtoneManager
import android.os.Bundle
import android.view.MotionEvent
import android.view.WindowManager
import androidx.appcompat.app.AlertDialog
import androidx.lifecycle.ViewModelProvider
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.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.core.utils.extensions.safeGetSerializableExtra
import info.nightscout.pump.medtrum.R
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.extension.replaceFragmentInActivity
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
@ -36,6 +44,8 @@ class MedtrumActivity : MedtrumBaseActivity<ActivityMedtrumBinding>() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_LOCKED
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
binding.apply {
viewModel = ViewModelProvider(this@MedtrumActivity, viewModelFactory).get(MedtrumViewModel::class.java)
@ -45,15 +55,33 @@ class MedtrumActivity : MedtrumBaseActivity<ActivityMedtrumBinding>() {
patchStep.observe(this@MedtrumActivity) {
when (it) {
PatchStep.PREPARE_PATCH -> setupViewFragment(MedtrumPreparePatchFragment.newInstance())
PatchStep.PREPARE_PATCH_CONNECT -> setupViewFragment(MedtrumPreparePatchConnectFragment.newInstance())
PatchStep.PRIME -> setupViewFragment(MedtrumPrimeFragment.newInstance())
PatchStep.PRIMING -> setupViewFragment(MedtrumPrimingFragment.newInstance())
PatchStep.PRIME_COMPLETE -> setupViewFragment(MedtrumPrimeCompleteFragment.newInstance())
PatchStep.ATTACH_PATCH -> setupViewFragment(MedtrumAttachPatchFragment.newInstance())
PatchStep.ACTIVATE -> setupViewFragment(MedtrumActivateFragment.newInstance())
PatchStep.COMPLETE -> this@MedtrumActivity.finish() // TODO proper finish
PatchStep.CANCEL -> this@MedtrumActivity.finish()
PatchStep.ACTIVATE_COMPLETE -> setupViewFragment(MedtrumActivateCompleteFragment.newInstance())
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.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,7 +97,9 @@ class MedtrumActivity : MedtrumBaseActivity<ActivityMedtrumBinding>() {
binding.viewModel?.apply {
intent?.run {
val step = intent.safeGetSerializableExtra(EXTRA_START_PATCH_STEP, PatchStep::class.java)
initializePatchStep(step)
if (step != null) {
initializePatchStep(step)
}
}
}
}

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.view.View
@ -32,14 +32,16 @@ class MedtrumAttachPatchFragment : MedtrumBaseFragment<FragmentMedtrumAttachPatc
viewModel?.apply {
setupStep.observe(viewLifecycleOwner) {
when (it) {
MedtrumViewModel.SetupStep.INITIAL,
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
moveStep(PatchStep.CANCEL)
}
else -> {
else -> {
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.view.View
@ -11,11 +11,13 @@ 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 MedtrumDeactivatePatchFragment : MedtrumBaseFragment<FragmentMedtrumDeactivatePatchBinding>() {
@Inject lateinit var aapsLogger: AAPSLogger
@Inject lateinit var rh: ResourceHelper
companion object {
@ -32,11 +34,16 @@ class MedtrumDeactivatePatchFragment : MedtrumBaseFragment<FragmentMedtrumDeacti
viewModel?.apply {
setupStep.observe(viewLifecycleOwner) {
when (it) {
MedtrumViewModel.SetupStep.STOPPED -> btnPositive.visibility = View.VISIBLE
MedtrumViewModel.SetupStep.STOPPED -> {
moveStep(PatchStep.DEACTIVATION_COMPLETE)
}
MedtrumViewModel.SetupStep.ERROR -> {
ToastUtils.errorToast(requireContext(), "Error deactivate") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL)
moveStep(PatchStep.ERROR)
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

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.view.View
@ -30,23 +30,6 @@ class MedtrumPreparePatchFragment : MedtrumBaseFragment<FragmentMedtrumPreparePa
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 -> {
ToastUtils.errorToast(requireContext(), "Unexpected state: $it") // TODO: String resource and show error message
moveStep(PatchStep.CANCEL)
}
}
}
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.view.View
@ -31,20 +31,19 @@ class MedtrumPrimeFragment : MedtrumBaseFragment<FragmentMedtrumPrimeBinding>()
viewModel?.apply {
setupStep.observe(viewLifecycleOwner) {
when (it) {
MedtrumViewModel.SetupStep.INITIAL,
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
moveStep(PatchStep.CANCEL)
}
else -> {
else -> {
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.view.View
@ -30,19 +30,7 @@ class MedtrumStartDeactivationFragment : MedtrumBaseFragment<FragmentMedtrumStar
binding.apply {
viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java)
viewModel?.apply {
setupStep.observe(viewLifecycleOwner) {
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()
updateSetupStep(MedtrumViewModel.SetupStep.START_DEACTIVATION)
}
}
}

View file

@ -29,14 +29,4 @@ abstract class BaseViewModel<N : MedtrumBaseNavigator> : ViewModel() {
fun finish() = navigator?.finish()
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.MutableLiveData
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.MedtrumPump
import info.nightscout.pump.medtrum.R
@ -35,7 +37,8 @@ class MedtrumViewModel @Inject constructor(
private val aapsSchedulers: AapsSchedulers,
private val fabricPrivacy: FabricPrivacy,
private val medtrumPlugin: MedtrumPlugin,
private val medtrumPump: MedtrumPump,
private val commandQueue: CommandQueue,
val medtrumPump: MedtrumPump,
private val sp: SP
) : BaseViewModel<MedtrumBaseNavigator>() {
@ -55,25 +58,43 @@ class MedtrumViewModel @Inject constructor(
get() = _eventHandler
private var mInitPatchStep: PatchStep? = null
private var connectRetryCounter = 0
init {
// TODO destroy scope
scope.launch {
medtrumPump.connectionStateFlow.collect { state ->
aapsLogger.debug(LTag.PUMP, "MedtrumViewModel connectionStateFlow: $state")
if (patchStep.value != null) {
when (state) {
ConnectionState.CONNECTED -> {
if (patchStep.value == PatchStep.START_DEACTIVATION) {
updateSetupStep(SetupStep.READY_DEACTIVATE)
}
medtrumPump.lastConnection = System.currentTimeMillis()
}
ConnectionState.DISCONNECTED -> {
if (patchStep.value != PatchStep.DEACTIVATION_COMPLETE && patchStep.value != PatchStep.COMPLETE && patchStep.value != PatchStep.CANCEL) {
ConnectionState.DISCONNECTED -> { // TODO: This is getting ridiciolous, refactor
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")
}
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 -> {
@ -132,21 +153,30 @@ class MedtrumViewModel @Inject constructor(
if (oldPatchStep != newPatchStep) {
when (newPatchStep) {
PatchStep.CANCEL -> {
if (medtrumService?.isConnected == true || medtrumService?.isConnecting == true) medtrumService?.disconnect("Cancel") else {
}
// TODO: For DEACTIVATE STATE we might want to move to force cancel screen
if (oldPatchStep == PatchStep.START_DEACTIVATION || oldPatchStep == PatchStep.DEACTIVATE) {
// What to do here?
}
// TODO: Are you sure?
// TODO: Dont disconnect when deactivating
medtrumService?.disconnect("Cancel")
}
PatchStep.COMPLETE -> {
if (medtrumService?.isConnected == true || medtrumService?.isConnecting == true) medtrumService?.disconnect("Complete") else {
}
medtrumService?.disconnect("Complete")
}
PatchStep.DEACTIVATION_COMPLETE -> {
if (medtrumService?.isConnected == true || medtrumService?.isConnecting == true) medtrumService?.disconnect("DeactivationComplete") else {
PatchStep.START_DEACTIVATION,
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,101 +196,108 @@ class MedtrumViewModel @Inject constructor(
aapsLogger.info(LTag.PUMP, "moveStep: $oldPatchStep -> $newPatchStep")
}
fun initializePatchStep(step: PatchStep?) {
fun initializePatchStep(step: PatchStep) {
mInitPatchStep = prepareStep(step)
}
fun preparePatch() {
// Make sure patch step is updated when already filled
// 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
if (medtrumService?.isConnected == false) {
aapsLogger.info(LTag.PUMP, "preparePatch: new session")
medtrumPump.patchSessionToken = Crypt().generateRandomToken()
// Connect to pump
medtrumService?.connect("PreparePatch")
} else {
aapsLogger.error(LTag.PUMP, "preparePatch: Already connected when trying to prepare patch")
// Do nothing here, continue with old key and connection
medtrumService?.disconnect("PreparePatch")
}
fun preparePatchConnect() {
scope.launch {
if (medtrumService?.isConnected == false) {
aapsLogger.info(LTag.PUMP, "preparePatch: new session")
// New session, generate new session token, only do this when not connected
medtrumPump.patchSessionToken = Crypt().generateRandomToken()
// Connect to pump
medtrumService?.connect("PreparePatch")
} else {
aapsLogger.error(LTag.PUMP, "preparePatch: Already connected when trying to prepare patch")
// Do nothing, we are already connected
}
}
}
fun startPrime() {
if (medtrumPump.pumpState == MedtrumPumpState.PRIMING) {
aapsLogger.info(LTag.PUMP, "startPrime: already priming!")
} else {
if (medtrumService?.startPrime() == true) {
aapsLogger.info(LTag.PUMP, "startPrime: success!")
scope.launch {
if (medtrumPump.pumpState == MedtrumPumpState.PRIMING) {
aapsLogger.info(LTag.PUMP, "startPrime: already priming!")
} else {
aapsLogger.info(LTag.PUMP, "startPrime: failure!")
updateSetupStep(SetupStep.ERROR)
if (medtrumService?.startPrime() == true) {
aapsLogger.info(LTag.PUMP, "startPrime: success!")
} else {
aapsLogger.info(LTag.PUMP, "startPrime: failure!")
updateSetupStep(SetupStep.ERROR)
}
}
}
}
fun startActivate() {
if (medtrumService?.startActivate() == true) {
aapsLogger.info(LTag.PUMP, "startActivate: success!")
} else {
aapsLogger.info(LTag.PUMP, "startActivate: failure!")
updateSetupStep(SetupStep.ERROR)
scope.launch {
if (medtrumService?.startActivate() == true) {
aapsLogger.info(LTag.PUMP, "startActivate: success!")
} else {
aapsLogger.info(LTag.PUMP, "startActivate: failure!")
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() {
if (medtrumService?.deactivatePatch() == true) {
aapsLogger.info(LTag.PUMP, "deactivatePatch: success!")
} else {
aapsLogger.info(LTag.PUMP, "deactivatePatch: failure!")
// TODO: State to force forget the patch or try again
updateSetupStep(SetupStep.ERROR)
}
}
private fun prepareStep(step: PatchStep?): PatchStep {
(step ?: convertToPatchStep(medtrumPump.pumpState)).let { newStep ->
when (newStep) {
PatchStep.PREPARE_PATCH -> R.string.step_prepare_patch
PatchStep.PRIME -> R.string.step_prime
PatchStep.ATTACH_PATCH -> R.string.step_attach
PatchStep.ACTIVATE -> R.string.step_activate
PatchStep.COMPLETE -> R.string.step_complete
PatchStep.START_DEACTIVATION, PatchStep.DEACTIVATE -> R.string.step_deactivate
PatchStep.DEACTIVATION_COMPLETE -> R.string.step_complete
else -> _title.value
}.let {
aapsLogger.info(LTag.PUMP, "prepareStep: title before cond: $it")
if (_title.value != it) {
aapsLogger.info(LTag.PUMP, "prepareStep: title: $it")
_title.postValue(it)
commandQueue.deactivate(object : Callback() {
override fun run() {
if (this.result.success) {
// Do nothing, state change will handle this
} else {
updateSetupStep(SetupStep.ERROR)
}
}
patchStep.postValue(newStep)
return newStep
}
})
}
enum class SetupStep { INITIAL, FILLED, PRIMED, ACTIVATED, ERROR, START_DEACTIVATION, STOPPED, READY_DEACTIVATE
fun resetPumpState() {
medtrumPump.pumpState = MedtrumPumpState.NONE
}
private fun prepareStep(newStep: PatchStep): PatchStep {
val stringResId = when (newStep) {
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.PRIMING -> R.string.step_priming
PatchStep.PRIME_COMPLETE -> R.string.step_priming_complete
PatchStep.ATTACH_PATCH -> R.string.step_attach
PatchStep.ACTIVATE -> R.string.step_activate
PatchStep.ACTIVATE_COMPLETE -> R.string.step_activate_complete
PatchStep.START_DEACTIVATION -> R.string.step_deactivate
PatchStep.DEACTIVATE -> R.string.step_deactivating
PatchStep.DEACTIVATION_COMPLETE -> R.string.step_deactivate_complete
PatchStep.COMPLETE,
PatchStep.FORCE_DEACTIVATION,
PatchStep.ERROR,
PatchStep.CANCEL -> _title.value
}
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)
return newStep
}
enum class SetupStep { INITIAL, FILLED, PRIMED, ACTIVATED, ERROR, START_DEACTIVATION, STOPPED
}
val setupStep = MutableLiveData<SetupStep>()
private fun updateSetupStep(newSetupStep: SetupStep) {
fun updateSetupStep(newSetupStep: SetupStep) {
aapsLogger.info(LTag.PUMP, "curSetupStep: ${setupStep.value}, newSetupStep: $newSetupStep")
setupStep.postValue(newSetupStep)
}

View file

@ -25,6 +25,20 @@
android:layout_height="wrap_content"
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
android:id="@+id/layout_button"
android:layout_width="match_parent"
@ -49,14 +63,15 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/string_start_complete"
android:text="@string/string_start_complete"
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.COMPLETE)}"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.ACTIVATE)}"
tools:visibility="visible" />
</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"
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
android:id="@+id/layout_button"
android:layout_width="match_parent"
@ -49,8 +78,8 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/string_start_activate"
android:text="@string/string_start_activate"
android:contentDescription="@string/next"
android:text="@string/next"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_negative"

View file

@ -25,6 +25,20 @@
android:layout_height="wrap_content"
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
android:id="@+id/layout_button"
android:layout_width="match_parent"
@ -39,23 +53,25 @@
android:layout_height="wrap_content"
android:contentDescription="@string/cancel"
android:text="@string/cancel"
android:visibility="gone"
app:layout_constraintEnd_toStartOf="@id/btn_positive"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.CANCEL)}" />
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.CANCEL)}"
tools:visibility="visible" />
<Button
android:id="@+id/btn_positive"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/string_start_complete"
android:text="@string/string_start_complete"
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.DEACTIVATION_COMPLETE)}"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.FORCE_DEACTIVATION)}"
tools:visibility="visible" />
</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"
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
android:id="@+id/layout_button"
android:layout_width="match_parent"
@ -33,6 +77,7 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent">
<Button
android:id="@+id/btn_negative"
android:layout_width="0dp"
@ -49,14 +94,12 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/string_start_prime"
android:text="@string/string_start_prime"
android:visibility="gone"
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.PRIME)}"
tools:visibility="visible" />
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.PREPARE_PATCH_CONNECT)}" />
</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"
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
android:id="@+id/layout_button"
android:layout_width="match_parent"
@ -49,13 +80,13 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/string_next"
android:text="@string/string_next"
android:visibility="gone"
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)}"
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.PRIMING)}"
tools:visibility="visible" />
</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"
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
android:id="@+id/layout_button"
android:layout_width="match_parent"
@ -49,14 +77,12 @@
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:contentDescription="@string/string_start_deactivate"
android:text="@string/string_start_deactivate"
android:visibility="gone"
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.DEACTIVATE)}"
tools:visibility="visible" />
app:onSafeClick="@{() -> viewModel.moveStep(PatchStep.DEACTIVATE)}" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View file

@ -24,7 +24,7 @@
<string name="medtrum">Medtrum</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="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>
@ -76,19 +76,45 @@
<string name="alarm_no_calibration">No calibration</string>
<!-- 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_deactivate">Deactivate patch</string>
<string name ="step_prepare_patch">Prepare patch</string>
<string name ="step_prime">Priming</string>
<string name ="step_attach">Attach patch</string>
<string name ="step_activate">Activation</string>
<string name ="step_complete">Complete</string>
<string name ="step_deactivate">Deactivation</string>
<string name ="step_prepare_patch">Activate Patch</string>
<string name ="step_prepare_patch_connect">Connect and Fill</string>
<string name ="step_prime">Prime</string>
<string name ="step_priming">Priming</string>
<string name ="step_priming_complete">Priming Complete</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-->
<string name="sn_input_title">Serial Number</string>