diff --git a/app/src/main/java/de/jotomo/ruffyscripter/History.java b/app/src/main/java/de/jotomo/ruffyscripter/History.java index 49e34d438f..cfe514565b 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/History.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/History.java @@ -1,5 +1,7 @@ package de.jotomo.ruffyscripter; -/** The history data read from "My data" */ +/** + * The history data read from "My data" + */ public class History { } diff --git a/app/src/main/java/de/jotomo/ruffyscripter/PumpCapabilities.java b/app/src/main/java/de/jotomo/ruffyscripter/PumpCapabilities.java index 1270851ea0..50016db80e 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/PumpCapabilities.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/PumpCapabilities.java @@ -2,7 +2,7 @@ package de.jotomo.ruffyscripter; /** * Created by adrian on 26/07/17. - * + *

* Contains the capabilities of the current pump model. */ diff --git a/app/src/main/java/de/jotomo/ruffyscripter/PumpState.java b/app/src/main/java/de/jotomo/ruffyscripter/PumpState.java index f40f542e4f..9323ab71a5 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/PumpState.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/PumpState.java @@ -11,11 +11,12 @@ public class PumpState { public int tbrPercent = -1; public double tbrRate = -1; public int tbrRemainingDuration = -1; - /** This is the error message (if any) displayed by the pump if there is an alarm, - e.g. if a "TBR cancelled alarm" is active, the value will be "TBR CANCELLED". - Generally, an error code is also displayed, but it flashes and it might take - longer to read that and the pump connection gets interrupted if we're not - reacting quickly. + /** + * This is the error message (if any) displayed by the pump if there is an alarm, + * e.g. if a "TBR cancelled alarm" is active, the value will be "TBR CANCELLED". + * Generally, an error code is also displayed, but it flashes and it might take + * longer to read that and the pump connection gets interrupted if we're not + * reacting quickly. */ public String errorMsg; public boolean suspended; diff --git a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java b/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java index 8f8d784e7d..4bf0f85833 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java @@ -344,6 +344,7 @@ public class RuffyScripter { } catch (CommandException e) { return e.toCommandResult(); } catch (Exception e) { + // TODO detect and report pump warnings/errors differently? log.error("Error in ruffyscripter/ruffy", e); return new CommandResult().exception(e).message("Unexpected exception communication with ruffy: " + e.getMessage()); } finally { @@ -528,6 +529,26 @@ public class RuffyScripter { log.debug("Releasing back key"); } + public void pressKeyMs(final byte key, long ms) { + long stepMs = 100; + try { + log.debug("Scroll: Pressing key for " + ms + " ms with step " + stepMs + " ms"); + ruffyService.rtSendKey(key, true); + ruffyService.rtSendKey(key, false); + while (ms > stepMs) { + SystemClock.sleep(stepMs); + ruffyService.rtSendKey(key, false); + ms -= stepMs; + } + SystemClock.sleep(ms); + ruffyService.rtSendKey(Key.NO_KEY, true); + log.debug("Releasing key"); + } catch (Exception e) { + throw new CommandException().exception(e).message("Error while pressing buttons"); + } + } + + public boolean waitForScreenUpdate(long timeout) { synchronized (screenlock) { try { diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java index 621a47fd76..cc096bdb00 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java @@ -11,12 +11,23 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import de.jotomo.ruffyscripter.PumpState; +import de.jotomo.ruffyscripter.RuffyScripter; + +import static de.jotomo.ruffyscripter.commands.BolusCommand.ProgressReportCallback.State.DELIVERING; +import static de.jotomo.ruffyscripter.commands.BolusCommand.ProgressReportCallback.State.STOPPED; +import static de.jotomo.ruffyscripter.commands.BolusCommand.ProgressReportCallback.State.STOPPING; +import static de.jotomo.ruffyscripter.commands.BolusCommand.ProgressReportCallback.State.DELIVERED; + public class BolusCommand extends BaseCommand { private static final Logger log = LoggerFactory.getLogger(BolusCommand.class); private final double bolus; + private final ProgressReportCallback progressReportCallback; + private volatile boolean cancelRequested; - public BolusCommand(double bolus) { + public BolusCommand(double bolus, ProgressReportCallback progressReportCallback) { + this.progressReportCallback = progressReportCallback; this.bolus = bolus; } @@ -34,31 +45,103 @@ public class BolusCommand extends BaseCommand { @Override public CommandResult execute() { try { + // TODO read reservoir level and reject request if reservoir < bolus enterBolusMenu(); inputBolusAmount(); verifyDisplayedBolusAmount(); + if (cancelRequested) { + progressReportCallback.report(STOPPING, 0, 0); + scripter.goToMainTypeScreen(MenuType.MAIN_MENU, 30 * 1000); + progressReportCallback.report(STOPPED, 0, 0); + return new CommandResult().success(true).enacted(false) + .message("Bolus cancelled as per user request with no insulin delivered"); + } + // confirm bolus scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER); scripter.pressCheckKey(); - // the pump displays the entered bolus and waits a bit to let user check and cancel - scripter.waitForMenuToBeLeft(MenuType.BOLUS_ENTER); - + // the pump displays the entered bolus and waits a few seconds to let user check and cancel + while (scripter.getCurrentMenu().getType() == MenuType.BOLUS_ENTER) { + if (cancelRequested) { + progressReportCallback.report(STOPPING, 0, 0); + scripter.pressUpKey(); + // wait up to 1s for a BOLUS_CANCELLED alert, if it doesn't happen we missed + // the window, simply continue and let the next cancel attempt try its luck + boolean alertWasCancelled = confirmAlert("BOLUS CANCELLED", 1000); + if (alertWasCancelled) { + progressReportCallback.report(STOPPED, 0, 0); + return new CommandResult().success(true).enacted(false) + .message("Bolus cancelled as per user request with no insulin delivered"); + } + } + SystemClock.sleep(10); + } scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU, "Pump did not return to MAIN_MEU from BOLUS_ENTER to deliver bolus. " + "Check pump manually, the bolus might not have been delivered."); + progressReportCallback.report(DELIVERING, 0, 0); + Double bolusRemaining = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_REMAINING); + double lastBolusReported = 0; + boolean lowCartdrigeAlarmTriggered = false; // wait for bolus delivery to complete; the remaining units to deliver are counted // down and are displayed on the main menu. - Double bolusRemaining = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_REMAINING); + // TODO extract into method + + // TODO 'low cartrdige' alarm must be handled inside, since the bolus continues regardless; + // it must be claread so we can see the remaining bolus again; while (bolusRemaining != null) { - log.debug("Delivering bolus, remaining: " + bolusRemaining); - SystemClock.sleep(200); + if (cancelRequested) { + progressReportCallback.report(STOPPING, 0, 0); + scripter.pressKeyMs(RuffyScripter.Key.UP, 3000); + progressReportCallback.report(STOPPED, 0, 0); + // if the bolus finished while we attempted to cancel it, there'll be no alarm + long timeout = System.currentTimeMillis() + 2000; + while (scripter.getCurrentMenu().getType() != MenuType.WARNING_OR_ERROR && System.currentTimeMillis() < timeout) { + SystemClock.sleep(10); + } + while (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { + // TODO make this cleaner, extract method, needed below too + scripter.pressCheckKey(); + SystemClock.sleep(200); + } + break; + } + if (lastBolusReported != bolusRemaining) { + log.debug("Delivering bolus, remaining: " + bolusRemaining); + int percentDelivered = (int) (100 - (bolusRemaining / bolus * 100)); + progressReportCallback.report(DELIVERING, percentDelivered, bolus - bolusRemaining); + lastBolusReported = bolusRemaining; + } + + if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { + String message = (String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); + if (message.equals("LOW CARTRIDGE")) { + lowCartdrigeAlarmTriggered = true; + confirmAlert("LOW CARTRIDGE", 2000); + } else { + // any other alert + break; + } + } + SystemClock.sleep(50); bolusRemaining = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_REMAINING); } + // wait up to 2s for any possible warning to be raised, if not raised already + long minWait = System.currentTimeMillis() + 2 * 1000; + while (scripter.getCurrentMenu().getType() != MenuType.WARNING_OR_ERROR || System.currentTimeMillis() < minWait) { + SystemClock.sleep(50); + } + + // process warnings (confirm them, report back to AAPS about them) + while (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR || System.currentTimeMillis() < minWait) { + // TODO + } + // TODO what if we hit 'cartridge low' alert here? is it immediately displayed or after the bolus? // TODO how are error states reported back to the caller that occur outside of calls in genal? Low battery, low cartridge? @@ -67,6 +150,9 @@ public class BolusCommand extends BaseCommand { "Bolus delivery did not complete as expected. " + "Check pump manually, the bolus might not have been delivered."); + + // TODO report back what was read from history + // read last bolus record; those menus display static data and therefore // only a single menu update is sent scripter.navigateToMenu(MenuType.MY_DATA_MENU); @@ -81,6 +167,8 @@ public class BolusCommand extends BaseCommand { .message("Bolus was delivered, but unable to confirm it with history record"); } + // TODO check date so we don't pick a false record if the previous bolus had the same amount; + // also, report back partial bolus. Just call ReadHsstory(timestamp, boluses=true) cmd ... double lastBolusInHistory = (double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS); if (Math.abs(bolus - lastBolusInHistory) > 0.05) { throw new CommandException().success(false).enacted(true) @@ -89,12 +177,13 @@ public class BolusCommand extends BaseCommand { } log.debug("Bolus record in history confirms delivered bolus"); - // leave menu to go back to main menu - scripter.pressCheckKey(); - scripter.waitForMenuToBeLeft(MenuType.BOLUS_DATA); - scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU, - "Bolus was correctly delivered and checked against history, but we " - + "did not return the main menu successfully."); + if (!scripter.goToMainTypeScreen(MenuType.MAIN_MENU, 15 * 1000)) { + throw new CommandException().success(false).enacted(true) + .message("Bolus was correctly delivered and checked against history, but we " + + "did not return the main menu successfully."); + } + + progressReportCallback.report(DELIVERED, 100, bolus); return new CommandResult().success(true).enacted(true) .message(String.format(Locale.US, "Delivered %02.1f U", bolus)); @@ -103,6 +192,13 @@ public class BolusCommand extends BaseCommand { } } + // TODO confirmAlarms? and report back which were cancelled? + + private boolean confirmAlert(String alertText, int maxWaitTillExpectedAlert) { + // TODO + return false; + } + private void enterBolusMenu() { scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU); scripter.navigateToMenu(MenuType.BOLUS_MENU); @@ -150,4 +246,15 @@ public class BolusCommand extends BaseCommand { "bolus=" + bolus + '}'; } + + public interface ProgressReportCallback { + enum State { + DELIVERING, + DELIVERED, + STOPPING, + STOPPED + } + + void report(State state, int percent, double delivered); + } } diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/Command.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/Command.java index e472d56fa9..60fa3c730f 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/Command.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/Command.java @@ -6,7 +6,7 @@ import de.jotomo.ruffyscripter.RuffyScripter; /** * Interface for all commands to be executed by the pump. - * + *

* Note on cammond methods and timing: a method shall wait before and after executing * as necessary to not cause timing issues, so the caller can just call methods in * sequence, letting the methods take care of waits. diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandException.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandException.java index 5c25ba914c..d2f31cc8e2 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandException.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandException.java @@ -6,7 +6,8 @@ public class CommandException extends RuntimeException { public Exception exception = null; public String message = null; - public CommandException() {} + public CommandException() { + } public CommandException success(boolean success) { this.success = success; diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java index ec9c444a97..b759eb32dc 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java @@ -31,7 +31,7 @@ public class CommandResult { } public CommandResult completionTime(long completionTime) { - this.completionTime = completionTime ; + this.completionTime = completionTime; return this; } @@ -57,12 +57,12 @@ public class CommandResult { public CommandResult history(History history) { this.history = history; - return this; + return this; } public CommandResult capabilities(PumpCapabilities capabilities) { this.capabilities = capabilities; - return this; + return this; } @Override diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/GetBasalRateProfileCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/GetBasalRateProfileCommand.java index a97a24f173..ff842af5dd 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/GetBasalRateProfileCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/GetBasalRateProfileCommand.java @@ -26,7 +26,7 @@ public class GetBasalRateProfileCommand extends BaseCommand { return violations; } -// private void tick() + // private void tick() // { // switch (state) // { @@ -103,15 +103,14 @@ public class GetBasalRateProfileCommand extends BaseCommand { @Override public CommandResult execute() { try { - Map rate = new HashMap<>(); + Map rate = new HashMap<>(); - for(int i = 0; i < 24;i++) - { - Log.v("BASAL_RATE","BASAL_RATE from "+String.format("%02d",i)+":00 = "+rate.get(i)); + for (int i = 0; i < 24; i++) { + Log.v("BASAL_RATE", "BASAL_RATE from " + String.format("%02d", i) + ":00 = " + rate.get(i)); } } catch (Exception e) { - log.error("failed to get basal",e); - return new CommandResult().success(false).message("failed to get basal: "+e.getMessage()); + log.error("failed to get basal", e); + return new CommandResult().success(false).message("failed to get basal: " + e.getMessage()); } return new CommandResult().success(true).enacted(true).message("Basal Rate was read"); } diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommandAlt.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommandAlt.java index 17af79a782..1a72e7153c 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommandAlt.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommandAlt.java @@ -120,6 +120,10 @@ public class SetTbrCommandAlt extends BaseCommand { if (increasePercentage) scripter.pressUpKey(); else scripter.pressDownKey(); SystemClock.sleep(100); + if (increasePercentage) scripter.pressUpKey(); + else scripter.pressDownKey(); + SystemClock.sleep(100); + log.debug("Push #" + (i + 1)); } // Give the pump time to finish any scrolling that might still be going on, can take // up to 1100ms. Plus some extra time to be sure @@ -269,7 +273,7 @@ public class SetTbrCommandAlt extends BaseCommand { @Override public String toString() { - return getClass().getSimpleName() + "{" + + return "SetTbrCommand{" + "percentage=" + percentage + ", duration=" + duration + '}'; 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 913cc12f8c..7c7bce1e2d 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 @@ -77,6 +77,9 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf private ComboPump pump = new ComboPump(); + @Nullable + private volatile BolusCommand runningBolusCommand; + private static PumpEnactResult OPERATION_NOT_SUPPORTED = new PumpEnactResult(); static { @@ -97,7 +100,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf pumpDescription.isBolusCapable = true; pumpDescription.bolusStep = 0.1d; - pumpDescription.isExtendedBolusCapable = false; // TODO GL#70 + pumpDescription.isExtendedBolusCapable = false; pumpDescription.extendedBolusStep = 0.1d; pumpDescription.extendedBolusDurationStep = 15; pumpDescription.extendedBolusMaxDuration = 12 * 60; @@ -127,7 +130,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf * The alerter frequently checks the result of the last executed command via the lastCmdResult * field and shows a notification with sound and vibration if an error occurred. * More details on the error can then be looked up in the Combo tab. - * + *

* The alarm is re-raised every 5 minutes for as long as the error persist. As soon * as a command succeeds no more new alerts are raised. */ @@ -203,7 +206,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf @Override public void onServiceConnected(ComponentName name, IBinder service) { - keepUnbound=false; + keepUnbound = false; ruffyScripter.start(IRuffyService.Stub.asInterface(service)); log.debug("ruffy serivce connected"); } @@ -213,7 +216,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf log.debug("ruffy service disconnected"); // try to reconnect ruffy service unless unbind was explicitly requested // via unbindRuffyService - if(!keepUnbound) { + if (!keepUnbound) { SystemClock.sleep(250); bindRuffyService(); } @@ -231,6 +234,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf } private boolean keepUnbound = false; + private void unbindRuffyService() { keepUnbound = true; ruffyScripter.unbind(); @@ -363,20 +367,64 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf return basal; } - // what a mess: pump integration code reading carb info from Detailed**Bolus**Info, - // writing carb treatments to the history table. What's PumpEnactResult for again? + private static BolusCommand.ProgressReportCallback bolusProgressReportCallback = new BolusCommand.ProgressReportCallback() { + @Override + public void report(BolusCommand.ProgressReportCallback.State state, int percent, double delivered) { + EventOverviewBolusProgress enent = EventOverviewBolusProgress.getInstance(); + switch (state) { + case DELIVERING: + enent.status = String.format(MainApp.sResources.getString(R.string.bolusdelivering), delivered); + break; + case DELIVERED: + enent.status = String.format(MainApp.sResources.getString(R.string.bolusdelivered), delivered); + break; + case STOPPING: + enent.status = MainApp.sResources.getString(R.string.bolusstopping); + break; + case STOPPED: + enent.status = MainApp.sResources.getString(R.string.bolusstopped); + break; + } + enent.percent = percent; + MainApp.bus().post(enent); + } + }; + + /** Updates Treatment records with carbs and boluses and delivers a bolus if needed */ @Override public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { if (detailedBolusInfo.insulin > 0) { // bolus needed, ask pump to deliver it - if (!Config.comboSplitBoluses) { - return deliverBolus(detailedBolusInfo); + + // TODO read history to ensure there are no boluses delivered on the pump we aren't + // aware of and haven't included in the bolus calulation + + // Note that the BolusCommand sends progress updates to the bolusProgressReporterCallback, + // which then posts appropriate events on the bus, so in this branch no posts are needed + runningBolusCommand = new BolusCommand(detailedBolusInfo.insulin, bolusProgressReportCallback); + CommandResult bolusCmdResult = runCommand(runningBolusCommand); + runningBolusCommand = null; + PumpEnactResult pumpEnactResult = new PumpEnactResult(); + pumpEnactResult.success = bolusCmdResult.success; + pumpEnactResult.enacted = bolusCmdResult.enacted; + pumpEnactResult.comment = bolusCmdResult.message; + + // if enacted by pump, add bolus and carbs to treatment history + if (pumpEnactResult.enacted) { + pumpEnactResult.bolusDelivered = detailedBolusInfo.insulin; + pumpEnactResult.carbsDelivered = detailedBolusInfo.carbs; + + detailedBolusInfo.date = bolusCmdResult.completionTime; + MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); } else { - return deliverSplittedBolus(detailedBolusInfo); + pumpEnactResult.bolusDelivered = 0d; + pumpEnactResult.carbsDelivered = 0d; } + return pumpEnactResult; } else { // no bolus required, carb only treatment + SystemClock.sleep(6000); PumpEnactResult pumpEnactResult = new PumpEnactResult(); pumpEnactResult.success = true; pumpEnactResult.enacted = true; @@ -403,60 +451,10 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf } } - @NonNull - private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) { - CommandResult bolusCmdResult = runCommand(new BolusCommand(detailedBolusInfo.insulin)); - PumpEnactResult pumpEnactResult = new PumpEnactResult(); - pumpEnactResult.success = bolusCmdResult.success; - pumpEnactResult.enacted = bolusCmdResult.enacted; - pumpEnactResult.comment = bolusCmdResult.message; - - // if enacted, add bolus and carbs to treatment history - if (pumpEnactResult.enacted) { - // TODO if no error occurred, the requested bolus is what the pump delievered, - // that has been checked. If an error occurred, we should check how much insulin - // was delivered, e.g. when the cartridge went empty mid-bolus - // For the first iteration, the alert the pump raises must suffice - pumpEnactResult.bolusDelivered = detailedBolusInfo.insulin; - pumpEnactResult.carbsDelivered = detailedBolusInfo.carbs; - - detailedBolusInfo.date = bolusCmdResult.completionTime; - MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); - } else { - pumpEnactResult.bolusDelivered = 0d; - pumpEnactResult.carbsDelivered = 0d; - } - return pumpEnactResult; - } - - @NonNull - private PumpEnactResult deliverSplittedBolus(DetailedBolusInfo detailedBolusInfo) { - // split up bolus into 2 U parts - PumpEnactResult pumpEnactResult = new PumpEnactResult(); - pumpEnactResult.success = true; - pumpEnactResult.enacted = true; - pumpEnactResult.bolusDelivered = 0d; - pumpEnactResult.carbsDelivered = detailedBolusInfo.carbs; - pumpEnactResult.comment = MainApp.instance().getString(R.string.virtualpump_resultok); - - double remainingBolus = detailedBolusInfo.insulin; - int split = 1; - while (remainingBolus > 0.05) { - double bolus = remainingBolus > 2 ? 2 : remainingBolus; - DetailedBolusInfo bolusInfo = new DetailedBolusInfo(); - bolusInfo.insulin = bolus; - bolusInfo.isValid = false; - log.debug("Delivering split bolus #" + split + " with " + bolus + " U"); - PumpEnactResult bolusResult = deliverBolus(bolusInfo); - if (!bolusResult.success) { - return bolusResult; - } - pumpEnactResult.bolusDelivered += bolus; - remainingBolus -= 2; - split++; - } - MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo); - return pumpEnactResult; + @Override + public void stopBolusDelivering() { + BolusCommand localRunningBolusCommand = runningBolusCommand; + if (localRunningBolusCommand != null) localRunningBolusCommand.requestCancellation(); } private CommandResult runCommand(Command command) { @@ -492,13 +490,6 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf return commandResult; } - @Override - public void stopBolusDelivering() { - // there's no way to stop the combo once delivery has started - // but before that, we could interrupt the command thread ... pause - // till pump times out or raises an error - } - // Note: AAPS calls this only to enact OpenAPS recommendations @Override public PumpEnactResult setTempBasalAbsolute(Double absoluteRate, Integer durationInMinutes, boolean force) { @@ -528,10 +519,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf adjustedPercent = rounded.intValue(); } - Command cmd = !Config.comboUseAlternateSetTbrCommand - ? new SetTbrCommand(adjustedPercent, durationInMinutes) - : new SetTbrCommandAlt(adjustedPercent, durationInMinutes); - CommandResult commandResult = runCommand(cmd); + CommandResult commandResult = runCommand(new SetTbrCommand(adjustedPercent, durationInMinutes)); if (commandResult.enacted) { TemporaryBasal tempStart = new TemporaryBasal(commandResult.completionTime); @@ -585,7 +573,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf tempBasal.source = Source.USER; pumpEnactResult.isTempCancel = true; } - } else if ((activeTemp.percentRate >= 90 && activeTemp.percentRate <= 110) && activeTemp.getPlannedRemainingMinutes() <= 15 ) { + } else if ((activeTemp.percentRate >= 90 && activeTemp.percentRate <= 110) && activeTemp.getPlannedRemainingMinutes() <= 15) { // Let fake neutral temp keep running (see below) log.debug("cancelTempBasal: skipping changing tbr since it already is at " + activeTemp.percentRate + "% and running for another " + activeTemp.getPlannedRemainingMinutes() + " mins."); pumpEnactResult.comment = "cancelTempBasal skipping changing tbr since it already is at " + activeTemp.percentRate + "% and running for another " + activeTemp.getPlannedRemainingMinutes() + " mins."; @@ -598,7 +586,7 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf } else { // Set a fake neutral temp to avoid TBR cancel alert. Decide 90% vs 110% based on // on whether the TBR we're cancelling is above or below 100%. - long percentage = (activeTemp.percentRate > 100) ? 110:90; + long percentage = (activeTemp.percentRate > 100) ? 110 : 90; log.debug("cancelTempBasal: changing tbr to " + percentage + "% for 15 mins."); commandResult = runCommand(new SetTbrCommand(percentage, 15)); if (commandResult.enacted) { @@ -623,7 +611,6 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf return pumpEnactResult; } - // TODO @Override public PumpEnactResult cancelExtendedBolus() { return OPERATION_NOT_SUPPORTED; @@ -713,12 +700,12 @@ public class ComboPlugin implements PluginBase, PumpInterface, ConstraintsInterf ToastUtils.showToastInUiThread(MainApp.instance(), "Ruffy not initialized."); return; } - if (isBusy()){ + if (isBusy()) { ToastUtils.showToastInUiThread(MainApp.instance(), "Pump busy!"); return; } CommandResult result = runCommand(new DetermineCapabilitiesCommand()); - if (result.success){ + if (result.success) { pumpDescription.maxTempPercent = (int) result.capabilities.maxTempPercent; SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(MainApp.instance()); SharedPreferences.Editor editor = preferences.edit(); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 48b4411ebb..bb258731db 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -704,5 +704,7 @@ ACTIVATE PROFILE Date INVALID + Stopping bolus delivery + Bolus delivery stopped