From 3314df7bb7323d420fbb13d434d08fedd0ef1e61 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sun, 30 May 2021 18:35:33 +0200 Subject: [PATCH 01/16] implement TempBasal pumpSync and confirmation --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 241 ++++++++++++------ .../omnipod/dash/driver/event/PodEvent.kt | 2 - .../dash/driver/pod/state/ConfirmedCommand.kt | 3 + .../pod/state/OmnipodDashPodStateManager.kt | 6 +- .../state/OmnipodDashPodStateManagerImpl.kt | 43 ++-- .../pump/omnipod/dash/history/DashHistory.kt | 9 +- .../dash/history/data/HistoryRecord.kt | 9 +- .../pump/omnipod/dash/history/data/Record.kt | 2 +- .../dash/history/database/HistoryRecordDao.kt | 3 + .../driver/comm/endecrypt/EnDecryptTest.kt | 2 +- .../driver/comm/message/MessagePacketTest.kt | 2 +- .../driver/comm/message/PayloadJoinerTest.kt | 2 +- .../comm/message/PayloadSplitJoinTest.kt | 2 +- .../comm/message/PayloadSplitterTest.kt | 2 +- .../dash/driver/comm/pair/KeyExchangeTest.kt | 2 +- .../driver/comm/session/EapMessageTest.kt | 2 +- .../dash/driver/comm/session/MilenageTest.kt | 2 +- 17 files changed, 222 insertions(+), 112 deletions(-) create mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/ConfirmedCommand.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 e43de9ed52..8c6879979d 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.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 import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.DashHistory import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.BolusRecord @@ -28,11 +29,14 @@ 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.Completable import io.reactivex.Observable import io.reactivex.Single import io.reactivex.rxkotlin.blockingSubscribeBy import io.reactivex.rxkotlin.subscribeBy import org.json.JSONObject +import java.lang.IllegalArgumentException +import java.lang.IllegalStateException import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -44,6 +48,7 @@ class OmnipodDashPumpPlugin @Inject constructor( private val sp: SP, private val profileFunction: ProfileFunction, private val history: DashHistory, + private val pumpSync: PumpSync, injector: HasAndroidInjector, aapsLogger: AAPSLogger, resourceHelper: ResourceHelper, @@ -151,12 +156,12 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun setNewBasalProfile(profile: Profile): PumpEnactResult { - return executeProgrammingCommand( + return executeSimpleProgrammingCommand( history.createRecord( commandType = OmnipodCommandType.SET_BASAL_PROFILE ), omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)) - ) + ).toPumpEnactResult() } override fun isThisProfileSet(profile: Profile): Boolean = podStateManager.basalProgram?.let { @@ -240,10 +245,10 @@ class OmnipodDashPumpPlugin @Inject constructor( override fun stopBolusDelivering() { // TODO update Treatments (?) - executeProgrammingCommand( + executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.CANCEL_BOLUS), omnipodManager.stopBolus(), - ) + ).toPumpEnactResult() } override fun setTempBasalAbsolute( @@ -253,24 +258,83 @@ class OmnipodDashPumpPlugin @Inject constructor( enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType ): PumpEnactResult { - // TODO update Treatments - // TODO check for existing basal - // check existing basal(locally and maybe? get status) - // if enforceNew -> cancel it() - // else -> return error that existing basal is running - // set new temp basal - // update treatments - // profit - return executeProgrammingCommand( - history.createRecord( - commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, - tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) - ), - omnipodManager.setTempBasal( - absoluteRate, - durationInMinutes.toShort() + return Completable.concat( + listOf( + observeNoActiveTempBasal(enforceNew), + podStateManager.observeNoActiveCommand().ignoreElements(), + history.createRecord( + commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, + tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) + ).flatMap { podStateManager.createActiveCommand(it) } + .map { pumpSyncTempBasal(it, tbrType) } + .ignoreElement(), + omnipodManager.setTempBasal( + absoluteRate, + durationInMinutes.toShort() + ).ignoreElements(), + history.updateFromState(podStateManager), + podStateManager.updateActiveCommand() + .map { handleCommandConfirmation(it) } + .ignoreElement() ) + ).toPumpEnactResult() + } + + private fun pumpSyncTempBasal( + activeCommand: OmnipodDashPodStateManager.ActiveCommand, + tbrType: PumpSync.TemporaryBasalType + ): Boolean { + 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.pumpId(), + rate = record.rate, + duration = record.duration.toLong(), + isAbsolute = true, + type = tbrType, + pumpId = historyEntry.pumpId(), + pumpType = PumpType.OMNIPOD_DASH, + pumpSerial = serialNumber() ) + aapsLogger.debug(LTag.PUMP, "Pump sync temp basal: $ret") + return ret + } + + private fun observeNoActiveTempBasal(enforeNew: Boolean): Completable { + return Completable.create { source -> + val expectedState = pumpSync.expectedPumpState() + when { + expectedState.temporaryBasal == null -> + source.onComplete() + !enforeNew -> + source.onError( + IllegalStateException( + "Temporary basal already active and enforeNew is not set." + ) + ) + else -> // enforceNew == true + executeSimpleProgrammingCommand( + history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), + omnipodManager.stopTempBasal() + ) + } + } + } + + private fun observeActiveTempBasal(): Completable { + return Completable.defer { + if (pumpSync.expectedPumpState().temporaryBasal != null) + Completable.complete() + else + Completable.error( + java.lang.IllegalStateException( + "There is no active basal to cancel" + ) + ) + } } override fun setTempBasalPercent( @@ -292,13 +356,61 @@ class OmnipodDashPumpPlugin @Inject constructor( } override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult { - // TODO update Treatments - return executeProgrammingCommand( - history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), - omnipodManager.stopTempBasal() + return executeSimpleProgrammingCommand( + observeCreateHistoryEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), + command = omnipodManager.stopTempBasal(), + pre = observeActiveTempBasal(), + ).toPumpEnactResult() + } + + fun Completable.toPumpEnactResult(): PumpEnactResult { + return this.toSingleDefault(PumpEnactResult(injector).success(true).enacted(true)) + .onErrorReturnItem(PumpEnactResult(injector).success(false).enacted(false)) + .blockingGet() + } + + private fun observeCancelTempBasal(): Completable { + return Completable.concat( + listOf( + observeActiveTempBasal(), + podStateManager.observeNoActiveCommand().ignoreElements(), + history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL) + .flatMap { podStateManager.createActiveCommand(it) } + .ignoreElement(), + omnipodManager.stopTempBasal().ignoreElements(), + history.updateFromState(podStateManager), + podStateManager.updateActiveCommand() + .map { handleCommandConfirmation(it) } + .ignoreElement() + ) ) } + private fun handleCommandConfirmation(confirmation: CommandConfirmed) { + val historyEntry = history.getById(confirmation.historyId) + when (historyEntry.commandType) { + OmnipodCommandType.CANCEL_TEMPORARY_BASAL -> + if (confirmation.success) { + pumpSync.syncStopTemporaryBasalWithPumpId( + historyEntry.createdAt, + historyEntry.pumpId(), + PumpType.OMNIPOD_DASH, + serialNumber() + ) + } + OmnipodCommandType.SET_TEMPORARY_BASAL -> + if (!confirmation.success) { + pumpSync.invalidateTemporaryBasal(historyEntry.pumpId()) + } + + else -> + throw IllegalArgumentException( + "Don't know how to sync confirmed command of type: $historyEntry and " + + "succes: ${confirmation.success}" + ) + } + } + override fun cancelExtendedBolus(): PumpEnactResult { // TODO i18n return PumpEnactResult(injector).success(false).enacted(false) @@ -414,26 +526,26 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun suspendDelivery(): PumpEnactResult { - return executeProgrammingCommand( + return executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.RESUME_DELIVERY), omnipodManager.suspendDelivery() - ) + ).toPumpEnactResult() } private fun resumeDelivery(): PumpEnactResult { return profileFunction.getProfile()?.let { - executeProgrammingCommand( + executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.RESUME_DELIVERY), omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)) - ) + ).toPumpEnactResult() } ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n } private fun deactivatePod(): PumpEnactResult { - return executeProgrammingCommand( + return executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.DEACTIVATE_POD), omnipodManager.deactivatePod() - ) + ).toPumpEnactResult() } private fun handleTimeChange(): PumpEnactResult { @@ -447,10 +559,10 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun playTestBeep(): PumpEnactResult { - return executeProgrammingCommand( + return executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.PLAY_TEST_BEEP), omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP) - ) + ).toPumpEnactResult() } override fun timezoneOrDSTChanged(timeChangeType: TimeChangeType) { @@ -474,50 +586,27 @@ class OmnipodDashPumpPlugin @Inject constructor( commandQueue.customCommand(CommandHandleTimeChange(false), null) } - private fun observeAddNewActiveCommandToHistory(observeCreateHistoryEntry: Single): Observable { - return observeCreateHistoryEntry.flatMapObservable { - podStateManager.createActiveCommand(it).toObservable() + private fun executeSimpleProgrammingCommand( + observeCreateHistoryEntry: Single, + command: Observable, + pre: Completable = Completable.complete(), + ): Completable { + return Completable.concat( + listOf( + pre, + podStateManager.observeNoActiveCommand().ignoreElements(), + observeCreateHistoryEntry + .flatMap { podStateManager.createActiveCommand(it) } + .ignoreElement(), + command.ignoreElements(), + history.updateFromState(podStateManager), + podStateManager.updateActiveCommand() + .map { handleCommandConfirmation(it) } + .ignoreElement() + ) + ).doOnError { error -> + aapsLogger.error(LTag.PUMP, "Error executing command", error) + podStateManager.maybeMarkActiveCommandFailed() } } - - private fun executeProgrammingCommand( - observeCreateHistoryEntry: Single, - command: Observable - ): PumpEnactResult { - return Single.create { source -> - Observable.concat( - listOf( - podStateManager.observeNoActiveCommand(), - observeAddNewActiveCommandToHistory(observeCreateHistoryEntry), - 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) - // Here we assume that onError will be called only BEFORE we manage to send a command - // If it gets called later, we will have the command as "not sent" in history and will not try to - // get it's final status, even if it was send - - podStateManager.maybeMarkActiveCommandFailed() - source.onSuccess( - PumpEnactResult(injector).success(false).enacted(false).comment(throwable.toString()) - ) - }, - onComplete = { - aapsLogger.debug("Command completed") - source.onSuccess( - PumpEnactResult(injector).success(true).enacted(true) - ) - } - ) - }.blockingGet() - } } 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 c2a721c208..08d33a43fe 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,6 +65,4 @@ sealed class PodEvent { return "ResponseReceived(command=$command, response=$response)" } } - - data class CommandConfirmed(val historyId: String, val success: Boolean) : PodEvent() } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/ConfirmedCommand.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/ConfirmedCommand.kt new file mode 100644 index 0000000000..d5f57243d8 --- /dev/null +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/ConfirmedCommand.kt @@ -0,0 +1,3 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state + +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/OmnipodDashPodStateManager.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/OmnipodDashPodStateManager.kt index 9fff97203d..2d57a6a9ec 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 @@ -8,9 +8,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response. 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 io.reactivex.Observable +import io.reactivex.Single import java.io.Serializable import java.util.* @@ -66,8 +66,8 @@ interface OmnipodDashPodStateManager { fun updateFromPairing(uniqueId: Id, pairResult: PairResult) fun reset() - fun createActiveCommand(historyId: String): Completable - fun updateActiveCommand(): Maybe + fun createActiveCommand(historyId: String): Single + fun updateActiveCommand(): Maybe fun observeNoActiveCommand(): Observable fun maybeMarkActiveCommandFailed() 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 a8e31905bc..af2ef287e8 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 @@ -17,9 +17,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response. 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 io.reactivex.Observable +import io.reactivex.Single import java.io.Serializable import java.util.* import javax.inject.Inject @@ -183,21 +183,24 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( get() = podState.activeCommand @Synchronized - override fun createActiveCommand(historyId: String) = Completable.create { source -> - if (activeCommand == null) { - podState.activeCommand = OmnipodDashPodStateManager.ActiveCommand( - podState.messageSequenceNumber, - createdRealtime = SystemClock.elapsedRealtime(), - historyId = historyId - ) - source.onComplete() - } else { - source.onError( - java.lang.IllegalStateException( - "Trying to send a command " + - "and the last command was not confirmed" + override fun createActiveCommand(historyId: String): Single { + return Single.create { source -> + if (activeCommand == null) { + val command = OmnipodDashPodStateManager.ActiveCommand( + podState.messageSequenceNumber, + createdRealtime = SystemClock.elapsedRealtime(), + historyId = historyId ) - ) + podState.activeCommand = command + source.onSuccess(command) + } else { + source.onError( + java.lang.IllegalStateException( + "Trying to send a command " + + "and the last command was not confirmed" + ) + ) + } } } @@ -228,7 +231,7 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( } @Synchronized - override fun updateActiveCommand() = Maybe.create { source -> + override fun updateActiveCommand() = Maybe.create { source -> podState.activeCommand?.run { logger.debug( "Trying to confirm active command with parameters: $activeCommand " + @@ -241,12 +244,12 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( else { podState.activeCommand = null if (sequenceNumberOfLastProgrammingCommand == sequence) - source.onSuccess(PodEvent.CommandConfirmed(historyId, true)) + source.onSuccess(CommandConfirmed(historyId, true)) else - source.onSuccess(PodEvent.CommandConfirmed(historyId, false)) + source.onSuccess(CommandConfirmed(historyId, false)) } - } - ?: source.onComplete() // no active programming command + } ?: source.onComplete() + // no active programming command } 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 66fc8f614b..dea243e814 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 @@ -35,6 +35,14 @@ class DashHistory @Inject constructor( currentTimeMillis() ) + fun getById(id: String): HistoryRecord { + val entry = dao.byIdBlocking(id) + if (entry == null) { + throw java.lang.IllegalArgumentException("history entry [$id] not found") + } + return historyMapper.entityToDomain(entry) + } + @Suppress("ReturnCount") fun createRecord( commandType: OmnipodCommandType, @@ -77,7 +85,6 @@ class DashHistory @Inject constructor( fun updateFromState(podState: OmnipodDashPodStateManager) = Completable.defer { podState.activeCommand?.run { when { - createdRealtime <= podState.lastStatusResponseReceived && sequence == podState.sequenceNumberOfLastProgrammingCommand -> dao.setInitialResult(historyId, InitialResult.SENT) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt index 56aa2dc6b2..65a2d5294c 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/history/data/HistoryRecord.kt @@ -1,6 +1,8 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data +import com.github.guepardoapps.kulid.ULID import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType +import java.nio.ByteBuffer data class HistoryRecord( val id: String, // ULID @@ -11,4 +13,9 @@ data class HistoryRecord( val record: Record?, val resolvedResult: ResolvedResult?, val resolvedAt: Long? -) +) { + fun pumpId(): Long { + val entropy = ULID.getEntropy(id) + return ByteBuffer.wrap(entropy).getLong() + } +} 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 bedeb1e4f5..188adfc848 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 @@ -14,7 +14,7 @@ enum class BolusType { companion object { fun fromBolusInfoBolusType(type: DetailedBolusInfo.BolusType): BolusType { return when (type) { - DetailedBolusInfo.BolusType.SMB -> SMB; + DetailedBolusInfo.BolusType.SMB -> SMB else -> DEFAULT } } 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 21ff7dbced..84ca7f9f4d 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 @@ -22,6 +22,9 @@ abstract class HistoryRecordDao { @Query("SELECT * from historyrecords WHERE createdAt <= :since") abstract fun allSince(since: Long): Single> + @Query("SELECT * FROM historyrecords WHERE id = :id LIMIT 1") + abstract fun byIdBlocking(id: String): HistoryRecordEntity? + @Insert(onConflict = OnConflictStrategy.REPLACE) abstract fun saveBlocking(historyRecordEntity: HistoryRecordEntity) diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt index 36a07eface..e6ad2844dc 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecryptTest.kt @@ -1,8 +1,8 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt +import info.nightscout.androidaps.extensions.toHex import info.nightscout.androidaps.logging.AAPSLoggerTest import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket -import info.nightscout.androidaps.extensions.toHex import org.junit.Assert import org.junit.Test import org.spongycastle.util.encoders.Hex diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt index e6a25e3eb6..6ca71c6b94 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessagePacketTest.kt @@ -1,9 +1,9 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message import com.google.crypto.tink.subtle.Hex +import info.nightscout.androidaps.extensions.toHex import info.nightscout.androidaps.logging.AAPSLoggerTest import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id -import info.nightscout.androidaps.extensions.toHex import org.junit.Assert.assertEquals import org.junit.Test diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoinerTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoinerTest.kt index b1a1d51519..0ff9673c1d 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoinerTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadJoinerTest.kt @@ -1,8 +1,8 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message import com.google.crypto.tink.subtle.Hex -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadJoiner import info.nightscout.androidaps.extensions.toHex +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadJoiner import org.junit.Assert.assertEquals import org.junit.Test diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitJoinTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitJoinTest.kt index 6a12e87bd5..ffc3510d57 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitJoinTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitJoinTest.kt @@ -1,8 +1,8 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message +import info.nightscout.androidaps.extensions.toHex import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadJoiner import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadSplitter -import info.nightscout.androidaps.extensions.toHex import org.junit.Assert.assertEquals import org.junit.Test import java.util.* diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitterTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitterTest.kt index bd08be97f6..a8f148acb4 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitterTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/PayloadSplitterTest.kt @@ -1,8 +1,8 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message import com.google.crypto.tink.subtle.Hex -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadSplitter import info.nightscout.androidaps.extensions.toHex +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadSplitter import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Test diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchangeTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchangeTest.kt index 6041748403..237d1041ad 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchangeTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/pair/KeyExchangeTest.kt @@ -1,9 +1,9 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair +import info.nightscout.androidaps.extensions.toHex import info.nightscout.androidaps.logging.AAPSLoggerTest import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.RandomByteGenerator import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.X25519KeyGenerator -import info.nightscout.androidaps.extensions.toHex import org.junit.Assert.assertEquals import org.junit.Test import org.mockito.ArgumentMatchers.anyInt diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessageTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessageTest.kt index fff01c494b..1289b9c93a 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessageTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/EapMessageTest.kt @@ -1,7 +1,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session -import info.nightscout.androidaps.logging.AAPSLoggerTest import info.nightscout.androidaps.extensions.toHex +import info.nightscout.androidaps.logging.AAPSLoggerTest import org.junit.Assert import org.junit.Test import org.spongycastle.util.encoders.Hex diff --git a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/MilenageTest.kt b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/MilenageTest.kt index 4fecfc01f9..107bfd7a03 100644 --- a/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/MilenageTest.kt +++ b/omnipod-dash/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/MilenageTest.kt @@ -1,7 +1,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session -import info.nightscout.androidaps.logging.AAPSLoggerTest import info.nightscout.androidaps.extensions.toHex +import info.nightscout.androidaps.logging.AAPSLoggerTest import org.junit.Assert import org.junit.Test import org.spongycastle.util.encoders.Hex From 3b26068fafd320bfe12a205f201ed378a4020b5d Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sun, 30 May 2021 19:03:26 +0200 Subject: [PATCH 02/16] set temp basal beeps --- .../plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt | 5 ++++- .../pump/omnipod/dash/driver/OmnipodDashManager.kt | 2 +- .../pump/omnipod/dash/driver/OmnipodDashManagerImpl.kt | 10 +++++----- 3 files changed, 10 insertions(+), 7 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 8c6879979d..d4013821dd 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 @@ -258,6 +258,8 @@ class OmnipodDashPumpPlugin @Inject constructor( enforceNew: Boolean, tbrType: PumpSync.TemporaryBasalType ): PumpEnactResult { + val tempBasalBeeps = sp.getBoolean(R.string.key_omnipod_common_tbr_beeps_enabled, false) + return Completable.concat( listOf( observeNoActiveTempBasal(enforceNew), @@ -270,7 +272,8 @@ class OmnipodDashPumpPlugin @Inject constructor( .ignoreElement(), omnipodManager.setTempBasal( absoluteRate, - durationInMinutes.toShort() + durationInMinutes.toShort(), + tempBasalBeeps, ).ignoreElements(), history.updateFromState(podStateManager), podStateManager.updateActiveCommand() diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManager.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManager.kt index 2b9333bdab..b6dccbf118 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManager.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/OmnipodDashManager.kt @@ -24,7 +24,7 @@ interface OmnipodDashManager { fun setTime(): Observable - fun setTempBasal(rate: Double, durationInMinutes: Short): Observable + fun setTempBasal(rate: Double, durationInMinutes: Short, tempBasalBeeps: Boolean): Observable fun stopTempBasal(): Observable 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 5de1c4fd1f..e92f578b11 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 @@ -460,14 +460,14 @@ class OmnipodDashManagerImpl @Inject constructor( return Observable.empty() } - private fun observeSendProgramTempBasalCommand(rate: Double, durationInMinutes: Short): Observable { + private fun observeSendProgramTempBasalCommand(rate: Double, durationInMinutes: Short, tempBasalBeeps: Boolean): Observable { return Observable.defer { - // TODO cancel current temp basal (if active) bleManager.sendCommand( ProgramTempBasalCommand.Builder() .setSequenceNumber(podStateManager.messageSequenceNumber) .setUniqueId(podStateManager.uniqueId!!.toInt()) .setNonce(NONCE) + .setProgramReminder(ProgramReminder(tempBasalBeeps, tempBasalBeeps, 0)) .setRateInUnitsPerHour(rate) .setDurationInMinutes(durationInMinutes) .build(), @@ -476,11 +476,11 @@ class OmnipodDashManagerImpl @Inject constructor( } } - override fun setTempBasal(rate: Double, durationInMinutes: Short): Observable { + override fun setTempBasal(rate: Double, durationInMinutes: Short, tempBasalBeeps: Boolean): Observable { return Observable.concat( observePodRunning, observeConnectToPod, - observeSendProgramTempBasalCommand(rate, durationInMinutes) + observeSendProgramTempBasalCommand(rate, durationInMinutes, tempBasalBeeps) ) // TODO these would be common for any observable returned in a public function in this class .doOnNext(PodEventInterceptor()) @@ -700,7 +700,7 @@ class OmnipodDashManagerImpl @Inject constructor( inner class ErrorInterceptor : Consumer { override fun accept(throwable: Throwable) { - logger.debug(LTag.PUMP, "Intercepted error in OmnipodDashManagerImpl: ${throwable.javaClass.simpleName}") + logger.debug(LTag.PUMP, "Intercepted error in OmnipodDashManagerImpl: ${throwable}") } } From 91957930ed3d9b1684a35c2369613a173bec00a5 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sun, 30 May 2021 22:49:35 +0200 Subject: [PATCH 03/16] display bluetooth connection status. display deliveryStatus. display lastConnection --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 4 +- .../dash/driver/comm/OmnipodDashBleManager.kt | 4 +- .../driver/comm/OmnipodDashBleManagerImpl.kt | 19 ++--- .../dash/driver/comm/session/Connection.kt | 17 +++- .../driver/comm/status/ConnectionStatus.kt | 10 --- .../pod/state/OmnipodDashPodStateManager.kt | 5 ++ .../state/OmnipodDashPodStateManagerImpl.kt | 11 ++- .../dash/ui/OmnipodDashOverviewFragment.kt | 44 +++++++---- ...omnipod_dash_overview_bluetooth_status.xml | 78 +++++++++---------- 9 files changed, 109 insertions(+), 83 deletions(-) delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/status/ConnectionStatus.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 d4013821dd..721907f831 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 @@ -407,8 +407,8 @@ class OmnipodDashPumpPlugin @Inject constructor( } else -> - throw IllegalArgumentException( - "Don't know how to sync confirmed command of type: $historyEntry and " + + aapsLogger.warn(LTag.PUMP, + "Will not sync confirmed command of type: $historyEntry and " + "succes: ${confirmation.success}" ) } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManager.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManager.kt index f3708c8031..b2400713c7 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManager.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/OmnipodDashBleManager.kt @@ -1,6 +1,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.ConnectionState import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response @@ -11,7 +11,7 @@ interface OmnipodDashBleManager { fun sendCommand(cmd: Command, responseType: KClass): Observable - fun getStatus(): ConnectionStatus + fun getStatus(): ConnectionState fun connect(): Observable 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 0b9eee3a52..4637d52b5c 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 @@ -11,7 +11,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptio import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.pair.LTKExchanger import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.* -import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response @@ -34,7 +33,6 @@ class OmnipodDashBleManagerImpl @Inject constructor( context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter private var connection: Connection? = null - private var status: ConnectionStatus = ConnectionStatus.IDLE private val ids = Ids(podState) override fun sendCommand(cmd: Command, responseType: KClass): Observable = @@ -85,13 +83,9 @@ class OmnipodDashBleManagerImpl @Inject constructor( ?: throw NotConnectedException("Missing session") } - override fun getStatus(): ConnectionStatus { - // TODO is this used? - var s: ConnectionStatus - synchronized(status) { - s = status - } - return s + override fun getStatus(): ConnectionState { + return connection?.let{ getStatus() } + ?: NotConnected } override fun connect(): Observable = Observable.create { emitter -> @@ -106,9 +100,10 @@ class OmnipodDashBleManagerImpl @Inject constructor( ?: throw FailedToConnectException("Missing bluetoothAddress, activate the pod first") val podDevice = bluetoothAdapter.getRemoteDevice(podAddress) val conn = connection - ?: Connection(podDevice, aapsLogger, context) + ?: 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()) @@ -121,7 +116,7 @@ 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) @@ -190,7 +185,7 @@ class OmnipodDashBleManagerImpl @Inject constructor( emitter.onNext(PodEvent.BluetoothConnecting) val podDevice = bluetoothAdapter.getRemoteDevice(podAddress) - val conn = Connection(podDevice, aapsLogger, context) + val conn = Connection(podDevice, aapsLogger, context, podState) connection = conn emitter.onNext(PodEvent.BluetoothConnected(podAddress)) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt index 104b7fc3a2..71bccf91b6 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt @@ -20,6 +20,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CmdBl import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.DataBleIO import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.IncomingPackets import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager sealed class ConnectionState @@ -29,7 +30,8 @@ object NotConnected : ConnectionState() class Connection( private val podDevice: BluetoothDevice, private val aapsLogger: AAPSLogger, - context: Context + context: Context, + private val podState: OmnipodDashPodStateManager ) : DisconnectHandler { private val incomingPackets = IncomingPackets() @@ -50,13 +52,15 @@ class Connection( aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to ${podDevice.address}") val autoConnect = false - + podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING gattConnection = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE) // OnDisconnect can be called after this point!!! val state = waitForConnection() if (state !is Connected) { + podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED throw FailedToConnectException(podDevice.address) } + podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks) val discoveredCharacteristics = discoverer.discoverServices() cmdBleIO = CmdBleIO( @@ -90,13 +94,18 @@ class Connection( disconnect() } aapsLogger.debug("Connecting") + podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING + if (!gattConnection.connect()) { throw FailedToConnectException("connect() returned false") } - if (waitForConnection() is NotConnected) { + if (waitForConnection() !is Connected) { + podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED throw FailedToConnectException(podDevice.address) } + podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED + val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks) val discovered = discoverer.discoverServices() @@ -110,6 +119,8 @@ class Connection( fun disconnect() { aapsLogger.debug(LTag.PUMPBTCOMM, "Disconnecting") + podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED + gattConnection.disconnect() bleCommCallbacks.resetConnection() session = null diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/status/ConnectionStatus.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/status/ConnectionStatus.kt deleted file mode 100644 index 6977f342f3..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/status/ConnectionStatus.kt +++ /dev/null @@ -1,10 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status - -enum class ConnectionStatus { - IDLE, - BUSY, - CONNECTING, - ESTABLISHING_SESSION, - PAIRING, - RUNNING_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 2d57a6a9ec..a1030d61eb 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 @@ -22,6 +22,7 @@ interface OmnipodDashPodStateManager { val isSuspended: Boolean val isPodRunning: Boolean var lastConnection: Long + var bluetoothConnectionState: BluetoothConnectionState val lastUpdatedSystem: Long // System.currentTimeMillis() val lastStatusResponseReceived: Long @@ -79,4 +80,8 @@ interface OmnipodDashPodStateManager { ) // TODO: set created to "now" on boot data class TempBasal(val startTime: Long, val rate: Double, val durationInMinutes: Short) : Serializable + + enum class BluetoothConnectionState { + CONNECTING, CONNECTED, DISCONNECTED + } } 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 af2ef287e8..f00b0d1dae 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 @@ -160,6 +160,14 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( override val lastStatusResponseReceived: Long get() = podState.lastStatusResponseReceived + override var bluetoothConnectionState: OmnipodDashPodStateManager.BluetoothConnectionState + get() = podState.bluetoothConnectionState + set(bluetoothConnectionState) { + podState.bluetoothConnectionState = bluetoothConnectionState + rxBus.send(EventOmnipodDashPumpValuesChanged()) + // do not store + } + override fun increaseMessageSequenceNumber() { podState.messageSequenceNumber = ((podState.messageSequenceNumber.toInt() + 1) and 0x0f).toShort() store() @@ -380,7 +388,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( var lastConnection: Long = 0 var lastUpdatedSystem: Long = 0 var lastStatusResponseReceived: Long = 0 - + var bluetoothConnectionState: OmnipodDashPodStateManager.BluetoothConnectionState = + OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED var messageSequenceNumber: Short = 0 var sequenceNumberOfLastProgrammingCommand: Short? = null var activationTime: Long? = null 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 95fdf5b155..3fe453d235 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 @@ -13,6 +13,7 @@ import info.nightscout.androidaps.Constants import info.nightscout.androidaps.activities.ErrorHelperActivity import info.nightscout.androidaps.events.EventPreferenceChange import info.nightscout.androidaps.interfaces.CommandQueueProvider +import info.nightscout.androidaps.interfaces.PumpSync import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.general.overview.events.EventDismissNotification import info.nightscout.androidaps.plugins.general.overview.notifications.Notification @@ -41,6 +42,7 @@ import info.nightscout.androidaps.utils.ui.UIRunnable import io.reactivex.disposables.CompositeDisposable import io.reactivex.rxkotlin.plusAssign import org.apache.commons.lang3.StringUtils +import org.joda.time.DateTime import org.joda.time.Duration import java.util.* import javax.inject.Inject @@ -58,6 +60,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() { @Inject lateinit var sp: SP @Inject lateinit var dateUtil: DateUtil @Inject lateinit var aapsSchedulers: AapsSchedulers + @Inject lateinit var pumpSync: PumpSync + companion object { @@ -211,11 +215,26 @@ class OmnipodDashOverviewFragment : DaggerFragment() { private fun updateUi() { // TODO update bluetooth status + updateBluetoothStatus() updateOmnipodStatus() updatePodActionButtons() updateQueueStatus() } + private fun updateBluetoothStatus(){ + bluetoothStatusBinding.omnipodDashBluetoothAddress.text = podStateManager.bluetoothAddress + ?: PLACEHOLDER + bluetoothStatusBinding.omnipodDashBluetoothStatus.text = + when (podStateManager.bluetoothConnectionState) { + OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED -> + "{fa-bluetooth}" + OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED -> + "{fa-bluetooth-b}" + OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTING -> + "{fa-bluetooth-b spin}" + } + } + private fun updateOmnipodStatus() { updateLastConnection() updateLastBolus() @@ -246,10 +265,9 @@ class OmnipodDashOverviewFragment : DaggerFragment() { podStateManager.firmwareVersion.toString(), podStateManager.bluetoothVersion.toString() ) - + podInfoBinding.timeOnPod.text = podStateManager.minutesSinceActivation.toString() + " minutes" // TODO /* - podInfoBinding.timeOnPod.text = readableZonedTime(podStateManager.time) podInfoBinding.timeOnPod.setTextColor(if (podStateManager.timeDeviatesMoreThan(OmnipodConstants.TIME_DEVIATION_THRESHOLD)) { Color.RED } else { @@ -373,7 +391,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() { if (podStateManager.isSuspended) { resourceHelper.gs(R.string.omnipod_common_pod_status_suspended) } else { - resourceHelper.gs(R.string.omnipod_common_pod_status_running) + resourceHelper.gs(R.string.omnipod_common_pod_status_running) + + podStateManager.deliveryStatus?.let{ " " + podStateManager.deliveryStatus.toString() } } // TODO /* @@ -421,10 +440,11 @@ class OmnipodDashOverviewFragment : DaggerFragment() { } private fun updateTempBasal() { - if (podStateManager.isActivationCompleted && podStateManager.tempBasalActive) { - val startTime = podStateManager.tempBasal!!.startTime - val rate = podStateManager.tempBasal!!.rate - val duration = podStateManager.tempBasal!!.durationInMinutes + val tempBasal = podStateManager.tempBasal + if (podStateManager.isActivationCompleted && podStateManager.tempBasalActive && tempBasal != null) { + val startTime = tempBasal.startTime + val rate = tempBasal.rate + val duration = tempBasal.durationInMinutes val minutesRunning = 0 // TODO @@ -560,12 +580,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() { } */ - private fun readableDuration(time: Long): String { - // TODO - return "TODO" - - /* - val duration = Duration(dateTime, DateTime.now()) + private fun readableDuration(dateTime: Long): String { + val duration = Duration(dateTime, System.currentTimeMillis()) val hours = duration.standardHours.toInt() val minutes = duration.standardMinutes.toInt() val seconds = duration.standardSeconds.toInt() @@ -599,7 +615,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() { return resourceHelper.gs(R.string.omnipod_common_time_ago, resourceHelper.gq(R.plurals.omnipod_common_days, days, days)) } } - */ + } private fun isQueueEmpty(): Boolean { diff --git a/omnipod-dash/src/main/res/layout/omnipod_dash_overview_bluetooth_status.xml b/omnipod-dash/src/main/res/layout/omnipod_dash_overview_bluetooth_status.xml index d9d95b3a60..8d7ac5e903 100644 --- a/omnipod-dash/src/main/res/layout/omnipod_dash_overview_bluetooth_status.xml +++ b/omnipod-dash/src/main/res/layout/omnipod_dash_overview_bluetooth_status.xml @@ -1,44 +1,6 @@ - - - - - - - - - - - + + + + + + + + + From 3ca88ef51b9c86e71d15c1e3315dd34985eb65a9 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sun, 30 May 2021 23:09:15 +0200 Subject: [PATCH 04/16] bugfix: set the tempbasal timestamp to the time when the historyEntry was created, not a random number :) --- .../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 721907f831..bf65106bce 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 @@ -293,7 +293,7 @@ class OmnipodDashPumpPlugin @Inject constructor( throw IllegalArgumentException("Illegal recording in history: $record. Expected a temp basal") } val ret = pumpSync.syncTemporaryBasalWithPumpId( - timestamp = historyEntry.pumpId(), + timestamp = historyEntry.createdAt, rate = record.rate, duration = record.duration.toLong(), isAbsolute = true, From c989c6a1c506e2c258aefdba557b74f52eac6346 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sun, 30 May 2021 23:55:47 +0200 Subject: [PATCH 05/16] duration is in ms --- .../plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt | 3 ++- 1 file changed, 2 insertions(+), 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 bf65106bce..04a6f36b6e 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 @@ -26,6 +26,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.history.data.TempBas 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.T import info.nightscout.androidaps.utils.TimeChangeType import info.nightscout.androidaps.utils.resources.ResourceHelper import info.nightscout.androidaps.utils.sharedPreferences.SP @@ -295,7 +296,7 @@ class OmnipodDashPumpPlugin @Inject constructor( val ret = pumpSync.syncTemporaryBasalWithPumpId( timestamp = historyEntry.createdAt, rate = record.rate, - duration = record.duration.toLong(), + duration = T.mins(record.duration.toLong()).msecs(), isAbsolute = true, type = tbrType, pumpId = historyEntry.pumpId(), From 8e64ca134ffbf62ad80cce1f682dc240ad84f688 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Mon, 31 May 2021 00:01:54 +0200 Subject: [PATCH 06/16] ktlintFormat --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 5 ++-- .../dash/driver/OmnipodDashManagerImpl.kt | 2 +- .../driver/comm/OmnipodDashBleManagerImpl.kt | 2 +- .../dash/driver/comm/session/Connection.kt | 1 - .../dash/ui/OmnipodDashOverviewFragment.kt | 27 ++++++++++--------- 5 files changed, 19 insertions(+), 18 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 04a6f36b6e..860b3e0122 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 @@ -296,7 +296,7 @@ class OmnipodDashPumpPlugin @Inject constructor( val ret = pumpSync.syncTemporaryBasalWithPumpId( timestamp = historyEntry.createdAt, rate = record.rate, - duration = T.mins(record.duration.toLong()).msecs(), + duration = T.mins(record.duration.toLong()).msecs(), isAbsolute = true, type = tbrType, pumpId = historyEntry.pumpId(), @@ -408,7 +408,8 @@ class OmnipodDashPumpPlugin @Inject constructor( } else -> - aapsLogger.warn(LTag.PUMP, + aapsLogger.warn( + LTag.PUMP, "Will not sync confirmed command of type: $historyEntry and " + "succes: ${confirmation.success}" ) 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 e92f578b11..0d44fd4b3f 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 @@ -700,7 +700,7 @@ class OmnipodDashManagerImpl @Inject constructor( inner class ErrorInterceptor : Consumer { override fun accept(throwable: Throwable) { - logger.debug(LTag.PUMP, "Intercepted error in OmnipodDashManagerImpl: ${throwable}") + logger.debug(LTag.PUMP, "Intercepted error in OmnipodDashManagerImpl: $throwable") } } 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 4637d52b5c..622b3663a3 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 @@ -84,7 +84,7 @@ class OmnipodDashBleManagerImpl @Inject constructor( } override fun getStatus(): ConnectionState { - return connection?.let{ getStatus() } + return connection?.let { getStatus() } ?: NotConnected } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt index 71bccf91b6..fb3ddc1cb5 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt @@ -106,7 +106,6 @@ class Connection( } podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED - val discoverer = ServiceDiscoverer(aapsLogger, gattConnection, bleCommCallbacks) val discovered = discoverer.discoverServices() dataBleIO.characteristic = discovered[CharacteristicType.DATA]!! 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 3fe453d235..9bd6f0015f 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 @@ -42,7 +42,6 @@ import info.nightscout.androidaps.utils.ui.UIRunnable import io.reactivex.disposables.CompositeDisposable import io.reactivex.rxkotlin.plusAssign import org.apache.commons.lang3.StringUtils -import org.joda.time.DateTime import org.joda.time.Duration import java.util.* import javax.inject.Inject @@ -62,7 +61,6 @@ class OmnipodDashOverviewFragment : DaggerFragment() { @Inject lateinit var aapsSchedulers: AapsSchedulers @Inject lateinit var pumpSync: PumpSync - companion object { private const val REFRESH_INTERVAL_MILLIS = 15 * 1000L // 15 seconds @@ -221,7 +219,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() { updateQueueStatus() } - private fun updateBluetoothStatus(){ + private fun updateBluetoothStatus() { bluetoothStatusBinding.omnipodDashBluetoothAddress.text = podStateManager.bluetoothAddress ?: PLACEHOLDER bluetoothStatusBinding.omnipodDashBluetoothStatus.text = @@ -392,7 +390,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() { resourceHelper.gs(R.string.omnipod_common_pod_status_suspended) } else { resourceHelper.gs(R.string.omnipod_common_pod_status_running) + - podStateManager.deliveryStatus?.let{ " " + podStateManager.deliveryStatus.toString() } + podStateManager.deliveryStatus?.let { " " + podStateManager.deliveryStatus.toString() } } // TODO /* @@ -586,36 +584,39 @@ class OmnipodDashOverviewFragment : DaggerFragment() { val minutes = duration.standardMinutes.toInt() val seconds = duration.standardSeconds.toInt() when { - seconds < 10 -> { + seconds < 10 -> { return resourceHelper.gs(R.string.omnipod_common_moments_ago) } - seconds < 60 -> { + seconds < 60 -> { return resourceHelper.gs(R.string.omnipod_common_less_than_a_minute_ago) } - seconds < 60 * 60 -> { // < 1 hour + seconds < 60 * 60 -> { // < 1 hour return resourceHelper.gs(R.string.omnipod_common_time_ago, resourceHelper.gq(R.plurals.omnipod_common_minutes, minutes, minutes)) } seconds < 24 * 60 * 60 -> { // < 1 day val minutesLeft = minutes % 60 if (minutesLeft > 0) - return resourceHelper.gs(R.string.omnipod_common_time_ago, - resourceHelper.gs(R.string.omnipod_common_composite_time, resourceHelper.gq(R.plurals.omnipod_common_hours, hours, hours), resourceHelper.gq(R.plurals.omnipod_common_minutes, minutesLeft, minutesLeft))) + return resourceHelper.gs( + R.string.omnipod_common_time_ago, + resourceHelper.gs(R.string.omnipod_common_composite_time, resourceHelper.gq(R.plurals.omnipod_common_hours, hours, hours), resourceHelper.gq(R.plurals.omnipod_common_minutes, minutesLeft, minutesLeft)) + ) return resourceHelper.gs(R.string.omnipod_common_time_ago, resourceHelper.gq(R.plurals.omnipod_common_hours, hours, hours)) } - else -> { + else -> { val days = hours / 24 val hoursLeft = hours % 24 if (hoursLeft > 0) - return resourceHelper.gs(R.string.omnipod_common_time_ago, - resourceHelper.gs(R.string.omnipod_common_composite_time, resourceHelper.gq(R.plurals.omnipod_common_days, days, days), resourceHelper.gq(R.plurals.omnipod_common_hours, hoursLeft, hoursLeft))) + return resourceHelper.gs( + R.string.omnipod_common_time_ago, + resourceHelper.gs(R.string.omnipod_common_composite_time, resourceHelper.gq(R.plurals.omnipod_common_days, days, days), resourceHelper.gq(R.plurals.omnipod_common_hours, hoursLeft, hoursLeft)) + ) return resourceHelper.gs(R.string.omnipod_common_time_ago, resourceHelper.gq(R.plurals.omnipod_common_days, days, days)) } } - } private fun isQueueEmpty(): Boolean { From a2b3ab5991e7154bd7db9cffe2006456559be585 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Mon, 31 May 2021 00:04:25 +0200 Subject: [PATCH 07/16] add TODO --- .../plugins/pump/omnipod/dash/ui/OmnipodDashOverviewFragment.kt | 1 + 1 file changed, 1 insertion(+) 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 9bd6f0015f..f79180f061 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 @@ -391,6 +391,7 @@ class OmnipodDashOverviewFragment : DaggerFragment() { } else { resourceHelper.gs(R.string.omnipod_common_pod_status_running) + podStateManager.deliveryStatus?.let { " " + podStateManager.deliveryStatus.toString() } + // TODO Display deliveryStatus in a nice way } // TODO /* From 7dc01cb1f84586428dff439232ce7e382bcb1e3f Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Mon, 31 May 2021 00:13:52 +0200 Subject: [PATCH 08/16] add comments --- .../plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt | 4 ++++ 1 file changed, 4 insertions(+) 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 860b3e0122..19df819b2b 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 @@ -282,6 +282,7 @@ class OmnipodDashPumpPlugin @Inject constructor( .ignoreElement() ) ).toPumpEnactResult() + // TODO: on error, invalidateTemporaryBasal or sync it only after sending the command } private fun pumpSyncTempBasal( @@ -394,6 +395,8 @@ class OmnipodDashPumpPlugin @Inject constructor( val historyEntry = history.getById(confirmation.historyId) when (historyEntry.commandType) { OmnipodCommandType.CANCEL_TEMPORARY_BASAL -> + // We can't invalidate this command, + // and this is why it pumpSync-ed at this point if (confirmation.success) { pumpSync.syncStopTemporaryBasalWithPumpId( historyEntry.createdAt, @@ -403,6 +406,7 @@ class OmnipodDashPumpPlugin @Inject constructor( ) } OmnipodCommandType.SET_TEMPORARY_BASAL -> + // This treatment was synced before sending the command if (!confirmation.success) { pumpSync.invalidateTemporaryBasal(historyEntry.pumpId()) } From 9d61c8ee8a91e6796b8df550d1cb6d172add16c4 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Mon, 31 May 2021 21:00:54 +0200 Subject: [PATCH 09/16] remove unused function --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 26 ++++--------------- 1 file changed, 5 insertions(+), 21 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 19df819b2b..85504d0e19 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 @@ -309,18 +309,19 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun observeNoActiveTempBasal(enforeNew: Boolean): Completable { - return Completable.create { source -> + return Completable.defer { val expectedState = pumpSync.expectedPumpState() when { expectedState.temporaryBasal == null -> - source.onComplete() + Completable.complete() !enforeNew -> - source.onError( + Completable.error( IllegalStateException( "Temporary basal already active and enforeNew is not set." ) ) else -> // enforceNew == true + // TODO: chain with the completable? executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), omnipodManager.stopTempBasal() @@ -374,29 +375,12 @@ class OmnipodDashPumpPlugin @Inject constructor( .blockingGet() } - private fun observeCancelTempBasal(): Completable { - return Completable.concat( - listOf( - observeActiveTempBasal(), - podStateManager.observeNoActiveCommand().ignoreElements(), - history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL) - .flatMap { podStateManager.createActiveCommand(it) } - .ignoreElement(), - omnipodManager.stopTempBasal().ignoreElements(), - history.updateFromState(podStateManager), - podStateManager.updateActiveCommand() - .map { handleCommandConfirmation(it) } - .ignoreElement() - ) - ) - } - 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 pumpSync-ed at this point + // and this is why it is pumpSync-ed at this point if (confirmation.success) { pumpSync.syncStopTemporaryBasalWithPumpId( historyEntry.createdAt, From a20cc1cca3da443f9a5c0da50678f5495a46dc2f Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Mon, 31 May 2021 22:09:49 +0200 Subject: [PATCH 10/16] simplify --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 78 +++++++++---------- ...onfirmedCommand.kt => CommandConfirmed.kt} | 0 2 files changed, 38 insertions(+), 40 deletions(-) rename omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/{ConfirmedCommand.kt => CommandConfirmed.kt} (100%) 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 85504d0e19..e572cea2a6 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 @@ -36,8 +36,6 @@ import io.reactivex.Single import io.reactivex.rxkotlin.blockingSubscribeBy import io.reactivex.rxkotlin.subscribeBy import org.json.JSONObject -import java.lang.IllegalArgumentException -import java.lang.IllegalStateException import java.util.* import javax.inject.Inject import javax.inject.Singleton @@ -161,7 +159,7 @@ class OmnipodDashPumpPlugin @Inject constructor( history.createRecord( commandType = OmnipodCommandType.SET_BASAL_PROFILE ), - omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)) + omnipodManager.setBasalProgram(mapProfileToBasalProgram(profile)).ignoreElements() ).toPumpEnactResult() } @@ -248,7 +246,7 @@ class OmnipodDashPumpPlugin @Inject constructor( // TODO update Treatments (?) executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.CANCEL_BOLUS), - omnipodManager.stopBolus(), + omnipodManager.stopBolus().ignoreElements() ).toPumpEnactResult() } @@ -261,34 +259,35 @@ class OmnipodDashPumpPlugin @Inject constructor( ): PumpEnactResult { val tempBasalBeeps = sp.getBoolean(R.string.key_omnipod_common_tbr_beeps_enabled, false) - return Completable.concat( - listOf( - observeNoActiveTempBasal(enforceNew), - podStateManager.observeNoActiveCommand().ignoreElements(), - history.createRecord( - commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, - tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) - ).flatMap { podStateManager.createActiveCommand(it) } - .map { pumpSyncTempBasal(it, tbrType) } - .ignoreElement(), - omnipodManager.setTempBasal( - absoluteRate, - durationInMinutes.toShort(), - tempBasalBeeps, - ).ignoreElements(), - history.updateFromState(podStateManager), - podStateManager.updateActiveCommand() - .map { handleCommandConfirmation(it) } - .ignoreElement() + return executeSimpleProgrammingCommand( + historyEntry = history.createRecord( + commandType = OmnipodCommandType.SET_TEMPORARY_BASAL, + tempBasalRecord = TempBasalRecord(duration = durationInMinutes, rate = absoluteRate) + ), + command = omnipodManager.setTempBasal( + absoluteRate, + durationInMinutes.toShort(), + tempBasalBeeps ) + .filter { podEvent -> podEvent is PodEvent.CommandSent } + .map { pumpSyncTempBasal(it, tbrType) } + .ignoreElements(), + pre = observeNoActiveTempBasal(enforceNew) ).toPumpEnactResult() - // TODO: on error, invalidateTemporaryBasal or sync it only after sending the command } private fun pumpSyncTempBasal( - activeCommand: OmnipodDashPodStateManager.ActiveCommand, + podEvent: PodEvent, tbrType: PumpSync.TemporaryBasalType ): Boolean { + val activeCommand = podStateManager.activeCommand + if (activeCommand == null || podEvent !is PodEvent.CommandSent) { + throw IllegalArgumentException( + "No active command or illegal podEvent: " + + "activeCommand=$activeCommand" + + "podEvent=$podEvent" + ) + } val historyEntry = history.getById(activeCommand.historyId) val record = historyEntry.record if (record == null || !(record is TempBasalRecord)) { @@ -324,7 +323,7 @@ class OmnipodDashPumpPlugin @Inject constructor( // TODO: chain with the completable? executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), - omnipodManager.stopTempBasal() + omnipodManager.stopTempBasal().ignoreElements() ) } } @@ -363,8 +362,8 @@ class OmnipodDashPumpPlugin @Inject constructor( override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult { return executeSimpleProgrammingCommand( - observeCreateHistoryEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), - command = omnipodManager.stopTempBasal(), + historyEntry = history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), + command = omnipodManager.stopTempBasal().ignoreElements(), pre = observeActiveTempBasal(), ).toPumpEnactResult() } @@ -521,7 +520,7 @@ class OmnipodDashPumpPlugin @Inject constructor( private fun suspendDelivery(): PumpEnactResult { return executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.RESUME_DELIVERY), - omnipodManager.suspendDelivery() + omnipodManager.suspendDelivery().ignoreElements() ).toPumpEnactResult() } @@ -529,7 +528,7 @@ class OmnipodDashPumpPlugin @Inject constructor( return profileFunction.getProfile()?.let { executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.RESUME_DELIVERY), - omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)) + omnipodManager.setBasalProgram(mapProfileToBasalProgram(it)).ignoreElements() ).toPumpEnactResult() } ?: PumpEnactResult(injector).success(false).enacted(false).comment("No profile active") // TODO i18n } @@ -537,7 +536,7 @@ class OmnipodDashPumpPlugin @Inject constructor( private fun deactivatePod(): PumpEnactResult { return executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.DEACTIVATE_POD), - omnipodManager.deactivatePod() + omnipodManager.deactivatePod().ignoreElements() ).toPumpEnactResult() } @@ -554,7 +553,7 @@ class OmnipodDashPumpPlugin @Inject constructor( private fun playTestBeep(): PumpEnactResult { return executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.PLAY_TEST_BEEP), - omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP) + omnipodManager.playBeep(BeepType.LONG_SINGLE_BEEP).ignoreElements() ).toPumpEnactResult() } @@ -580,26 +579,25 @@ class OmnipodDashPumpPlugin @Inject constructor( } private fun executeSimpleProgrammingCommand( - observeCreateHistoryEntry: Single, - command: Observable, + historyEntry: Single, + command: Completable, pre: Completable = Completable.complete(), ): Completable { return Completable.concat( listOf( pre, podStateManager.observeNoActiveCommand().ignoreElements(), - observeCreateHistoryEntry + historyEntry .flatMap { podStateManager.createActiveCommand(it) } .ignoreElement(), - command.ignoreElements(), + command.doOnError { + aapsLogger.error(LTag.PUMP, "Error executing command", it) + }.onErrorComplete(), history.updateFromState(podStateManager), podStateManager.updateActiveCommand() .map { handleCommandConfirmation(it) } .ignoreElement() ) - ).doOnError { error -> - aapsLogger.error(LTag.PUMP, "Error executing command", error) - podStateManager.maybeMarkActiveCommandFailed() - } + ) } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/ConfirmedCommand.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt similarity index 100% rename from omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/ConfirmedCommand.kt rename to omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/pod/state/CommandConfirmed.kt From e867b1397db6ac8e4742afb67acaf54886fe3688 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Mon, 31 May 2021 22:15:39 +0200 Subject: [PATCH 11/16] remove maybeMarkActiveCommandFailed. this logic was moved in "updateActiveCommand" --- .../pod/state/OmnipodDashPodStateManager.kt | 1 - .../state/OmnipodDashPodStateManagerImpl.kt | 18 ++++++------------ 2 files changed, 6 insertions(+), 13 deletions(-) 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 a1030d61eb..1396f97443 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 @@ -70,7 +70,6 @@ interface OmnipodDashPodStateManager { fun createActiveCommand(historyId: String): Single fun updateActiveCommand(): Maybe fun observeNoActiveCommand(): Observable - fun maybeMarkActiveCommandFailed() 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 f00b0d1dae..38819f0a0f 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 @@ -228,16 +228,6 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( } } - @Synchronized - override fun maybeMarkActiveCommandFailed() { - podState.activeCommand?.run { - if (sentRealtime < createdRealtime) { - // command was not sent - podState.activeCommand = null - } - } - } - @Synchronized override fun updateActiveCommand() = Maybe.create { source -> podState.activeCommand?.run { @@ -246,8 +236,12 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( "lastResponse=$lastStatusResponseReceived " + "$sequenceNumberOfLastProgrammingCommand $historyId" ) - if (createdRealtime >= lastStatusResponseReceived) - // we did not receive a valid response yet + if (sentRealtime < createdRealtime) { + // command was not sent, clear it up + podState.activeCommand = null + source.onComplete() + } else if (createdRealtime >= lastStatusResponseReceived) + // we did not receive a valid response yet source.onComplete() else { podState.activeCommand = null From d0b1757268390cf7f93ac068648696e0d2d1a283 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Tue, 1 Jun 2021 00:18:38 +0200 Subject: [PATCH 12/16] bugfix: send error when we can't send the command --- .../pump/omnipod/dash/OmnipodDashPumpPlugin.kt | 11 ++++++++--- .../driver/pod/state/OmnipodDashPodStateManager.kt | 3 ++- .../pod/state/OmnipodDashPodStateManagerImpl.kt | 11 +++++++---- 3 files changed, 17 insertions(+), 8 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 e572cea2a6..d6d128a7cb 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 @@ -311,20 +311,24 @@ class OmnipodDashPumpPlugin @Inject constructor( return Completable.defer { val expectedState = pumpSync.expectedPumpState() when { - expectedState.temporaryBasal == null -> + expectedState.temporaryBasal == null -> { + 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 - // TODO: chain with the completable? + else -> { + // enforceNew == true + aapsLogger.info(LTag.PUMP, "Canceling existing temp basal") executeSimpleProgrammingCommand( history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), omnipodManager.stopTempBasal().ignoreElements() ) + } } } } @@ -591,6 +595,7 @@ class OmnipodDashPumpPlugin @Inject constructor( .flatMap { podStateManager.createActiveCommand(it) } .ignoreElement(), command.doOnError { + podStateManager.activeCommand?.sendError = it aapsLogger.error(LTag.PUMP, "Error executing command", it) }.onErrorComplete(), history.updateFromState(podStateManager), 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 1396f97443..bc5fdf060a 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 @@ -75,7 +75,8 @@ interface OmnipodDashPodStateManager { val sequence: Short, val createdRealtime: Long, var sentRealtime: Long = 0, - val historyId: String + val historyId: String, + var sendError: Throwable?, ) // 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 38819f0a0f..f100620760 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 @@ -197,7 +197,8 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( val command = OmnipodDashPodStateManager.ActiveCommand( podState.messageSequenceNumber, createdRealtime = SystemClock.elapsedRealtime(), - historyId = historyId + historyId = historyId, + sendError = null, ) podState.activeCommand = command source.onSuccess(command) @@ -236,10 +237,12 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( "lastResponse=$lastStatusResponseReceived " + "$sequenceNumberOfLastProgrammingCommand $historyId" ) - if (sentRealtime < createdRealtime) { - // command was not sent, clear it up + + if (sentRealtime < createdRealtime) { // command was not sent, clear it up podState.activeCommand = null - source.onComplete() + 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() From c8fee31ae88c971ac1a19a949c10ef9030bbb9e1 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Tue, 1 Jun 2021 08:12:03 +0200 Subject: [PATCH 13/16] cleanup --- .../plugins/pump/omnipod/dash/driver/comm/io/IOState.kt | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.kt diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.kt deleted file mode 100644 index b426f8420f..0000000000 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/io/IOState.kt +++ /dev/null @@ -1,5 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io - -enum class IOState { - IDLE, WRITING, READING -} From 34103931f59c174ad462e3e96151b7b0505adf62 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Thu, 3 Jun 2021 22:00:42 +0200 Subject: [PATCH 14/16] add comment --- .../plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt | 1 + 1 file changed, 1 insertion(+) 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..99133748f3 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 @@ -395,6 +395,7 @@ class OmnipodDashPumpPlugin @Inject constructor( OmnipodCommandType.SET_TEMPORARY_BASAL -> // This treatment was synced before sending the command if (!confirmation.success) { + // TODO: the ID here is the temp basal id, not the pumpId!! pumpSync.invalidateTemporaryBasal(historyEntry.pumpId()) } From 3dc47816925265f50588d8bc52b229fda2d68b6a Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Thu, 3 Jun 2021 22:15:26 +0200 Subject: [PATCH 15/16] use delivery status for checking if there is a tempbasal to cancel --- .../plugins/pump/omnipod/dash/OmnipodDashPumpPlugin.kt | 6 +++--- .../dash/driver/pod/state/OmnipodDashPodStateManagerImpl.kt | 2 +- 2 files changed, 4 insertions(+), 4 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 99133748f3..62d9d3748d 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 @@ -307,7 +307,7 @@ class OmnipodDashPumpPlugin @Inject constructor( return ret } - private fun observeNoActiveTempBasal(enforeNew: Boolean): Completable { + private fun observeNoActiveTempBasal(enforceNew: Boolean): Completable { return Completable.defer { val expectedState = pumpSync.expectedPumpState() when { @@ -315,7 +315,7 @@ class OmnipodDashPumpPlugin @Inject constructor( aapsLogger.info(LTag.PUMP, "No temporary basal to cancel") Completable.complete() } - !enforeNew -> + !enforceNew -> Completable.error( IllegalStateException( "Temporary basal already active and enforeNew is not set." @@ -335,7 +335,7 @@ class OmnipodDashPumpPlugin @Inject constructor( private fun observeActiveTempBasal(): Completable { return Completable.defer { - if (pumpSync.expectedPumpState().temporaryBasal != null) + if (podStateManager.tempBasalActive) Completable.complete() else Completable.error( 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..b84cf5eb13 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 @@ -148,7 +148,7 @@ 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 From b440003de4ea754c904cd67b4cc5357b5094a320 Mon Sep 17 00:00:00 2001 From: Andrei Vereha Date: Sat, 5 Jun 2021 20:14:28 +0200 Subject: [PATCH 16/16] ignore enforeNew for now --- .../omnipod/dash/OmnipodDashPumpPlugin.kt | 33 +++++++------------ .../state/OmnipodDashPodStateManagerImpl.kt | 14 +++++--- 2 files changed, 21 insertions(+), 26 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 62d9d3748d..5c60486659 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 @@ -272,7 +272,7 @@ class OmnipodDashPumpPlugin @Inject constructor( .filter { podEvent -> podEvent is PodEvent.CommandSent } .map { pumpSyncTempBasal(it, tbrType) } .ignoreElements(), - pre = observeNoActiveTempBasal(enforceNew) + pre = observeNoActiveTempBasal() ).toPumpEnactResult() } @@ -307,28 +307,19 @@ class OmnipodDashPumpPlugin @Inject constructor( return ret } - private fun observeNoActiveTempBasal(enforceNew: Boolean): Completable { + private fun observeNoActiveTempBasal(): Completable { return Completable.defer { val expectedState = pumpSync.expectedPumpState() - when { - expectedState.temporaryBasal == null -> { - aapsLogger.info(LTag.PUMP, "No temporary basal to cancel") - Completable.complete() - } - !enforceNew -> - Completable.error( - IllegalStateException( - "Temporary basal already active and enforeNew is not set." - ) - ) - else -> { - // enforceNew == true - aapsLogger.info(LTag.PUMP, "Canceling existing temp basal") - executeSimpleProgrammingCommand( - history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), - omnipodManager.stopTempBasal().ignoreElements() - ) - } + if (expectedState.temporaryBasal == null) { + aapsLogger.info(LTag.PUMP, "No temporary basal to cancel") + Completable.complete() + } else { + // enforceNew == true + aapsLogger.info(LTag.PUMP, "Canceling existing temp basal") + executeSimpleProgrammingCommand( + history.createRecord(OmnipodCommandType.CANCEL_TEMPORARY_BASAL), + omnipodManager.stopTempBasal().ignoreElements() + ) } } } 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 b84cf5eb13..9724f7f819 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 @@ -240,11 +240,15 @@ class OmnipodDashPodStateManagerImpl @Inject constructor( 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.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