From 7afa0beb0a57a0c8584db8ab5f718b2c54009030 Mon Sep 17 00:00:00 2001
From: jbr7rr <>
Date: Sat, 11 Mar 2023 20:19:06 +0100
Subject: [PATCH] Prepare patch step WIP
---
pump/medtrum/src/main/AndroidManifest.xml | 1 +
.../nightscout/pump/medtrum/MedtrumPlugin.kt | 59 ++++----
.../nightscout/pump/medtrum/code/EventType.kt | 11 ++
.../nightscout/pump/medtrum/code/PatchStep.kt | 18 +++
.../pump/medtrum/di/MedtrumModule.kt | 28 +++-
.../extension/AppCompatActivityExtension.kt | 19 +++
.../pump/medtrum/services/BLEComm.kt | 9 +-
.../pump/medtrum/services/MedtrumService.kt | 85 ++++++++++--
.../pump/medtrum/ui/MedtrumActivity.kt | 97 +++++++++++++
.../medtrum/ui/MedtrumOverviewFragment.kt | 35 +++--
.../medtrum/ui/MedtrumPreparePatchFragment.kt | 42 ++++++
.../pump/medtrum/ui/MedtrumPrimeFragment.kt | 32 +++++
.../pump/medtrum/ui/event/SingleLiveEvent.kt | 29 ++++
.../pump/medtrum/ui/event/UIEvent.kt | 7 +
.../ui/viewmodel/MedtrumOverviewViewModel.kt | 65 +++++++--
.../medtrum/ui/viewmodel/MedtrumViewModel.kt | 128 ++++++++++++++++++
.../src/main/res/layout/activity_medtrum.xml | 50 +++++++
...ment.xml => fragment_medtrum_overview.xml} | 12 +-
.../layout/fragment_medtrum_prepare_patch.xml | 66 +++++++++
.../res/layout/fragment_medtrum_prime.xml | 33 +++++
pump/medtrum/src/main/res/values/strings.xml | 12 +-
21 files changed, 750 insertions(+), 88 deletions(-)
create mode 100644 pump/medtrum/src/main/java/info/nightscout/pump/medtrum/code/EventType.kt
create mode 100644 pump/medtrum/src/main/java/info/nightscout/pump/medtrum/code/PatchStep.kt
create mode 100644 pump/medtrum/src/main/java/info/nightscout/pump/medtrum/extension/AppCompatActivityExtension.kt
create mode 100644 pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumActivity.kt
create mode 100644 pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumPreparePatchFragment.kt
create mode 100644 pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumPrimeFragment.kt
create mode 100644 pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/event/SingleLiveEvent.kt
create mode 100644 pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/event/UIEvent.kt
create mode 100644 pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumViewModel.kt
create mode 100644 pump/medtrum/src/main/res/layout/activity_medtrum.xml
rename pump/medtrum/src/main/res/layout/{medtrum_overview_fragment.xml => fragment_medtrum_overview.xml} (98%)
create mode 100644 pump/medtrum/src/main/res/layout/fragment_medtrum_prepare_patch.xml
create mode 100644 pump/medtrum/src/main/res/layout/fragment_medtrum_prime.xml
diff --git a/pump/medtrum/src/main/AndroidManifest.xml b/pump/medtrum/src/main/AndroidManifest.xml
index f589b49319..2e03434790 100644
--- a/pump/medtrum/src/main/AndroidManifest.xml
+++ b/pump/medtrum/src/main/AndroidManifest.xml
@@ -7,6 +7,7 @@
+
- if (event.isChanged(rh.gs(info.nightscout.pump.medtrum.R.string.key_snInput))) {
- pumpSync.connectNewPump()
- changePump()
- }
- }, fabricPrivacy::logException)
- changePump()
}
override fun onStop() {
@@ -122,15 +111,8 @@ class MedtrumPlugin @Inject constructor(
}
}
- fun changePump() {
- aapsLogger.debug(LTag.PUMP, "changePump: called!")
- try {
- mDeviceSN = sp.getString(info.nightscout.pump.medtrum.R.string.key_snInput, " ").toLong(radix = 16)
- } catch (e: NumberFormatException) {
- aapsLogger.debug(LTag.PUMP, "changePump: Invalid input!")
- }
- // TODO: add medtrumPump.reset()
- commandQueue.readStatus(rh.gs(info.nightscout.core.ui.R.string.device_changed), null)
+ fun getService(): MedtrumService? {
+ return medtrumService
}
override fun isInitialized(): Boolean {
@@ -138,14 +120,17 @@ class MedtrumPlugin @Inject constructor(
}
override fun isSuspended(): Boolean {
- return false
+ return true
}
override fun isBusy(): Boolean {
- return false
+ return true
+ }
+
+ override fun isConnected(): Boolean {
+ return if (!isInitialized()) true else medtrumService?.isConnected ?: true // This is a workaround to prevent AAPS to trigger connects when we are initializing
}
- override fun isConnected(): Boolean = medtrumService?.isConnected ?: false
override fun isConnecting(): Boolean = medtrumService?.isConnecting ?: false
override fun isHandshakeInProgress(): Boolean = false
@@ -153,19 +138,23 @@ class MedtrumPlugin @Inject constructor(
}
override fun connect(reason: String) {
- aapsLogger.debug(LTag.PUMP, "Medtrum connect - reason:$reason")
- aapsLogger.debug(LTag.PUMP, "Medtrum connect - service::$medtrumService")
- aapsLogger.debug(LTag.PUMP, "Medtrum connect - mDeviceSN:$mDeviceSN")
- if (medtrumService != null && mDeviceSN != 0.toLong()) {
- aapsLogger.debug(LTag.PUMP, "Medtrum connect - Attempt connection!")
- val success = medtrumService?.connect(reason, mDeviceSN) ?: false
- if (!success) ToastUtils.errorToast(context, info.nightscout.core.ui.R.string.ble_not_supported_or_not_paired)
+ if (isInitialized()) {
+ aapsLogger.debug(LTag.PUMP, "Medtrum connect - reason:$reason")
+ aapsLogger.debug(LTag.PUMP, "Medtrum connect - service::$medtrumService")
+ // aapsLogger.debug(LTag.PUMP, "Medtrum connect - mDeviceSN:$mDeviceSN")
+ if (medtrumService != null) {
+ aapsLogger.debug(LTag.PUMP, "Medtrum connect - Attempt connection!")
+ val success = medtrumService?.connect(reason) ?: false
+ if (!success) ToastUtils.errorToast(context, info.nightscout.core.ui.R.string.ble_not_supported_or_not_paired)
+ }
}
}
override fun disconnect(reason: String) {
- aapsLogger.debug(LTag.PUMP, "RS disconnect from: $reason")
- medtrumService?.disconnect(reason)
+ if (isInitialized()) {
+ aapsLogger.debug(LTag.PUMP, "Medtrum disconnect from: $reason")
+ medtrumService?.disconnect(reason)
+ }
}
override fun stopConnecting() {
@@ -173,11 +162,13 @@ class MedtrumPlugin @Inject constructor(
}
override fun getPumpStatus(reason: String) {
- medtrumService?.readPumpStatus()
+ if (isInitialized()) {
+ medtrumService?.readPumpStatus()
+ }
}
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
- return PumpEnactResult(injector) // TODO
+ return PumpEnactResult(injector).success(true).enacted(true) // TODO
}
override fun isThisProfileSet(profile: Profile): Boolean {
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/code/EventType.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/code/EventType.kt
new file mode 100644
index 0000000000..32b4efb4ed
--- /dev/null
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/code/EventType.kt
@@ -0,0 +1,11 @@
+package info.nightscout.pump.medtrum.code
+
+enum class EventType {
+ ACTIVATION_CLICKED,
+ DEACTIVATION_CLICKED,
+ INVALID_BASAL_RATE,
+ PROFILE_NOT_SET,
+ FINISH_ACTIVITY,
+ SHOW_DISCARD_DIALOG
+ ;
+}
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/code/PatchStep.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/code/PatchStep.kt
new file mode 100644
index 0000000000..3b2c973ae6
--- /dev/null
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/code/PatchStep.kt
@@ -0,0 +1,18 @@
+package info.nightscout.pump.medtrum.code
+
+enum class PatchStep {
+ SAFE_DEACTIVATION,
+ MANUALLY_TURNING_OFF_ALARM,
+ DISCARDED,
+ DISCARDED_FOR_CHANGE,
+ DISCARDED_FROM_ALARM,
+ PREPARE_PATCH,
+ PRIME,
+ ATTACH_INSERT_NEEDLE,
+ BASAL_SCHEDULE,
+ CHECK_CONNECTION,
+ CANCEL,
+ COMPLETE,
+ BACK_TO_HOME,
+ FINISH;
+}
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/di/MedtrumModule.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/di/MedtrumModule.kt
index 71af92437e..1666a4defe 100644
--- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/di/MedtrumModule.kt
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/di/MedtrumModule.kt
@@ -7,17 +7,21 @@ import dagger.Module
import dagger.Provides
import dagger.android.ContributesAndroidInjector
import dagger.multibindings.IntoMap
+import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumPreparePatchFragment
+import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumPrimeFragment
import info.nightscout.pump.medtrum.services.MedtrumService
+import info.nightscout.pump.medtrum.ui.MedtrumActivity
import info.nightscout.pump.medtrum.ui.MedtrumOverviewFragment
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumOverviewViewModel
+import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
import info.nightscout.pump.medtrum.ui.viewmodel.ViewModelFactory
import info.nightscout.pump.medtrum.ui.viewmodel.ViewModelKey
import javax.inject.Provider
-
@Module
@Suppress("unused")
abstract class MedtrumModule {
+
companion object {
@Provides
@@ -34,11 +38,29 @@ abstract class MedtrumModule {
@ViewModelKey(MedtrumOverviewViewModel::class)
internal abstract fun bindsMedtrumOverviewViewmodel(viewModel: MedtrumOverviewViewModel): ViewModel
+ @Binds
+ @IntoMap
+ @MedtrumPluginQualifier
+ @ViewModelKey(MedtrumViewModel::class)
+ internal abstract fun bindsMedtrumViewModel(viewModel: MedtrumViewModel): ViewModel
+
// FRAGMENTS
@ContributesAndroidInjector
abstract fun contributesMedtrumOverviewFragment(): MedtrumOverviewFragment
+ @FragmentScope
+ @ContributesAndroidInjector
+ internal abstract fun contributesPreparePatchFragment(): MedtrumPreparePatchFragment
+
+ @FragmentScope
+ @ContributesAndroidInjector
+ internal abstract fun contributesPrimeFragment(): MedtrumPrimeFragment
+
+ // ACTIVITIES
+ @ContributesAndroidInjector
+ abstract fun contributesMedtrumActivity(): MedtrumActivity
+
// SERVICE
- @ContributesAndroidInjector
- abstract fun contributesDanaRSService(): MedtrumService
+ @ContributesAndroidInjector
+ abstract fun contributesMedtrumService(): MedtrumService
}
\ No newline at end of file
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/extension/AppCompatActivityExtension.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/extension/AppCompatActivityExtension.kt
new file mode 100644
index 0000000000..7345091cb4
--- /dev/null
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/extension/AppCompatActivityExtension.kt
@@ -0,0 +1,19 @@
+package info.nightscout.pump.medtrum.extension
+
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.FragmentManager
+import androidx.fragment.app.FragmentTransaction
+
+fun AppCompatActivity.replaceFragmentInActivity(fragment: Fragment, frameId: Int, addToBackStack: Boolean = false) {
+ supportFragmentManager.transact {
+ replace(frameId, fragment)
+ if (addToBackStack) addToBackStack(null)
+ }
+}
+
+private inline fun FragmentManager.transact(action: FragmentTransaction.() -> Unit) {
+ beginTransaction().apply {
+ action()
+ }.commit()
+}
\ No newline at end of file
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt
index b6ad902279..fb71c5c388 100644
--- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/BLEComm.kt
@@ -49,7 +49,9 @@ import javax.inject.Inject
import javax.inject.Singleton
interface BLECommCallback {
+
fun onBLEConnected()
+ fun onBLEDisconnected()
fun onNotification(notification: ByteArray)
fun onIndication(indication: ByteArray)
fun onSendMessageError(reason: String)
@@ -88,8 +90,8 @@ class BLEComm @Inject internal constructor(
private val mBluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
private var mBluetoothGatt: BluetoothGatt? = null
- var isConnected = false
- var isConnecting = false
+ var isConnected = false // TODO: These may be removed have no function
+ var isConnecting = false// TODO: These may be removed have no function
private var uartWrite: BluetoothGattCharacteristic? = null
private var uartRead: BluetoothGattCharacteristic? = null
@@ -179,7 +181,6 @@ class BLEComm @Inject internal constructor(
}
aapsLogger.debug(LTag.PUMPBTCOMM, "disconnect from: $from")
mBluetoothGatt?.disconnect()
- mBluetoothGatt = null
}
@Synchronized
@@ -373,7 +374,7 @@ class BLEComm @Inject internal constructor(
close()
isConnected = false
isConnecting = false
- rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTED))
+ mCallback?.onBLEDisconnected()
aapsLogger.debug(LTag.PUMPBTCOMM, "Device was disconnected " + gatt.device.name) //Device was disconnected
}
}
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt
index aa9fd7e552..7ff73f7a35 100644
--- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/services/MedtrumService.kt
@@ -32,6 +32,7 @@ import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.events.EventAppExit
import info.nightscout.rx.events.EventInitializationChanged
import info.nightscout.rx.events.EventOverviewBolusProgress
+import info.nightscout.rx.events.EventPreferenceChange
import info.nightscout.rx.events.EventProfileSwitchChanged
import info.nightscout.rx.events.EventPumpStatusChanged
import info.nightscout.rx.logging.AAPSLogger
@@ -79,6 +80,8 @@ class MedtrumService : DaggerService(), BLECommCallback {
private var mDeviceSN: Long = 0
private var currentState: State = IdleState()
+ var isConnected = false
+ var isConnecting = false
// TODO: Stuff like this in a settings class?
private var mLastDeviceTime: Long = 0
@@ -90,6 +93,16 @@ class MedtrumService : DaggerService(), BLECommCallback {
.toObservable(EventAppExit::class.java)
.observeOn(aapsSchedulers.io)
.subscribe({ stopSelf() }, fabricPrivacy::logException)
+ disposable += rxBus
+ .toObservable(EventPreferenceChange::class.java)
+ .observeOn(aapsSchedulers.io)
+ .subscribe({ event ->
+ if (event.isChanged(rh.gs(info.nightscout.pump.medtrum.R.string.key_snInput))) {
+ pumpSync.connectNewPump()
+ changePump()
+ }
+ }, fabricPrivacy::logException)
+ changePump()
}
override fun onDestroy() {
@@ -97,26 +110,27 @@ class MedtrumService : DaggerService(), BLECommCallback {
super.onDestroy()
}
- val isConnected: Boolean
- get() = bleComm.isConnected
-
- val isConnecting: Boolean
- get() = bleComm.isConnecting
-
- fun connect(from: String, deviceSN: Long): Boolean {
- // TODO Check we might want to replace this with start scan?
- mDeviceSN = deviceSN
- return bleComm.connect(from, deviceSN)
+ fun connect(from: String): Boolean {
+ aapsLogger.debug(LTag.PUMP, "connect: called!")
+ if (currentState is IdleState) {
+ isConnecting = true
+ isConnected = false
+ rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTING))
+ return bleComm.connect(from, mDeviceSN)
+ } else {
+ aapsLogger.error(LTag.PUMPCOMM, "Connect attempt when in non Idle state from: " + from)
+ return false
+ }
}
fun stopConnecting() {
// TODO proper way for this might need send commands etc
- // bleComm.stopConnecting()
+ bleComm.stopConnecting()
}
fun disconnect(from: String) {
// TODO proper way for this might need send commands etc
- // bleComm.disconnect(from)
+ bleComm.disconnect(from)
}
fun readPumpStatus() {
@@ -156,11 +170,30 @@ class MedtrumService : DaggerService(), BLECommCallback {
return false
}
+ fun changePump() {
+ aapsLogger.debug(LTag.PUMP, "changePump: called!")
+ try {
+ mDeviceSN = sp.getString(info.nightscout.pump.medtrum.R.string.key_snInput, " ").toLong(radix = 16)
+ } catch (e: NumberFormatException) {
+ aapsLogger.debug(LTag.PUMP, "changePump: Invalid input!")
+ }
+ // TODO: What do we do with active patch here?
+ when (currentState) {
+ // is IdleState -> connect("changePump")
+ // is ReadyState -> disconnect("changePump")
+ else -> null // TODO: What to do here? Abort stuff?
+ }
+ }
+
/** BLECommCallbacks */
override fun onBLEConnected() {
currentState.onConnected()
}
+ override fun onBLEDisconnected() {
+ currentState.onDisconnected()
+ }
+
override fun onNotification(notification: ByteArray) {
aapsLogger.debug(LTag.PUMPCOMM, "<<<<< onNotification" + notification.contentToString())
// TODO
@@ -207,14 +240,34 @@ class MedtrumService : DaggerService(), BLECommCallback {
aapsLogger.debug(LTag.PUMPCOMM, "onIndicationr: " + this.toString() + "Should not be called here!")
}
- open fun onConnected() {}
+ open fun onConnected() {
+ aapsLogger.debug(LTag.PUMPCOMM, "onConnected")
+ }
+
+ open fun onDisconnected() {
+ aapsLogger.debug(LTag.PUMPCOMM, "onDisconnected")
+ isConnecting = false
+ isConnected = false
+ rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTED))
+
+ // TODO: Check flow for this
+ toState(IdleState())
+ }
}
private inner class IdleState : State() {
+ override fun onEnter() {}
+
override fun onConnected() {
+ super.onConnected()
toState(AuthState())
}
+
+ override fun onDisconnected() {
+ super.onDisconnected()
+ // TODO replace this by proper connecting state where we can retry
+ }
}
private inner class AuthState : State() {
@@ -391,7 +444,11 @@ class MedtrumService : DaggerService(), BLECommCallback {
override fun onEnter() {
aapsLogger.debug(LTag.PUMPCOMM, "Medtrum Service reached ReadyState!")
+ // Now we are fully connected and authenticated and we can start sending commands. Let AAPS know
+ isConnecting = false
+ isConnected = true
+ rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTED))
}
// Just a placeholder, this state is reached when the patch is ready to receive commands (Bolus, temp basal and whatever)
}
-}
\ No newline at end of file
+}
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumActivity.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumActivity.kt
new file mode 100644
index 0000000000..7b49049a6e
--- /dev/null
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumActivity.kt
@@ -0,0 +1,97 @@
+package info.nightscout.pump.medtrum.ui
+
+import android.app.Dialog
+import android.content.Context
+import android.content.Intent
+import android.media.MediaPlayer
+import android.media.RingtoneManager
+import android.os.Bundle
+import android.view.MotionEvent
+import androidx.appcompat.app.AlertDialog
+import androidx.lifecycle.ViewModelProvider
+import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumPreparePatchFragment
+import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumPrimeFragment
+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.databinding.ActivityMedtrumBinding
+import info.nightscout.pump.medtrum.extension.replaceFragmentInActivity
+import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumViewModel
+
+class MedtrumActivity : MedtrumBaseActivity() {
+
+ override fun getLayoutId(): Int = R.layout.activity_medtrum
+
+ override fun dispatchTouchEvent(event: MotionEvent): Boolean {
+ if (event.actionMasked == MotionEvent.ACTION_UP) {
+ // TODO
+ }
+
+ return super.dispatchTouchEvent(event)
+ }
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+ super.onCreate(savedInstanceState)
+
+ binding.apply {
+ viewModel = ViewModelProvider(this@MedtrumActivity, viewModelFactory).get(MedtrumViewModel::class.java)
+ viewModel?.apply {
+ processIntent(intent)
+
+ patchStep.observe(this@MedtrumActivity) {
+ when (it) {
+ PatchStep.PREPARE_PATCH -> setupViewFragment(MedtrumPreparePatchFragment.newInstance())
+ PatchStep.PRIME -> setupViewFragment(MedtrumPrimeFragment.newInstance())
+ PatchStep.CANCEL -> this@MedtrumActivity.finish()
+ else -> Unit
+ }
+ }
+ }
+ }
+ }
+
+ override fun onNewIntent(intent: Intent?) {
+ super.onNewIntent(intent)
+ processIntent(intent)
+ }
+
+ private fun processIntent(intent: Intent?) {
+ binding.viewModel?.apply {
+ intent?.run {
+ val step = intent.safeGetSerializableExtra(EXTRA_START_PATCH_STEP, PatchStep::class.java)
+ initializePatchStep(step)
+ }
+ }
+ }
+
+ override fun onDestroy() {
+ super.onDestroy()
+ // TODO
+ }
+
+ override fun onBackPressed() {
+ binding.viewModel?.apply {
+ // TODO DEACTIVATION ?
+ }
+ }
+
+ companion object {
+
+ const val EXTRA_START_PATCH_STEP = "EXTRA_START_PATCH_FRAGMENT_UI"
+ const val EXTRA_START_FROM_MENU = "EXTRA_START_FROM_MENU"
+
+ @JvmStatic
+ fun createIntentFromMenu(context: Context, patchStep: PatchStep): Intent {
+ return Intent(context, MedtrumActivity::class.java).apply {
+ putExtra(EXTRA_START_PATCH_STEP, patchStep)
+ putExtra(EXTRA_START_FROM_MENU, true)
+ }
+ }
+
+ }
+
+ private fun setupViewFragment(baseFragment: MedtrumBaseFragment<*>) {
+ replaceFragmentInActivity(baseFragment, R.id.framelayout_fragment, false)
+ }
+
+}
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumOverviewFragment.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumOverviewFragment.kt
index a29b8c60ad..25aad5ce89 100644
--- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumOverviewFragment.kt
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumOverviewFragment.kt
@@ -6,18 +6,18 @@ import android.view.View
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.lifecycle.ViewModelProvider
-import info.nightscout.pump.medtrum.databinding.MedtrumOverviewFragmentBinding
+import info.nightscout.pump.medtrum.databinding.FragmentMedtrumOverviewBinding
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumOverviewViewModel
import info.nightscout.pump.medtrum.R
+import info.nightscout.pump.medtrum.code.EventType
+import info.nightscout.pump.medtrum.code.PatchStep
import info.nightscout.rx.AapsSchedulers
-import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger
import io.reactivex.rxjava3.disposables.CompositeDisposable
import javax.inject.Inject
-class MedtrumOverviewFragment : MedtrumBaseFragment() {
+class MedtrumOverviewFragment : MedtrumBaseFragment() {
- @Inject lateinit var rxBus: RxBus
@Inject lateinit var aapsSchedulers: AapsSchedulers
@Inject lateinit var aapsLogger: AAPSLogger
private lateinit var resultLauncherForResume: ActivityResultLauncher
@@ -25,7 +25,7 @@ class MedtrumOverviewFragment : MedtrumBaseFragment
+ when (evt.peekContent()) {
+ EventType.ACTIVATION_CLICKED -> requireContext().apply { startActivity(MedtrumActivity.createIntentFromMenu(this, PatchStep.PREPARE_PATCH)) }
+ else -> Unit
+ }
}
- }
- resultLauncherForPause = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
- when (it.resultCode) {
- // TODO Handle events here, see eopatch eventhandler
+ resultLauncherForResume = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
+ when (it.resultCode) {
+ // TODO Handle events here, see eopatch eventhandler
+ }
+ }
+
+ resultLauncherForPause = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
+ when (it.resultCode) {
+ // TODO Handle events here, see eopatch eventhandler
+ }
}
}
}
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumPreparePatchFragment.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumPreparePatchFragment.kt
new file mode 100644
index 0000000000..650d103f6e
--- /dev/null
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumPreparePatchFragment.kt
@@ -0,0 +1,42 @@
+package info.nightscout.androidaps.plugins.pump.eopatch.ui
+
+import android.os.Bundle
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import info.nightscout.pump.medtrum.R
+import info.nightscout.pump.medtrum.databinding.FragmentMedtrumPreparePatchBinding
+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 MedtrumPreparePatchFragment : MedtrumBaseFragment() {
+
+ @Inject lateinit var aapsLogger: AAPSLogger
+
+ companion object {
+
+ fun newInstance(): MedtrumPreparePatchFragment = MedtrumPreparePatchFragment()
+ }
+
+ override fun getLayoutId(): Int = R.layout.fragment_medtrum_prepare_patch
+
+ 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) {
+ // TODO: Confirmation dialog
+ MedtrumViewModel.SetupStep.CONNECTED -> btnPositive.visibility = View.VISIBLE
+ else -> Unit
+ }
+ }
+ preparePatch()
+ }
+ }
+ }
+}
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumPrimeFragment.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumPrimeFragment.kt
new file mode 100644
index 0000000000..42f27d3105
--- /dev/null
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/MedtrumPrimeFragment.kt
@@ -0,0 +1,32 @@
+package info.nightscout.androidaps.plugins.pump.eopatch.ui
+
+import android.os.Bundle
+import android.view.View
+import androidx.lifecycle.ViewModelProvider
+import info.nightscout.pump.medtrum.R
+import info.nightscout.pump.medtrum.databinding.FragmentMedtrumPrimeBinding
+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 MedtrumPrimeFragment : MedtrumBaseFragment() {
+
+ @Inject lateinit var aapsLogger: AAPSLogger
+
+ companion object {
+
+ fun newInstance(): MedtrumPrimeFragment = MedtrumPrimeFragment()
+ }
+
+ override fun getLayoutId(): Int = R.layout.fragment_medtrum_prime
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ super.onViewCreated(view, savedInstanceState)
+ binding.apply {
+ viewModel = ViewModelProvider(requireActivity(), viewModelFactory).get(MedtrumViewModel::class.java)
+ // TODO do stuff
+ }
+ }
+}
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/event/SingleLiveEvent.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/event/SingleLiveEvent.kt
new file mode 100644
index 0000000000..2d52d4d7cd
--- /dev/null
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/event/SingleLiveEvent.kt
@@ -0,0 +1,29 @@
+package info.nightscout.pump.medtrum.ui.event
+
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.MutableLiveData
+import androidx.lifecycle.Observer
+import androidx.annotation.MainThread
+import java.util.concurrent.atomic.AtomicBoolean
+
+open class SingleLiveEvent : MutableLiveData() {
+ private val mPending = AtomicBoolean(false)
+ override fun observe(owner: LifecycleOwner, observer: Observer) {
+ super.observe(owner) { t ->
+ if (mPending.compareAndSet(true, false)) {
+ observer.onChanged(t)
+ }
+ }
+ }
+
+ @MainThread
+ override fun setValue(t: T?) {
+ mPending.set(true)
+ super.setValue(t)
+ }
+
+ @MainThread
+ fun call() {
+ value = null
+ }
+}
\ No newline at end of file
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/event/UIEvent.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/event/UIEvent.kt
new file mode 100644
index 0000000000..e1f879799b
--- /dev/null
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/event/UIEvent.kt
@@ -0,0 +1,7 @@
+package info.nightscout.pump.medtrum.ui.event
+
+open class UIEvent(private val content: T) {
+ var value: Any? = null
+ fun peekContent(): T = content
+}
+
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumOverviewViewModel.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumOverviewViewModel.kt
index 0cce7e419c..d270275c03 100644
--- a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumOverviewViewModel.kt
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumOverviewViewModel.kt
@@ -1,32 +1,77 @@
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.pump.medtrum.code.EventType
import info.nightscout.pump.medtrum.ui.MedtrumBaseNavigator
+import info.nightscout.pump.medtrum.ui.event.SingleLiveEvent
+import info.nightscout.pump.medtrum.ui.event.UIEvent
import info.nightscout.pump.medtrum.ui.viewmodel.BaseViewModel
+import info.nightscout.interfaces.profile.ProfileFunction
+import info.nightscout.rx.AapsSchedulers
+import info.nightscout.rx.bus.RxBus
+import info.nightscout.rx.events.EventPumpStatusChanged
import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+import io.reactivex.rxjava3.kotlin.plusAssign
import javax.inject.Inject
class MedtrumOverviewViewModel @Inject constructor(
- private val aapsLogger: AAPSLogger
+ private val aapsLogger: AAPSLogger,
+ private val rxBus: RxBus,
+ private val aapsSchedulers: AapsSchedulers,
+ private val fabricPrivacy: FabricPrivacy,
+ private val profileFunction: ProfileFunction,
) : BaseViewModel() {
- val isPatchActivated : Boolean
+ private var disposable: CompositeDisposable = CompositeDisposable()
+
+ private val _eventHandler = SingleLiveEvent>()
+ val eventHandler: LiveData>
+ get() = _eventHandler
+
+ private val _bleStatus = SingleLiveEvent()
+ val bleStatus: LiveData
+ get() = _bleStatus
+
+ // TODO make these livedata
+ val isPatchActivated: Boolean
get() = false // TODO
- val isPatchConnected: Boolean
- get() = false // TODO
- val bleStatus : String
- get() ="" //TODO
init {
- // TODO
+ disposable += rxBus
+ .toObservable(EventPumpStatusChanged::class.java)
+ .observeOn(aapsSchedulers.main)
+ .subscribe({
+ _bleStatus.value = when (it.status) {
+ EventPumpStatusChanged.Status.CONNECTING ->
+ "{fa-bluetooth-b spin} ${it.secondsElapsed}s"
+
+ EventPumpStatusChanged.Status.CONNECTED ->
+ "{fa-bluetooth}"
+
+ EventPumpStatusChanged.Status.DISCONNECTED ->
+ "{fa-bluetooth-b}"
+
+ else ->
+ ""
+ }
+ }, fabricPrivacy::logException)
}
- fun onClickActivation(){
+ fun onClickActivation() {
aapsLogger.debug(LTag.PUMP, "Start Patch clicked!")
- // TODO
+ val profile = profileFunction.getProfile()
+ if (profile == null) {
+ _eventHandler.postValue(UIEvent(EventType.PROFILE_NOT_SET))
+ } else {
+ _eventHandler.postValue(UIEvent(EventType.ACTIVATION_CLICKED))
+ }
}
- fun onClickDeactivation(){
+ fun onClickDeactivation() {
aapsLogger.debug(LTag.PUMP, "Stop Patch clicked!")
// TODO
}
diff --git a/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumViewModel.kt b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumViewModel.kt
new file mode 100644
index 0000000000..328b42a89a
--- /dev/null
+++ b/pump/medtrum/src/main/java/info/nightscout/pump/medtrum/ui/viewmodel/MedtrumViewModel.kt
@@ -0,0 +1,128 @@
+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.pump.medtrum.MedtrumPlugin
+import info.nightscout.pump.medtrum.services.MedtrumService
+import info.nightscout.pump.medtrum.code.EventType
+import info.nightscout.pump.medtrum.code.PatchStep
+import info.nightscout.pump.medtrum.ui.MedtrumBaseNavigator
+import info.nightscout.pump.medtrum.ui.event.SingleLiveEvent
+import info.nightscout.pump.medtrum.ui.event.UIEvent
+import info.nightscout.shared.interfaces.ResourceHelper
+import info.nightscout.rx.AapsSchedulers
+import info.nightscout.rx.bus.RxBus
+import info.nightscout.rx.events.EventPumpStatusChanged
+import info.nightscout.rx.logging.AAPSLogger
+import info.nightscout.rx.logging.LTag
+import info.nightscout.shared.sharedPreferences.SP
+import io.reactivex.rxjava3.disposables.CompositeDisposable
+import io.reactivex.rxjava3.kotlin.plusAssign
+import javax.inject.Inject
+
+class MedtrumViewModel @Inject constructor(
+ private val rh: ResourceHelper,
+ private val aapsLogger: AAPSLogger,
+ private val rxBus: RxBus,
+ private val aapsSchedulers: AapsSchedulers,
+ private val fabricPrivacy: FabricPrivacy,
+ private val medtrumPlugin: MedtrumPlugin,
+ private val sp: SP
+) : BaseViewModel() {
+
+ val patchStep = MutableLiveData()
+
+ val title = "Activation"
+
+ val medtrumService: MedtrumService?
+ get() = medtrumPlugin.getService()
+
+ private var disposable: CompositeDisposable = CompositeDisposable()
+
+ private val _eventHandler = SingleLiveEvent>()
+ val eventHandler: LiveData>
+ get() = _eventHandler
+
+ private var mInitPatchStep: PatchStep? = null
+
+ init {
+ disposable += rxBus
+ .toObservable(EventPumpStatusChanged::class.java)
+ .observeOn(aapsSchedulers.main)
+ .subscribe({
+ when (it.status) {
+ EventPumpStatusChanged.Status.CONNECTING -> {}
+
+ EventPumpStatusChanged.Status.CONNECTED
+ -> if (patchStep.value == PatchStep.PREPARE_PATCH) setupStep.postValue(SetupStep.CONNECTED) else {
+ }
+
+ EventPumpStatusChanged.Status.DISCONNECTED -> {}
+
+ else -> {}
+ }
+ }, fabricPrivacy::logException)
+ }
+
+ fun moveStep(newPatchStep: PatchStep) {
+ val oldPatchStep = patchStep.value
+
+ if (oldPatchStep != newPatchStep) {
+ when (newPatchStep) {
+ PatchStep.CANCEL -> {
+ if (medtrumService?.isConnected == true || medtrumService?.isConnecting == true) medtrumService?.disconnect("Cancel") else {
+ }
+ }
+
+ else -> null
+ }?.let {
+ // TODO Update lifecycle
+ }
+ }
+
+ prepareStep(newPatchStep)
+
+ aapsLogger.info(LTag.PUMP, "moveStep: $oldPatchStep -> $newPatchStep")
+ }
+
+ fun initializePatchStep(step: PatchStep?) {
+ mInitPatchStep = prepareStep(step)
+ }
+
+ fun preparePatch() {
+ // TODO: Decide if we want to connect already when user is still filling, or if we want to wait after user is done filling
+ medtrumService?.connect("PreparePatch")
+ }
+
+ private fun prepareStep(step: PatchStep?): PatchStep {
+ // TODO Title per screen :) And proper sync with patchstate
+ // (step ?: convertToPatchStep(patchConfig.lifecycleEvent.lifeCycle)).let { newStep ->
+
+ (step ?: PatchStep.SAFE_DEACTIVATION).let { newStep ->
+ when (newStep) {
+
+ else -> ""
+ }.let {
+
+ }
+
+ patchStep.postValue(newStep)
+
+ return newStep
+ }
+ }
+
+ enum class SetupStep {
+ CONNECTED,
+ PRIME_READY,
+ ACTIVATED
+ }
+
+ val setupStep = MutableLiveData()
+
+ private fun updateSetupStep(newSetupStep: SetupStep) {
+ aapsLogger.info(LTag.PUMP, "curSetupStep: ${setupStep.value}, newSetupStep: $newSetupStep")
+ setupStep.postValue(newSetupStep)
+ }
+}
diff --git a/pump/medtrum/src/main/res/layout/activity_medtrum.xml b/pump/medtrum/src/main/res/layout/activity_medtrum.xml
new file mode 100644
index 0000000000..c7658e2ce9
--- /dev/null
+++ b/pump/medtrum/src/main/res/layout/activity_medtrum.xml
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pump/medtrum/src/main/res/layout/medtrum_overview_fragment.xml b/pump/medtrum/src/main/res/layout/fragment_medtrum_overview.xml
similarity index 98%
rename from pump/medtrum/src/main/res/layout/medtrum_overview_fragment.xml
rename to pump/medtrum/src/main/res/layout/fragment_medtrum_overview.xml
index 471d939b6d..b7b6cdedfe 100644
--- a/pump/medtrum/src/main/res/layout/medtrum_overview_fragment.xml
+++ b/pump/medtrum/src/main/res/layout/fragment_medtrum_overview.xml
@@ -3,9 +3,10 @@
xmlns:tools="http://schemas.android.com/tools">
+
+ type="info.nightscout.pump.medtrum.ui.viewmodel.MedtrumOverviewViewModel" />
+
+ android:text="@string/string_new_patch"
+ app:onSafeClick="@{() -> viewmodel.onClickActivation()}" />
+ android:text="@string/string_stop_patch"
+ app:onSafeClick="@{() -> viewmodel.onClickDeactivation()}" />
diff --git a/pump/medtrum/src/main/res/layout/fragment_medtrum_prepare_patch.xml b/pump/medtrum/src/main/res/layout/fragment_medtrum_prepare_patch.xml
new file mode 100644
index 0000000000..b03f5e0446
--- /dev/null
+++ b/pump/medtrum/src/main/res/layout/fragment_medtrum_prepare_patch.xml
@@ -0,0 +1,66 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pump/medtrum/src/main/res/layout/fragment_medtrum_prime.xml b/pump/medtrum/src/main/res/layout/fragment_medtrum_prime.xml
new file mode 100644
index 0000000000..cbdb2073e1
--- /dev/null
+++ b/pump/medtrum/src/main/res/layout/fragment_medtrum_prime.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pump/medtrum/src/main/res/values/strings.xml b/pump/medtrum/src/main/res/values/strings.xml
index c6c5f1620b..9ea34ecd97 100644
--- a/pump/medtrum/src/main/res/values/strings.xml
+++ b/pump/medtrum/src/main/res/values/strings.xml
@@ -11,10 +11,16 @@
BLE Status
-
- SN
- Serial number pump base
Start new patch
Stop patch
+
+ Discard/Change Patch
+ Start priming
+
+
+ SN
+ Serial number pump base
+
+