From b91e8506a087633afad6a4e1373f19bd970e9023 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Tue, 1 Jun 2021 21:41:13 +0200 Subject: [PATCH 01/11] move the common code to getCommandConfirmationFromState --- .../dash/dagger/OmnipodDashHistoryModule.kt | 5 +- .../comm/exceptions/CouldNotReadResponse.kt | 3 + .../pod/state/OmnipodDashPodStateManager.kt | 8 ++ .../state/OmnipodDashPodStateManagerImpl.kt | 78 ++++++++++++++----- .../pump/omnipod/dash/history/DashHistory.kt | 46 +++++------ 5 files changed, 96 insertions(+), 44 deletions(-) create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotReadResponse.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashHistoryModule.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashHistoryModule.kt index 1ac3c8dd3b..92c2368ee9 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashHistoryModule.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/dagger/OmnipodDashHistoryModule.kt @@ -4,6 +4,7 @@ import android.content.Context import dagger.Module import dagger.Provides import dagger.Reusable +import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.DashHistoryDatabase import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.database.HistoryRecordDao @@ -28,6 +29,6 @@ class OmnipodDashHistoryModule { @Provides @Singleton - internal fun provideDashHistory(dao: HistoryRecordDao, historyMapper: HistoryMapper) = - DashHistory(dao, historyMapper) + internal fun provideDashHistory(dao: HistoryRecordDao, historyMapper: HistoryMapper, logger: AAPSLogger) = + DashHistory(dao, historyMapper, logger) } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotReadResponse.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotReadResponse.kt new file mode 100644 index 0000000000..98d81b66cf --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/exceptions/CouldNotReadResponse.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions + +class CouldNotReadResponse 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 bc5fdf060a..b44c82fde3 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 @@ -14,6 +14,13 @@ import io.reactivex.Single import java.io.Serializable import java.util.* +sealed class CommandConfirmationFromState +object CommandSendingFailure : CommandConfirmationFromState() +object CommandSendingNotConfirmed : CommandConfirmationFromState() +object CommandConfirmationDenied : CommandConfirmationFromState() +object CommandConfirmationSuccess : CommandConfirmationFromState() +object NoActiveCommand : CommandConfirmationFromState() + interface OmnipodDashPodStateManager { var activationProgress: ActivationProgress @@ -70,6 +77,7 @@ interface OmnipodDashPodStateManager { fun createActiveCommand(historyId: String): Single fun updateActiveCommand(): Maybe fun observeNoActiveCommand(): Observable + fun getCommandConfirmationFromState(): CommandConfirmationFromState data class ActiveCommand( val sequence: Short, 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 f100620760..9a3d3c7ceb 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 @@ -231,30 +231,70 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( @Synchronized override fun updateActiveCommand() = Maybe.create { source -> - podState.activeCommand?.run { + val activeCommand = podState.activeCommand + if (activeCommand == null) { + logger.error("No active command to update") + source.onComplete() + return@create + } + + when (getCommandConfirmationFromState()) { + CommandSendingFailure -> { + podState.activeCommand = null + source.onError( + activeCommand?.sendError + ?: java.lang.IllegalStateException( + "Could not send command and sendError is " + + "missing" + ) + ) + } + + CommandSendingNotConfirmed -> { + // we did not receive a valid response yet + source.onComplete() + } + + CommandConfirmationDenied -> { + podState.activeCommand = null + source.onSuccess(CommandConfirmed(activeCommand.historyId, false)) + } + + CommandConfirmationSuccess -> { + podState.activeCommand = null + source.onSuccess(CommandConfirmed(activeCommand.historyId, false)) + } + + NoActiveCommand -> { + source.onComplete() + } + } + } + + @Synchronized + override fun getCommandConfirmationFromState(): CommandConfirmationFromState { + return podState.activeCommand?.run { logger.debug( - "Trying to confirm active command with parameters: $activeCommand " + + "Getting command state with parameters: $activeCommand " + "lastResponse=$lastStatusResponseReceived " + "$sequenceNumberOfLastProgrammingCommand $historyId" ) - - if (sentRealtime < createdRealtime) { // command was not sent, clear it up - podState.activeCommand = null - source.onError(this.sendError - ?: java.lang.IllegalStateException("Could not send command and sendError is " + - "missing") ) - } else if (createdRealtime >= lastStatusResponseReceived) - // we did not receive a valid response yet - source.onComplete() - else { - podState.activeCommand = null - if (sequenceNumberOfLastProgrammingCommand == sequence) - source.onSuccess(CommandConfirmed(historyId, true)) - else - source.onSuccess(CommandConfirmed(historyId, false)) + when { + createdRealtime <= podState.lastStatusResponseReceived && + sequence == podState.sequenceNumberOfLastProgrammingCommand -> + CommandConfirmationSuccess + createdRealtime <= podState.lastStatusResponseReceived && + sequence != podState.sequenceNumberOfLastProgrammingCommand -> + CommandConfirmationDenied + // no response received after this point + createdRealtime <= sentRealtime -> + CommandSendingNotConfirmed + createdRealtime > sentRealtime -> + CommandSendingFailure + else -> // this can't happen, see the previous two conditions + NoActiveCommand } - } ?: source.onComplete() - // no active programming command + } ?: NoActiveCommand } override fun increaseEapAkaSequenceNumber(): ByteArray { 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 dea243e814..fc623d01f3 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 @@ -1,10 +1,12 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.history import com.github.guepardoapps.kulid.ULID +import info.nightscout.androidaps.logging.AAPSLogger +import info.nightscout.androidaps.logging.LTag 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.driver.pod.state.* 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 @@ -20,7 +22,8 @@ import javax.inject.Inject class DashHistory @Inject constructor( private val dao: HistoryRecordDao, - private val historyMapper: HistoryMapper + private val historyMapper: HistoryMapper, + private val logger: AAPSLogger ) { private fun markSuccess(id: String): Completable = dao.markResolved( @@ -83,26 +86,23 @@ class DashHistory @Inject constructor( fun getRecordsAfter(time: Long): Single> = dao.allSince(time) fun updateFromState(podState: OmnipodDashPodStateManager) = Completable.defer { - 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 + val historyId = podState.activeCommand?.historyId + if (historyId == null) { + logger.error(LTag.PUMP, "HistoryId not found to for updating from state") + return@defer Completable.complete() + } + when (podState.getCommandConfirmationFromState()) { + CommandSendingFailure -> + dao.setInitialResult(historyId, InitialResult.FAILURE_SENDING) + CommandSendingNotConfirmed -> + dao.setInitialResult(historyId, InitialResult.SENT) + CommandConfirmationDenied -> + markFailure(historyId) + CommandConfirmationSuccess -> + dao.setInitialResult(historyId, InitialResult.SENT) + .andThen(markSuccess(historyId)) + NoActiveCommand -> + Completable.complete() + } } } From 432e06adaa07581fe958aa10c145bf6c04250e4f Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Tue, 1 Jun 2021 21:50:55 +0200 Subject: [PATCH 02/11] simplify: use lastUpdatedSystem for lastConnection --- .../omnipod/dash/driver/comm/OmnipodDashBleManagerImpl.kt | 2 -- .../dash/driver/pod/state/OmnipodDashPodStateManager.kt | 1 - .../driver/pod/state/OmnipodDashPodStateManagerImpl.kt | 8 -------- .../pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt | 4 ++-- 4 files changed, 2 insertions(+), 13 deletions(-) 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 622b3663a3..8af2a9c1fc 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 @@ -103,7 +103,6 @@ class OmnipodDashBleManagerImpl @Inject constructor( ?: Connection(podDevice, aapsLogger, context, podState) connection = conn if (conn.connectionState() is Connected) { - podState.lastConnection = System.currentTimeMillis() if (conn.session == null) { emitter.onNext(PodEvent.EstablishingSession) establishSession(1.toByte()) @@ -116,7 +115,6 @@ class OmnipodDashBleManagerImpl @Inject constructor( } conn.connect() emitter.onNext(PodEvent.BluetoothConnected(podAddress)) - podState.lastConnection = System.currentTimeMillis() emitter.onNext(PodEvent.EstablishingSession) establishSession(1.toByte()) emitter.onNext(PodEvent.Connected) 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 b44c82fde3..32713d5bdb 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 @@ -28,7 +28,6 @@ interface OmnipodDashPodStateManager { val isActivationCompleted: Boolean val isSuspended: Boolean val isPodRunning: Boolean - var lastConnection: Long var bluetoothConnectionState: BluetoothConnectionState val lastUpdatedSystem: Long // System.currentTimeMillis() 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 9a3d3c7ceb..d22c4f29a8 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 @@ -58,13 +58,6 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( override val isPodRunning: Boolean get() = podState.podStatus?.isRunning() ?: false - override var lastConnection: Long - get() = podState.lastConnection - set(lastConnection) { - podState.lastConnection = lastConnection - store() - } - override val lastUpdatedSystem: Long get() = podState.lastUpdatedSystem @@ -422,7 +415,6 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( class PodState : Serializable { var activationProgress: ActivationProgress = ActivationProgress.NOT_STARTED - var lastConnection: Long = 0 var lastUpdatedSystem: Long = 0 var lastStatusResponseReceived: Long = 0 var bluetoothConnectionState: OmnipodDashPodStateManager.BluetoothConnectionState = diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt index f79180f061..c88c13cbb3 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt @@ -357,7 +357,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() { private fun updateLastConnection() { if (podStateManager.isUniqueIdSet) { - podInfoBinding.lastConnection.text = readableDuration(podStateManager.lastConnection) + podInfoBinding.lastConnection.text = readableDuration(podStateManager.lastUpdatedSystem) val lastConnectionColor = if (omnipodDashPumpPlugin.isUnreachableAlertTimeoutExceeded(getPumpUnreachableTimeout().millis)) { Color.RED @@ -367,7 +367,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() { podInfoBinding.lastConnection.setTextColor(lastConnectionColor) } else { podInfoBinding.lastConnection.setTextColor(Color.WHITE) - podInfoBinding.lastConnection.text = readableDuration(podStateManager.lastConnection) + podInfoBinding.lastConnection.text = readableDuration(podStateManager.lastUpdatedSystem) } } From d392caa6e95e665342b7083fa554ac1dacb481fe Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Tue, 1 Jun 2021 22:00:16 +0200 Subject: [PATCH 03/11] move private fun at the end --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 60 ++++++++++--------- 1 file changed, 31 insertions(+), 29 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 d6d128a7cb..fcb9d88a0e 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 @@ -315,12 +315,14 @@ class OmnipodDashPumpPlugin @Inject constructor( aapsLogger.info(LTag.PUMP, "No temporary basal to cancel") Completable.complete() } + !enforeNew -> Completable.error( IllegalStateException( "Temporary basal already active and enforeNew is not set." ) ) + else -> { // enforceNew == true aapsLogger.info(LTag.PUMP, "Canceling existing temp basal") @@ -378,35 +380,6 @@ class OmnipodDashPumpPlugin @Inject constructor( .blockingGet() } - private fun handleCommandConfirmation(confirmation: CommandConfirmed) { - val historyEntry = history.getById(confirmation.historyId) - when (historyEntry.commandType) { - OmnipodCommandType.CANCEL_TEMPORARY_BASAL -> - // We can't invalidate this command, - // and this is why it is pumpSync-ed at this point - if (confirmation.success) { - pumpSync.syncStopTemporaryBasalWithPumpId( - historyEntry.createdAt, - historyEntry.pumpId(), - PumpType.OMNIPOD_DASH, - serialNumber() - ) - } - OmnipodCommandType.SET_TEMPORARY_BASAL -> - // This treatment was synced before sending the command - if (!confirmation.success) { - pumpSync.invalidateTemporaryBasal(historyEntry.pumpId()) - } - - else -> - aapsLogger.warn( - LTag.PUMP, - "Will not sync confirmed command of type: $historyEntry and " + - "succes: ${confirmation.success}" - ) - } - } - override fun cancelExtendedBolus(): PumpEnactResult { // TODO i18n return PumpEnactResult(injector).success(false).enacted(false) @@ -605,4 +578,33 @@ class OmnipodDashPumpPlugin @Inject constructor( ) ) } + + private fun handleCommandConfirmation(confirmation: CommandConfirmed) { + val historyEntry = history.getById(confirmation.historyId) + when (historyEntry.commandType) { + OmnipodCommandType.CANCEL_TEMPORARY_BASAL -> + // We can't invalidate this command, + // and this is why it is pumpSync-ed at this point + if (confirmation.success) { + pumpSync.syncStopTemporaryBasalWithPumpId( + historyEntry.createdAt, + historyEntry.pumpId(), + PumpType.OMNIPOD_DASH, + serialNumber() + ) + } + OmnipodCommandType.SET_TEMPORARY_BASAL -> + // This treatment was synced before sending the command + if (!confirmation.success) { + pumpSync.invalidateTemporaryBasal(historyEntry.pumpId()) + } + + else -> + aapsLogger.warn( + LTag.PUMP, + "Will not sync confirmed command of type: $historyEntry and " + + "succes: ${confirmation.success}" + ) + } + } } From 2afe220d2826b3157ea5a94d90057864d4917c4c Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Thu, 3 Jun 2021 19:43:59 +0200 Subject: [PATCH 04/11] suspend/resume --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 64 +++++++++++++++---- .../dash/driver/OmnipodDashManagerImpl.kt | 1 + .../dash/driver/pod/state/CommandConfirmed.kt | 2 +- .../state/OmnipodDashPodStateManagerImpl.kt | 16 +++-- .../dash/ui/OmnipodDashOverviewFragment.kt | 15 ++--- 5 files changed, 70 insertions(+), 28 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 fcb9d88a0e..80ed239609 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 @@ -16,6 +16,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashMa 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.definition.DeliveryStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.CommandConfirmed import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager @@ -36,7 +37,6 @@ import io.reactivex.Single import io.reactivex.rxkotlin.blockingSubscribeBy import io.reactivex.rxkotlin.subscribeBy import org.json.JSONObject -import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -156,16 +156,41 @@ class OmnipodDashPumpPlugin @Inject constructor( override fun setNewBasalProfile(profile: Profile): PumpEnactResult { return executeSimpleProgrammingCommand( - history.createRecord( + historyEntry = history.createRecord( commandType = OmnipodCommandType.SET_BASAL_PROFILE ), - omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)).ignoreElements() + command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)).ignoreElements(), + pre = suspendDeliveryIfActive(), ).toPumpEnactResult() } - override fun isThisProfileSet(profile: Profile): Boolean = podStateManager.basalProgram?.let { - it == mapProfileToBasalProgram(profile) - } ?: true + private fun suspendDeliveryIfActive(): Completable = Completable.defer { + if (podStateManager.deliveryStatus == DeliveryStatus.SUSPENDED) + Completable.complete() + else + executeSimpleProgrammingCommand( + history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY), + omnipodManager.suspendDelivery().ignoreElements() + ) + } + + private fun observeDeliverySuspended(): Completable = Completable.defer { + if (podStateManager.deliveryStatus == DeliveryStatus.SUSPENDED) + Completable.complete() + else { + Completable.error(java.lang.IllegalStateException("Expected suspended delivery")) + } + } + + override fun isThisProfileSet(profile: Profile): Boolean { + if (!podStateManager.isActivationCompleted) { + // prevent setBasal requests + return true + } + // TODO: what do we have to answer here if delivery is suspended? + val running = pumpSync.expectedPumpState().profile + return running?.isEqual(profile) ?: false + } override fun lastDataTime(): Long { return podStateManager.lastUpdatedSystem @@ -173,6 +198,7 @@ class OmnipodDashPumpPlugin @Inject constructor( override val baseBasalRate: Double get() = podStateManager.basalProgram?.rateAt(Date()) ?: 0.0 + //pumpSync.expectedPumpState().profile?.getBasal() ?: 0.0 override val reservoirLevel: Double get() { @@ -309,9 +335,10 @@ class OmnipodDashPumpPlugin @Inject constructor( private fun observeNoActiveTempBasal(enforeNew: Boolean): Completable { return Completable.defer { - val expectedState = pumpSync.expectedPumpState() when { - expectedState.temporaryBasal == null -> { + podStateManager.deliveryStatus !in + arrayOf(DeliveryStatus.TEMP_BASAL_ACTIVE, DeliveryStatus.BOLUS_AND_TEMP_BASAL_ACTIVE) -> { + // TODO: what happens if we try to cancel inexistent temp basal? aapsLogger.info(LTag.PUMP, "No temporary basal to cancel") Completable.complete() } @@ -496,16 +523,25 @@ class OmnipodDashPumpPlugin @Inject constructor( private fun suspendDelivery(): PumpEnactResult { return executeSimpleProgrammingCommand( - history.createRecord(OmnipodCommandType.RESUME_DELIVERY), - omnipodManager.suspendDelivery().ignoreElements() + history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY), + omnipodManager.suspendDelivery().ignoreElements(), + pre = observeDeliveryActive(), ).toPumpEnactResult() } + private fun observeDeliveryActive(): Completable = Completable.defer { + if (podStateManager.deliveryStatus != DeliveryStatus.SUSPENDED) + Completable.complete() + else + Completable.error(java.lang.IllegalStateException("Expected active delivery")) + } + private fun resumeDelivery(): PumpEnactResult { return profileFunction.getProfile()?.let { executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.RESUME_DELIVERY), - omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).ignoreElements() + omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).ignoreElements(), + pre = observeDeliverySuspended(), ).toPumpEnactResult() } ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n } @@ -581,6 +617,7 @@ class OmnipodDashPumpPlugin @Inject constructor( private fun handleCommandConfirmation(confirmation: CommandConfirmed) { val historyEntry = history.getById(confirmation.historyId) + aapsLogger.debug(LTag.PUMPCOMM, "handling confirmation command: $confirmation") when (historyEntry.commandType) { OmnipodCommandType.CANCEL_TEMPORARY_BASAL -> // We can't invalidate this command, @@ -593,11 +630,14 @@ class OmnipodDashPumpPlugin @Inject constructor( serialNumber() ) } - OmnipodCommandType.SET_TEMPORARY_BASAL -> + + OmnipodCommandType.SET_TEMPORARY_BASAL -> { // This treatment was synced before sending the command + aapsLogger.info(LTag.PUMPCOMM, "temporary basal denied. PumpId: ${historyEntry.pumpId()}") if (!confirmation.success) { pumpSync.invalidateTemporaryBasal(historyEntry.pumpId()) } + } else -> aapsLogger.warn( 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 0d44fd4b3f..6f9750be35 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 @@ -172,6 +172,7 @@ class OmnipodDashManagerImpl @Inject constructor( DefaultStatusResponse::class ) }.doOnComplete { + // TODO: remove podStateManager.basalProgram? podStateManager.basalProgram = basalProgram } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt index d5f57243d8..0df5b92adf 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt @@ -1,3 +1,3 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state -class CommandConfirmed(val historyId: String, val success: Boolean) +data class CommandConfirmed(val historyId: String, val success: Boolean) 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 d22c4f29a8..eb3a15ffa6 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 @@ -53,7 +53,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( override val isSuspended: Boolean get() = podState.deliveryStatus?.equals(DeliveryStatus.SUSPENDED) - ?: true + ?: false override val isPodRunning: Boolean get() = podState.podStatus?.isRunning() ?: false @@ -141,7 +141,11 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( get() = podState.tempBasal override val tempBasalActive: Boolean - get() = tempBasal != null && tempBasal!!.startTime + tempBasal!!.durationInMinutes * 60 * 1000 > System.currentTimeMillis() + get() = podState.deliveryStatus in + arrayOf( + DeliveryStatus.TEMP_BASAL_ACTIVE, + DeliveryStatus.BOLUS_AND_TEMP_BASAL_ACTIVE + ) override var basalProgram: BasalProgram? get() = podState.basalProgram @@ -230,8 +234,9 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( source.onComplete() return@create } - - when (getCommandConfirmationFromState()) { + val cmdConfirmation = getCommandConfirmationFromState() + logger.info(LTag.PUMPCOMM, "Update active command with confirmation: $cmdConfirmation") + when (cmdConfirmation) { CommandSendingFailure -> { podState.activeCommand = null source.onError( @@ -255,7 +260,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( CommandConfirmationSuccess -> { podState.activeCommand = null - source.onSuccess(CommandConfirmed(activeCommand.historyId, false)) + + source.onSuccess(CommandConfirmed(activeCommand.historyId, false)) // TODO: remove test } NoActiveCommand -> { diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt index c88c13cbb3..48645b4920 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt @@ -298,15 +298,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() { */ // base basal rate - podInfoBinding.baseBasalRate.text = if (podStateManager.basalProgram != null) { - resourceHelper.gs( - R.string.pump_basebasalrate, - omnipodDashPumpPlugin.model() - .determineCorrectBasalSize(podStateManager.basalProgram!!.rateAt(Date())) - ) - } else { - PLACEHOLDER - } + // TODO: check if delivery is suspended + podInfoBinding.baseBasalRate.text = PLACEHOLDER // total delivered podInfoBinding.totalDelivered.text = @@ -518,7 +511,9 @@ class OmnipodDashOverviewFragment : DaggerFragment() { private fun updateSuspendDeliveryButton() { // If the Pod is currently suspended, we show the Resume delivery button instead. - if (isSuspendDeliveryButtonEnabled() && + // TODO: isSuspendDeliveryButtonEnabled doesn't work + val isSuspendDeliveryButtonEnabled = true + if (isSuspendDeliveryButtonEnabled && podStateManager.isPodRunning && (!podStateManager.isSuspended || commandQueue.isCustomCommandInQueue(CommandSuspendDelivery::class.java)) ) { From 25141d393963923219a7c31a6669e070ff1d97c5 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Thu, 3 Jun 2021 21:48:03 +0200 Subject: [PATCH 05/11] undo the last change --- .../plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 80ed239609..421ffb0c7c 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 @@ -37,6 +37,7 @@ import io.reactivex.Single import io.reactivex.rxkotlin.blockingSubscribeBy import io.reactivex.rxkotlin.subscribeBy import org.json.JSONObject +import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -198,7 +199,6 @@ class OmnipodDashPumpPlugin @Inject constructor( override val baseBasalRate: Double get() = podStateManager.basalProgram?.rateAt(Date()) ?: 0.0 - //pumpSync.expectedPumpState().profile?.getBasal() ?: 0.0 override val reservoirLevel: Double get() { From 76a0e93ee2094a0da6eb019b66baa0c68ad3813b Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Thu, 3 Jun 2021 22:19:51 +0200 Subject: [PATCH 06/11] stop testing failed commands --- .../dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 eb3a15ffa6..b42e4c657e 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 @@ -261,7 +261,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( CommandConfirmationSuccess -> { podState.activeCommand = null - source.onSuccess(CommandConfirmed(activeCommand.historyId, false)) // TODO: remove test + source.onSuccess(CommandConfirmed(activeCommand.historyId, true)) } NoActiveCommand -> { From 5d3b2faeb9fd002aeeda58df160486e0e9da41d1 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Fri, 4 Jun 2021 19:32:00 +0200 Subject: [PATCH 07/11] pumpsync on suspend/resume --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 39 +++++++++++++------ .../driver/pod/definition/PodConstants.kt | 9 +++++ .../pod/state/OmnipodDashPodStateManager.kt | 3 +- .../state/OmnipodDashPodStateManagerImpl.kt | 6 ++- 4 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt 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 1e0bbc56e1..e3934e0020 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 @@ -17,6 +17,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEven 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.definition.DeliveryStatus +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodConstants import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.ResponseType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.CommandConfirmed import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager @@ -296,7 +297,7 @@ class OmnipodDashPumpPlugin @Inject constructor( tempBasalBeeps ) .filter { podEvent -> podEvent is PodEvent.CommandSent } - .map { pumpSyncTempBasal(it, tbrType) } + .map { pumpSyncTempBasal(it, absoluteRate, durationInMinutes.toLong(), tbrType) } .ignoreElements(), pre = observeNoActiveTempBasal(enforceNew) ).toPumpEnactResult() @@ -304,6 +305,8 @@ class OmnipodDashPumpPlugin @Inject constructor( private fun pumpSyncTempBasal( podEvent: PodEvent, + absoluteRate: Double, + durationInMinutes: Long, tbrType: PumpSync.TemporaryBasalType ): Boolean { val activeCommand = podStateManager.activeCommand @@ -315,14 +318,11 @@ class OmnipodDashPumpPlugin @Inject constructor( ) } val historyEntry = history.getById(activeCommand.historyId) - val record = historyEntry.record - if (record == null || !(record is TempBasalRecord)) { - throw IllegalArgumentException("Illegal recording in history: $record. Expected a temp basal") - } + val ret = pumpSync.syncTemporaryBasalWithPumpId( timestamp = historyEntry.createdAt, - rate = record.rate, - duration = T.mins(record.duration.toLong()).msecs(), + rate = absoluteRate, + duration = T.mins(durationInMinutes.toLong()).msecs(), isAbsolute = true, type = tbrType, pumpId = historyEntry.pumpId(), @@ -363,8 +363,9 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun observeActiveTempBasal(): Completable { + return Completable.defer { - if (podStateManager.tempBasalActive) + if (podStateManager.tempBasalActive || pumpSync.expectedPumpState().temporaryBasal != null) Completable.complete() else Completable.error( @@ -523,8 +524,16 @@ class OmnipodDashPumpPlugin @Inject constructor( private fun suspendDelivery(): PumpEnactResult { return executeSimpleProgrammingCommand( - history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY), - omnipodManager.suspendDelivery().ignoreElements(), + historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY), + command = omnipodManager.suspendDelivery() + .filter { podEvent -> podEvent is PodEvent.CommandSent } + .map { + pumpSyncTempBasal(it, + 0.0, + PodConstants.MAX_POD_LIFETIME.standardMinutes, + PumpSync.TemporaryBasalType.PUMP_SUSPEND) + } + .ignoreElements(), pre = observeDeliveryActive(), ).toPumpEnactResult() } @@ -619,7 +628,9 @@ class OmnipodDashPumpPlugin @Inject constructor( val historyEntry = history.getById(confirmation.historyId) aapsLogger.debug(LTag.PUMPCOMM, "handling confirmation command: $confirmation") when (historyEntry.commandType) { - OmnipodCommandType.CANCEL_TEMPORARY_BASAL -> + OmnipodCommandType.CANCEL_TEMPORARY_BASAL, + OmnipodCommandType.SET_BASAL_PROFILE, + OmnipodCommandType.RESUME_DELIVERY -> // We can't invalidate this command, // and this is why it is pumpSync-ed at this point if (confirmation.success) { @@ -639,6 +650,12 @@ class OmnipodDashPumpPlugin @Inject constructor( } } + OmnipodCommandType.SUSPEND_DELIVERY -> { + if (!confirmation.success) { + pumpSync.invalidateTemporaryBasal(historyEntry.pumpId()) + } + } + else -> aapsLogger.warn( LTag.PUMP, diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt new file mode 100644 index 0000000000..4c9a1175eb --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt @@ -0,0 +1,9 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition + +import org.joda.time.Duration + +class PodConstants { + companion object { + val MAX_POD_LIFETIME = Duration.standardHours(80) + } +} \ No newline at end of file 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 32713d5bdb..f684f24d9f 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 @@ -73,7 +73,7 @@ interface OmnipodDashPodStateManager { fun updateFromPairing(uniqueId: Id, pairResult: PairResult) fun reset() - fun createActiveCommand(historyId: String): Single + fun createActiveCommand(historyId: String, basalProgram: BasalProgram?=null): Single fun updateActiveCommand(): Maybe fun observeNoActiveCommand(): Observable fun getCommandConfirmationFromState(): CommandConfirmationFromState @@ -84,6 +84,7 @@ interface OmnipodDashPodStateManager { var sentRealtime: Long = 0, val historyId: String, var sendError: Throwable?, + var basalProgram: BasalProgram? ) // 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 b42e4c657e..fd25212775 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 @@ -188,7 +188,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( get() = podState.activeCommand @Synchronized - override fun createActiveCommand(historyId: String): Single { + override fun createActiveCommand(historyId: String, basalProgram: BasalProgram?): + Single { return Single.create { source -> if (activeCommand == null) { val command = OmnipodDashPodStateManager.ActiveCommand( @@ -196,6 +197,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( createdRealtime = SystemClock.elapsedRealtime(), historyId = historyId, sendError = null, + basalProgram = basalProgram, ) podState.activeCommand = command source.onSuccess(command) @@ -261,7 +263,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( CommandConfirmationSuccess -> { podState.activeCommand = null - source.onSuccess(CommandConfirmed(activeCommand.historyId, true)) + source.onSuccess(CommandConfirmed(activeCommand.historyId, true)) } NoActiveCommand -> { From 33243a7ed44fbd70ddd7ce4b44f544ba8fce7c39 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Fri, 4 Jun 2021 22:56:58 +0200 Subject: [PATCH 08/11] create fake TBR on suspend. Fix createHistory timing bug --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 31 ++++++++++------ .../driver/pod/definition/PodConstants.kt | 2 +- .../pod/state/OmnipodDashPodStateManager.kt | 2 +- .../state/OmnipodDashPodStateManagerImpl.kt | 36 +++++++++---------- .../pump/omnipod/dash/history/DashHistory.kt | 34 +++++++++--------- 5 files changed, 58 insertions(+), 47 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 e3934e0020..c0c9c569ad 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 @@ -158,11 +158,10 @@ class OmnipodDashPumpPlugin @Inject constructor( override fun setNewBasalProfile(profile: Profile): PumpEnactResult { return executeSimpleProgrammingCommand( - historyEntry = history.createRecord( - commandType = OmnipodCommandType.SET_BASAL_PROFILE - ), - command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)).ignoreElements(), pre = suspendDeliveryIfActive(), + historyEntry = history.createRecord(commandType = OmnipodCommandType.SET_BASAL_PROFILE), + command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)) + .ignoreElements(), ).toPumpEnactResult() } @@ -172,7 +171,17 @@ class OmnipodDashPumpPlugin @Inject constructor( else executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY), - omnipodManager.suspendDelivery().ignoreElements() + omnipodManager.suspendDelivery() + .filter { podEvent -> podEvent is PodEvent.CommandSent } + .map { + pumpSyncTempBasal( + it, + 0.0, + PodConstants.MAX_POD_LIFETIME.standardMinutes, + PumpSync.TemporaryBasalType.PUMP_SUSPEND + ) + } + .ignoreElements(), ) } @@ -528,10 +537,12 @@ class OmnipodDashPumpPlugin @Inject constructor( command = omnipodManager.suspendDelivery() .filter { podEvent -> podEvent is PodEvent.CommandSent } .map { - pumpSyncTempBasal(it, - 0.0, - PodConstants.MAX_POD_LIFETIME.standardMinutes, - PumpSync.TemporaryBasalType.PUMP_SUSPEND) + pumpSyncTempBasal( + it, + 0.0, + PodConstants.MAX_POD_LIFETIME.standardMinutes, + PumpSync.TemporaryBasalType.PUMP_SUSPEND + ) } .ignoreElements(), pre = observeDeliveryActive(), @@ -626,7 +637,7 @@ class OmnipodDashPumpPlugin @Inject constructor( private fun handleCommandConfirmation(confirmation: CommandConfirmed) { val historyEntry = history.getById(confirmation.historyId) - aapsLogger.debug(LTag.PUMPCOMM, "handling confirmation command: $confirmation") + aapsLogger.debug(LTag.PUMPCOMM, "handling command confirmation: $confirmation") when (historyEntry.commandType) { OmnipodCommandType.CANCEL_TEMPORARY_BASAL, OmnipodCommandType.SET_BASAL_PROFILE, diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt index 4c9a1175eb..f52cc8fb5f 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/PodConstants.kt @@ -6,4 +6,4 @@ class PodConstants { companion object { val MAX_POD_LIFETIME = Duration.standardHours(80) } -} \ No newline at end of file +} 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 f684f24d9f..2b9dc3dc7e 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 @@ -73,7 +73,7 @@ interface OmnipodDashPodStateManager { fun updateFromPairing(uniqueId: Id, pairResult: PairResult) fun reset() - fun createActiveCommand(historyId: String, basalProgram: BasalProgram?=null): Single + fun createActiveCommand(historyId: String, basalProgram: BasalProgram? = null): Single fun updateActiveCommand(): Maybe fun observeNoActiveCommand(): Observable fun getCommandConfirmationFromState(): CommandConfirmationFromState 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 fd25212775..a1500c49ac 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 @@ -190,27 +190,27 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( @Synchronized override fun createActiveCommand(historyId: String, basalProgram: BasalProgram?): Single { - return Single.create { source -> - if (activeCommand == null) { - val command = OmnipodDashPodStateManager.ActiveCommand( - podState.messageSequenceNumber, - createdRealtime = SystemClock.elapsedRealtime(), - historyId = historyId, - sendError = null, - basalProgram = basalProgram, - ) - podState.activeCommand = command - source.onSuccess(command) - } else { - source.onError( - java.lang.IllegalStateException( - "Trying to send a command " + - "and the last command was not confirmed" + return Single.create { source -> + if (activeCommand == null) { + val command = OmnipodDashPodStateManager.ActiveCommand( + podState.messageSequenceNumber, + createdRealtime = SystemClock.elapsedRealtime(), + historyId = historyId, + sendError = null, + basalProgram = basalProgram, ) - ) + podState.activeCommand = command + source.onSuccess(command) + } else { + source.onError( + java.lang.IllegalStateException( + "Trying to send a command " + + "and the last command was not confirmed" + ) + ) + } } } - } @Synchronized override fun observeNoActiveCommand(): Observable { 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 fc623d01f3..f1e91651f7 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 @@ -55,29 +55,29 @@ class DashHistory @Inject constructor( bolusRecord: BolusRecord? = null, resolveResult: ResolvedResult? = null, resolvedAt: Long? = null - ): Single { + ): Single = Single.defer { val id = ULID.random() when { commandType == SET_BOLUS && bolusRecord == null -> - return Single.error(IllegalArgumentException("bolusRecord missing on SET_BOLUS")) + Single.error(IllegalArgumentException("bolusRecord missing on SET_BOLUS")) commandType == SET_TEMPORARY_BASAL && tempBasalRecord == null -> - return Single.error(IllegalArgumentException("tempBasalRecord missing on SET_TEMPORARY_BASAL")) + Single.error(IllegalArgumentException("tempBasalRecord missing on SET_TEMPORARY_BASAL")) + else -> + dao.save( + HistoryRecordEntity( + id = id, + date = date, + createdAt = currentTimeMillis(), + commandType = commandType, + tempBasalRecord = tempBasalRecord, + bolusRecord = bolusRecord, + initialResult = initialResult, + resolvedResult = resolveResult, + resolvedAt = resolvedAt + ) + ).toSingle { id } } - - return dao.save( - HistoryRecordEntity( - id = id, - date = date, - createdAt = currentTimeMillis(), - commandType = commandType, - tempBasalRecord = tempBasalRecord, - bolusRecord = bolusRecord, - initialResult = initialResult, - resolvedResult = resolveResult, - resolvedAt = resolvedAt - ) - ).toSingle { id } } fun getRecords(): Single> = From 7c20bfb7f06bb75813c86a1510f770b3f5528d40 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sat, 5 Jun 2021 14:18:04 +0200 Subject: [PATCH 09/11] implement basals --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 80 +++++++++++++------ .../driver/pod/definition/BasalProgram.kt | 11 ++- .../dash/driver/pod/state/CommandConfirmed.kt | 2 +- .../state/OmnipodDashPodStateManagerImpl.kt | 4 +- .../dash/ui/OmnipodDashOverviewFragment.kt | 11 ++- 5 files changed, 76 insertions(+), 32 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 c0c9c569ad..e59a225160 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 @@ -15,6 +15,7 @@ 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.BasalProgram import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.PodConstants @@ -136,35 +137,42 @@ 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( - onNext = { podEvent -> - aapsLogger.debug( - LTag.PUMP, - "Received PodEvent in getPumpStatus: $podEvent" - ) - }, - onError = { throwable -> - aapsLogger.error(LTag.PUMP, "Error in getPumpStatus", throwable) - }, - onComplete = { - aapsLogger.debug("getPumpStatus completed") - } - ) + val throwable = Completable.concat(listOf( + omnipodManager + .getStatus(ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE) + .ignoreElements(), + history.updateFromState(podStateManager), + podStateManager.updateActiveCommand() + .map { handleCommandConfirmation(it) } + .ignoreElement(), + )).blockingGet() + if (throwable != null){ + aapsLogger.error(LTag.PUMP, "Error in getPumpStatus", throwable) + } else { + aapsLogger.info(LTag.PUMP, "getPumpStatus executed with success") + + } } override fun setNewBasalProfile(profile: Profile): PumpEnactResult { + val basalProgram = mapProfileToBasalProgram(profile) return executeSimpleProgrammingCommand( pre = suspendDeliveryIfActive(), historyEntry = history.createRecord(commandType = OmnipodCommandType.SET_BASAL_PROFILE), - command = omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)) - .ignoreElements(), + command = omnipodManager.setBasalProgram(basalProgram).ignoreElements(), + basalProgram = basalProgram, + post = failWhenUnconfirmed(), ).toPumpEnactResult() } + private fun failWhenUnconfirmed(): Completable = Completable.defer{ + if (podStateManager.activeCommand != null) { + Completable.error(java.lang.IllegalStateException("Command not confirmed")) + }else { + Completable.complete() + } + } + private fun suspendDeliveryIfActive(): Completable = Completable.defer { if (podStateManager.deliveryStatus == DeliveryStatus.SUSPENDED) Completable.complete() @@ -199,8 +207,10 @@ class OmnipodDashPumpPlugin @Inject constructor( return true } // TODO: what do we have to answer here if delivery is suspended? - val running = pumpSync.expectedPumpState().profile - return running?.isEqual(profile) ?: false + val running = podStateManager.basalProgram + val equal = (mapProfileToBasalProgram(profile) == running) + aapsLogger.info(LTag.PUMP, "isThisProfileSet: $equal") + return equal } override fun lastDataTime(): Long { @@ -615,13 +625,15 @@ class OmnipodDashPumpPlugin @Inject constructor( historyEntry: Single, command: Completable, pre: Completable = Completable.complete(), + basalProgram: BasalProgram? = null, + post: Completable = Completable.complete(), ): Completable { return Completable.concat( listOf( pre, podStateManager.observeNoActiveCommand().ignoreElements(), historyEntry - .flatMap { podStateManager.createActiveCommand(it) } + .flatMap { podStateManager.createActiveCommand(it, basalProgram) } .ignoreElement(), command.doOnError { podStateManager.activeCommand?.sendError = it @@ -630,17 +642,18 @@ class OmnipodDashPumpPlugin @Inject constructor( history.updateFromState(podStateManager), podStateManager.updateActiveCommand() .map { handleCommandConfirmation(it) } - .ignoreElement() + .ignoreElement(), + post, ) ) } private fun handleCommandConfirmation(confirmation: CommandConfirmed) { - val historyEntry = history.getById(confirmation.historyId) + val command = confirmation.command + val historyEntry = history.getById(command.historyId) aapsLogger.debug(LTag.PUMPCOMM, "handling command confirmation: $confirmation") when (historyEntry.commandType) { OmnipodCommandType.CANCEL_TEMPORARY_BASAL, - OmnipodCommandType.SET_BASAL_PROFILE, OmnipodCommandType.RESUME_DELIVERY -> // We can't invalidate this command, // and this is why it is pumpSync-ed at this point @@ -653,6 +666,21 @@ class OmnipodDashPumpPlugin @Inject constructor( ) } + OmnipodCommandType.SET_BASAL_PROFILE -> { + if (confirmation.success) { + podStateManager.basalProgram = command.basalProgram + if (podStateManager.basalProgram == null) { + aapsLogger.warn(LTag.PUMP, "Saving null basal profile") + } + pumpSync.syncStopTemporaryBasalWithPumpId( + historyEntry.createdAt, + historyEntry.pumpId(), + PumpType.OMNIPOD_DASH, + serialNumber() + ) + } + } + OmnipodCommandType.SET_TEMPORARY_BASAL -> { // This treatment was synced before sending the command aapsLogger.info(LTag.PUMPCOMM, "temporary basal denied. PumpId: ${historyEntry.pumpId()}") diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt index b003fba0d1..78119feceb 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt @@ -17,7 +17,16 @@ class BasalProgram( fun isZeroBasal() = segments.sumBy(Segment::basalRateInHundredthUnitsPerHour) == 0 - fun rateAt(date: Date): Double = 0.0 // TODO + fun rateAt(date: Date): Double { + val instance = Calendar.getInstance() + instance.time = date + val hourOfDay = instance[Calendar.HOUR_OF_DAY] + val minuteOfHour = instance[Calendar.MINUTE] + val slotIndex = hourOfDay * 2 + minuteOfHour.div(30) + val slot = segments.find { it.startSlotIndex <= slotIndex && slotIndex< it.endSlotIndex } + val ret = (slot?.basalRateInHundredthUnitsPerHour ?: 0).toDouble() / 100 + return ret + } class Segment( val startSlotIndex: Short, diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt index 0df5b92adf..266c671c33 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt @@ -1,3 +1,3 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state -data class CommandConfirmed(val historyId: String, val success: Boolean) +data class CommandConfirmed(val command: OmnipodDashPodStateManager.ActiveCommand, val success: Boolean) 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 a1500c49ac..104f4f1cfc 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 @@ -257,13 +257,13 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( CommandConfirmationDenied -> { podState.activeCommand = null - source.onSuccess(CommandConfirmed(activeCommand.historyId, false)) + source.onSuccess(CommandConfirmed(activeCommand, false)) } CommandConfirmationSuccess -> { podState.activeCommand = null - source.onSuccess(CommandConfirmed(activeCommand.historyId, true)) + source.onSuccess(CommandConfirmed(activeCommand, true)) } NoActiveCommand -> { diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt index 48645b4920..16963b3da8 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt @@ -298,8 +298,15 @@ class OmnipodDashOverviewFragment : DaggerFragment() { */ // base basal rate - // TODO: check if delivery is suspended - podInfoBinding.baseBasalRate.text = PLACEHOLDER + podInfoBinding.baseBasalRate.text = if (podStateManager.basalProgram != null && !podStateManager.isSuspended) { + resourceHelper.gs( + R.string.pump_basebasalrate, + omnipodDashPumpPlugin.model() + .determineCorrectBasalSize(podStateManager.basalProgram!!.rateAt(Date())) + ) + } else { + PLACEHOLDER + } // total delivered podInfoBinding.totalDelivered.text = From 70eb5e6d0c769f9ed4b0101b776b95ab8c6d3d7f Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sat, 5 Jun 2021 14:52:58 +0200 Subject: [PATCH 10/11] recover unconfirmed basal --- .../plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt | 9 +++++++++ .../omnipod/dash/driver/pod/definition/BasalProgram.kt | 3 +-- 2 files changed, 10 insertions(+), 2 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 e59a225160..bc459ceef8 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 @@ -3,9 +3,11 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash import dagger.android.HasAndroidInjector import info.nightscout.androidaps.data.DetailedBolusInfo import info.nightscout.androidaps.data.PumpEnactResult +import info.nightscout.androidaps.events.EventProfileSwitchChanged import info.nightscout.androidaps.interfaces.* import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.LTag +import info.nightscout.androidaps.plugins.bus.RxBusWrapper 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 @@ -28,6 +30,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusTy 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.Command import info.nightscout.androidaps.queue.commands.CustomCommand import info.nightscout.androidaps.utils.T import info.nightscout.androidaps.utils.TimeChangeType @@ -51,6 +54,8 @@ class OmnipodDashPumpPlugin @Inject constructor( private val profileFunction: ProfileFunction, private val history: DashHistory, private val pumpSync: PumpSync, + private val rxBus: RxBusWrapper, + injector: HasAndroidInjector, aapsLogger: AAPSLogger, resourceHelper: ResourceHelper, @@ -672,6 +677,10 @@ class OmnipodDashPumpPlugin @Inject constructor( if (podStateManager.basalProgram == null) { aapsLogger.warn(LTag.PUMP, "Saving null basal profile") } + if (!commandQueue.isRunning(Command.CommandType.BASAL_PROFILE)) { + // we are late-confirming this command. before that, we answered with success:false + rxBus.send(EventProfileSwitchChanged()) + } pumpSync.syncStopTemporaryBasalWithPumpId( historyEntry.createdAt, historyEntry.pumpId(), diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt index 78119feceb..73b70126d6 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/definition/BasalProgram.kt @@ -24,8 +24,7 @@ class BasalProgram( val minuteOfHour = instance[Calendar.MINUTE] val slotIndex = hourOfDay * 2 + minuteOfHour.div(30) val slot = segments.find { it.startSlotIndex <= slotIndex && slotIndex< it.endSlotIndex } - val ret = (slot?.basalRateInHundredthUnitsPerHour ?: 0).toDouble() / 100 - return ret + return (slot?.basalRateInHundredthUnitsPerHour ?: 0).toDouble() / 100 } class Segment( From ffe3246fc095583af6d9b41e6af7ac0745bb2716 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sat, 5 Jun 2021 15:23:03 +0200 Subject: [PATCH 11/11] remove 'Using connected state for unconfirmed commands' --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 25 ++----------------- 1 file changed, 2 insertions(+), 23 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 bc459ceef8..d9d4bf7845 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 @@ -91,23 +91,7 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun isConnected(): Boolean { - // NOTE: Using connected state for unconfirmed commands - - // We are faking connection lost on unconfirmed commands. - // During normal execution, the activeCommand is set to null after a command was executed with success or we - // were not able to send that command. - // If we are not sure if the POD received the command or not, then we answer with "success" but keep this - // activeCommand set until we can confirm/deny it. - - // In order to prevent AAPS from sending us other programming commands while the current command was not - // confirmed, we are simulating "connection lost". - // We need to prevent AAPS from sending other commands because they would overwrite the ID of the last - // programming command reported by the POD. And we using that ID to confirm/deny the activeCommand. - - // The effect of answering with 'false' here is that AAPS will call connect() and will not sent any new - // commands. On connect(), we are calling getPodStatus where we are always trying to confirm/deny the - // activeCommand. - return podStateManager.activeCommand == null + return true } override fun isConnecting(): Boolean { @@ -125,12 +109,7 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun connect(reason: String) { - // See: - // NOTE: Using connected state for unconfirmed commands - if (podStateManager.activeCommand == null) { - return - } - getPumpStatus("unconfirmed command") + // empty on purpose } override fun disconnect(reason: String) {