Add OmnipodDashPodStateManager

This commit is contained in:
Bart Sopers 2021-02-26 01:26:21 +01:00
parent bc8eefaffd
commit 41b2602d61
10 changed files with 263 additions and 15 deletions

View file

@ -1,10 +1,14 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.dagger
import dagger.Module
import dagger.Provides
import dagger.android.ContributesAndroidInjector
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.ActivityScope
import info.nightscout.androidaps.plugins.pump.omnipod.common.dagger.OmnipodWizardModule
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.BleManager
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManager
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManagerImpl
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.DashPodManagementActivity
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.OmnipodDashOverviewFragment
import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.activation.DashPodActivationWizardActivity
@ -31,6 +35,12 @@ abstract class OmnipodDashModule {
@ContributesAndroidInjector
abstract fun contributesOmnipodDashOverviewFragment(): OmnipodDashOverviewFragment
@ContributesAndroidInjector
abstract fun contributesBleManager(): BleManager
companion object {
@Provides
fun providesBleManager(bleManager: BleManager): OmnipodDashBleManager = bleManager
@Provides
fun providesPodStateManager(podStateManager: OmnipodDashPodStateManagerImpl): OmnipodDashPodStateManager = podStateManager
}
}

View file

@ -1,4 +1,3 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver;
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver
public interface OmnipodDashManager {
}
interface OmnipodDashManager

View file

