Prepare patch step WIP
This commit is contained in:
parent
8f6dfbdf88
commit
7afa0beb0a
21 changed files with 750 additions and 88 deletions
|
@ -7,6 +7,7 @@
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
||||||
|
|
||||||
<application>
|
<application>
|
||||||
|
<activity android:name=".ui.MedtrumActivity" />
|
||||||
<service
|
<service
|
||||||
android:name=".services.MedtrumService"
|
android:name=".services.MedtrumService"
|
||||||
android:enabled="true"
|
android:enabled="true"
|
||||||
|
|
|
@ -79,7 +79,6 @@ class MedtrumPlugin @Inject constructor(
|
||||||
private var medtrumService: MedtrumService? = null
|
private var medtrumService: MedtrumService? = null
|
||||||
private var mPumpType: PumpType = PumpType.MEDTRUM_NANO
|
private var mPumpType: PumpType = PumpType.MEDTRUM_NANO
|
||||||
private val mPumpDescription = PumpDescription(mPumpType)
|
private val mPumpDescription = PumpDescription(mPumpType)
|
||||||
private var mDeviceSN: Long = 0
|
|
||||||
|
|
||||||
override fun onStart() {
|
override fun onStart() {
|
||||||
super.onStart()
|
super.onStart()
|
||||||
|
@ -90,16 +89,6 @@ class MedtrumPlugin @Inject constructor(
|
||||||
.toObservable(EventAppExit::class.java)
|
.toObservable(EventAppExit::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ context.unbindService(mConnection) }, fabricPrivacy::logException)
|
.subscribe({ context.unbindService(mConnection) }, 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 onStop() {
|
override fun onStop() {
|
||||||
|
@ -122,15 +111,8 @@ class MedtrumPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changePump() {
|
fun getService(): MedtrumService? {
|
||||||
aapsLogger.debug(LTag.PUMP, "changePump: called!")
|
return medtrumService
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isInitialized(): Boolean {
|
override fun isInitialized(): Boolean {
|
||||||
|
@ -138,14 +120,17 @@ class MedtrumPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isSuspended(): Boolean {
|
override fun isSuspended(): Boolean {
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isBusy(): Boolean {
|
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 isConnecting(): Boolean = medtrumService?.isConnecting ?: false
|
||||||
override fun isHandshakeInProgress(): Boolean = false
|
override fun isHandshakeInProgress(): Boolean = false
|
||||||
|
|
||||||
|
@ -153,31 +138,37 @@ class MedtrumPlugin @Inject constructor(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun connect(reason: String) {
|
override fun connect(reason: String) {
|
||||||
|
if (isInitialized()) {
|
||||||
aapsLogger.debug(LTag.PUMP, "Medtrum connect - reason:$reason")
|
aapsLogger.debug(LTag.PUMP, "Medtrum connect - reason:$reason")
|
||||||
aapsLogger.debug(LTag.PUMP, "Medtrum connect - service::$medtrumService")
|
aapsLogger.debug(LTag.PUMP, "Medtrum connect - service::$medtrumService")
|
||||||
aapsLogger.debug(LTag.PUMP, "Medtrum connect - mDeviceSN:$mDeviceSN")
|
// aapsLogger.debug(LTag.PUMP, "Medtrum connect - mDeviceSN:$mDeviceSN")
|
||||||
if (medtrumService != null && mDeviceSN != 0.toLong()) {
|
if (medtrumService != null) {
|
||||||
aapsLogger.debug(LTag.PUMP, "Medtrum connect - Attempt connection!")
|
aapsLogger.debug(LTag.PUMP, "Medtrum connect - Attempt connection!")
|
||||||
val success = medtrumService?.connect(reason, mDeviceSN) ?: false
|
val success = medtrumService?.connect(reason) ?: false
|
||||||
if (!success) ToastUtils.errorToast(context, info.nightscout.core.ui.R.string.ble_not_supported_or_not_paired)
|
if (!success) ToastUtils.errorToast(context, info.nightscout.core.ui.R.string.ble_not_supported_or_not_paired)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun disconnect(reason: String) {
|
override fun disconnect(reason: String) {
|
||||||
aapsLogger.debug(LTag.PUMP, "RS disconnect from: $reason")
|
if (isInitialized()) {
|
||||||
|
aapsLogger.debug(LTag.PUMP, "Medtrum disconnect from: $reason")
|
||||||
medtrumService?.disconnect(reason)
|
medtrumService?.disconnect(reason)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun stopConnecting() {
|
override fun stopConnecting() {
|
||||||
medtrumService?.stopConnecting()
|
medtrumService?.stopConnecting()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPumpStatus(reason: String) {
|
override fun getPumpStatus(reason: String) {
|
||||||
|
if (isInitialized()) {
|
||||||
medtrumService?.readPumpStatus()
|
medtrumService?.readPumpStatus()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
|
override fun setNewBasalProfile(profile: Profile): PumpEnactResult {
|
||||||
return PumpEnactResult(injector) // TODO
|
return PumpEnactResult(injector).success(true).enacted(true) // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isThisProfileSet(profile: Profile): Boolean {
|
override fun isThisProfileSet(profile: Profile): Boolean {
|
||||||
|
|
|
@ -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
|
||||||
|
;
|
||||||
|
}
|
|
@ -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;
|
||||||
|
}
|
|
@ -7,17 +7,21 @@ import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.android.ContributesAndroidInjector
|
import dagger.android.ContributesAndroidInjector
|
||||||
import dagger.multibindings.IntoMap
|
import dagger.multibindings.IntoMap
|
||||||
|
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumPreparePatchFragment
|
||||||
|
import info.nightscout.androidaps.plugins.pump.eopatch.ui.MedtrumPrimeFragment
|
||||||
import info.nightscout.pump.medtrum.services.MedtrumService
|
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.MedtrumOverviewFragment
|
||||||
import info.nightscout.pump.medtrum.ui.viewmodel.MedtrumOverviewViewModel
|
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.ViewModelFactory
|
||||||
import info.nightscout.pump.medtrum.ui.viewmodel.ViewModelKey
|
import info.nightscout.pump.medtrum.ui.viewmodel.ViewModelKey
|
||||||
import javax.inject.Provider
|
import javax.inject.Provider
|
||||||
|
|
||||||
|
|
||||||
@Module
|
@Module
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
abstract class MedtrumModule {
|
abstract class MedtrumModule {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
@ -34,11 +38,29 @@ abstract class MedtrumModule {
|
||||||
@ViewModelKey(MedtrumOverviewViewModel::class)
|
@ViewModelKey(MedtrumOverviewViewModel::class)
|
||||||
internal abstract fun bindsMedtrumOverviewViewmodel(viewModel: MedtrumOverviewViewModel): ViewModel
|
internal abstract fun bindsMedtrumOverviewViewmodel(viewModel: MedtrumOverviewViewModel): ViewModel
|
||||||
|
|
||||||
|
@Binds
|
||||||
|
@IntoMap
|
||||||
|
@MedtrumPluginQualifier
|
||||||
|
@ViewModelKey(MedtrumViewModel::class)
|
||||||
|
internal abstract fun bindsMedtrumViewModel(viewModel: MedtrumViewModel): ViewModel
|
||||||
|
|
||||||
// FRAGMENTS
|
// FRAGMENTS
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun contributesMedtrumOverviewFragment(): MedtrumOverviewFragment
|
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
|
// SERVICE
|
||||||
@ContributesAndroidInjector
|
@ContributesAndroidInjector
|
||||||
abstract fun contributesDanaRSService(): MedtrumService
|
abstract fun contributesMedtrumService(): MedtrumService
|
||||||
}
|
}
|
|
@ -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()
|
||||||
|
}
|
|
@ -49,7 +49,9 @@ import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
|
||||||
interface BLECommCallback {
|
interface BLECommCallback {
|
||||||
|
|
||||||
fun onBLEConnected()
|
fun onBLEConnected()
|
||||||
|
fun onBLEDisconnected()
|
||||||
fun onNotification(notification: ByteArray)
|
fun onNotification(notification: ByteArray)
|
||||||
fun onIndication(indication: ByteArray)
|
fun onIndication(indication: ByteArray)
|
||||||
fun onSendMessageError(reason: String)
|
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 val mBluetoothAdapter: BluetoothAdapter? get() = (context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?)?.adapter
|
||||||
private var mBluetoothGatt: BluetoothGatt? = null
|
private var mBluetoothGatt: BluetoothGatt? = null
|
||||||
|
|
||||||
var isConnected = false
|
var isConnected = false // TODO: These may be removed have no function
|
||||||
var isConnecting = false
|
var isConnecting = false// TODO: These may be removed have no function
|
||||||
private var uartWrite: BluetoothGattCharacteristic? = null
|
private var uartWrite: BluetoothGattCharacteristic? = null
|
||||||
private var uartRead: BluetoothGattCharacteristic? = null
|
private var uartRead: BluetoothGattCharacteristic? = null
|
||||||
|
|
||||||
|
@ -179,7 +181,6 @@ class BLEComm @Inject internal constructor(
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "disconnect from: $from")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "disconnect from: $from")
|
||||||
mBluetoothGatt?.disconnect()
|
mBluetoothGatt?.disconnect()
|
||||||
mBluetoothGatt = null
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
|
@ -373,7 +374,7 @@ class BLEComm @Inject internal constructor(
|
||||||
close()
|
close()
|
||||||
isConnected = false
|
isConnected = false
|
||||||
isConnecting = false
|
isConnecting = false
|
||||||
rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.DISCONNECTED))
|
mCallback?.onBLEDisconnected()
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Device was disconnected " + gatt.device.name) //Device was disconnected
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Device was disconnected " + gatt.device.name) //Device was disconnected
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ import info.nightscout.rx.bus.RxBus
|
||||||
import info.nightscout.rx.events.EventAppExit
|
import info.nightscout.rx.events.EventAppExit
|
||||||
import info.nightscout.rx.events.EventInitializationChanged
|
import info.nightscout.rx.events.EventInitializationChanged
|
||||||
import info.nightscout.rx.events.EventOverviewBolusProgress
|
import info.nightscout.rx.events.EventOverviewBolusProgress
|
||||||
|
import info.nightscout.rx.events.EventPreferenceChange
|
||||||
import info.nightscout.rx.events.EventProfileSwitchChanged
|
import info.nightscout.rx.events.EventProfileSwitchChanged
|
||||||
import info.nightscout.rx.events.EventPumpStatusChanged
|
import info.nightscout.rx.events.EventPumpStatusChanged
|
||||||
import info.nightscout.rx.logging.AAPSLogger
|
import info.nightscout.rx.logging.AAPSLogger
|
||||||
|
@ -79,6 +80,8 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
||||||
|
|
||||||
private var mDeviceSN: Long = 0
|
private var mDeviceSN: Long = 0
|
||||||
private var currentState: State = IdleState()
|
private var currentState: State = IdleState()
|
||||||
|
var isConnected = false
|
||||||
|
var isConnecting = false
|
||||||
|
|
||||||
// TODO: Stuff like this in a settings class?
|
// TODO: Stuff like this in a settings class?
|
||||||
private var mLastDeviceTime: Long = 0
|
private var mLastDeviceTime: Long = 0
|
||||||
|
@ -90,6 +93,16 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
||||||
.toObservable(EventAppExit::class.java)
|
.toObservable(EventAppExit::class.java)
|
||||||
.observeOn(aapsSchedulers.io)
|
.observeOn(aapsSchedulers.io)
|
||||||
.subscribe({ stopSelf() }, fabricPrivacy::logException)
|
.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() {
|
override fun onDestroy() {
|
||||||
|
@ -97,26 +110,27 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
val isConnected: Boolean
|
fun connect(from: String): Boolean {
|
||||||
get() = bleComm.isConnected
|
aapsLogger.debug(LTag.PUMP, "connect: called!")
|
||||||
|
if (currentState is IdleState) {
|
||||||
val isConnecting: Boolean
|
isConnecting = true
|
||||||
get() = bleComm.isConnecting
|
isConnected = false
|
||||||
|
rxBus.send(EventPumpStatusChanged(EventPumpStatusChanged.Status.CONNECTING))
|
||||||
fun connect(from: String, deviceSN: Long): Boolean {
|
return bleComm.connect(from, mDeviceSN)
|
||||||
// TODO Check we might want to replace this with start scan?
|
} else {
|
||||||
mDeviceSN = deviceSN
|
aapsLogger.error(LTag.PUMPCOMM, "Connect attempt when in non Idle state from: " + from)
|
||||||
return bleComm.connect(from, deviceSN)
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun stopConnecting() {
|
fun stopConnecting() {
|
||||||
// TODO proper way for this might need send commands etc
|
// TODO proper way for this might need send commands etc
|
||||||
// bleComm.stopConnecting()
|
bleComm.stopConnecting()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun disconnect(from: String) {
|
fun disconnect(from: String) {
|
||||||
// TODO proper way for this might need send commands etc
|
// TODO proper way for this might need send commands etc
|
||||||
// bleComm.disconnect(from)
|
bleComm.disconnect(from)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun readPumpStatus() {
|
fun readPumpStatus() {
|
||||||
|
@ -156,11 +170,30 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
||||||
return false
|
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 */
|
/** BLECommCallbacks */
|
||||||
override fun onBLEConnected() {
|
override fun onBLEConnected() {
|
||||||
currentState.onConnected()
|
currentState.onConnected()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onBLEDisconnected() {
|
||||||
|
currentState.onDisconnected()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onNotification(notification: ByteArray) {
|
override fun onNotification(notification: ByteArray) {
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "<<<<< onNotification" + notification.contentToString())
|
aapsLogger.debug(LTag.PUMPCOMM, "<<<<< onNotification" + notification.contentToString())
|
||||||
// TODO
|
// TODO
|
||||||
|
@ -207,14 +240,34 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "onIndicationr: " + this.toString() + "Should not be called here!")
|
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() {
|
private inner class IdleState : State() {
|
||||||
|
|
||||||
|
override fun onEnter() {}
|
||||||
|
|
||||||
override fun onConnected() {
|
override fun onConnected() {
|
||||||
|
super.onConnected()
|
||||||
toState(AuthState())
|
toState(AuthState())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDisconnected() {
|
||||||
|
super.onDisconnected()
|
||||||
|
// TODO replace this by proper connecting state where we can retry
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class AuthState : State() {
|
private inner class AuthState : State() {
|
||||||
|
@ -391,6 +444,10 @@ class MedtrumService : DaggerService(), BLECommCallback {
|
||||||
|
|
||||||
override fun onEnter() {
|
override fun onEnter() {
|
||||||
aapsLogger.debug(LTag.PUMPCOMM, "Medtrum Service reached ReadyState!")
|
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)
|
// Just a placeholder, this state is reached when the patch is ready to receive commands (Bolus, temp basal and whatever)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<ActivityMedtrumBinding>() {
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -6,18 +6,18 @@ import android.view.View
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
import androidx.activity.result.ActivityResultLauncher
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.lifecycle.ViewModelProvider
|
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.ui.viewmodel.MedtrumOverviewViewModel
|
||||||
import info.nightscout.pump.medtrum.R
|
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.AapsSchedulers
|
||||||
import info.nightscout.rx.bus.RxBus
|
|
||||||
import info.nightscout.rx.logging.AAPSLogger
|
import info.nightscout.rx.logging.AAPSLogger
|
||||||
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MedtrumOverviewFragment : MedtrumBaseFragment<MedtrumOverviewFragmentBinding>() {
|
class MedtrumOverviewFragment : MedtrumBaseFragment<FragmentMedtrumOverviewBinding>() {
|
||||||
|
|
||||||
@Inject lateinit var rxBus: RxBus
|
|
||||||
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
@Inject lateinit var aapsSchedulers: AapsSchedulers
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
@Inject lateinit var aapsLogger: AAPSLogger
|
||||||
private lateinit var resultLauncherForResume: ActivityResultLauncher<Intent>
|
private lateinit var resultLauncherForResume: ActivityResultLauncher<Intent>
|
||||||
|
@ -25,7 +25,7 @@ class MedtrumOverviewFragment : MedtrumBaseFragment<MedtrumOverviewFragmentBindi
|
||||||
|
|
||||||
private var disposable: CompositeDisposable = CompositeDisposable()
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
|
|
||||||
override fun getLayoutId(): Int = R.layout.medtrum_overview_fragment
|
override fun getLayoutId(): Int = R.layout.fragment_medtrum_overview
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
@ -38,7 +38,11 @@ class MedtrumOverviewFragment : MedtrumBaseFragment<MedtrumOverviewFragmentBindi
|
||||||
binding.apply {
|
binding.apply {
|
||||||
viewmodel = ViewModelProvider(this@MedtrumOverviewFragment, viewModelFactory).get(MedtrumOverviewViewModel::class.java)
|
viewmodel = ViewModelProvider(this@MedtrumOverviewFragment, viewModelFactory).get(MedtrumOverviewViewModel::class.java)
|
||||||
viewmodel?.apply {
|
viewmodel?.apply {
|
||||||
// TODO Handle events here, see eopatch eventhandler
|
eventHandler.observe(viewLifecycleOwner) { evt ->
|
||||||
|
when (evt.peekContent()) {
|
||||||
|
EventType.ACTIVATION_CLICKED -> requireContext().apply { startActivity(MedtrumActivity.createIntentFromMenu(this, PatchStep.PREPARE_PATCH)) }
|
||||||
|
else -> Unit
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resultLauncherForResume = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
resultLauncherForResume = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||||
|
@ -54,6 +58,7 @@ class MedtrumOverviewFragment : MedtrumBaseFragment<MedtrumOverviewFragmentBindi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
super.onPause()
|
super.onPause()
|
||||||
|
|
|
@ -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<FragmentMedtrumPreparePatchBinding>() {
|
||||||
|
|
||||||
|
@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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<FragmentMedtrumPrimeBinding>() {
|
||||||
|
|
||||||
|
@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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<T> : MutableLiveData<T>() {
|
||||||
|
private val mPending = AtomicBoolean(false)
|
||||||
|
override fun observe(owner: LifecycleOwner, observer: Observer<in T>) {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package info.nightscout.pump.medtrum.ui.event
|
||||||
|
|
||||||
|
open class UIEvent<out T>(private val content: T) {
|
||||||
|
var value: Any? = null
|
||||||
|
fun peekContent(): T = content
|
||||||
|
}
|
||||||
|
|
|
@ -1,32 +1,77 @@
|
||||||
package info.nightscout.pump.medtrum.ui.viewmodel
|
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.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.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.AAPSLogger
|
||||||
import info.nightscout.rx.logging.LTag
|
import info.nightscout.rx.logging.LTag
|
||||||
|
import io.reactivex.rxjava3.disposables.CompositeDisposable
|
||||||
|
import io.reactivex.rxjava3.kotlin.plusAssign
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class MedtrumOverviewViewModel @Inject constructor(
|
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<MedtrumBaseNavigator>() {
|
) : BaseViewModel<MedtrumBaseNavigator>() {
|
||||||
|
|
||||||
val isPatchActivated : Boolean
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
|
|
||||||
|
private val _eventHandler = SingleLiveEvent<UIEvent<EventType>>()
|
||||||
|
val eventHandler: LiveData<UIEvent<EventType>>
|
||||||
|
get() = _eventHandler
|
||||||
|
|
||||||
|
private val _bleStatus = SingleLiveEvent<String>()
|
||||||
|
val bleStatus: LiveData<String>
|
||||||
|
get() = _bleStatus
|
||||||
|
|
||||||
|
// TODO make these livedata
|
||||||
|
val isPatchActivated: Boolean
|
||||||
get() = false // TODO
|
get() = false // TODO
|
||||||
val isPatchConnected: Boolean
|
|
||||||
get() = false // TODO
|
|
||||||
val bleStatus : String
|
|
||||||
get() ="" //TODO
|
|
||||||
|
|
||||||
init {
|
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!")
|
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!")
|
aapsLogger.debug(LTag.PUMP, "Stop Patch clicked!")
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<MedtrumBaseNavigator>() {
|
||||||
|
|
||||||
|
val patchStep = MutableLiveData<PatchStep>()
|
||||||
|
|
||||||
|
val title = "Activation"
|
||||||
|
|
||||||
|
val medtrumService: MedtrumService?
|
||||||
|
get() = medtrumPlugin.getService()
|
||||||
|
|
||||||
|
private var disposable: CompositeDisposable = CompositeDisposable()
|
||||||
|
|
||||||
|
private val _eventHandler = SingleLiveEvent<UIEvent<EventType>>()
|
||||||
|
val eventHandler: LiveData<UIEvent<EventType>>
|
||||||
|
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<SetupStep>()
|
||||||
|
|
||||||
|
private fun updateSetupStep(newSetupStep: SetupStep) {
|
||||||
|
aapsLogger.info(LTag.PUMP, "curSetupStep: ${setupStep.value}, newSetupStep: $newSetupStep")
|
||||||
|
setupStep.postValue(newSetupStep)
|
||||||
|
}
|
||||||
|
}
|
50
pump/medtrum/src/main/res/layout/activity_medtrum.xml
Normal file
50
pump/medtrum/src/main/res/layout/activity_medtrum.xml
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?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>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".ui.MedtrumActivity">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/layout_toolbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="60dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
|
||||||
|
android:text="@{viewModel.title}"
|
||||||
|
android:textSize="18sp"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
|
tools:text="@string/string_change_patch" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<FrameLayout
|
||||||
|
android:id="@+id/framelayout_fragment"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginBottom="15dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</layout>
|
|
@ -3,9 +3,10 @@
|
||||||
xmlns:tools="http://schemas.android.com/tools">
|
xmlns:tools="http://schemas.android.com/tools">
|
||||||
|
|
||||||
<data>
|
<data>
|
||||||
|
|
||||||
<variable
|
<variable
|
||||||
name="viewmodel"
|
name="viewmodel"
|
||||||
type="info.nightscout.pump.medtrum.ui.viewmodel.MedtrumOverviewViewModel"/>
|
type="info.nightscout.pump.medtrum.ui.viewmodel.MedtrumOverviewViewModel" />
|
||||||
</data>
|
</data>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
|
@ -100,15 +101,16 @@
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:orientation="horizontal">
|
android:orientation="horizontal">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button1"
|
android:id="@+id/button1"
|
||||||
style="@style/ButtonMediumFontStyle"
|
style="@style/ButtonMediumFontStyle"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/string_new_patch"
|
|
||||||
android:enabled="@{!viewmodel.isPatchActivated}"
|
android:enabled="@{!viewmodel.isPatchActivated}"
|
||||||
app:onSafeClick="@{() -> viewmodel.onClickActivation()}"/>
|
android:text="@string/string_new_patch"
|
||||||
|
app:onSafeClick="@{() -> viewmodel.onClickActivation()}" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/button2"
|
android:id="@+id/button2"
|
||||||
|
@ -116,9 +118,9 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
android:text="@string/string_stop_patch"
|
|
||||||
android:enabled="@{viewmodel.isPatchActivated}"
|
android:enabled="@{viewmodel.isPatchActivated}"
|
||||||
app:onSafeClick="@{() -> viewmodel.onClickDeactivation()}"/>
|
android:text="@string/string_stop_patch"
|
||||||
|
app:onSafeClick="@{() -> viewmodel.onClickDeactivation()}" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
|
@ -0,0 +1,66 @@
|
||||||
|
<?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">
|
||||||
|
|
||||||
|
<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/string_start_prime"
|
||||||
|
android:text="@string/string_start_prime"
|
||||||
|
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>
|
33
pump/medtrum/src/main/res/layout/fragment_medtrum_prime.xml
Normal file
33
pump/medtrum/src/main/res/layout/fragment_medtrum_prime.xml
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<?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">
|
||||||
|
|
||||||
|
<!-- TODO some stuff here that we are waiting :) -->
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
</layout>
|
|
@ -11,10 +11,16 @@
|
||||||
|
|
||||||
<!-- overview fragment -->
|
<!-- overview fragment -->
|
||||||
<string name="medtrum_ble_status">BLE Status</string>
|
<string name="medtrum_ble_status">BLE Status</string>
|
||||||
|
|
||||||
<string name="snInput_title">SN</string>
|
|
||||||
<string name="snInput_summary">Serial number pump base</string>
|
|
||||||
<string name="string_new_patch">Start new patch</string>
|
<string name="string_new_patch">Start new patch</string>
|
||||||
<string name="string_stop_patch">Stop patch</string>
|
<string name="string_stop_patch">Stop patch</string>
|
||||||
|
|
||||||
|
<!-- wizard-->
|
||||||
|
<string name="string_change_patch">Discard/Change Patch</string> <!-- TODO check-->
|
||||||
|
<string name="string_start_prime">Start priming</string>
|
||||||
|
|
||||||
|
<!-- settings-->
|
||||||
|
<string name="snInput_title">SN</string>
|
||||||
|
<string name="snInput_summary">Serial number pump base</string>
|
||||||
|
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|
Loading…
Reference in a new issue