From 842f196ae8d1a9f2fa25fcb17876ea945b9c773b Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sun, 18 Apr 2021 21:39:20 +0200 Subject: [PATCH 01/21] confirm/deny commands --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 65 ++++++++++------ .../dash/driver/OmnipodDashManagerImpl.kt | 6 ++ .../pump/omnipod/dash/driver/comm/Id.kt | 1 - .../pump/omnipod/dash/driver/comm/Ids.kt | 2 +- .../driver/comm/OmnipodDashBleManagerImpl.kt | 2 +- .../dash/driver/comm/packet/PayloadJoiner.kt | 2 +- .../dash/driver/comm/pair/LTKExchanger.kt | 22 +++--- .../dash/driver/comm/session/Session.kt | 1 - .../driver/comm/session/SessionEstablisher.kt | 1 - .../omnipod/dash/driver/event/PodEvent.kt | 4 + .../driver/pod/command/ProgramBasalCommand.kt | 2 +- .../dash/driver/pod/command/base/Command.kt | 1 + .../pod/command/base/HeaderEnabledCommand.kt | 2 +- .../pod/state/OmnipodDashPodStateManager.kt | 19 ++++- .../state/OmnipodDashPodStateManagerImpl.kt | 60 +++++++++++++-- .../pump/omnipod/dash/history/DashHistory.kt | 34 ++++++++- .../omnipod/dash/history/data/ResultStates.kt | 2 +- .../dash/history/database/HistoryRecordDao.kt | 4 + .../pod/response/DefaultStatusResponseTest.kt | 76 +++++++++---------- 19 files changed, 212 insertions(+), 94 deletions(-) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt index ca291751d2..e535549a0e 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt @@ -11,18 +11,23 @@ import info.nightscout.androidaps.plugins.common.ManufacturerType import info.nightscout.androidaps.plugins.general.actions.defs.CustomAction import info.nightscout.androidaps.plugins.general.actions.defs.CustomActionType import info.nightscout.androidaps.plugins.pump.common.defs.PumpType +import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.* import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager +import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory +import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord +import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusType import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.OmnipodDashOverviewFragment import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.mapProfileToBasalProgram import info.nightscout.androidaps.queue.commands.CustomCommand import info.nightscout.androidaps.utils.TimeChangeType import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP +import io.reactivex.Observable import io.reactivex.Single import io.reactivex.rxkotlin.blockingSubscribeBy import io.reactivex.rxkotlin.subscribeBy @@ -37,6 +42,7 @@ class OmnipodDashPumpPlugin @Inject constructor( private val podStateManager: OmnipodDashPodStateManager, private val sp: SP, private val profileFunction: ProfileFunction, + private val history: DashHistory, injector: HasAndroidInjector, aapsLogger: AAPSLogger, resourceHelper: ResourceHelper, @@ -147,7 +153,6 @@ class OmnipodDashPumpPlugin @Inject constructor( it == mapProfileToBasalProgram(profile) } ?: true - override fun lastDataTime(): Long { return podStateManager.lastConnection } @@ -172,7 +177,6 @@ class OmnipodDashPumpPlugin @Inject constructor( get() = 0 override fun deliverTreatment(detailedBolusInfo: DetailedBolusInfo): PumpEnactResult { - // TODO history // TODO update Treatments (?) // TODO bolus progress // TODO report actual delivered amount after Pod Alarm and bolus cancellation @@ -180,29 +184,44 @@ class OmnipodDashPumpPlugin @Inject constructor( return Single.create { source -> val bolusBeeps = sp.getBoolean(R.string.key_omnipod_common_bolus_beeps_enabled, false) - omnipodManager.bolus( - detailedBolusInfo.insulin, - bolusBeeps, - bolusBeeps - ).subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in deliverTreatment: $podEvent" - ) + Observable.concat( + history.createRecord( + commandType = OmnipodCommandType.SET_BOLUS, + bolusRecord = BolusRecord( + detailedBolusInfo.insulin, + if (detailedBolusInfo.isSMB) BolusType.SMB else BolusType.DEFAULT + ), + ).flatMapObservable { + recordId -> + podStateManager.createActiveCommand(recordId).toObservable() }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in deliverTreatment", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("deliverTreatment completed") - source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(detailedBolusInfo.insulin) - .carbsDelivered(detailedBolusInfo.carbs) - ) - } + omnipodManager.bolus( + detailedBolusInfo.insulin, + bolusBeeps, + bolusBeeps + ), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), ) + .subscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent in deliverTreatment: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error in deliverTreatment", throwable) + source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) + }, + onComplete = { + aapsLogger.debug("deliverTreatment completed") + source.onSuccess( + PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(detailedBolusInfo.insulin) + .carbsDelivered(detailedBolusInfo.carbs) + ) + } + ) }.blockingGet() } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManagerImpl.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManagerImpl.kt index 681ff8d43c..8fbb6ca64b 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManagerImpl.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManagerImpl.kt @@ -1,5 +1,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver +import android.os.SystemClock import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManager @@ -643,6 +644,11 @@ class OmnipodDashManagerImpl @Inject constructor( } is PodEvent.CommandSent -> { + podStateManager.activeCommand?.let { + if (it.sequence == event.command.sequenceNumber) { + it.sentRealtime = SystemClock.elapsedRealtime() + } + } podStateManager.increaseMessageSequenceNumber() } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt index cccb42a989..e330434faf 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Id.kt @@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm import info.nightscout.androidaps.utils.extensions.toHex import java.nio.ByteBuffer - data class Id(val address: ByteArray) { init { require(address.size == 4) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Ids.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Ids.kt index ac3e2e8406..e22ed866db 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Ids.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/Ids.kt @@ -17,4 +17,4 @@ class Ids(podState: OmnipodDashPodStateManager) { ) } } -} \ No newline at end of file +} diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt index 55bddace08..76cf563d81 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt @@ -83,7 +83,7 @@ class OmnipodDashBleManagerImpl @Inject constructor( val conn = assertConnected() return conn.session ?: throw NotConnectedException("Missing session") - } + } override fun getStatus(): ConnectionStatus { // TODO is this used? diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadJoiner.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadJoiner.kt index 17ef1a6000..766a19cf5e 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadJoiner.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/packet/PayloadJoiner.kt @@ -42,7 +42,7 @@ class PayloadJoiner(private val firstPacket: ByteArray) { oneExtraPacket = lastPacket.oneExtraPacket } - idx == fullFragments+1 && oneExtraPacket -> { + idx == fullFragments + 1 && oneExtraPacket -> { fragments.add(LastOptionalPlusOneBlePacket.parse(packet)) } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt index ef64c71ea7..549d8f034d 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/LTKExchanger.kt @@ -2,15 +2,12 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Ids import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.MessageIOException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.PairingException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageSendErrorSending import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageSendSuccess -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding.Companion.parseKeys import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.RandomByteGenerator import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.X25519KeyGenerator @@ -35,7 +32,7 @@ internal class LTKExchanger( keys = arrayOf(SP1, SP2), payloads = arrayOf(ids.podId.address, sp2()) ) - throwOnSendError(sp1sp2.messagePacket, SP1+SP2) + throwOnSendError(sp1sp2.messagePacket, SP1 + SP2) seq++ val sps1 = PairMessage( @@ -67,16 +64,16 @@ internal class LTKExchanger( seq++ // send SP0GP0 - val sp0gp0 = PairMessage ( - sequenceNumber = seq, - source = ids.myId, - destination = podAddress, - keys = arrayOf(SP0GP0), - payloads = arrayOf(ByteArray(0)) - ) + val sp0gp0 = PairMessage( + sequenceNumber = seq, + source = ids.myId, + destination = podAddress, + keys = arrayOf(SP0GP0), + payloads = arrayOf(ByteArray(0)) + ) val result = msgIO.sendMessage(sp0gp0.messagePacket) if (result !is MessageSendSuccess) { - aapsLogger.warn(LTag.PUMPBTCOMM,"Error sending SP0GP0: $result") + aapsLogger.warn(LTag.PUMPBTCOMM, "Error sending SP0GP0: $result") } msgIO.receiveMessage() @@ -97,7 +94,6 @@ internal class LTKExchanger( } } - private fun processSps1FromPod(msg: MessagePacket) { aapsLogger.debug(LTag.PUMPBTCOMM, "Received SPS1 from pod: ${msg.payload.toHex()}") diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt index abf138e673..a549b2fe3d 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt @@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Ids import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt.EnDecrypt import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotParseResponseException diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt index 355cab8daf..deb430d65d 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/SessionEstablisher.kt @@ -2,7 +2,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Ids import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt.Nonce import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.SessionEstablishmentException diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/event/PodEvent.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/event/PodEvent.kt index 08d33a43fe..dfee0dfcb5 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/event/PodEvent.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/event/PodEvent.kt @@ -65,4 +65,8 @@ sealed class PodEvent { return "ResponseReceived(command=$command, response=$response)" } } + + data class CommandConfirmed(val historyId: String) : PodEvent() + + data class CommandDenied(val historyId: String) : PodEvent() } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.kt index f717659dbb..f8a15f7178 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/ProgramBasalCommand.kt @@ -31,7 +31,7 @@ class ProgramBasalCommand private constructor( private val delayUntilNextTenthPulseInUsec: Int val length: Short get() = (insulinProgramElements.size * 6 + 10).toShort() - val bodyLength: Byte + private val bodyLength: Byte get() = (insulinProgramElements.size * 6 + 8).toByte() override val encoded: ByteArray diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/Command.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/Command.kt index 0b509a8ae1..11f0836ab8 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/Command.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/Command.kt @@ -6,4 +6,5 @@ import java.io.Serializable interface Command : Encodable, Serializable { val commandType: CommandType + val sequenceNumber: Short } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/HeaderEnabledCommand.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/HeaderEnabledCommand.kt index a4507b9d1a..c921424883 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/HeaderEnabledCommand.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/command/base/HeaderEnabledCommand.kt @@ -6,7 +6,7 @@ import java.nio.ByteBuffer abstract class HeaderEnabledCommand protected constructor( override val commandType: CommandType, protected val uniqueId: Int, - protected val sequenceNumber: Short, + override val sequenceNumber: Short, protected val multiCommandFlag: Boolean ) : Command { diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt index 6f2a66300d..67bcac8209 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt @@ -2,11 +2,14 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair.PairResult +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.* 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 io.reactivex.Completable +import io.reactivex.Maybe import java.io.Serializable import java.util.* @@ -18,7 +21,10 @@ interface OmnipodDashPodStateManager { val isSuspended: Boolean val isPodRunning: Boolean var lastConnection: Long - val lastUpdated: Long + + val lastUpdatedSystem: Long // System.currentTimeMillis() + // TODO: set lastUpdatedRealtime to 0 on boot + val lastStatusResponseReceived: Long val messageSequenceNumber: Short val sequenceNumberOfLastProgrammingCommand: Short? @@ -48,6 +54,7 @@ interface OmnipodDashPodStateManager { val tempBasal: TempBasal? val tempBasalActive: Boolean var basalProgram: BasalProgram? + val activeCommand: ActiveCommand? fun increaseMessageSequenceNumber() fun increaseEapAkaSequenceNumber(): ByteArray @@ -59,5 +66,15 @@ interface OmnipodDashPodStateManager { fun updateFromPairing(uniqueId: Id, pairResult: PairResult) fun reset() + fun createActiveCommand(historyId: String): Completable + fun updateActiveCommand(): Maybe + + data class ActiveCommand( + val sequence: Short, + val createdRealtime: Long, + var sentRealtime: Long = 0, + val historyId: String + ) + // TODO: set created to "now" on boot data class TempBasal(val startTime: Long, val rate: Double, val durationInMinutes: Short) : Serializable } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt index 8fcd23b213..bc9c433f83 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt @@ -1,5 +1,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state +import android.os.SystemClock import com.google.gson.Gson import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag @@ -9,12 +10,15 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.R import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair.PairResult import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.EapSqn +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.* 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.sharedPreferences.SP +import io.reactivex.Completable +import io.reactivex.Maybe import java.io.Serializable import java.util.* import javax.inject.Inject @@ -60,8 +64,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( store() } - override val lastUpdated: Long - get() = podState.lastUpdated + override val lastUpdatedSystem: Long + get() = podState.lastUpdatedSystem override val messageSequenceNumber: Short get() = podState.messageSequenceNumber @@ -152,6 +156,9 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( store() } + override val lastStatusResponseReceived: Long + get() = podState.lastStatusResponseReceived + override fun increaseMessageSequenceNumber() { podState.messageSequenceNumber = ((podState.messageSequenceNumber.toInt() + 1) and 0x0f).toShort() store() @@ -171,6 +178,41 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( store() } + override val activeCommand: OmnipodDashPodStateManager.ActiveCommand? + get() = podState.activeCommand + + @Synchronized + override fun createActiveCommand(historyId: String): Completable { + return if (activeCommand == null) { + podState.activeCommand = OmnipodDashPodStateManager.ActiveCommand( + podState.messageSequenceNumber, + createdRealtime = SystemClock.elapsedRealtime(), + historyId = historyId + ) + Completable.complete() + } else { + Completable.error( + java.lang.IllegalStateException( + "Trying to send a command " + + "and the last command was not confirmed" + ) + ) + } + } + + @Synchronized + override fun updateActiveCommand(): Maybe { + return podState.activeCommand?.run { + if (createdRealtime >= lastStatusResponseReceived) + Maybe.empty() + else if (sequenceNumberOfLastProgrammingCommand == sequence) + Maybe.just(PodEvent.CommandConfirmed(historyId)) + else + Maybe.just(PodEvent.CommandDenied(historyId)) + } + ?: Maybe.empty() // no active programming command + } + override fun increaseEapAkaSequenceNumber(): ByteArray { podState.eapAkaSequenceNumber++ return EapSqn(podState.eapAkaSequenceNumber).value @@ -191,7 +233,9 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( podState.minutesSinceActivation = response.minutesSinceActivation podState.activeAlerts = response.activeAlerts - podState.lastUpdated = System.currentTimeMillis() + podState.lastUpdatedSystem = System.currentTimeMillis() + podState.lastStatusResponseReceived = SystemClock.elapsedRealtime() + store() rxBus.send(EventOmnipodDashPumpValuesChanged()) } @@ -211,7 +255,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( podState.lotNumber = response.lotNumber podState.podSequenceNumber = response.podSequenceNumber - podState.lastUpdated = System.currentTimeMillis() + podState.lastUpdatedSystem = System.currentTimeMillis() + store() rxBus.send(EventOmnipodDashPumpValuesChanged()) } @@ -237,7 +282,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( podState.podSequenceNumber = response.podSequenceNumber podState.uniqueId = response.uniqueIdReceivedInCommand - podState.lastUpdated = System.currentTimeMillis() + podState.lastUpdatedSystem = System.currentTimeMillis() + store() rxBus.send(EventOmnipodDashPumpValuesChanged()) } @@ -293,7 +339,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( var activationProgress: ActivationProgress = ActivationProgress.NOT_STARTED var lastConnection: Long = 0 - var lastUpdated: Long = 0 + var lastUpdatedSystem: Long = 0 + var lastStatusResponseReceived: Long = 0 var messageSequenceNumber: Short = 0 var sequenceNumberOfLastProgrammingCommand: Short? = null @@ -322,5 +369,6 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( var basalProgram: BasalProgram? = null var tempBasal: OmnipodDashPodStateManager.TempBasal? = null + var activeCommand: OmnipodDashPodStateManager.ActiveCommand? = null } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt index f2af4c972c..a7161169e6 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/DashHistory.kt @@ -4,6 +4,7 @@ import com.github.guepardoapps.kulid.ULID import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType.SET_BOLUS import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType.SET_TEMPORARY_BASAL +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.HistoryRecord import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.InitialResult @@ -22,13 +23,13 @@ class DashHistory @Inject constructor( private val historyMapper: HistoryMapper ) { - fun markSuccess(id: String, date: Long): Completable = dao.markResolved( + private fun markSuccess(id: String): Completable = dao.markResolved( id, ResolvedResult.SUCCESS, currentTimeMillis() ) - fun markFailure(id: String, date: Long): Completable = dao.markResolved( + private fun markFailure(id: String): Completable = dao.markResolved( id, ResolvedResult.FAILURE, currentTimeMillis() @@ -37,8 +38,8 @@ class DashHistory @Inject constructor( @Suppress("ReturnCount") fun createRecord( commandType: OmnipodCommandType, - date: Long, - initialResult: InitialResult = InitialResult.UNCONFIRMED, + date: Long = System.currentTimeMillis(), + initialResult: InitialResult = InitialResult.CREATED, tempBasalRecord: TempBasalRecord? = null, bolusRecord: BolusRecord? = null, resolveResult: ResolvedResult? = null, @@ -72,4 +73,29 @@ class DashHistory @Inject constructor( dao.all().map { list -> list.map(historyMapper::entityToDomain) } fun getRecordsAfter(time: Long): Single> = dao.allSince(time) + + fun updateFromState(podState: OmnipodDashPodStateManager): Completable { + return podState.activeCommand?.run { + when { + + createdRealtime <= podState.lastStatusResponseReceived && + sequence == podState.sequenceNumberOfLastProgrammingCommand -> + dao.setInitialResult(historyId, InitialResult.SENT) + .andThen(markSuccess(historyId)) + + createdRealtime <= podState.lastStatusResponseReceived && + sequence != podState.sequenceNumberOfLastProgrammingCommand -> + markFailure(historyId) + + // no response received after this point + createdRealtime <= sentRealtime -> + dao.setInitialResult(historyId, InitialResult.SENT) + + createdRealtime > sentRealtime -> + dao.setInitialResult(historyId, InitialResult.FAILURE_SENDING) + + else -> Completable.error(IllegalStateException("This can't happen. Could not update history")) + } + } ?: Completable.complete() // no active programming command + } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt index 8f0c353763..c7b134c5fb 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/ResultStates.kt @@ -1,7 +1,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data enum class InitialResult { - SUCCESS, FAILURE, UNCONFIRMED + CREATED, FAILURE_SENDING, UNCONFIRMED, SENT } enum class ResolvedResult { diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt index 93b292c067..21ff7dbced 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/database/HistoryRecordDao.kt @@ -5,6 +5,7 @@ import androidx.room.Delete import androidx.room.Insert import androidx.room.OnConflictStrategy import androidx.room.Query +import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.InitialResult import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.ResolvedResult import io.reactivex.Completable import io.reactivex.Single @@ -32,4 +33,7 @@ abstract class HistoryRecordDao { @Query("UPDATE historyrecords SET resolvedResult = :resolvedResult, resolvedAt = :resolvedAt WHERE id = :id ") abstract fun markResolved(id: String, resolvedResult: ResolvedResult, resolvedAt: Long): Completable + + @Query("UPDATE historyrecords SET initialResult = :initialResult WHERE id = :id ") + abstract fun setInitialResult(id: String, initialResult: InitialResult): Completable } diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponseTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponseTest.kt index 9de6513fd4..bcce591db4 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponseTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/response/DefaultStatusResponseTest.kt @@ -28,25 +28,25 @@ class DefaultStatusResponseTest { /** * response (hex) 08202EAA0C0A1D1905281000004387D3039A - Status response: 29 - Pod status: RUNNING_BELOW_MIN_VOLUME - Basal active: true - Temp Basal active: false - Immediate bolus active: false - Extended bolus active: false - Bolus pulses remaining: 0 - sequence number of last programing command: 2 - Total full pulses delivered: 2640 - Full reservoir pulses remaining: 979 - Time since activation: 4321 - Alert 1 is InActive - Alert 2 is InActive - Alert 3 is InActive - Alert 4 is InActive - Alert 5 is InActive - Alert 6 is InActive - Alert 7 is InActive - Occlusion alert active false + Status response: 29 + Pod status: RUNNING_BELOW_MIN_VOLUME + Basal active: true + Temp Basal active: false + Immediate bolus active: false + Extended bolus active: false + Bolus pulses remaining: 0 + sequence number of last programing command: 2 + Total full pulses delivered: 2640 + Full reservoir pulses remaining: 979 + Time since activation: 4321 + Alert 1 is InActive + Alert 2 is InActive + Alert 3 is InActive + Alert 4 is InActive + Alert 5 is InActive + Alert 6 is InActive + Alert 7 is InActive + Occlusion alert active false */ @Test @Throws(DecoderException::class) fun testValidResponseBelowMin() { val encoded = Hex.decodeHex("1D1905281000004387D3039A") @@ -67,25 +67,25 @@ class DefaultStatusResponseTest { /** * response (hex) 08202EAA080A1D180519C00E0039A7FF8085 - Status response: 29 - Pod status: RUNNING_ABOVE_MIN_VOLUME - Basal active: true - Temp Basal active: false - Immediate bolus active: false - Extended bolus active: false - Bolus pulses remaining: 14 - sequence number of last programing command: 8 - Total full pulses delivered: 2611 - Full reservoir pulses remaining: 1023 - Time since activation: 3689 - Alert 1 is InActive - Alert 2 is InActive - Alert 3 is InActive - Alert 4 is InActive - Alert 5 is InActive - Alert 6 is InActive - Alert 7 is InActive - Occlusion alert active false + Status response: 29 + Pod status: RUNNING_ABOVE_MIN_VOLUME + Basal active: true + Temp Basal active: false + Immediate bolus active: false + Extended bolus active: false + Bolus pulses remaining: 14 + sequence number of last programing command: 8 + Total full pulses delivered: 2611 + Full reservoir pulses remaining: 1023 + Time since activation: 3689 + Alert 1 is InActive + Alert 2 is InActive + Alert 3 is InActive + Alert 4 is InActive + Alert 5 is InActive + Alert 6 is InActive + Alert 7 is InActive + Occlusion alert active false */ @Test @Throws(DecoderException::class) fun testValidResponseBolusPulsesRemaining() { val encoded = Hex.decodeHex("1D180519C00E0039A7FF8085") From 142ad126b551c78c9b33706ea58498eac1b3b147 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sun, 18 Apr 2021 21:54:50 +0200 Subject: [PATCH 02/21] add history, command confirmation for more commands --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 83 ++++++++++++------- .../pump/omnipod/dash/history/data/Record.kt | 2 +- 2 files changed, 55 insertions(+), 30 deletions(-) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt index e535549a0e..e7f2be82ad 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt @@ -21,6 +21,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.Omn import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusType +import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.TempBasalRecord import info.nightscout.androidaps.plugins.pump.omnipod.dash.ui.OmnipodDashOverviewFragment import info.nightscout.androidaps.plugins.pump.omnipod.dash.util.mapProfileToBasalProgram import info.nightscout.androidaps.queue.commands.CustomCommand @@ -191,8 +192,7 @@ class OmnipodDashPumpPlugin @Inject constructor( detailedBolusInfo.insulin, if (detailedBolusInfo.isSMB) BolusType.SMB else BolusType.DEFAULT ), - ).flatMapObservable { - recordId -> + ).flatMapObservable { recordId -> podStateManager.createActiveCommand(recordId).toObservable() }, omnipodManager.bolus( @@ -202,34 +202,41 @@ class OmnipodDashPumpPlugin @Inject constructor( ), history.updateFromState(podStateManager).toObservable(), podStateManager.updateActiveCommand().toObservable(), + ).subscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent in deliverTreatment: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error in deliverTreatment", throwable) + source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) + }, + onComplete = { + aapsLogger.debug("deliverTreatment completed") + source.onSuccess( + PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(detailedBolusInfo.insulin) + .carbsDelivered(detailedBolusInfo.carbs) + ) + } ) - .subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in deliverTreatment: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in deliverTreatment", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("deliverTreatment completed") - source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(detailedBolusInfo.insulin) - .carbsDelivered(detailedBolusInfo.carbs) - ) - } - ) }.blockingGet() } override fun stopBolusDelivering() { - // TODO history // TODO update Treatments (?) - omnipodManager.stopBolus().blockingSubscribeBy( + Observable.concat( + history.createRecord( + commandType = OmnipodCommandType.CANCEL_BOLUS, + ).flatMapObservable { recordId -> + podStateManager.createActiveCommand(recordId).toObservable() + }, + omnipodManager.stopBolus(), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).blockingSubscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, @@ -251,13 +258,22 @@ class OmnipodDashPumpPlugin @Inject constructor( profile: Profile, enforceNew: Boolean ): PumpEnactResult { - // TODO history // TODO update Treatments return Single.create { source -> - omnipodManager.setTempBasal( - absoluteRate, - durationInMinutes.toShort() + Observable.concat( + history.createRecord( + commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, + tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) + ).flatMapObservable { recordId -> + podStateManager.createActiveCommand(recordId).toObservable() + }, + omnipodManager.setTempBasal( + absoluteRate, + durationInMinutes.toShort() + ), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), ).subscribeBy( onNext = { podEvent -> aapsLogger.debug( @@ -298,11 +314,20 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult { - // TODO history // TODO update Treatments return Single.create { source -> - omnipodManager.stopTempBasal().subscribeBy( + + Observable.concat( + history.createRecord( + commandType = OmnipodCommandType.CANCEL_TEMPORARY_BASAL + ).flatMapObservable { recordId -> + podStateManager.createActiveCommand(recordId).toObservable() + }, + omnipodManager.stopTempBasal(), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).subscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt index a4f636c497..c0316e99ad 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/Record.kt @@ -4,7 +4,7 @@ sealed class Record data class BolusRecord(val amout: Double, val bolusType: BolusType) : Record() -data class TempBasalRecord(val duration: Long, val rate: Double) : Record() +data class TempBasalRecord(val duration: Int, val rate: Double) : Record() enum class BolusType { DEFAULT, SMB From 05047029ea03658df15afa11e0e44273e629f8b7 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Mon, 19 Apr 2021 21:46:50 +0200 Subject: [PATCH 03/21] remove duplication --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 281 ++++++------------ 1 file changed, 97 insertions(+), 184 deletions(-) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt index e7f2be82ad..d3b50f1986 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt @@ -14,6 +14,7 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.* import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType @@ -110,8 +111,11 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun getPumpStatus(reason: String) { - // TODO history - omnipodManager.getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE).blockingSubscribeBy( + Observable.concat( + omnipodManager.getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).blockingSubscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, @@ -128,26 +132,12 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun setNewBasalProfile(profile: Profile): PumpEnactResult { - // TODO history - - return Single.create { source -> - omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)).subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in setNewBasalProfile: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in setNewBasalProfile", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("setNewBasalProfile completed") - source.onSuccess(PumpEnactResult(injector).success(true).enacted(true)) - } - ) - }.blockingGet() + return executeProgrammingCommand( + history.createRecord( + commandType = OmnipodCommandType.SET_BASAL_PROFILE + ), + omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)) + ) } override fun isThisProfileSet(profile: Profile): Boolean = podStateManager.basalProgram?.let { @@ -155,7 +145,7 @@ class OmnipodDashPumpPlugin @Inject constructor( } ?: true override fun lastDataTime(): Long { - return podStateManager.lastConnection + return podStateManager.lastUpdatedSystem } override val baseBasalRate: Double @@ -211,12 +201,15 @@ class OmnipodDashPumpPlugin @Inject constructor( }, onError = { throwable -> aapsLogger.error(LTag.PUMP, "Error in deliverTreatment", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) + source.onSuccess( + PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message) + ) }, onComplete = { aapsLogger.debug("deliverTreatment completed") source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(detailedBolusInfo.insulin) + PumpEnactResult(injector).success(true).enacted(true) + .bolusDelivered(detailedBolusInfo.insulin) .carbsDelivered(detailedBolusInfo.carbs) ) } @@ -226,29 +219,9 @@ class OmnipodDashPumpPlugin @Inject constructor( override fun stopBolusDelivering() { // TODO update Treatments (?) - - Observable.concat( - history.createRecord( - commandType = OmnipodCommandType.CANCEL_BOLUS, - ).flatMapObservable { recordId -> - podStateManager.createActiveCommand(recordId).toObservable() - }, + executeProgrammingCommand( + history.createRecord(OmnipodCommandType.CANCEL_BOLUS), omnipodManager.stopBolus(), - history.updateFromState(podStateManager).toObservable(), - podStateManager.updateActiveCommand().toObservable(), - ).blockingSubscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in stopBolusDelivering: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in stopBolusDelivering", throwable) - }, - onComplete = { - aapsLogger.debug("stopBolusDelivering completed") - } ) } @@ -259,41 +232,17 @@ class OmnipodDashPumpPlugin @Inject constructor( enforceNew: Boolean ): PumpEnactResult { // TODO update Treatments - - return Single.create { source -> - Observable.concat( - history.createRecord( - commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, - tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) - ).flatMapObservable { recordId -> - podStateManager.createActiveCommand(recordId).toObservable() - }, - omnipodManager.setTempBasal( - absoluteRate, - durationInMinutes.toShort() - ), - history.updateFromState(podStateManager).toObservable(), - podStateManager.updateActiveCommand().toObservable(), - ).subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in setTempBasalAbsolute: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in setTempBasalAbsolute", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("setTempBasalAbsolute completed") - source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true).absolute(absoluteRate) - .duration(durationInMinutes) - ) - } + // TODO check for existing basal + return executeProgrammingCommand( + history.createRecord( + commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, + tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) + ), + omnipodManager.setTempBasal( + absoluteRate, + durationInMinutes.toShort() ) - }.blockingGet() + ) } override fun setTempBasalPercent( @@ -315,37 +264,10 @@ class OmnipodDashPumpPlugin @Inject constructor( override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult { // TODO update Treatments - - return Single.create { source -> - - Observable.concat( - history.createRecord( - commandType = OmnipodCommandType.CANCEL_TEMPORARY_BASAL - ).flatMapObservable { recordId -> - podStateManager.createActiveCommand(recordId).toObservable() - }, - omnipodManager.stopTempBasal(), - history.updateFromState(podStateManager).toObservable(), - podStateManager.updateActiveCommand().toObservable(), - ).subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in cancelTempBasal: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in cancelTempBasal", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("cancelTempBasal completed") - source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true) - ) - } - ) - }.blockingGet() + return executeProgrammingCommand( + history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), + omnipodManager.stopTempBasal() + ) } override fun cancelExtendedBolus(): PumpEnactResult { @@ -370,11 +292,8 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun serialNumber(): String { - return if (podStateManager.uniqueId == null) { - "n/a" // TODO i18n - } else { - podStateManager.uniqueId.toString() - } + return podStateManager.uniqueId?.toString() + ?: "n/a" // TODO i18n } override fun shortStatus(veryShort: Boolean): String { @@ -433,12 +352,15 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun silenceAlerts(): PumpEnactResult { - // TODO history // TODO filter alert types - return podStateManager.activeAlerts?.let { Single.create { source -> - omnipodManager.silenceAlerts(it).subscribeBy( + Observable.concat( + // TODO: is this a programming command? if yes, save to history + omnipodManager.silenceAlerts(it), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).subscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, @@ -459,75 +381,26 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun suspendDelivery(): PumpEnactResult { - // TODO history - - return Single.create { source -> - omnipodManager.suspendDelivery().subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in suspendDelivery: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in suspendDelivery", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("suspendDelivery completed") - source.onSuccess(PumpEnactResult(injector).success(true)) - } - ) - }.blockingGet() + return executeProgrammingCommand( + history.createRecord(OmnipodCommandType.RESUME_DELIVERY), + omnipodManager.suspendDelivery() + ) } private fun resumeDelivery(): PumpEnactResult { - // TODO history - return profileFunction.getProfile()?.let { - - Single.create { source -> - omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in resumeDelivery: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in resumeDelivery", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("resumeDelivery completed") - source.onSuccess(PumpEnactResult(injector).success(true)) - } - ) - }.blockingGet() + executeProgrammingCommand( + history.createRecord(OmnipodCommandType.RESUME_DELIVERY), + omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)) + ) } ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n } private fun deactivatePod(): PumpEnactResult { - // TODO history - - return Single.create { source -> - omnipodManager.deactivatePod().subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in deactivatePod: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in deactivatePod", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("deactivatePod completed") - source.onSuccess(PumpEnactResult(injector).success(true)) - } - ) - }.blockingGet() + return executeProgrammingCommand( + history.createRecord(OmnipodCommandType.DEACTIVATE_POD), + omnipodManager.deactivatePod() + ) } private fun handleTimeChange(): PumpEnactResult { @@ -541,10 +414,13 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun playTestBeep(): PumpEnactResult { - // TODO history return Single.create { source -> - omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).subscribeBy( + Observable.concat( + omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).subscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, @@ -553,7 +429,9 @@ class OmnipodDashPumpPlugin @Inject constructor( }, onError = { throwable -> aapsLogger.error(LTag.PUMP, "Error in playTestBeep", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) + source.onSuccess( + PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message) + ) }, onComplete = { aapsLogger.debug("playTestBeep completed") @@ -585,4 +463,39 @@ class OmnipodDashPumpPlugin @Inject constructor( commandQueue.customCommand(CommandHandleTimeChange(false), null) } + + private fun executeProgrammingCommand( + historyEntry: Single, + command: Observable + ): PumpEnactResult { + return Single.create { source -> + Observable.concat( + historyEntry.flatMapObservable { recordId -> + podStateManager.createActiveCommand(recordId).toObservable() + }, + command, + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).subscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error executing command", throwable) + source.onSuccess( + PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message) + ) + }, + onComplete = { + aapsLogger.debug("Command completed") + source.onSuccess( + PumpEnactResult(injector).success(true).enacted(true) + ) + } + ) + }.blockingGet() + } } From d49b87d124b301ce426f20b44be0fdc73516c2a6 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Mon, 19 Apr 2021 21:55:45 +0200 Subject: [PATCH 04/21] Revert "remove duplication" This reverts commit 05047029ea03658df15afa11e0e44273e629f8b7. --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 281 ++++++++++++------ 1 file changed, 184 insertions(+), 97 deletions(-) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt index d3b50f1986..e7f2be82ad 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt @@ -14,7 +14,6 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.* import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType @@ -111,11 +110,8 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun getPumpStatus(reason: String) { - Observable.concat( - omnipodManager.getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE), - history.updateFromState(podStateManager).toObservable(), - podStateManager.updateActiveCommand().toObservable(), - ).blockingSubscribeBy( + // TODO history + omnipodManager.getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE).blockingSubscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, @@ -132,12 +128,26 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun setNewBasalProfile(profile: Profile): PumpEnactResult { - return executeProgrammingCommand( - history.createRecord( - commandType = OmnipodCommandType.SET_BASAL_PROFILE - ), - omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)) - ) + // TODO history + + return Single.create { source -> + omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)).subscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent in setNewBasalProfile: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error in setNewBasalProfile", throwable) + source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) + }, + onComplete = { + aapsLogger.debug("setNewBasalProfile completed") + source.onSuccess(PumpEnactResult(injector).success(true).enacted(true)) + } + ) + }.blockingGet() } override fun isThisProfileSet(profile: Profile): Boolean = podStateManager.basalProgram?.let { @@ -145,7 +155,7 @@ class OmnipodDashPumpPlugin @Inject constructor( } ?: true override fun lastDataTime(): Long { - return podStateManager.lastUpdatedSystem + return podStateManager.lastConnection } override val baseBasalRate: Double @@ -201,15 +211,12 @@ class OmnipodDashPumpPlugin @Inject constructor( }, onError = { throwable -> aapsLogger.error(LTag.PUMP, "Error in deliverTreatment", throwable) - source.onSuccess( - PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message) - ) + source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) }, onComplete = { aapsLogger.debug("deliverTreatment completed") source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true) - .bolusDelivered(detailedBolusInfo.insulin) + PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(detailedBolusInfo.insulin) .carbsDelivered(detailedBolusInfo.carbs) ) } @@ -219,9 +226,29 @@ class OmnipodDashPumpPlugin @Inject constructor( override fun stopBolusDelivering() { // TODO update Treatments (?) - executeProgrammingCommand( - history.createRecord(OmnipodCommandType.CANCEL_BOLUS), + + Observable.concat( + history.createRecord( + commandType = OmnipodCommandType.CANCEL_BOLUS, + ).flatMapObservable { recordId -> + podStateManager.createActiveCommand(recordId).toObservable() + }, omnipodManager.stopBolus(), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).blockingSubscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent in stopBolusDelivering: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error in stopBolusDelivering", throwable) + }, + onComplete = { + aapsLogger.debug("stopBolusDelivering completed") + } ) } @@ -232,17 +259,41 @@ class OmnipodDashPumpPlugin @Inject constructor( enforceNew: Boolean ): PumpEnactResult { // TODO update Treatments - // TODO check for existing basal - return executeProgrammingCommand( - history.createRecord( - commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, - tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) - ), - omnipodManager.setTempBasal( - absoluteRate, - durationInMinutes.toShort() + + return Single.create { source -> + Observable.concat( + history.createRecord( + commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, + tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) + ).flatMapObservable { recordId -> + podStateManager.createActiveCommand(recordId).toObservable() + }, + omnipodManager.setTempBasal( + absoluteRate, + durationInMinutes.toShort() + ), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).subscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent in setTempBasalAbsolute: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error in setTempBasalAbsolute", throwable) + source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) + }, + onComplete = { + aapsLogger.debug("setTempBasalAbsolute completed") + source.onSuccess( + PumpEnactResult(injector).success(true).enacted(true).absolute(absoluteRate) + .duration(durationInMinutes) + ) + } ) - ) + }.blockingGet() } override fun setTempBasalPercent( @@ -264,10 +315,37 @@ class OmnipodDashPumpPlugin @Inject constructor( override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult { // TODO update Treatments - return executeProgrammingCommand( - history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), - omnipodManager.stopTempBasal() - ) + + return Single.create { source -> + + Observable.concat( + history.createRecord( + commandType = OmnipodCommandType.CANCEL_TEMPORARY_BASAL + ).flatMapObservable { recordId -> + podStateManager.createActiveCommand(recordId).toObservable() + }, + omnipodManager.stopTempBasal(), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).subscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent in cancelTempBasal: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error in cancelTempBasal", throwable) + source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) + }, + onComplete = { + aapsLogger.debug("cancelTempBasal completed") + source.onSuccess( + PumpEnactResult(injector).success(true).enacted(true) + ) + } + ) + }.blockingGet() } override fun cancelExtendedBolus(): PumpEnactResult { @@ -292,8 +370,11 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun serialNumber(): String { - return podStateManager.uniqueId?.toString() - ?: "n/a" // TODO i18n + return if (podStateManager.uniqueId == null) { + "n/a" // TODO i18n + } else { + podStateManager.uniqueId.toString() + } } override fun shortStatus(veryShort: Boolean): String { @@ -352,15 +433,12 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun silenceAlerts(): PumpEnactResult { + // TODO history // TODO filter alert types + return podStateManager.activeAlerts?.let { Single.create { source -> - Observable.concat( - // TODO: is this a programming command? if yes, save to history - omnipodManager.silenceAlerts(it), - history.updateFromState(podStateManager).toObservable(), - podStateManager.updateActiveCommand().toObservable(), - ).subscribeBy( + omnipodManager.silenceAlerts(it).subscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, @@ -381,26 +459,75 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun suspendDelivery(): PumpEnactResult { - return executeProgrammingCommand( - history.createRecord(OmnipodCommandType.RESUME_DELIVERY), - omnipodManager.suspendDelivery() - ) + // TODO history + + return Single.create { source -> + omnipodManager.suspendDelivery().subscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent in suspendDelivery: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error in suspendDelivery", throwable) + source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message)) + }, + onComplete = { + aapsLogger.debug("suspendDelivery completed") + source.onSuccess(PumpEnactResult(injector).success(true)) + } + ) + }.blockingGet() } private fun resumeDelivery(): PumpEnactResult { + // TODO history + return profileFunction.getProfile()?.let { - executeProgrammingCommand( - history.createRecord(OmnipodCommandType.RESUME_DELIVERY), - omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)) - ) + + Single.create { source -> + omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).subscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent in resumeDelivery: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error in resumeDelivery", throwable) + source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message)) + }, + onComplete = { + aapsLogger.debug("resumeDelivery completed") + source.onSuccess(PumpEnactResult(injector).success(true)) + } + ) + }.blockingGet() } ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n } private fun deactivatePod(): PumpEnactResult { - return executeProgrammingCommand( - history.createRecord(OmnipodCommandType.DEACTIVATE_POD), - omnipodManager.deactivatePod() - ) + // TODO history + + return Single.create { source -> + omnipodManager.deactivatePod().subscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent in deactivatePod: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error in deactivatePod", throwable) + source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message)) + }, + onComplete = { + aapsLogger.debug("deactivatePod completed") + source.onSuccess(PumpEnactResult(injector).success(true)) + } + ) + }.blockingGet() } private fun handleTimeChange(): PumpEnactResult { @@ -414,13 +541,10 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun playTestBeep(): PumpEnactResult { + // TODO history return Single.create { source -> - Observable.concat( - omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP), - history.updateFromState(podStateManager).toObservable(), - podStateManager.updateActiveCommand().toObservable(), - ).subscribeBy( + omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).subscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, @@ -429,9 +553,7 @@ class OmnipodDashPumpPlugin @Inject constructor( }, onError = { throwable -> aapsLogger.error(LTag.PUMP, "Error in playTestBeep", throwable) - source.onSuccess( - PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message) - ) + source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) }, onComplete = { aapsLogger.debug("playTestBeep completed") @@ -463,39 +585,4 @@ class OmnipodDashPumpPlugin @Inject constructor( commandQueue.customCommand(CommandHandleTimeChange(false), null) } - - private fun executeProgrammingCommand( - historyEntry: Single, - command: Observable - ): PumpEnactResult { - return Single.create { source -> - Observable.concat( - historyEntry.flatMapObservable { recordId -> - podStateManager.createActiveCommand(recordId).toObservable() - }, - command, - history.updateFromState(podStateManager).toObservable(), - podStateManager.updateActiveCommand().toObservable(), - ).subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error executing command", throwable) - source.onSuccess( - PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message) - ) - }, - onComplete = { - aapsLogger.debug("Command completed") - source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true) - ) - } - ) - }.blockingGet() - } } From 1e4cda01a3e84e3ebd03d4fc9188bc6bc9105efb Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Wed, 21 Apr 2021 20:44:26 +0200 Subject: [PATCH 05/21] Revert "Revert "remove duplication"" This reverts commit d49b87d124b301ce426f20b44be0fdc73516c2a6. --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 281 ++++++------------ 1 file changed, 97 insertions(+), 184 deletions(-) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt index e7f2be82ad..d3b50f1986 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt @@ -14,6 +14,7 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.* import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType @@ -110,8 +111,11 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun getPumpStatus(reason: String) { - // TODO history - omnipodManager.getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE).blockingSubscribeBy( + Observable.concat( + omnipodManager.getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).blockingSubscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, @@ -128,26 +132,12 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun setNewBasalProfile(profile: Profile): PumpEnactResult { - // TODO history - - return Single.create { source -> - omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)).subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in setNewBasalProfile: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in setNewBasalProfile", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("setNewBasalProfile completed") - source.onSuccess(PumpEnactResult(injector).success(true).enacted(true)) - } - ) - }.blockingGet() + return executeProgrammingCommand( + history.createRecord( + commandType = OmnipodCommandType.SET_BASAL_PROFILE + ), + omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)) + ) } override fun isThisProfileSet(profile: Profile): Boolean = podStateManager.basalProgram?.let { @@ -155,7 +145,7 @@ class OmnipodDashPumpPlugin @Inject constructor( } ?: true override fun lastDataTime(): Long { - return podStateManager.lastConnection + return podStateManager.lastUpdatedSystem } override val baseBasalRate: Double @@ -211,12 +201,15 @@ class OmnipodDashPumpPlugin @Inject constructor( }, onError = { throwable -> aapsLogger.error(LTag.PUMP, "Error in deliverTreatment", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) + source.onSuccess( + PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message) + ) }, onComplete = { aapsLogger.debug("deliverTreatment completed") source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true).bolusDelivered(detailedBolusInfo.insulin) + PumpEnactResult(injector).success(true).enacted(true) + .bolusDelivered(detailedBolusInfo.insulin) .carbsDelivered(detailedBolusInfo.carbs) ) } @@ -226,29 +219,9 @@ class OmnipodDashPumpPlugin @Inject constructor( override fun stopBolusDelivering() { // TODO update Treatments (?) - - Observable.concat( - history.createRecord( - commandType = OmnipodCommandType.CANCEL_BOLUS, - ).flatMapObservable { recordId -> - podStateManager.createActiveCommand(recordId).toObservable() - }, + executeProgrammingCommand( + history.createRecord(OmnipodCommandType.CANCEL_BOLUS), omnipodManager.stopBolus(), - history.updateFromState(podStateManager).toObservable(), - podStateManager.updateActiveCommand().toObservable(), - ).blockingSubscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in stopBolusDelivering: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in stopBolusDelivering", throwable) - }, - onComplete = { - aapsLogger.debug("stopBolusDelivering completed") - } ) } @@ -259,41 +232,17 @@ class OmnipodDashPumpPlugin @Inject constructor( enforceNew: Boolean ): PumpEnactResult { // TODO update Treatments - - return Single.create { source -> - Observable.concat( - history.createRecord( - commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, - tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) - ).flatMapObservable { recordId -> - podStateManager.createActiveCommand(recordId).toObservable() - }, - omnipodManager.setTempBasal( - absoluteRate, - durationInMinutes.toShort() - ), - history.updateFromState(podStateManager).toObservable(), - podStateManager.updateActiveCommand().toObservable(), - ).subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in setTempBasalAbsolute: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in setTempBasalAbsolute", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("setTempBasalAbsolute completed") - source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true).absolute(absoluteRate) - .duration(durationInMinutes) - ) - } + // TODO check for existing basal + return executeProgrammingCommand( + history.createRecord( + commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, + tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) + ), + omnipodManager.setTempBasal( + absoluteRate, + durationInMinutes.toShort() ) - }.blockingGet() + ) } override fun setTempBasalPercent( @@ -315,37 +264,10 @@ class OmnipodDashPumpPlugin @Inject constructor( override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult { // TODO update Treatments - - return Single.create { source -> - - Observable.concat( - history.createRecord( - commandType = OmnipodCommandType.CANCEL_TEMPORARY_BASAL - ).flatMapObservable { recordId -> - podStateManager.createActiveCommand(recordId).toObservable() - }, - omnipodManager.stopTempBasal(), - history.updateFromState(podStateManager).toObservable(), - podStateManager.updateActiveCommand().toObservable(), - ).subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in cancelTempBasal: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in cancelTempBasal", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("cancelTempBasal completed") - source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true) - ) - } - ) - }.blockingGet() + return executeProgrammingCommand( + history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), + omnipodManager.stopTempBasal() + ) } override fun cancelExtendedBolus(): PumpEnactResult { @@ -370,11 +292,8 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun serialNumber(): String { - return if (podStateManager.uniqueId == null) { - "n/a" // TODO i18n - } else { - podStateManager.uniqueId.toString() - } + return podStateManager.uniqueId?.toString() + ?: "n/a" // TODO i18n } override fun shortStatus(veryShort: Boolean): String { @@ -433,12 +352,15 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun silenceAlerts(): PumpEnactResult { - // TODO history // TODO filter alert types - return podStateManager.activeAlerts?.let { Single.create { source -> - omnipodManager.silenceAlerts(it).subscribeBy( + Observable.concat( + // TODO: is this a programming command? if yes, save to history + omnipodManager.silenceAlerts(it), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).subscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, @@ -459,75 +381,26 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun suspendDelivery(): PumpEnactResult { - // TODO history - - return Single.create { source -> - omnipodManager.suspendDelivery().subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in suspendDelivery: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in suspendDelivery", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("suspendDelivery completed") - source.onSuccess(PumpEnactResult(injector).success(true)) - } - ) - }.blockingGet() + return executeProgrammingCommand( + history.createRecord(OmnipodCommandType.RESUME_DELIVERY), + omnipodManager.suspendDelivery() + ) } private fun resumeDelivery(): PumpEnactResult { - // TODO history - return profileFunction.getProfile()?.let { - - Single.create { source -> - omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in resumeDelivery: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in resumeDelivery", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("resumeDelivery completed") - source.onSuccess(PumpEnactResult(injector).success(true)) - } - ) - }.blockingGet() + executeProgrammingCommand( + history.createRecord(OmnipodCommandType.RESUME_DELIVERY), + omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)) + ) } ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n } private fun deactivatePod(): PumpEnactResult { - // TODO history - - return Single.create { source -> - omnipodManager.deactivatePod().subscribeBy( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in deactivatePod: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in deactivatePod", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).comment(throwable.message)) - }, - onComplete = { - aapsLogger.debug("deactivatePod completed") - source.onSuccess(PumpEnactResult(injector).success(true)) - } - ) - }.blockingGet() + return executeProgrammingCommand( + history.createRecord(OmnipodCommandType.DEACTIVATE_POD), + omnipodManager.deactivatePod() + ) } private fun handleTimeChange(): PumpEnactResult { @@ -541,10 +414,13 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun playTestBeep(): PumpEnactResult { - // TODO history return Single.create { source -> - omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).subscribeBy( + Observable.concat( + omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP), + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).subscribeBy( onNext = { podEvent -> aapsLogger.debug( LTag.PUMP, @@ -553,7 +429,9 @@ class OmnipodDashPumpPlugin @Inject constructor( }, onError = { throwable -> aapsLogger.error(LTag.PUMP, "Error in playTestBeep", throwable) - source.onSuccess(PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message)) + source.onSuccess( + PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message) + ) }, onComplete = { aapsLogger.debug("playTestBeep completed") @@ -585,4 +463,39 @@ class OmnipodDashPumpPlugin @Inject constructor( commandQueue.customCommand(CommandHandleTimeChange(false), null) } + + private fun executeProgrammingCommand( + historyEntry: Single, + command: Observable + ): PumpEnactResult { + return Single.create { source -> + Observable.concat( + historyEntry.flatMapObservable { recordId -> + podStateManager.createActiveCommand(recordId).toObservable() + }, + command, + history.updateFromState(podStateManager).toObservable(), + podStateManager.updateActiveCommand().toObservable(), + ).subscribeBy( + onNext = { podEvent -> + aapsLogger.debug( + LTag.PUMP, + "Received PodEvent: $podEvent" + ) + }, + onError = { throwable -> + aapsLogger.error(LTag.PUMP, "Error executing command", throwable) + source.onSuccess( + PumpEnactResult(injector).success(false).enacted(false).comment(throwable.message) + ) + }, + onComplete = { + aapsLogger.debug("Command completed") + source.onSuccess( + PumpEnactResult(injector).success(true).enacted(true) + ) + } + ) + }.blockingGet() + } } From 3ef983b732ffcfa14c7a9a905e9e3f21902e33c5 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Wed, 21 Apr 2021 21:02:35 +0200 Subject: [PATCH 06/21] fix crash on pod deactivation --- .../deactivation/fragment/action/DeactivatePodFragment.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/action/DeactivatePodFragment.kt b/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/action/DeactivatePodFragment.kt index 679a12967b..baf0ea5bca 100644 --- a/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/action/DeactivatePodFragment.kt +++ b/omnipod-common/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/common/ui/wizard/deactivation/fragment/action/DeactivatePodFragment.kt @@ -31,7 +31,8 @@ class DeactivatePodFragment : ActionFragmentBase() { override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - view.findViewById