@ -20,13 +20,13 @@ import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class BleManager @Inject constructor(private val context: Context, private val aapsLogger: AAPSLogger) : OmnipodDashCommunicationManager {
class BleManager @Inject constructor(private val context: Context, private val aapsLogger: AAPSLogger) : OmnipodDashBleManager {
private val bluetoothManager: BluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
@Throws(InterruptedException::class, ScanFailException::class, FailedToConnectException::class, CouldNotSendBleException::class, BleIOBusyException::class, TimeoutException::class, CouldNotConfirmWriteException::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class)
fun activateNewPod() {
override fun activateNewPod() {
aapsLogger.info(LTag.PUMPBTCOMM, "starting new pod activation")
val podScanner = PodScanner(aapsLogger, bluetoothAdapter)
val podAddress = podScanner.scanForPod(PodScanner.SCAN_FOR_SERVICE_UUID, PodScanner.POD_ID_NOT_ACTIVATED).scanResult.device.address

View file

@ -0,0 +1,7 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm
interface OmnipodDashBleManager {
// TODO should we keep this method?
fun activateNewPod()
}

View file

@ -1,3 +0,0 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm
interface OmnipodDashCommunicationManager

View file

@ -0,0 +1,18 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition
enum class ActivationProgress {
NOT_STARTED,
GOT_POD_VERSION,
SET_UNIQUE_ID,
PROGRAMMED_LOW_RESERVOIR_ALERTS,
REPROGRAMMED_LUMP_OF_COAL_ALERT,
PRIMING,
PRIME_COMPLETED,
PROGRAMMED_USER_SET_EXPIRATION_ALERT,
PHASE_1_COMPLETED,
PROGRAMMED_BASAL,
PROGRAMMED_CANCEL_LOC_ETC_ALERT,
INSERTING_CANNULA,
CANNULA_INSERTED,
COMPLETED
}

View file

@ -0,0 +1,5 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition
import java.io.Serializable
data class SoftwareVersion(private val major: Int, private val minor: Int, private val interim: Int) : Serializable

View file

@ -1,3 +1,51 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state
interface OmnipodDashPodStateManager
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BasalProgram
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.SoftwareVersion
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.AlarmStatusResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.DefaultStatusResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.SetUniqueIdResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.VersionResponse
import java.io.Serializable
interface OmnipodDashPodStateManager {
var activationProgress: ActivationProgress
var lastConnectionTime: Long
val messageSequenceNumber: Short
val activationTime: Long?
val uniqueId: Int?
val bluetoothAddress: String?
val bluetoothVersion: SoftwareVersion?
val firmwareVersion: SoftwareVersion?
val lotNumber: Int?
val podSequenceNumber: Int?
val pulseRate: Int?
val primePulseRate: Int?
val podLifeInHours: Int?
val firstPrimeBolusVolume: Int?
val secondPrimeBolusVolume: Int?
val pulsesDelivered: Int?
val pulsesRemaining: Int?
val podStatus: PodStatus?
val deliveryStatus: DeliveryStatus?
val tempBasal: TempBasal?
val tempBasalActive: Boolean
val basalProgram: BasalProgram?
fun increaseMessageSequenceNumber()
fun updateFromDefaultStatusResponse(response: DefaultStatusResponse)
fun updateFromVersionResponse(response: VersionResponse)
fun updateFromSetUniqueIdResponse(response: SetUniqueIdResponse)
fun updateFromAlarmStatusResponse(response: AlarmStatusResponse)
fun reset()
data class TempBasal(val startTime: Long, val rate: Double, val durationInMinutes: Int) : Serializable
}

View file

@ -0,0 +1,166 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state
import com.google.gson.Gson
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.omnipod.dash.R
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BasalProgram
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodStatus
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.SoftwareVersion
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.AlarmStatusResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.DefaultStatusResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.SetUniqueIdResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.VersionResponse
import info.nightscout.androidaps.utils.resources.ResourceHelper
import info.nightscout.androidaps.utils.sharedPreferences.SP
import java.io.Serializable
import javax.inject.Inject
import javax.inject.Singleton
@Singleton
class OmnipodDashPodStateManagerImpl @Inject constructor(
private val resourceHelper: ResourceHelper,
private val logger: AAPSLogger,
private val sharedPreferences: SP
) : OmnipodDashPodStateManager {
private var podState: PodState
init {
podState = load()
}
override var activationProgress: ActivationProgress
get() = podState.activationProgress
set(value) {
podState.activationProgress = value
store()
}
override var lastConnectionTime: Long
get() = podState.lastConnectionTime
set(value) {
podState.lastConnectionTime = value
store()
}
override val messageSequenceNumber: Short = podState.messageSequenceNumber
override val activationTime: Long? = podState.activationTime
override val uniqueId: Int? = podState.uniqueId
override val bluetoothAddress: String? = podState.bluetoothAddress
override val bluetoothVersion: SoftwareVersion? = podState.bluetoothVersion
override val firmwareVersion: SoftwareVersion? = podState.firmwareVersion
override val lotNumber: Int? = podState.lotNumber
override val podSequenceNumber: Int? = podState.podSequenceNumber
override val pulseRate: Int? = podState.pulseRate
override val primePulseRate: Int? = podState.primePulseRate
override val podLifeInHours: Int? = podState.podLifeInHours
override val firstPrimeBolusVolume: Int? = podState.firstPrimeBolusVolume
override val secondPrimeBolusVolume: Int? = podState.secondPrimeBolusVolume
override val pulsesDelivered: Int? = podState.pulsesDelivered
override val pulsesRemaining: Int? = podState.pulsesRemaining
override val podStatus: PodStatus? = podState.podStatus
override val deliveryStatus: DeliveryStatus? = podState.deliveryStatus
override val tempBasal: OmnipodDashPodStateManager.TempBasal? = podState.tempBasal
override val tempBasalActive: Boolean
get() = tempBasal != null && tempBasal.startTime + tempBasal.durationInMinutes * 60 * 1000 > System.currentTimeMillis()
override val basalProgram: BasalProgram? = podState.basalProgram
override fun increaseMessageSequenceNumber() {
podState.messageSequenceNumber = ((podState.messageSequenceNumber.toInt() + 1) and 0x0f).toShort()
store()
}
override fun updateFromDefaultStatusResponse(response: DefaultStatusResponse) {
TODO("Not yet implemented")
}
override fun updateFromVersionResponse(response: VersionResponse) {
TODO("Not yet implemented")
}
override fun updateFromSetUniqueIdResponse(response: SetUniqueIdResponse) {
response.getBleVersionInterim()
}
override fun updateFromAlarmStatusResponse(response: AlarmStatusResponse) {
TODO("Not yet implemented")
}
override fun reset() {
podState = PodState()
store()
}
private fun store() {
try {
val serialized = Gson().toJson(podState)
logger.debug(LTag.PUMP, "Storing Pod state: $serialized")
sharedPreferences.putString(R.string.key_omnipod_dash_pod_state, serialized)
} catch (ex: Exception) {
logger.error(LTag.PUMP, "Failed to store Pod state", ex)
}
}
private fun load(): PodState {
if (sharedPreferences.contains(R.string.key_omnipod_dash_pod_state)) {
try {
return Gson().fromJson(sharedPreferences.getString(R.string.key_omnipod_dash_pod_state, ""), PodState::class.java)
} catch (ex: Exception) {
logger.error(LTag.PUMP, "Failed to deserialize Pod state", ex)
}
}
logger.debug(LTag.PUMP, "Creating new Pod state")
return PodState()
}
class PodState : Serializable {
var activationProgress: ActivationProgress = ActivationProgress.NOT_STARTED
var lastConnectionTime: Long = 0
var messageSequenceNumber: Short = 0
var activationTime: Long? = null
var uniqueId: Int? = null
var bluetoothAddress: String? = null
var bluetoothVersion: SoftwareVersion? = null
var firmwareVersion: SoftwareVersion? = null
var lotNumber: Int? = null
var podSequenceNumber: Int? = null
var pulseRate: Int? = null
var primePulseRate: Int? = null
var podLifeInHours: Int? = null
var firstPrimeBolusVolume: Int? = null
var secondPrimeBolusVolume: Int? = null
var pulsesDelivered: Int? = null
var pulsesRemaining: Int? = null
var podStatus: PodStatus? = null
var deliveryStatus: DeliveryStatus? = null
var basalProgram: BasalProgram? = null
var tempBasal: OmnipodDashPodStateManager.TempBasal? = null
}
}

View file

@ -2,20 +2,18 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.wizard.activatio
import android.os.AsyncTask
import androidx.annotation.StringRes
import androidx.lifecycle.viewModelScope
import dagger.android.HasAndroidInjector
import info.nightscout.androidaps.data.PumpEnactResult
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action.InitializePodViewModel
import info.nightscout.androidaps.plugins.pump.omnipod.dash.R
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.BleManager
import kotlinx.coroutines.launch
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManager
import javax.inject.Inject
class DashInitializePodViewModel @Inject constructor(private val aapsLogger: AAPSLogger,
private val injector: HasAndroidInjector,
private val bleManager: BleManager) : InitializePodViewModel() {
private val bleManager: OmnipodDashBleManager) : InitializePodViewModel() {
override fun isPodInAlarm(): Boolean = false // TODO