fix unconfirmed commands

This commit is contained in:
Andrei Vereha 2021-06-12 23:30:37 +02:00
parent fc7fc2df5b
commit 59d0245980
4 changed files with 51 additions and 28 deletions

View file

@ -17,7 +17,6 @@ import info.nightscout.androidaps.plugins.pump.common.defs.PumpType
import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType import info.nightscout.androidaps.plugins.pump.omnipod.common.definition.OmnipodCommandType
import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.* import info.nightscout.androidaps.plugins.pump.omnipod.common.queue.command.*
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.OmnipodDashManager
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.ActivationProgress
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.BeepType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definition.DeliveryStatus
@ -215,10 +214,9 @@ class OmnipodDashPumpPlugin @Inject constructor(
executeProgrammingCommand( executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY), historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY),
command = omnipodManager.suspendDelivery() command = omnipodManager.suspendDelivery()
.filter { podEvent -> podEvent is PodEvent.CommandSent } .filter { podEvent -> podEvent.isCommandSent() }
.map { .map {
pumpSyncTempBasal( pumpSyncTempBasal(
it,
0.0, 0.0,
PodConstants.MAX_POD_LIFETIME.standardMinutes, PodConstants.MAX_POD_LIFETIME.standardMinutes,
PumpSync.TemporaryBasalType.PUMP_SUSPEND PumpSync.TemporaryBasalType.PUMP_SUSPEND
@ -336,8 +334,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
detailedBolusInfo.insulin, detailedBolusInfo.insulin,
bolusBeeps, bolusBeeps,
bolusBeeps bolusBeeps
).filter { podEvent -> podEvent is PodEvent.CommandSent } ).filter { podEvent -> podEvent.isCommandSent() }
.map { pumpSyncBolusStart(it, requestedBolusAmount, detailedBolusInfo.bolusType) } .map { pumpSyncBolusStart(requestedBolusAmount, detailedBolusInfo.bolusType) }
.ignoreElements(), .ignoreElements(),
post = waitForBolusDeliveryToComplete(5, requestedBolusAmount, detailedBolusInfo.bolusType) post = waitForBolusDeliveryToComplete(5, requestedBolusAmount, detailedBolusInfo.bolusType)
.map { .map {
@ -393,13 +391,14 @@ class OmnipodDashPumpPlugin @Inject constructor(
Thread.sleep(3000) // retry every 3 sec Thread.sleep(3000) // retry every 3 sec
continue continue
} }
if (podStateManager.deliveryStatus in val bolusInDeliveryState =
podStateManager.deliveryStatus in
arrayOf( arrayOf(
DeliveryStatus.BOLUS_AND_TEMP_BASAL_ACTIVE, DeliveryStatus.BOLUS_AND_TEMP_BASAL_ACTIVE,
DeliveryStatus.BOLUS_AND_BASAL_ACTIVE DeliveryStatus.BOLUS_AND_BASAL_ACTIVE
) && )
!bolusCanceled
) { if (bolusInDeliveryState && !bolusCanceled) {
// delivery not complete yet // delivery not complete yet
val remainingUnits = podStateManager.lastBolus!!.bolusUnitsRemaining val remainingUnits = podStateManager.lastBolus!!.bolusUnitsRemaining
val progressUpdateEvent = EventOverviewBolusProgress val progressUpdateEvent = EventOverviewBolusProgress
@ -421,16 +420,14 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
private fun pumpSyncBolusStart( private fun pumpSyncBolusStart(
podEvent: PodEvent,
requestedBolusAmount: Double, requestedBolusAmount: Double,
bolusType: DetailedBolusInfo.BolusType bolusType: DetailedBolusInfo.BolusType
): Boolean { ): Boolean {
val activeCommand = podStateManager.activeCommand val activeCommand = podStateManager.activeCommand
if (activeCommand == null || podEvent !is PodEvent.CommandSent) { if (activeCommand == null) {
throw IllegalArgumentException( throw IllegalArgumentException(
"No active command or illegal podEvent: " + "No active command or illegal podEvent: " +
"activeCommand=$activeCommand" + "activeCommand=$activeCommand"
"podEvent=$podEvent"
) )
} }
val historyEntry = history.getById(activeCommand.historyId) val historyEntry = history.getById(activeCommand.historyId)
@ -498,8 +495,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
durationInMinutes.toShort(), durationInMinutes.toShort(),
tempBasalBeeps tempBasalBeeps
) )
.filter { podEvent -> podEvent is PodEvent.CommandSent } .filter { podEvent -> podEvent.isCommandSent() }
.map { pumpSyncTempBasal(it, absoluteRate, durationInMinutes.toLong(), tbrType) } .map { pumpSyncTempBasal(absoluteRate, durationInMinutes.toLong(), tbrType) }
.ignoreElements(), .ignoreElements(),
).toPumpEnactResult() ).toPumpEnactResult()
aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute: result=$ret") aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute: result=$ret")
@ -507,21 +504,19 @@ class OmnipodDashPumpPlugin @Inject constructor(
} }
private fun pumpSyncTempBasal( private fun pumpSyncTempBasal(
podEvent: PodEvent,
absoluteRate: Double, absoluteRate: Double,
durationInMinutes: Long, durationInMinutes: Long,
tbrType: PumpSync.TemporaryBasalType tbrType: PumpSync.TemporaryBasalType
): Boolean { ): Boolean {
val activeCommand = podStateManager.activeCommand val activeCommand = podStateManager.activeCommand
if (activeCommand == null || podEvent !is PodEvent.CommandSent) { if (activeCommand == null) {
throw IllegalArgumentException( throw IllegalArgumentException(
"No active command or illegal podEvent: " + "No active command: " +
"activeCommand=$activeCommand" + "activeCommand=$activeCommand"
"podEvent=$podEvent"
) )
} }
val historyEntry = history.getById(activeCommand.historyId) val historyEntry = history.getById(activeCommand.historyId)
aapsLogger.debug(LTag.PUMP, "pumpSyncTempBasal: absoluteRate=$absoluteRate, durationInMinutes=$durationInMinutes")
val ret = pumpSync.syncTemporaryBasalWithPumpId( val ret = pumpSync.syncTemporaryBasalWithPumpId(
timestamp = historyEntry.createdAt, timestamp = historyEntry.createdAt,
rate = absoluteRate, rate = absoluteRate,
@ -585,7 +580,8 @@ class OmnipodDashPumpPlugin @Inject constructor(
override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult { override fun cancelTempBasal(enforceNew: Boolean): PumpEnactResult {
if (!podStateManager.tempBasalActive && if (!podStateManager.tempBasalActive &&
pumpSync.expectedPumpState().temporaryBasal == null) { pumpSync.expectedPumpState().temporaryBasal == null
) {
// nothing to cancel // nothing to cancel
return PumpEnactResult(injector).success(true).enacted(false) return PumpEnactResult(injector).success(true).enacted(false)
} }
@ -700,10 +696,9 @@ class OmnipodDashPumpPlugin @Inject constructor(
return executeProgrammingCommand( return executeProgrammingCommand(
historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY), historyEntry = history.createRecord(OmnipodCommandType.SUSPEND_DELIVERY),
command = omnipodManager.suspendDelivery() command = omnipodManager.suspendDelivery()
.filter { podEvent -> podEvent is PodEvent.CommandSent } .filter { podEvent -> podEvent.isCommandSent() }
.map { .map {
pumpSyncTempBasal( pumpSyncTempBasal(
it,
0.0, 0.0,
PodConstants.MAX_POD_LIFETIME.standardMinutes, PodConstants.MAX_POD_LIFETIME.standardMinutes,
PumpSync.TemporaryBasalType.PUMP_SUSPEND PumpSync.TemporaryBasalType.PUMP_SUSPEND
@ -847,7 +842,11 @@ class OmnipodDashPumpPlugin @Inject constructor(
// This treatment was synced before sending the command // This treatment was synced before sending the command
if (!confirmation.success) { if (!confirmation.success) {
aapsLogger.info(LTag.PUMPCOMM, "temporary basal denied. PumpId: ${historyEntry.pumpId()}") aapsLogger.info(LTag.PUMPCOMM, "temporary basal denied. PumpId: ${historyEntry.pumpId()}")
pumpSync.invalidateTemporaryBasal(historyEntry.pumpId()) pumpSync.invalidateTemporaryBasalWithPumpId(
historyEntry.pumpId(),
PumpType.OMNIPOD_DASH,
serialNumber()
)
} else { } else {
podStateManager.tempBasal = command.tempBasal podStateManager.tempBasal = command.tempBasal
} }
@ -855,7 +854,7 @@ class OmnipodDashPumpPlugin @Inject constructor(
OmnipodCommandType.SUSPEND_DELIVERY -> { OmnipodCommandType.SUSPEND_DELIVERY -> {
if (!confirmation.success) { if (!confirmation.success) {
pumpSync.invalidateTemporaryBasal(historyEntry.pumpId()) pumpSync.invalidateTemporaryBasalWithPumpId(historyEntry.pumpId(), PumpType.OMNIPOD_DASH, serialNumber())
} else { } else {
podStateManager.tempBasal = null podStateManager.tempBasal = null
} }

View file

@ -44,6 +44,14 @@ class OmnipodDashBleManagerImpl @Inject constructor(
val session = assertSessionEstablished() val session = assertSessionEstablished()
emitter.onNext(PodEvent.CommandSending(cmd)) emitter.onNext(PodEvent.CommandSending(cmd))
/*
if (Random.nextBoolean()) {
// XXX use this to test "failed to confirm" commands
emitter.onNext(PodEvent.CommandSendNotConfirmed(cmd))
emitter.tryOnError(MessageIOException("XXX random failure to test unconfirmed commands"))
return@create
}
*/
when (session.sendCommand(cmd)) { when (session.sendCommand(cmd)) {
is CommandSendErrorSending -> { is CommandSendErrorSending -> {
emitter.tryOnError(CouldNotSendCommandException()) emitter.tryOnError(CouldNotSendCommandException())
@ -55,7 +63,12 @@ class OmnipodDashBleManagerImpl @Inject constructor(
is CommandSendErrorConfirming -> is CommandSendErrorConfirming ->
emitter.onNext(PodEvent.CommandSendNotConfirmed(cmd)) emitter.onNext(PodEvent.CommandSendNotConfirmed(cmd))
} }
/*
if (Random.nextBoolean()) {
// XXX use this commands confirmed with success
emitter.tryOnError(MessageIOException("XXX random failure to test unconfirmed commands"))
return@create
}*/
when (val readResult = session.readAndAckResponse(responseType)) { when (val readResult = session.readAndAckResponse(responseType)) {
is CommandReceiveSuccess -> is CommandReceiveSuccess ->
emitter.onNext(PodEvent.ResponseReceived(cmd, readResult.result)) emitter.onNext(PodEvent.ResponseReceived(cmd, readResult.result))

View file

@ -65,4 +65,8 @@ sealed class PodEvent {
return "ResponseReceived(command=$command, response=$response)" return "ResponseReceived(command=$command, response=$response)"
} }
} }
fun isCommandSent(): Boolean {
return this is CommandSent || this is CommandSendNotConfirmed
}
} }

View file

@ -274,6 +274,13 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
*/ */
// TODO // TODO
if (podStateManager.activeCommand != null) {
podInfoBinding.podExpiryDate.setTextColor(Color.RED)
podInfoBinding.podExpiryDate.text = "Active command"
} else {
podInfoBinding.podExpiryDate.text = PLACEHOLDER
podInfoBinding.podExpiryDate.setTextColor(Color.WHITE)
}
/* /*
val expiresAt = podStateManager.expiresAt val expiresAt = podStateManager.expiresAt