Omnipod: if Cancel bolus has been pressed before the bolus command has been executed, await bolus command execution before cancelling

This commit is contained in:
Bart Sopers 2020-08-19 02:36:33 +02:00
parent e39c222203
commit 5d83e2a26b
3 changed files with 37 additions and 1 deletions

View file

@ -61,6 +61,8 @@ public class OmnipodManager {
private PodStateManager podStateManager; private PodStateManager podStateManager;
private ActiveBolusData activeBolusData; private ActiveBolusData activeBolusData;
private SingleSubject<Boolean> bolusCommandExecutionSubject;
private final Object bolusDataMutex = new Object(); private final Object bolusDataMutex = new Object();
private AAPSLogger aapsLogger; private AAPSLogger aapsLogger;
@ -277,12 +279,16 @@ public class OmnipodManager {
logStartingCommandExecution("bolus [units=" + units + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]"); logStartingCommandExecution("bolus [units=" + units + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]");
bolusCommandExecutionSubject = SingleSubject.create();
CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS; CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS;
try { try {
executeAndVerify(() -> communicationService.executeAction(new BolusAction(podStateManager, units, acknowledgementBeep, completionBeep))); executeAndVerify(() -> communicationService.executeAction(new BolusAction(podStateManager, units, acknowledgementBeep, completionBeep)));
} catch (OmnipodException ex) { } catch (OmnipodException ex) {
if (ex.isCertainFailure()) { if (ex.isCertainFailure()) {
bolusCommandExecutionSubject.onSuccess(false);
bolusCommandExecutionSubject = null;
throw ex; throw ex;
} }
@ -319,6 +325,11 @@ public class OmnipodManager {
activeBolusData = new ActiveBolusData(units, startDate, bolusCompletionSubject, disposables); activeBolusData = new ActiveBolusData(units, startDate, bolusCompletionSubject, disposables);
} }
// Return successful command execution AFTER storing activeBolusData
// Otherwise, hasActiveBolus() would return false and the caller would not cancel the bolus.
bolusCommandExecutionSubject.onSuccess(true);
bolusCommandExecutionSubject = null;
disposables.add(Completable.complete() // disposables.add(Completable.complete() //
.delay(estimatedRemainingBolusDuration.getMillis() + 250, TimeUnit.MILLISECONDS) // .delay(estimatedRemainingBolusDuration.getMillis() + 250, TimeUnit.MILLISECONDS) //
.observeOn(Schedulers.io()) // .observeOn(Schedulers.io()) //
@ -486,6 +497,10 @@ public class OmnipodManager {
} }
} }
public SingleSubject<Boolean> getBolusCommandExecutionSubject() {
return bolusCommandExecutionSubject;
}
// Only works for commands with nonce resyncable message blocks // Only works for commands with nonce resyncable message blocks
// FIXME method is too big, needs refactoring // FIXME method is too big, needs refactoring
private StatusResponse executeAndVerify(Supplier<StatusResponse> supplier) { private StatusResponse executeAndVerify(Supplier<StatusResponse> supplier) {

View file

@ -75,6 +75,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.util.OmnipodUtil;
import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.resources.ResourceHelper;
import info.nightscout.androidaps.utils.sharedPreferences.SP; import info.nightscout.androidaps.utils.sharedPreferences.SP;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
import io.reactivex.subjects.SingleSubject;
@Singleton @Singleton
public class AapsOmnipodManager implements IOmnipodManager { public class AapsOmnipodManager implements IOmnipodManager {
@ -294,18 +295,37 @@ public class AapsOmnipodManager implements IOmnipodManager {
@Override @Override
public PumpEnactResult cancelBolus() { public PumpEnactResult cancelBolus() {
SingleSubject<Boolean> bolusCommandExecutionSubject = delegate.getBolusCommandExecutionSubject();
if (bolusCommandExecutionSubject != null) {
// Wait until the bolus command has actually been executed before sending the cancel bolus command
aapsLogger.debug(LTag.PUMP, "Cancel bolus was requested, but the bolus command is still being executed. Awaiting bolus command execution");
boolean bolusCommandSuccessfullyExecuted = bolusCommandExecutionSubject.blockingGet();
if (bolusCommandSuccessfullyExecuted) {
aapsLogger.debug(LTag.PUMP, "Bolus command successfully executed. Proceeding bolus cancellation");
} else {
aapsLogger.debug(LTag.PUMP, "Not cancelling bolus: bolus command failed");
String comment = getStringResource(R.string.omnipod_bolus_did_not_succeed);
addFailureToHistory(System.currentTimeMillis(), PodHistoryEntryType.CancelBolus, comment);
return new PumpEnactResult(injector).success(true).enacted(false).comment(comment);
}
}
long time = System.currentTimeMillis(); long time = System.currentTimeMillis();
String comment = null; String comment = null;
while (delegate.hasActiveBolus()) { for (int i = 1; delegate.hasActiveBolus(); i++) {
aapsLogger.debug(LTag.PUMP, "Attempting to cancel bolus (#{})", i);
try { try {
delegate.cancelBolus(isBolusBeepsEnabled()); delegate.cancelBolus(isBolusBeepsEnabled());
aapsLogger.debug(LTag.PUMP, "Successfully cancelled bolus", i);
addSuccessToHistory(time, PodHistoryEntryType.CancelBolus, null); addSuccessToHistory(time, PodHistoryEntryType.CancelBolus, null);
return new PumpEnactResult(injector).success(true).enacted(true); return new PumpEnactResult(injector).success(true).enacted(true);
} catch (PodFaultException ex) { } catch (PodFaultException ex) {
aapsLogger.debug(LTag.PUMP, "Successfully cancelled bolus (implicitly because of a Pod Fault)");
showPodFaultErrorDialog(ex.getFaultEvent().getFaultEventCode(), null); showPodFaultErrorDialog(ex.getFaultEvent().getFaultEventCode(), null);
addSuccessToHistory(time, PodHistoryEntryType.CancelBolus, null); addSuccessToHistory(time, PodHistoryEntryType.CancelBolus, null);
return new PumpEnactResult(injector).success(true).enacted(true); return new PumpEnactResult(injector).success(true).enacted(true);
} catch (Exception ex) { } catch (Exception ex) {
aapsLogger.debug(LTag.PUMP, "Failed to cancel bolus", ex);
comment = handleAndTranslateException(ex); comment = handleAndTranslateException(ex);
} }
} }

View file

@ -148,6 +148,7 @@
<string name="omnipod_composite_time">%1$s and %2$s</string> <string name="omnipod_composite_time">%1$s and %2$s</string>
<string name="omnipod_time_ago">%1$s ago</string> <string name="omnipod_time_ago">%1$s ago</string>
<string name="omnipod_waiting_for_rileylink_connection">Waiting for RileyLink connection...</string> <string name="omnipod_waiting_for_rileylink_connection">Waiting for RileyLink connection...</string>
<string name="omnipod_bolus_did_not_succeed">Bolus did not succeed</string>
<plurals name="omnipod_minutes"> <plurals name="omnipod_minutes">
<item quantity="one">%1$d minute</item> <item quantity="one">%1$d minute</item>