From 9121aa5217bc652f118e205cc17f2231474a1c59 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Tue, 31 Oct 2017 11:01:58 +0100 Subject: [PATCH] Bolus cancellation for all stages. --- .../plugins/PumpCombo/ComboPlugin.java | 30 ++++++++++++++----- .../ruffy/spi/history/WarningOrErrorCode.java | 9 +++++- .../jotomo/ruffyscripter/RuffyScripter.java | 15 ++++++++-- .../ruffyscripter/commands/BolusCommand.java | 15 ++++++---- 4 files changed, 52 insertions(+), 17 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java index c3dd9f29a5..6d483e7f70 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java @@ -56,6 +56,9 @@ public class ComboPlugin implements PluginBase, PumpInterface { private static ComboPlugin plugin = null; + private volatile boolean bolusInProgress; + private volatile boolean cancelBolus; + public static ComboPlugin getPlugin() { if (plugin == null) plugin = new ComboPlugin(); @@ -400,6 +403,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { return pumpEnactResult; } } finally { + cancelBolus = false; MainApp.bus().post(new EventComboPumpUpdateGUI()); } } @@ -407,12 +411,22 @@ public class ComboPlugin implements PluginBase, PumpInterface { @NonNull private PumpEnactResult deliverBolus(final DetailedBolusInfo detailedBolusInfo) { // TODO - // before non-SMB: check enough insulin is available, check we're up to date on boluses - // after bolus: update reservoir level and check the bolus we just did is actually there + // before non-SMB: check enough insulin is available, check we're up to date on boluses + // after bolus: update reservoir level and check the bolus we just did is actually there + if (cancelBolus) { + PumpEnactResult pumpEnactResult = new PumpEnactResult(); + pumpEnactResult.success = true; + pumpEnactResult.enacted = false; + return pumpEnactResult; + } + + bolusInProgress = true; // retry flag: reconnect, kill warning, check if command can be restarted, restart - CommandResult bolusCmdResult = runCommand(MainApp.sResources.getString(R.string.combo_action_bolusing), () -> ruffyScripter.deliverBolus(detailedBolusInfo.insulin, - detailedBolusInfo.isSMB ? nullBolusProgressReporter : bolusProgressReporter)); + CommandResult bolusCmdResult = runCommand(MainApp.sResources.getString(R.string.combo_pump_action_bolusing), 0, + () -> ruffyScripter.deliverBolus(detailedBolusInfo.insulin, + detailedBolusInfo.isSMB ? nullBolusProgressReporter : bolusProgressReporter)); + bolusInProgress = false; PumpEnactResult pumpEnactResult = new PumpEnactResult(); pumpEnactResult.success = bolusCmdResult.success; @@ -438,9 +452,11 @@ public class ComboPlugin implements PluginBase, PumpInterface { @Override public void stopBolusDelivering() { - // TODO note that we requested this, so we can thandle this proper in runCommand; - // or is it fine if the command returns success with noting enacted and history checks as well/**/ - ruffyScripter.cancelBolus(); + if (bolusInProgress) { + ruffyScripter.cancelBolus(); + } else { + cancelBolus = true; + } } // Note: AAPS calls this only to enact OpenAPS recommendations diff --git a/ruffy-spi/src/main/java/de/jotomo/ruffy/spi/history/WarningOrErrorCode.java b/ruffy-spi/src/main/java/de/jotomo/ruffy/spi/history/WarningOrErrorCode.java index 371ce069ee..f9cfa9c620 100644 --- a/ruffy-spi/src/main/java/de/jotomo/ruffy/spi/history/WarningOrErrorCode.java +++ b/ruffy-spi/src/main/java/de/jotomo/ruffy/spi/history/WarningOrErrorCode.java @@ -1,10 +1,17 @@ package de.jotomo.ruffy.spi.history; +import android.support.annotation.Nullable; + public class WarningOrErrorCode { + @Nullable public final Integer warningCode; + @Nullable public final Integer errorCode; - public WarningOrErrorCode(Integer warningCode, Integer errorCode) { + public WarningOrErrorCode(@Nullable Integer warningCode, @Nullable Integer errorCode) { + if (warningCode == null && errorCode == null) { + throw new IllegalArgumentException("Either code must be non-null"); + } this.warningCode = warningCode; this.errorCode = errorCode; } diff --git a/ruffyscripter/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java b/ruffyscripter/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java index b0ad99aabf..b307bd83e2 100644 --- a/ruffyscripter/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java +++ b/ruffyscripter/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java @@ -7,6 +7,7 @@ import android.content.ServiceConnection; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; +import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.google.common.base.Joiner; @@ -502,6 +503,8 @@ public class RuffyScripter implements RuffyCommands { // === pump ops === public Menu getCurrentMenu() { + if (Thread.currentThread().isInterrupted()) + throw new CommandException("Interrupted"); long timeout = System.currentTimeMillis() + 5 * 1000; // TODO this is probably due to a disconnect and rtDisconnect having nulled currentMenu. // This here might just work, but needs a more controlled approach when implementing @@ -569,11 +572,13 @@ public class RuffyScripter implements RuffyCommands { // TODO sort out usages of this method and waitForMenu update, which have the same intent, // but approach things differently; private void waitForScreenUpdate() { + if (Thread.currentThread().isInterrupted()) + throw new CommandException("Interrupted"); synchronized (screenlock) { try { - screenlock.wait((long) 2000); // usually ~500, occassionally up to 1100ms - } catch (Exception e) { - log.debug("Ignoring exception in wait for screenlock", e); + screenlock.wait((long) 2000); // updates usually come in every ~500, occasionally up to 1100ms + } catch (InterruptedException e) { + throw new CommandException("Interrupted"); } } } @@ -601,6 +606,8 @@ public class RuffyScripter implements RuffyCommands { } private void pressKey(final byte key) { + if (Thread.currentThread().isInterrupted()) + throw new CommandException("Interrupted"); try { ruffyService.rtSendKey(key, true); SystemClock.sleep(150); @@ -701,6 +708,8 @@ public class RuffyScripter implements RuffyCommands { public void cancelBolus() { if (activeCmd instanceof BolusCommand) { ((BolusCommand) activeCmd).requestCancellation(); + } else { + log.error("cancelBolus called, but active command is not a bolus:" + activeCmd); } } diff --git a/ruffyscripter/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java b/ruffyscripter/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java index 5f3e33b0d4..839dbe8f30 100644 --- a/ruffyscripter/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java +++ b/ruffyscripter/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java @@ -104,18 +104,19 @@ public class BolusCommand extends BaseCommand { // wait for bolus delivery to complete; the remaining units to deliver are counted down boolean cancelInProgress = false; - double lastBolusReported = 0; + Double lastBolusReported = 0d; Double bolusRemaining = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_REMAINING); - while (bolusRemaining != null) { + while (bolusRemaining != null || scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { if (cancelRequested && !cancelInProgress) { bolusProgressReporter.report(STOPPING, 0, 0); cancelInProgress = true; - new Thread(() -> scripter.pressKeyMs(RuffyScripter.Key.UP, 3000), "bolus-canceller").start(); + new Thread(() -> + scripter.pressKeyMs(RuffyScripter.Key.UP, 3000), "bolus-canceller").start(); } if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { - // confirm warning alerts and update the result to indicate alerts occurred + // confirm warning alert and update the result to indicate alerts occurred WarningOrErrorCode warningOrErrorCode = scripter.readWarningOrErrorCode(); - if (warningOrErrorCode.errorCode != 0) { + if (warningOrErrorCode.errorCode != null) { throw new CommandException("Pump is in error state"); } int warningCode = warningOrErrorCode.warningCode; @@ -130,9 +131,11 @@ public class BolusCommand extends BaseCommand { } else if (warningCode == PumpWarningCodes.BATTERY_LOW) { scripter.confirmAlert(PumpWarningCodes.BATTERY_LOW, 2000); result.alertConfirmed = true; + } else { + throw new CommandException("Pump is showing exotic warning: " + warningCode); } } - if (lastBolusReported != bolusRemaining) { + if (bolusRemaining != null && !bolusRemaining.equals(lastBolusReported)) { log.debug("Delivering bolus, remaining: " + bolusRemaining); int percentDelivered = (int) (100 - (bolusRemaining / bolus * 100)); bolusProgressReporter.report(DELIVERING, percentDelivered, bolus - bolusRemaining);