From bf9369babc0e0da417ee7eb5b53a5a4dc1511f3c Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Tue, 29 Aug 2017 01:10:56 +0200 Subject: [PATCH 01/28] Move readDuration method to SetTbrCommand. --- .../de/jotomo/ruffyscripter/RuffyScripter.java | 5 ----- .../ruffyscripter/commands/SetTbrCommand.java | 18 ++++++++++-------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java b/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java index ae3269dcae..953ade2414 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java @@ -676,9 +676,4 @@ public class RuffyScripter { } return (T) value; } - - public long readDisplayedDuration() { - MenuTime duration = readBlinkingValue(MenuTime.class, MenuAttribute.RUNTIME); - return duration.getHour() * 60 + duration.getMinute(); - } } diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java index 206e27ba9e..0bf0deeed6 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java @@ -12,8 +12,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import de.jotomo.ruffyscripter.PumpState; - public class SetTbrCommand extends BaseCommand { private static final Logger log = LoggerFactory.getLogger(SetTbrCommand.class); @@ -174,7 +172,7 @@ public class SetTbrCommand extends BaseCommand { } private long calculateDurationSteps() { - long currentDuration = scripter.readDisplayedDuration(); + long currentDuration = readDisplayedDuration(); log.debug("Initial TBR duration: " + currentDuration); long difference = duration - currentDuration; @@ -190,7 +188,7 @@ public class SetTbrCommand extends BaseCommand { scripter.verifyMenuIsDisplayed(MenuType.TBR_DURATION); // wait up to 5s for any scrolling to finish - long displayedDuration = scripter.readDisplayedDuration(); + long displayedDuration = readDisplayedDuration(); long timeout = System.currentTimeMillis() + 10 * 1000; while (timeout > System.currentTimeMillis() && ((increasingPercentage && displayedDuration < duration) @@ -198,7 +196,7 @@ public class SetTbrCommand extends BaseCommand { log.debug("Waiting for pump to process scrolling input for duration, current: " + displayedDuration + ", desired: " + duration + ", scrolling up: " + increasingPercentage); SystemClock.sleep(50); - displayedDuration = scripter.readDisplayedDuration(); + displayedDuration = readDisplayedDuration(); } log.debug("Final displayed TBR duration: " + displayedDuration); @@ -209,7 +207,7 @@ public class SetTbrCommand extends BaseCommand { // check again to ensure the displayed value hasn't change due to due scrolling taking extremely long SystemClock.sleep(1000); scripter.verifyMenuIsDisplayed(MenuType.TBR_DURATION); - long refreshedDisplayedTbrDuration = scripter.readDisplayedDuration(); + long refreshedDisplayedTbrDuration = readDisplayedDuration(); if (displayedDuration != refreshedDisplayedTbrDuration) { throw new CommandException().message("Failed to set TBR duration: " + "duration changed after input stopped from " @@ -217,8 +215,6 @@ public class SetTbrCommand extends BaseCommand { } } - - private void cancelTbrAndConfirmCancellationWarning() { // confirm entered TBR scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); @@ -239,6 +235,7 @@ public class SetTbrCommand extends BaseCommand { // A wait till the error code can be read results in the code hanging, despite // menu updates coming in, so just check the message. // TODO v2 this only works when the pump's language is English + // TODO extract confirmAlert method String errorMsg = (String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); if (!errorMsg.equals("TBR CANCELLED")) { throw new CommandException().success(false).enacted(false) @@ -285,6 +282,11 @@ public class SetTbrCommand extends BaseCommand { } } + private long readDisplayedDuration() { + MenuTime duration = scripter.readBlinkingValue(MenuTime.class, MenuAttribute.RUNTIME); + return duration.getHour() * 60 + duration.getMinute(); + } + @Override public String toString() { return "SetTbrCommand{" + From 9d6ff73b342520f9d985936eec0c34e74bb9850b Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 30 Aug 2017 00:13:05 +0200 Subject: [PATCH 02/28] SetTbrCommand: extract method refactoring and minor cleanup. --- .../ruffyscripter/commands/SetTbrCommand.java | 31 ++++++++++++------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java index 0bf0deeed6..33d33ed3c9 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java @@ -106,7 +106,7 @@ public class SetTbrCommand extends BaseCommand { private boolean inputTbrPercentage() { scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); - long currentPercent = scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE).longValue(); + long currentPercent = readDisplayedPercentage(); log.debug("Current TBR %: " + currentPercent); long percentageChange = percentage - currentPercent; long percentageSteps = percentageChange / 10; @@ -126,29 +126,31 @@ public class SetTbrCommand extends BaseCommand { return increasePercentage; } - // TODO refactor: extract verification into a method TBR percentage, duration and bolus amount private void verifyDisplayedTbrPercentage(boolean increasingPercentage) { scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); // wait up to 5s for any scrolling to finish - long displayedPercentage = scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE).longValue(); + long displayedPercentage = readDisplayedPercentage(); long timeout = System.currentTimeMillis() + 10 * 1000; while (timeout > System.currentTimeMillis() && ((increasingPercentage && displayedPercentage < percentage) || (!increasingPercentage && displayedPercentage > percentage))) { log.debug("Waiting for pump to process scrolling input for percentage, current: " - + displayedPercentage + ", desired: " + percentage + ", scrolling up: " + increasingPercentage); + + displayedPercentage + ", desired: " + percentage + ", scrolling " + + (increasingPercentage ? "up" : "down")); SystemClock.sleep(50); - displayedPercentage = scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE).longValue(); + displayedPercentage = readDisplayedPercentage(); } log.debug("Final displayed TBR percentage: " + displayedPercentage); if (displayedPercentage != percentage) { - throw new CommandException().message("Failed to set TBR percentage, requested: " + percentage + ", actual: " + displayedPercentage); + throw new CommandException().message("Failed to set TBR percentage, requested: " + + percentage + ", actual: " + displayedPercentage); } - // check again to ensure the displayed value hasn't change due to due scrolling taking extremely long + // check again to ensure the displayed value hasn't change and scrolled past the desired + // value due to due scrolling taking extremely long SystemClock.sleep(1000); scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); - long refreshedDisplayedTbrPecentage = scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE).longValue(); + long refreshedDisplayedTbrPecentage = readDisplayedPercentage(); if (displayedPercentage != refreshedDisplayedTbrPecentage) { throw new CommandException().message("Failed to set TBR percentage: " + "percentage changed after input stopped from " @@ -194,17 +196,20 @@ public class SetTbrCommand extends BaseCommand { && ((increasingPercentage && displayedDuration < duration) || (!increasingPercentage && displayedDuration > duration))) { log.debug("Waiting for pump to process scrolling input for duration, current: " - + displayedDuration + ", desired: " + duration + ", scrolling up: " + increasingPercentage); + + displayedDuration + ", desired: " + duration + + ", scrolling " + (increasingPercentage ? "up" : "down")); SystemClock.sleep(50); displayedDuration = readDisplayedDuration(); } log.debug("Final displayed TBR duration: " + displayedDuration); if (displayedDuration != duration) { - throw new CommandException().message("Failed to set TBR duration, requested: " + duration + ", actual: " + displayedDuration); + throw new CommandException().message("Failed to set TBR duration, requested: " + + duration + ", actual: " + displayedDuration); } - // check again to ensure the displayed value hasn't change due to due scrolling taking extremely long + // check again to ensure the displayed value hasn't change and scrolled past the desired + // value due to due scrolling taking extremely long SystemClock.sleep(1000); scripter.verifyMenuIsDisplayed(MenuType.TBR_DURATION); long refreshedDisplayedTbrDuration = readDisplayedDuration(); @@ -287,6 +292,10 @@ public class SetTbrCommand extends BaseCommand { return duration.getHour() * 60 + duration.getMinute(); } + private long readDisplayedPercentage() { + return scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE).longValue(); + } + @Override public String toString() { return "SetTbrCommand{" + From 9649682ae3d975fdbd52d8e80bb021e6453de800 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 30 Aug 2017 15:06:00 +0200 Subject: [PATCH 03/28] Don't raise alerts if loop is disabled. (cherry picked from commit dc7fd2b) --- .../nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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 ea8280ff41..c76bc95579 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 @@ -139,7 +139,8 @@ public class ComboPlugin implements PluginBase, PumpInterface { if (localLastCmdResult != null && !localLastCmdResult.success) { long now = System.currentTimeMillis(); long fiveMinutesSinceLastAlarm = lastAlarmTime + (5 * 60 * 1000) + (15 * 1000); - if (now > fiveMinutesSinceLastAlarm) { + boolean loopEnabled = ConfigBuilderPlugin.getActiveLoop() != null; + if (now > fiveMinutesSinceLastAlarm && loopEnabled) { log.error("Command failed: " + localLastCmd); log.error("Command result: " + localLastCmdResult); PumpState localPumpState = pump.state; From 21a37c92478d88f25cefd3d1c101ab1904854676 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 30 Aug 2017 15:11:24 +0200 Subject: [PATCH 04/28] Add experimental option to avoid one vibration after bolusing. (cherry picked from commit 104777c) --- .../ruffyscripter/commands/BolusCommand.java | 19 ++++++++++++++++--- .../info/nightscout/androidaps/Config.java | 7 +++++-- 2 files changed, 21 insertions(+), 5 deletions(-) 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 b18b09c0d0..8d4a763408 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java @@ -11,6 +11,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; +import info.nightscout.androidaps.Config; + public class BolusCommand extends BaseCommand { private static final Logger log = LoggerFactory.getLogger(BolusCommand.class); @@ -96,9 +98,20 @@ 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); + if (Config.comboExperimentalFeatures) { + // returning to main menu using the 'back' key should not cause a vibration + // TODO this is too brute-force; at least check for WARNING_OR_ERROR menu type + do { + log.debug("Going back to main menu, currently at " + scripter.getCurrentMenu().getType()); + scripter.pressBackKey(); + scripter.waitForMenuUpdate(); + } while (scripter.getCurrentMenu().getType() != MenuType.MAIN_MENU); + } else { + // 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."); diff --git a/app/src/main/java/info/nightscout/androidaps/Config.java b/app/src/main/java/info/nightscout/androidaps/Config.java index b8ab7ed8dd..7194b49709 100644 --- a/app/src/main/java/info/nightscout/androidaps/Config.java +++ b/app/src/main/java/info/nightscout/androidaps/Config.java @@ -49,11 +49,14 @@ public class Config { public static final boolean logDanaSerialEngine = true; // Combo specific + // TODO try turning this into preferences + public static final boolean comboExperimentalFeatures = true; + /** enable the UNFINISHED and currently BROKEN bolus cammand that reports progress and can be cancelled */ - public static final boolean comboExperimentalBolus = false; + public static final boolean comboExperimentalBolus = false && comboExperimentalFeatures; /** Very quick hack to split up bolus into 2 U parts, spaced roughly 45s apart. * If there's an error during bolusing, no record is created in AAPS. * Don't combine with experimental bolus! */ - public static final boolean comboExperimentalSplitBoluses = false && !comboExperimentalBolus; + public static final boolean comboExperimentalSplitBoluses = false && comboExperimentalFeatures && !comboExperimentalBolus; } From 17dd6df5272c151c731eaf417d28619711881a16 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 30 Aug 2017 15:26:24 +0200 Subject: [PATCH 05/28] Move config options to preferences. (cherry picked from commit 24657ed) --- .../ruffyscripter/commands/BolusCommand.java | 5 +++-- .../java/info/nightscout/androidaps/Config.java | 12 ------------ .../androidaps/plugins/PumpCombo/ComboPlugin.java | 5 ++--- app/src/main/res/values/strings.xml | 6 ++++++ app/src/main/res/xml/pref_combo.xml | 15 +++++++++++++++ 5 files changed, 26 insertions(+), 17 deletions(-) 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 8d4a763408..a3374a2e11 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java @@ -11,7 +11,8 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import info.nightscout.androidaps.Config; +import info.nightscout.androidaps.R; +import info.nightscout.utils.SP; public class BolusCommand extends BaseCommand { private static final Logger log = LoggerFactory.getLogger(BolusCommand.class); @@ -98,7 +99,7 @@ public class BolusCommand extends BaseCommand { } log.debug("Bolus record in history confirms delivered bolus"); - if (Config.comboExperimentalFeatures) { + if(SP.getBoolean(R.string.key_combo_enable_experimental_features, false)) { // returning to main menu using the 'back' key should not cause a vibration // TODO this is too brute-force; at least check for WARNING_OR_ERROR menu type do { diff --git a/app/src/main/java/info/nightscout/androidaps/Config.java b/app/src/main/java/info/nightscout/androidaps/Config.java index 7194b49709..7f3aad2f93 100644 --- a/app/src/main/java/info/nightscout/androidaps/Config.java +++ b/app/src/main/java/info/nightscout/androidaps/Config.java @@ -47,16 +47,4 @@ public class Config { public static final boolean logDanaBTComm = true; public static final boolean logDanaMessageDetail = true; public static final boolean logDanaSerialEngine = true; - - // Combo specific - // TODO try turning this into preferences - public static final boolean comboExperimentalFeatures = true; - - /** enable the UNFINISHED and currently BROKEN bolus cammand that reports progress and can be cancelled */ - public static final boolean comboExperimentalBolus = false && comboExperimentalFeatures; - - /** Very quick hack to split up bolus into 2 U parts, spaced roughly 45s apart. - * If there's an error during bolusing, no record is created in AAPS. - * Don't combine with experimental bolus! */ - public static final boolean comboExperimentalSplitBoluses = false && comboExperimentalFeatures && !comboExperimentalBolus; } 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 c76bc95579..b800404c3f 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 @@ -33,7 +33,6 @@ import de.jotomo.ruffyscripter.commands.CommandResult; import de.jotomo.ruffyscripter.commands.GetPumpStateCommand; import de.jotomo.ruffyscripter.commands.SetTbrCommand; import info.nightscout.androidaps.BuildConfig; -import info.nightscout.androidaps.Config; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.data.DetailedBolusInfo; @@ -390,7 +389,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { if (detailedBolusInfo.insulin > 0) { // bolus needed, ask pump to deliver it - if (!Config.comboExperimentalSplitBoluses) { + if (!SP.getBoolean(R.string.key_combo_enable_experimental_split_bolus, false)) { return deliverBolus(detailedBolusInfo); } else { // split up bolus into 2 U parts @@ -457,7 +456,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { @NonNull private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) { - runningBolusCommand = Config.comboExperimentalBolus + runningBolusCommand = SP.getBoolean(R.string.key_combo_enable_experimental_bolus, false) ? new CancellableBolusCommand(detailedBolusInfo.insulin, bolusProgressReportCallback) : new BolusCommand(detailedBolusInfo.insulin); CommandResult bolusCmdResult = runCommand(runningBolusCommand); diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 3640f13f2a..6c9385bdd1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -712,5 +712,11 @@ wizard_include_basal_iob Stopping bolus delivery Bolus delivery stopped + combo_enable_experimental_features + Enable experimental features + combo_enable_experimental_bolus + Experimental bolus + combo_experimental_split_bolus + Experimental split bolus feature diff --git a/app/src/main/res/xml/pref_combo.xml b/app/src/main/res/xml/pref_combo.xml index 3f2a8800b7..b527a14b51 100644 --- a/app/src/main/res/xml/pref_combo.xml +++ b/app/src/main/res/xml/pref_combo.xml @@ -4,6 +4,21 @@ android:key="combopump" android:title="@string/combopump_settings"> + + + + \ No newline at end of file From 4aac46f2bcb265fb2315211d366e9be73ed929eb Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Thu, 31 Aug 2017 01:58:00 +0200 Subject: [PATCH 06/28] Cleanup. (cherry picked from commit e7fe202) --- .../de/jotomo/ruffyscripter/commands/SetTbrCommand.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java index 33d33ed3c9..87af7d78ce 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java @@ -110,13 +110,9 @@ public class SetTbrCommand extends BaseCommand { log.debug("Current TBR %: " + currentPercent); long percentageChange = percentage - currentPercent; long percentageSteps = percentageChange / 10; - boolean increasePercentage = true; - if (percentageSteps < 0) { - increasePercentage = false; - percentageSteps = Math.abs(percentageSteps); - } + boolean increasePercentage = percentageSteps > 0; log.debug("Pressing " + (increasePercentage ? "up" : "down") + " " + percentageSteps + " times"); - for (int i = 0; i < percentageSteps; i++) { + for (int i = 0; i < Math.abs(percentageSteps); i++) { scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); log.debug("Push #" + (i + 1)); if (increasePercentage) scripter.pressUpKey(); From 6019323740c7082b0fd75b7344f3e8e938ce66db Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Thu, 31 Aug 2017 11:17:59 +0200 Subject: [PATCH 07/28] Work around curentMenu being null, maybe. (cherry picked from commit da49be0) --- .../main/java/de/jotomo/ruffyscripter/RuffyScripter.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java b/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java index 953ade2414..7230b5668c 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java @@ -464,6 +464,12 @@ public class RuffyScripter { // === pump ops === public Menu getCurrentMenu() { + // TODO workaround, supposedly fixed in latest ruffy? + while (currentMenu == null) { + log.error("currentMenu == null, waiting"); + SystemClock.sleep(500); + waitForMenuUpdate(); + } return currentMenu; } From 81b97b5278227149582fd29b08177a2e1cf56acc Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Thu, 31 Aug 2017 23:26:55 +0200 Subject: [PATCH 08/28] Add option to ignore setting a TBR as long as it does't occur twice in a row. (cherry picked from commit 238e85c) --- .../plugins/PumpCombo/ComboPlugin.java | 20 +++++++++++++++++-- app/src/main/res/values/strings.xml | 2 ++ app/src/main/res/xml/pref_combo.xml | 4 ++++ 3 files changed, 24 insertions(+), 2 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 b800404c3f..6eed939412 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 @@ -67,6 +67,8 @@ public class ComboPlugin implements PluginBase, PumpInterface { private ComboPump pump = new ComboPump(); + private boolean ignoreLastSetTbrFailure = false; + @Nullable private volatile BolusCommand runningBolusCommand; @@ -98,7 +100,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { pumpDescription.isTempBasalCapable = true; pumpDescription.tempBasalStyle = PumpDescription.PERCENT; - pumpDescription.maxTempPercent = SP.getInt(COMBO_MAX_TEMP_PERCENT_SP, 500); + pumpDescription.maxTempPercent = 500; pumpDescription.tempPercentStep = 10; pumpDescription.tempDurationStep = 15; @@ -139,7 +141,8 @@ public class ComboPlugin implements PluginBase, PumpInterface { long now = System.currentTimeMillis(); long fiveMinutesSinceLastAlarm = lastAlarmTime + (5 * 60 * 1000) + (15 * 1000); boolean loopEnabled = ConfigBuilderPlugin.getActiveLoop() != null; - if (now > fiveMinutesSinceLastAlarm && loopEnabled) { + if (now > fiveMinutesSinceLastAlarm && loopEnabled + && !(SP.getBoolean(R.string.key_combo_ignore_transient_tbr_errors, false) && localLastCmd instanceof SetTbrCommand && ignoreLastSetTbrFailure)) { log.error("Command failed: " + localLastCmd); log.error("Command result: " + localLastCmdResult); PumpState localPumpState = pump.state; @@ -505,6 +508,19 @@ public class ComboPlugin implements PluginBase, PumpInterface { log.error("Exception received from pump", commandResult.exception); } + // error tolerance + if (commandResult.success) ignoreLastSetTbrFailure = false; + + if (command instanceof SetTbrCommand) { + if (!commandResult.success && !ignoreLastSetTbrFailure) { + // ignore this once + ignoreLastSetTbrFailure = true; + } else { + // second failure in a row + ignoreLastSetTbrFailure = false; + } + } + pump.lastCmd = command; pump.lastCmdTime = new Date(); pump.lastCmdResult = commandResult; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c9385bdd1..4d0ea04beb 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -718,5 +718,7 @@ Experimental bolus combo_experimental_split_bolus Experimental split bolus feature + combo_ignore_transient_tbr_errors + Ignore transient TBR errors diff --git a/app/src/main/res/xml/pref_combo.xml b/app/src/main/res/xml/pref_combo.xml index b527a14b51..857281b097 100644 --- a/app/src/main/res/xml/pref_combo.xml +++ b/app/src/main/res/xml/pref_combo.xml @@ -18,6 +18,10 @@ android:defaultValue="false" android:key="@string/key_combo_enable_experimental_split_bolus" android:title="@string/combo_enable_experimental_split_bolus" /> + From 9b6cd23cddf8f5f17746487fe25f8509add554b1 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Thu, 31 Aug 2017 23:57:19 +0200 Subject: [PATCH 09/28] Experimental options: for specifc prefs, always check experimental options are turned on. While the specific prefs are disabled when disabling experimental options, they can still be turned on. (cherry picked from commit 6270239) --- .../androidaps/plugins/PumpCombo/ComboPlugin.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 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 6eed939412..96b5b2f4d0 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 @@ -141,8 +141,9 @@ public class ComboPlugin implements PluginBase, PumpInterface { long now = System.currentTimeMillis(); long fiveMinutesSinceLastAlarm = lastAlarmTime + (5 * 60 * 1000) + (15 * 1000); boolean loopEnabled = ConfigBuilderPlugin.getActiveLoop() != null; - if (now > fiveMinutesSinceLastAlarm && loopEnabled - && !(SP.getBoolean(R.string.key_combo_ignore_transient_tbr_errors, false) && localLastCmd instanceof SetTbrCommand && ignoreLastSetTbrFailure)) { + boolean ignoreLastFailedTbrCmd = SP.getBoolean(R.string.key_combo_ignore_transient_tbr_errors, false) + && localLastCmd instanceof SetTbrCommand && ignoreLastSetTbrFailure; + if (now > fiveMinutesSinceLastAlarm && loopEnabled && !ignoreLastFailedTbrCmd) { log.error("Command failed: " + localLastCmd); log.error("Command result: " + localLastCmdResult); PumpState localPumpState = pump.state; @@ -392,7 +393,8 @@ public class ComboPlugin implements PluginBase, PumpInterface { if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) { if (detailedBolusInfo.insulin > 0) { // bolus needed, ask pump to deliver it - if (!SP.getBoolean(R.string.key_combo_enable_experimental_split_bolus, false)) { + if (!(SP.getBoolean(R.string.key_combo_enable_experimental_features, false) + && SP.getBoolean(R.string.key_combo_enable_experimental_split_bolus, false))) { return deliverBolus(detailedBolusInfo); } else { // split up bolus into 2 U parts @@ -459,7 +461,8 @@ public class ComboPlugin implements PluginBase, PumpInterface { @NonNull private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) { - runningBolusCommand = SP.getBoolean(R.string.key_combo_enable_experimental_bolus, false) + runningBolusCommand = SP.getBoolean(R.string.key_combo_enable_experimental_features, false) + && SP.getBoolean(R.string.key_combo_enable_experimental_bolus, false) ? new CancellableBolusCommand(detailedBolusInfo.insulin, bolusProgressReportCallback) : new BolusCommand(detailedBolusInfo.insulin); CommandResult bolusCmdResult = runCommand(runningBolusCommand); From b1d000eae3f6ce0b731aa0016da28dcd713edf1f Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 1 Sep 2017 02:55:36 +0200 Subject: [PATCH 10/28] SetTbrCommand: extract confirrmAlert method. (cherry picked from commit 329ff14) --- .../ruffyscripter/commands/SetTbrCommand.java | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java index 87af7d78ce..1d4da448ab 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java @@ -224,29 +224,31 @@ public class SetTbrCommand extends BaseCommand { // A "TBR CANCELLED alert" is only raised by the pump when the remaining time is // greater than 60s (displayed as 0:01, the pump goes from there to finished. // We could read the remaining duration from MAIN_MENU, but by the time we're here, - // the pumup could have moved from 0:02 to 0:01, so instead, check if a "TBR CANCELLED" alert + // the pump could have moved from 0:02 to 0:01, so instead, check if a "TBR CANCELLED" alert // is raised and if so dismiss it - long inFiveSeconds = System.currentTimeMillis() + 5 * 1000; + confirmAlert("TBR CANCELLED", 5000); + } + + /** Confirms and dismisses the given alert if it's raised before the timeout */ + private void confirmAlert(String alertMessage, int maxWaitMs) { + long inFiveSeconds = System.currentTimeMillis() + maxWaitMs; boolean alertProcessed = false; while (System.currentTimeMillis() < inFiveSeconds && !alertProcessed) { if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { - // Check the raised alarm is TBR CANCELLED, so we're not accidentally cancelling - // a different alarm that might be raised at the same time. // Note that the message is permanently displayed, while the error code is blinking. // A wait till the error code can be read results in the code hanging, despite // menu updates coming in, so just check the message. - // TODO v2 this only works when the pump's language is English - // TODO extract confirmAlert method + // TODO quick try if the can't make reading the error code work .. String errorMsg = (String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); - if (!errorMsg.equals("TBR CANCELLED")) { + if (!errorMsg.equals(alertMessage)) { throw new CommandException().success(false).enacted(false) - .message("An alert other than the expected TBR CANCELLED was raised by the pump: " + .message("An alert other than the expected " + alertMessage + " was raised by the pump: " + errorMsg + ". Please check the pump."); } - // confirm "TBR CANCELLED" alert + // confirm alert scripter.verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR); scripter.pressCheckKey(); - // dismiss "TBR CANCELLED" alert + // dismiss alert scripter.verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR); scripter.pressCheckKey(); scripter.waitForMenuToBeLeft(MenuType.WARNING_OR_ERROR); From c96122cbed3940269740d0db19cf131f11d71d20 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 1 Sep 2017 02:56:56 +0200 Subject: [PATCH 11/28] Move confirmAlert method to scripter. (cherry picked from commit f018d42) --- .../jotomo/ruffyscripter/RuffyScripter.java | 33 +++++++++++++++++++ .../ruffyscripter/commands/BaseCommand.java | 19 +++++++++-- .../commands/CancellableBolusCommand.java | 7 ---- .../ruffyscripter/commands/SetTbrCommand.java | 31 +---------------- 4 files changed, 50 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java b/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java index 7230b5668c..5b21f348c8 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java @@ -582,6 +582,39 @@ public class RuffyScripter { // only ensureConnected() uses the method with the timeout parameter; inline that code, // so we can use a custom timeout and give a better error message in case of failure + + // TODO confirmAlarms? and report back which were cancelled? + + /** Confirms and dismisses the given alert if it's raised before the timeout */ + public boolean confirmAlert(String alertMessage, int maxWaitMs) { + long inFiveSeconds = System.currentTimeMillis() + maxWaitMs; + boolean alertProcessed = false; + while (System.currentTimeMillis() < inFiveSeconds && !alertProcessed) { + if (getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { + // Note that the message is permanently displayed, while the error code is blinking. + // A wait till the error code can be read results in the code hanging, despite + // menu updates coming in, so just check the message. + // TODO quick try if the can't make reading the error code work .. + String errorMsg = (String) getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); + if (!errorMsg.equals(alertMessage)) { + throw new CommandException().success(false).enacted(false) + .message("An alert other than the expected " + alertMessage + " was raised by the pump: " + + errorMsg + ". Please check the pump."); + } + // confirm alert + verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR); + pressCheckKey(); + // dismiss alert + verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR); + pressCheckKey(); + waitForMenuToBeLeft(MenuType.WARNING_OR_ERROR); + alertProcessed = true; + } + SystemClock.sleep(10); + } + return alertProcessed; + } + /** * Wait until the menu update is in */ diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/BaseCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/BaseCommand.java index 0e83f0c1a1..45370187f0 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/BaseCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/BaseCommand.java @@ -1,17 +1,30 @@ package de.jotomo.ruffyscripter.commands; +import android.os.SystemClock; + +import org.monkey.d.ruffy.ruffy.driver.display.MenuAttribute; +import org.monkey.d.ruffy.ruffy.driver.display.MenuType; + import de.jotomo.ruffyscripter.RuffyScripter; public abstract class BaseCommand implements Command { // RS will inject itself here protected RuffyScripter scripter; - @Override public void setScripter(RuffyScripter scripter) { this.scripter = scripter; } + + @Override + public void setScripter(RuffyScripter scripter) { + this.scripter = scripter; + } // TODO upcoming protected final boolean canBeCancelled = true; protected volatile boolean cancelRequested = false; + public void requestCancellation() { - cancelRequested = true; + cancelRequested = true; + } + + public boolean isCancellable() { + return canBeCancelled; } - public boolean isCancellable() { return canBeCancelled; } } diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java index dcf06424da..409a2eb8db 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java @@ -191,13 +191,6 @@ public class CancellableBolusCommand extends BolusCommand { } } - // TODO confirmAlarms? and report back which were cancelled? - - private boolean confirmAlert(String alertText, int maxWaitTillExpectedAlert) { - // TODO - return false; - } - public void requestCancellation() { cancelRequested = true; progressReportCallback.report(STOPPING, 0, 0); diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java index 1d4da448ab..4ebee15fe6 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java @@ -226,36 +226,7 @@ public class SetTbrCommand extends BaseCommand { // We could read the remaining duration from MAIN_MENU, but by the time we're here, // the pump could have moved from 0:02 to 0:01, so instead, check if a "TBR CANCELLED" alert // is raised and if so dismiss it - confirmAlert("TBR CANCELLED", 5000); - } - - /** Confirms and dismisses the given alert if it's raised before the timeout */ - private void confirmAlert(String alertMessage, int maxWaitMs) { - long inFiveSeconds = System.currentTimeMillis() + maxWaitMs; - boolean alertProcessed = false; - while (System.currentTimeMillis() < inFiveSeconds && !alertProcessed) { - if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { - // Note that the message is permanently displayed, while the error code is blinking. - // A wait till the error code can be read results in the code hanging, despite - // menu updates coming in, so just check the message. - // TODO quick try if the can't make reading the error code work .. - String errorMsg = (String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); - if (!errorMsg.equals(alertMessage)) { - throw new CommandException().success(false).enacted(false) - .message("An alert other than the expected " + alertMessage + " was raised by the pump: " - + errorMsg + ". Please check the pump."); - } - // confirm alert - scripter.verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR); - scripter.pressCheckKey(); - // dismiss alert - scripter.verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR); - scripter.pressCheckKey(); - scripter.waitForMenuToBeLeft(MenuType.WARNING_OR_ERROR); - alertProcessed = true; - } - SystemClock.sleep(10); - } + scripter.confirmAlert("TBR CANCELLED", 5000); } private void verifyMainMenuShowsNoActiveTbr() { From 58757735f8e684933af6b2b77c23a4b9401eeaac Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 1 Sep 2017 10:45:06 +0200 Subject: [PATCH 12/28] Refactor. (cherry picked from commit 06a454d) --- .../jotomo/ruffyscripter/RuffyScripter.java | 57 ++++--------------- .../ruffyscripter/commands/BolusCommand.java | 8 +-- .../commands/CancellableBolusCommand.java | 10 ++-- 3 files changed, 19 insertions(+), 56 deletions(-) diff --git a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java b/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java index 5b21f348c8..24aeb792eb 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java @@ -193,6 +193,16 @@ public class RuffyScripter { this.ruffyService = null; } + public void returnToMainMenu() { + // returning to main menu using the 'back' key should not cause a vibration + // TODO this is too brute-force; at least check for WARNING_OR_ERROR menu type + do { + log.debug("Going back to main menu, currently at " + getCurrentMenu().getType()); + pressBackKey(); + waitForMenuUpdate(); + } while (getCurrentMenu().getType() != MenuType.MAIN_MENU); + } + private static class Returnable { CommandResult cmdResult; } @@ -540,49 +550,11 @@ public class RuffyScripter { return true; } - public boolean goToMainTypeScreen(MenuType screen, long timeout) { - long start = System.currentTimeMillis(); - while ((currentMenu == null || currentMenu.getType() != screen) && start + timeout > System.currentTimeMillis()) { - if (currentMenu != null && currentMenu.getType() == MenuType.WARNING_OR_ERROR) { - throw new CommandException().message("Warning/errors raised by pump, please check pump"); - // since warnings and errors can occur at any time, they should be dealt with in - // a more general way, see the handleMenuUpdate callback above - //FIXME bad thing to do :D - // yup, commenting this out since I don't want an occlusionn alert to hidden by this :-) - //pressCheckKey(); - } else if (currentMenu != null && !currentMenu.getType().isMaintype()) { - pressBackKey(); - } else - pressMenuKey(); - waitForScreenUpdate(250); - } - return currentMenu != null && currentMenu.getType() == screen; - } - - public boolean enterMenu(MenuType startType, MenuType targetType, byte key, long timeout) { - if (currentMenu.getType() == targetType) - return true; - if (currentMenu == null || currentMenu.getType() != startType) - return false; - long start = System.currentTimeMillis(); - pressKey(key, 2000); - while ((currentMenu == null || currentMenu.getType() != targetType) && start + timeout > System.currentTimeMillis()) { - waitForScreenUpdate(100); - } - return currentMenu != null && currentMenu.getType() == targetType; - } - - public void step(int steps, byte key, long timeout) { - for (int i = 0; i < Math.abs(steps); i++) - pressKey(key, timeout); - } - // TODO v2, rework these two methods: waitForMenuUpdate shoud only be used by commands // then anything longer than a few seconds is an error; // only ensureConnected() uses the method with the timeout parameter; inline that code, // so we can use a custom timeout and give a better error message in case of failure - // TODO confirmAlarms? and report back which were cancelled? /** Confirms and dismisses the given alert if it's raised before the timeout */ @@ -615,10 +587,7 @@ public class RuffyScripter { return alertProcessed; } - /** - * Wait until the menu update is in - */ - // TODO donn't use this in ensureConnected + /** Wait until the menu is updated */ public void waitForMenuUpdate() { waitForMenuUpdate(60, "Timeout waiting for menu update"); } @@ -669,9 +638,7 @@ public class RuffyScripter { } } - /** - * Wait till a menu changed has completed, "away" from the menu provided as argument. - */ + /** Wait till a menu changed has completed, "away" from the menu provided as argument. */ public void waitForMenuToBeLeft(MenuType menuType) { long timeout = System.currentTimeMillis() + 60 * 1000; while (currentMenu.getType() == menuType) { 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 a3374a2e11..4e689a851d 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java @@ -100,13 +100,7 @@ public class BolusCommand extends BaseCommand { log.debug("Bolus record in history confirms delivered bolus"); if(SP.getBoolean(R.string.key_combo_enable_experimental_features, false)) { - // returning to main menu using the 'back' key should not cause a vibration - // TODO this is too brute-force; at least check for WARNING_OR_ERROR menu type - do { - log.debug("Going back to main menu, currently at " + scripter.getCurrentMenu().getType()); - scripter.pressBackKey(); - scripter.waitForMenuUpdate(); - } while (scripter.getCurrentMenu().getType() != MenuType.MAIN_MENU); + scripter.returnToMainMenu(); } else { // leave menu to go back to main menu scripter.pressCheckKey(); diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java index 409a2eb8db..b1194ae0c6 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java @@ -52,7 +52,7 @@ public class CancellableBolusCommand extends BolusCommand { if (cancelRequested) { progressReportCallback.report(STOPPING, 0, 0); - scripter.goToMainTypeScreen(MenuType.MAIN_MENU, 30 * 1000); + scripter.returnToMainMenu(); progressReportCallback.report(STOPPED, 0, 0); return new CommandResult().success(true).enacted(false) .message("Bolus cancelled as per user request with no insulin delivered"); @@ -69,7 +69,7 @@ public class CancellableBolusCommand extends BolusCommand { 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); + boolean alertWasCancelled = scripter.confirmAlert("BOLUS CANCELLED", 1000); if (alertWasCancelled) { progressReportCallback.report(STOPPED, 0, 0); return new CommandResult().success(true).enacted(false) @@ -120,7 +120,7 @@ public class CancellableBolusCommand extends BolusCommand { String message = (String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); if (message.equals("LOW CARTRIDGE")) { lowCartdrigeAlarmTriggered = true; - confirmAlert("LOW CARTRIDGE", 2000); + scripter.confirmAlert("LOW CARTRIDGE", 2000); } else { // any other alert break; @@ -176,7 +176,9 @@ public class CancellableBolusCommand extends BolusCommand { } log.debug("Bolus record in history confirms delivered bolus"); - if (!scripter.goToMainTypeScreen(MenuType.MAIN_MENU, 15 * 1000)) { + // TODO how would this call fail? more generally ...... + scripter.returnToMainMenu(); + if (scripter.getCurrentMenu().getType() != MenuType.MAIN_MENU) { 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."); From c8c445c608a65dd5fe4fa77910f8520c3a1eac79 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 1 Sep 2017 16:00:10 +0200 Subject: [PATCH 13/28] Add option to skip small TBR changes, add summaries to prefs. (cherry picked from commit a76b03a) --- .../plugins/PumpCombo/ComboPlugin.java | 17 ++++++++++++- app/src/main/res/values/strings.xml | 11 ++++++-- app/src/main/res/xml/pref_combo.xml | 25 +++++++++++++++---- 3 files changed, 45 insertions(+), 8 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 96b5b2f4d0..0fe788d72e 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 @@ -141,7 +141,8 @@ public class ComboPlugin implements PluginBase, PumpInterface { long now = System.currentTimeMillis(); long fiveMinutesSinceLastAlarm = lastAlarmTime + (5 * 60 * 1000) + (15 * 1000); boolean loopEnabled = ConfigBuilderPlugin.getActiveLoop() != null; - boolean ignoreLastFailedTbrCmd = SP.getBoolean(R.string.key_combo_ignore_transient_tbr_errors, false) + boolean ignoreLastFailedTbrCmd = SP.getBoolean(R.string.key_combo_enable_experimental_features, false) + && SP.getBoolean(R.string.key_combo_experimental_ignore_transient_tbr_errors, false) && localLastCmd instanceof SetTbrCommand && ignoreLastSetTbrFailure; if (now > fiveMinutesSinceLastAlarm && loopEnabled && !ignoreLastFailedTbrCmd) { log.error("Command failed: " + localLastCmd); @@ -554,6 +555,20 @@ public class ComboPlugin implements PluginBase, PumpInterface { if (unroundedPercentage != roundedPercentage) { log.debug("Rounded requested rate " + unroundedPercentage + "% -> " + roundedPercentage + "%"); } + + TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); + if (!force && activeTemp != null) { + int minRequiredDelta = SP.getInt(R.string.key_combo_experimental_reject_tbr_changes_below_delta, 0); + boolean deltaBelowThreshold = Math.abs(activeTemp.percentRate - roundedPercentage) < minRequiredDelta; + if (deltaBelowThreshold) { + log.debug("Skipping setting APS-requested TBR change, since the requested change from " + + activeTemp.percentRate + " -> " + roundedPercentage + " is below the delta threshold of " + minRequiredDelta); + PumpEnactResult pumpEnactResult = new PumpEnactResult(); + pumpEnactResult.success = true; + pumpEnactResult.enacted = false; + return pumpEnactResult; + } + } return setTempBasalPercent(roundedPercentage, durationInMinutes); } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4d0ea04beb..4f95d46808 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -718,7 +718,14 @@ Experimental bolus combo_experimental_split_bolus Experimental split bolus feature - combo_ignore_transient_tbr_errors - Ignore transient TBR errors + combo_ignore_transient_tbr_errors + Ignore transient TBR errors + combo_experimental_reject_tbr_changes_below_delta + Reject TBR changes below threshold (%) + Don\'t set a TBR if the difference between the new and a running TBR is below this threshold in percent. Specifying 0 disables this option. + Ignore failures when setting a TBR, unless setting the next TBR also fails. + Splits boluses into 2 U parts and waits around 45 after each to slow down bolus delivery. + Enables the in-development bolus with progress report and cancel option. + Unlocks experimental features which are in development and might be broken entirely. diff --git a/app/src/main/res/xml/pref_combo.xml b/app/src/main/res/xml/pref_combo.xml index 857281b097..d1d1cd5a6b 100644 --- a/app/src/main/res/xml/pref_combo.xml +++ b/app/src/main/res/xml/pref_combo.xml @@ -7,21 +7,36 @@ + android:title="@string/combo_enable_experimental_features" + android:summary="@string/combo_enable_experimental_features_summary" /> + android:title="@string/combo_enable_experimental_bolus" + android:summary="@string/combo_enable_experimental_bolus_summary" /> + android:title="@string/combo_enable_experimental_split_bolus" + android:summary="@string/combo_enable_experimental_split_bolus_summary"/> + + android:key="@string/key_combo_experimental_ignore_transient_tbr_errors" + android:title="@string/combo_experimental_ignore_transient_tbr_errors" + android:summary="@string/combo_experimental_ignore_transient_tbr_errors_summary"/> + + + From 516a8c044bbe4eea8f2a8e78f954ede3f9513b7b Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 1 Sep 2017 19:01:24 +0200 Subject: [PATCH 14/28] Move RuffyScripter to PumpCombo package. (cherry picked from commit 7875ac0) --- .../plugins/PumpCombo/ComboFragment.java | 6 +++--- .../plugins/PumpCombo/ComboPlugin.java | 18 +++++++++--------- .../plugins/PumpCombo/ComboPump.java | 6 +++--- .../plugins/PumpCombo/scripter}/History.java | 2 +- .../plugins/PumpCombo/scripter}/PumpState.java | 2 +- .../PumpCombo/scripter}/RuffyScripter.java | 10 +++++----- .../scripter}/commands/BaseCommand.java | 4 ++-- .../scripter}/commands/BolusCommand.java | 2 +- .../scripter}/commands/CancelTbrCommand.java | 4 ++-- .../commands/CancellableBolusCommand.java | 14 +++++++------- .../PumpCombo/scripter}/commands/Command.java | 4 ++-- .../scripter}/commands/CommandException.java | 2 +- .../scripter}/commands/CommandResult.java | 6 +++--- .../commands/GetBasalRateProfileCommand.java | 4 ++-- .../commands/GetPumpStateCommand.java | 4 ++-- .../commands/GetReservoirLevelCommand.java | 2 +- .../commands/SetBasalRateProfileCommand.java | 2 +- .../scripter}/commands/SetTbrCommand.java | 2 +- 18 files changed, 47 insertions(+), 47 deletions(-) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/History.java (54%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/PumpState.java (97%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/RuffyScripter.java (98%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/BaseCommand.java (82%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/BolusCommand.java (99%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/CancelTbrCommand.java (95%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/CancellableBolusCommand.java (92%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/Command.java (75%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/CommandException.java (94%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/CommandResult.java (88%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/GetBasalRateProfileCommand.java (96%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/GetPumpStateCommand.java (96%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/GetReservoirLevelCommand.java (91%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/SetBasalRateProfileCommand.java (80%) rename app/src/main/java/{de/jotomo/ruffyscripter => info/nightscout/androidaps/plugins/PumpCombo/scripter}/commands/SetTbrCommand.java (99%) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java index f4d49c0a94..ef974b8046 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java @@ -17,9 +17,9 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import de.jotomo.ruffyscripter.PumpState; -import de.jotomo.ruffyscripter.commands.Command; -import de.jotomo.ruffyscripter.commands.CommandResult; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.Command; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandResult; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI; 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 0fe788d72e..2441584928 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 @@ -23,15 +23,15 @@ import org.slf4j.LoggerFactory; import java.util.Date; -import de.jotomo.ruffyscripter.PumpState; -import de.jotomo.ruffyscripter.RuffyScripter; -import de.jotomo.ruffyscripter.commands.BolusCommand; -import de.jotomo.ruffyscripter.commands.CancelTbrCommand; -import de.jotomo.ruffyscripter.commands.CancellableBolusCommand; -import de.jotomo.ruffyscripter.commands.Command; -import de.jotomo.ruffyscripter.commands.CommandResult; -import de.jotomo.ruffyscripter.commands.GetPumpStateCommand; -import de.jotomo.ruffyscripter.commands.SetTbrCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancelTbrCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancellableBolusCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.Command; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandResult; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.GetPumpStateCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.SetTbrCommand; import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPump.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPump.java index d24a31607c..3160a32fee 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPump.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPump.java @@ -5,9 +5,9 @@ import android.support.annotation.Nullable; import java.util.Date; -import de.jotomo.ruffyscripter.PumpState; -import de.jotomo.ruffyscripter.commands.Command; -import de.jotomo.ruffyscripter.commands.CommandResult; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.Command; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandResult; class ComboPump { @NonNull diff --git a/app/src/main/java/de/jotomo/ruffyscripter/History.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/History.java similarity index 54% rename from app/src/main/java/de/jotomo/ruffyscripter/History.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/History.java index cfe514565b..ed9ac66061 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/History.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/History.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter; +package info.nightscout.androidaps.plugins.PumpCombo.scripter; /** * The history data read from "My data" diff --git a/app/src/main/java/de/jotomo/ruffyscripter/PumpState.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/PumpState.java similarity index 97% rename from app/src/main/java/de/jotomo/ruffyscripter/PumpState.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/PumpState.java index 9323ab71a5..0db577bf7a 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/PumpState.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/PumpState.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter; +package info.nightscout.androidaps.plugins.PumpCombo.scripter; import java.util.Date; diff --git a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java similarity index 98% rename from app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java index 24aeb792eb..d0d126235e 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/RuffyScripter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter; +package info.nightscout.androidaps.plugins.PumpCombo.scripter; import android.os.RemoteException; import android.os.SystemClock; @@ -16,10 +16,10 @@ import org.slf4j.LoggerFactory; import java.util.List; -import de.jotomo.ruffyscripter.commands.Command; -import de.jotomo.ruffyscripter.commands.CommandException; -import de.jotomo.ruffyscripter.commands.CommandResult; -import de.jotomo.ruffyscripter.commands.GetPumpStateCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.Command; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandException; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandResult; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.GetPumpStateCommand; // TODO regularly read "My data" history (boluses, TBR) to double check all commands ran successfully. // Automatically compare against AAPS db, or log all requests in the PumpInterface (maybe Milos diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/BaseCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BaseCommand.java similarity index 82% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/BaseCommand.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BaseCommand.java index 45370187f0..1a145c3efc 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/BaseCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BaseCommand.java @@ -1,11 +1,11 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import android.os.SystemClock; import org.monkey.d.ruffy.ruffy.driver.display.MenuAttribute; import org.monkey.d.ruffy.ruffy.driver.display.MenuType; -import de.jotomo.ruffyscripter.RuffyScripter; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; public abstract class BaseCommand implements Command { // RS will inject itself here diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BolusCommand.java similarity index 99% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BolusCommand.java index 4e689a851d..5593974281 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/BolusCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BolusCommand.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import android.os.SystemClock; diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/CancelTbrCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancelTbrCommand.java similarity index 95% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/CancelTbrCommand.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancelTbrCommand.java index 7d6fa98d37..de4bb27862 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/CancelTbrCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancelTbrCommand.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import org.monkey.d.ruffy.ruffy.driver.display.MenuType; import org.slf4j.Logger; @@ -7,7 +7,7 @@ import org.slf4j.LoggerFactory; import java.util.Collections; import java.util.List; -import de.jotomo.ruffyscripter.PumpState; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; import info.nightscout.androidaps.MainApp; // TODO robustness: can a TBR run out, whilst we're trying to cancel it? diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancellableBolusCommand.java similarity index 92% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancellableBolusCommand.java index b1194ae0c6..92edfff6b1 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/CancellableBolusCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancellableBolusCommand.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import android.os.SystemClock; @@ -11,13 +11,13 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import de.jotomo.ruffyscripter.PumpState; -import de.jotomo.ruffyscripter.RuffyScripter; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; -import static de.jotomo.ruffyscripter.commands.CancellableBolusCommand.ProgressReportCallback.State.DELIVERED; -import static de.jotomo.ruffyscripter.commands.CancellableBolusCommand.ProgressReportCallback.State.DELIVERING; -import static de.jotomo.ruffyscripter.commands.CancellableBolusCommand.ProgressReportCallback.State.STOPPED; -import static de.jotomo.ruffyscripter.commands.CancellableBolusCommand.ProgressReportCallback.State.STOPPING; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancellableBolusCommand.ProgressReportCallback.State.DELIVERED; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancellableBolusCommand.ProgressReportCallback.State.DELIVERING; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancellableBolusCommand.ProgressReportCallback.State.STOPPED; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancellableBolusCommand.ProgressReportCallback.State.STOPPING; public class CancellableBolusCommand extends BolusCommand { private static final Logger log = LoggerFactory.getLogger(CancellableBolusCommand.class); diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/Command.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/Command.java similarity index 75% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/Command.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/Command.java index 60fa3c730f..f1572f56aa 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/Command.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/Command.java @@ -1,8 +1,8 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import java.util.List; -import de.jotomo.ruffyscripter.RuffyScripter; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; /** * Interface for all commands to be executed by the pump. diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandException.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CommandException.java similarity index 94% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/CommandException.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CommandException.java index d2f31cc8e2..75cac9014a 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandException.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CommandException.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; public class CommandException extends RuntimeException { public boolean success = false; diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CommandResult.java similarity index 88% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CommandResult.java index 9d1bbb321e..c99c6f29df 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CommandResult.java @@ -1,9 +1,9 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import java.util.Date; -import de.jotomo.ruffyscripter.History; -import de.jotomo.ruffyscripter.PumpState; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.History; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; public class CommandResult { public boolean success; diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/GetBasalRateProfileCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetBasalRateProfileCommand.java similarity index 96% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/GetBasalRateProfileCommand.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetBasalRateProfileCommand.java index ff842af5dd..4e4aeafbca 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/GetBasalRateProfileCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetBasalRateProfileCommand.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import android.util.Log; @@ -10,7 +10,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import de.jotomo.ruffyscripter.RuffyScripter; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; public class GetBasalRateProfileCommand extends BaseCommand { private static final Logger log = LoggerFactory.getLogger(GetBasalRateProfileCommand.class); diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/GetPumpStateCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetPumpStateCommand.java similarity index 96% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/GetPumpStateCommand.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetPumpStateCommand.java index b298fcb41e..1f29580216 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/GetPumpStateCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetPumpStateCommand.java @@ -1,11 +1,11 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import org.monkey.d.ruffy.ruffy.driver.display.MenuType; import java.util.Collections; import java.util.List; -import static de.jotomo.ruffyscripter.commands.GetPumpStateCommand.Stepper.runStep; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.GetPumpStateCommand.Stepper.runStep; public class GetPumpStateCommand extends BaseCommand { interface Step { diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/GetReservoirLevelCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java similarity index 91% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/GetReservoirLevelCommand.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java index 3a620a0fef..b6c80cb1a6 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/GetReservoirLevelCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import java.util.List; diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetBasalRateProfileCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SetBasalRateProfileCommand.java similarity index 80% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/SetBasalRateProfileCommand.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SetBasalRateProfileCommand.java index 6d98c94d42..7dd2d029ba 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetBasalRateProfileCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SetBasalRateProfileCommand.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import java.util.List; diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SetTbrCommand.java similarity index 99% rename from app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SetTbrCommand.java index 4ebee15fe6..b5449ffc7d 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/SetTbrCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SetTbrCommand.java @@ -1,4 +1,4 @@ -package de.jotomo.ruffyscripter.commands; +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; import android.os.SystemClock; From a76fbefee8ccac476c02adf2a1373561cc527d3f Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 1 Sep 2017 19:25:46 +0200 Subject: [PATCH 15/28] Add pref to disable all pump comm alerts. (cherry picked from commit f074a5b) --- .../androidaps/plugins/PumpCombo/ComboPlugin.java | 3 ++- app/src/main/res/values/strings.xml | 3 +++ app/src/main/res/xml/pref_combo.xml | 6 ++++++ 3 files changed, 11 insertions(+), 1 deletion(-) 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 2441584928..37ec5ac41d 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 @@ -137,7 +137,8 @@ public class ComboPlugin implements PluginBase, PumpInterface { while (true) { Command localLastCmd = pump.lastCmd; CommandResult localLastCmdResult = pump.lastCmdResult; - if (localLastCmdResult != null && !localLastCmdResult.success) { + if (!SP.getBoolean(R.string.combo_disable_alerts, false) && + localLastCmdResult != null && !localLastCmdResult.success) { long now = System.currentTimeMillis(); long fiveMinutesSinceLastAlarm = lastAlarmTime + (5 * 60 * 1000) + (15 * 1000); boolean loopEnabled = ConfigBuilderPlugin.getActiveLoop() != null; diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4f95d46808..4c204d2cbf 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -727,5 +727,8 @@ Splits boluses into 2 U parts and waits around 45 after each to slow down bolus delivery. Enables the in-development bolus with progress report and cancel option. Unlocks experimental features which are in development and might be broken entirely. + combo_disable_alerts + Disable all alerts + Ignore all errors encountered while communicating with the pump. diff --git a/app/src/main/res/xml/pref_combo.xml b/app/src/main/res/xml/pref_combo.xml index d1d1cd5a6b..9e2927d4cf 100644 --- a/app/src/main/res/xml/pref_combo.xml +++ b/app/src/main/res/xml/pref_combo.xml @@ -38,6 +38,12 @@ android:numeric="decimal" android:dialogMessage="@string/combo_experimental_reject_tbr_changes_below_delta_summary"/> + + \ No newline at end of file From add3011e4bbcfe33eacaf04148b5d84293bc3710 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 1 Sep 2017 20:32:46 +0200 Subject: [PATCH 16/28] Update pref descriptions (cherry picked from commit 13e358a) --- app/src/main/res/values/strings.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4c204d2cbf..470b827667 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -724,11 +724,11 @@ Reject TBR changes below threshold (%) Don\'t set a TBR if the difference between the new and a running TBR is below this threshold in percent. Specifying 0 disables this option. Ignore failures when setting a TBR, unless setting the next TBR also fails. - Splits boluses into 2 U parts and waits around 45 after each to slow down bolus delivery. + Splits boluses into 2 U parts and waits around 45 after each to slow down bolus delivery (only active with non-experimental bolus). Enables the in-development bolus with progress report and cancel option. Unlocks experimental features which are in development and might be broken entirely. combo_disable_alerts - Disable all alerts + Dentist appointment mode Ignore all errors encountered while communicating with the pump. From 0fda86dffa5b05673280ce544b861ada72d0ac5d Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Sun, 3 Sep 2017 21:54:02 +0200 Subject: [PATCH 17/28] A little less broken CancellableBolusCommand. (cherry picked from commit 9d56f23) --- .../commands/CancellableBolusCommand.java | 22 +++++++++++++------ 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancellableBolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancellableBolusCommand.java index 92edfff6b1..d42ea3c7bf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancellableBolusCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancellableBolusCommand.java @@ -91,9 +91,11 @@ public class CancellableBolusCommand extends BolusCommand { // 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; + // it must be cleared so we can see the remaining bolus again; while (bolusRemaining != null) { if (cancelRequested) { + // cancel running bolus by pressing up for 3s, while raise a BOLUS CANCELLED + // alert, unless the bolus finished within those 3s. progressReportCallback.report(STOPPING, 0, 0); scripter.pressKeyMs(RuffyScripter.Key.UP, 3000); progressReportCallback.report(STOPPED, 0, 0); @@ -116,6 +118,8 @@ public class CancellableBolusCommand extends BolusCommand { lastBolusReported = bolusRemaining; } + // TODO think through situatiotns where an alarm can be raised, not just when pressing a button, + // but a 'low battery' alarm can trigger at any time ... if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { String message = (String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); if (message.equals("LOW CARTRIDGE")) { @@ -129,17 +133,23 @@ public class CancellableBolusCommand extends BolusCommand { SystemClock.sleep(50); bolusRemaining = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_REMAINING); } + progressReportCallback.report(DELIVERED, 100, bolus); // 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) { + // TODO what could be raised here, other than those alarms than can ring at any time anyways? + long timeout = System.currentTimeMillis() + 2 * 1000; + while (scripter.getCurrentMenu().getType() != MenuType.WARNING_OR_ERROR && System.currentTimeMillis() < timeout) { 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 +// while (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR || System.currentTimeMillis() < timeout) { + // TODO brute-force hack + if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { + scripter.confirmAlert(((String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE)), 1000); } +// SystemClock.sleep(50); +// } // 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? @@ -149,7 +159,6 @@ public class CancellableBolusCommand extends BolusCommand { "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 @@ -184,7 +193,6 @@ public class CancellableBolusCommand extends BolusCommand { + "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)); From a33d7db47178cefcc3e2e89ed34555abf9bf12d0 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Sun, 3 Sep 2017 21:55:40 +0200 Subject: [PATCH 18/28] Refactorings and notes. (cherry picked from commit 8c77f0e) --- .../plugins/PumpCombo/ComboPlugin.java | 10 +++++----- ...and.java => ExperimentalBolusCommand.java} | 14 ++++++------- .../commands/GetReservoirLevelCommand.java | 20 +++++++++++-------- .../commands/SuperMicroBolusCommand.java | 15 ++++++++++++++ 4 files changed, 39 insertions(+), 20 deletions(-) rename app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/{CancellableBolusCommand.java => ExperimentalBolusCommand.java} (94%) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SuperMicroBolusCommand.java 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 37ec5ac41d..abf29a5acd 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 @@ -27,7 +27,7 @@ import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand; import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancelTbrCommand; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancellableBolusCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand; import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.Command; import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandResult; import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.GetPumpStateCommand; @@ -365,10 +365,10 @@ public class ComboPlugin implements PluginBase, PumpInterface { return basal; } - private static CancellableBolusCommand.ProgressReportCallback bolusProgressReportCallback = - new CancellableBolusCommand.ProgressReportCallback() { + private static ExperimentalBolusCommand.ProgressReportCallback bolusProgressReportCallback = + new ExperimentalBolusCommand.ProgressReportCallback() { @Override - public void report(CancellableBolusCommand.ProgressReportCallback.State state, int percent, double delivered) { + public void report(ExperimentalBolusCommand.ProgressReportCallback.State state, int percent, double delivered) { EventOverviewBolusProgress enent = EventOverviewBolusProgress.getInstance(); switch (state) { case DELIVERING: @@ -465,7 +465,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) { runningBolusCommand = SP.getBoolean(R.string.key_combo_enable_experimental_features, false) && SP.getBoolean(R.string.key_combo_enable_experimental_bolus, false) - ? new CancellableBolusCommand(detailedBolusInfo.insulin, bolusProgressReportCallback) + ? new ExperimentalBolusCommand(detailedBolusInfo.insulin, bolusProgressReportCallback) : new BolusCommand(detailedBolusInfo.insulin); CommandResult bolusCmdResult = runCommand(runningBolusCommand); PumpEnactResult pumpEnactResult = new PumpEnactResult(); diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancellableBolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java similarity index 94% rename from app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancellableBolusCommand.java rename to app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java index d42ea3c7bf..951b025edf 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/CancellableBolusCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java @@ -14,18 +14,18 @@ import java.util.Locale; import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; -import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancellableBolusCommand.ProgressReportCallback.State.DELIVERED; -import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancellableBolusCommand.ProgressReportCallback.State.DELIVERING; -import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancellableBolusCommand.ProgressReportCallback.State.STOPPED; -import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancellableBolusCommand.ProgressReportCallback.State.STOPPING; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.DELIVERED; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.DELIVERING; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.STOPPED; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.STOPPING; -public class CancellableBolusCommand extends BolusCommand { - private static final Logger log = LoggerFactory.getLogger(CancellableBolusCommand.class); +public class ExperimentalBolusCommand extends BolusCommand { + private static final Logger log = LoggerFactory.getLogger(ExperimentalBolusCommand.class); private final ProgressReportCallback progressReportCallback; private volatile boolean cancelRequested; - public CancellableBolusCommand(double bolus, ProgressReportCallback progressReportCallback) { + public ExperimentalBolusCommand(double bolus, ProgressReportCallback progressReportCallback) { super(bolus); this.progressReportCallback = progressReportCallback; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java index b6c80cb1a6..2d61d26fcc 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java @@ -5,15 +5,19 @@ import java.util.List; public class GetReservoirLevelCommand extends BaseCommand { @Override public CommandResult execute() { - // TODO stub - // watch out, level goes into PumpState, which is usually set by RuffyScripter - // after a command ran, unless a command has already set it ... I don't like - // that, it's too implicit ... + // TODO merge this into GetPumpHistory / GetFullPumpState; or maybe just have + // GetPumpState and parameterize to just read the displayed menu, read reservoir level, read history? + // TODO rough version, no error handling thought out - // also, maybe ditch this command and add a parameter to GetPumpStateCommand to also - // read the reservoir level if possible (pump must be in a state to accept commands - // (possible on main, stop ...) - return null; + // turn into a method; bolus commands needs this as a precheck, parameterize GetPumpState command + // to include reservoir level if desired + scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU); + scripter.pressCheckKey(); + scripter.waitForMenuToBeLeft(MenuType.MAIN_MENU); + scripter.verifyMenuIsDisplayed(MenuType.QUICK_INFO); + int remainingInsulin = ((Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.REMAINING_INSULIN)).intValue(); + scripter.returnToMainMenu(); + return new CommandResult().success(true).enacted(false).reservoirLevel(remainingInsulin); } @Override diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SuperMicroBolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SuperMicroBolusCommand.java new file mode 100644 index 0000000000..a08ea1c595 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SuperMicroBolusCommand.java @@ -0,0 +1,15 @@ +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; + +/** + * Draft. + * + * small bolus, don't check reservoir level beforehand ... ?? + * not cancellable + * less of an issue if it fails + * can be retried automatically + */ +public class SuperMicroBolusCommand extends BolusCommand { + public SuperMicroBolusCommand(double bolus) { + super(bolus); + } +} From fd7f4ae1450c1c19617d3ddcd4b5b9a1f64fc156 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Sun, 3 Sep 2017 22:05:44 +0200 Subject: [PATCH 19/28] Option to ignore TBR failures: also ignore errors when reading pump state. (cherry picked from commit 82052e8) --- .../plugins/PumpCombo/ComboPlugin.java | 19 ++++++++++--------- app/src/main/res/values/strings.xml | 18 +++++++++--------- app/src/main/res/xml/pref_combo.xml | 12 ++++++------ 3 files changed, 25 insertions(+), 24 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 abf29a5acd..0203708d87 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 @@ -67,7 +67,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { private ComboPump pump = new ComboPump(); - private boolean ignoreLastSetTbrFailure = false; + private boolean ignoreLastSetTbrOrReadStateFailure = false; @Nullable private volatile BolusCommand runningBolusCommand; @@ -143,8 +143,9 @@ public class ComboPlugin implements PluginBase, PumpInterface { long fiveMinutesSinceLastAlarm = lastAlarmTime + (5 * 60 * 1000) + (15 * 1000); boolean loopEnabled = ConfigBuilderPlugin.getActiveLoop() != null; boolean ignoreLastFailedTbrCmd = SP.getBoolean(R.string.key_combo_enable_experimental_features, false) - && SP.getBoolean(R.string.key_combo_experimental_ignore_transient_tbr_errors, false) - && localLastCmd instanceof SetTbrCommand && ignoreLastSetTbrFailure; + && SP.getBoolean(R.string.key_combo_experimental_ignore_transient_errors, false) + && (localLastCmd instanceof SetTbrCommand || localLastCmd instanceof GetPumpStateCommand) + && ignoreLastSetTbrOrReadStateFailure; if (now > fiveMinutesSinceLastAlarm && loopEnabled && !ignoreLastFailedTbrCmd) { log.error("Command failed: " + localLastCmd); log.error("Command result: " + localLastCmdResult); @@ -514,15 +515,15 @@ public class ComboPlugin implements PluginBase, PumpInterface { } // error tolerance - if (commandResult.success) ignoreLastSetTbrFailure = false; + if (commandResult.success) ignoreLastSetTbrOrReadStateFailure = false; - if (command instanceof SetTbrCommand) { - if (!commandResult.success && !ignoreLastSetTbrFailure) { + if (command instanceof SetTbrCommand || command instanceof GetPumpStateCommand) { + if (!commandResult.success && !ignoreLastSetTbrOrReadStateFailure) { // ignore this once - ignoreLastSetTbrFailure = true; + ignoreLastSetTbrOrReadStateFailure = true; } else { // second failure in a row - ignoreLastSetTbrFailure = false; + ignoreLastSetTbrOrReadStateFailure = false; } } @@ -559,7 +560,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis()); if (!force && activeTemp != null) { - int minRequiredDelta = SP.getInt(R.string.key_combo_experimental_reject_tbr_changes_below_delta, 0); + int minRequiredDelta = SP.getInt(R.string.key_combo_experimental_skip_tbr_changes_below_delta, 0); boolean deltaBelowThreshold = Math.abs(activeTemp.percentRate - roundedPercentage) < minRequiredDelta; if (deltaBelowThreshold) { log.debug("Skipping setting APS-requested TBR change, since the requested change from " diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 470b827667..14ff96af76 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -714,19 +714,19 @@ Bolus delivery stopped combo_enable_experimental_features Enable experimental features + Unlocks experimental features which are in development and might be broken entirely. combo_enable_experimental_bolus Experimental bolus + Enables the in-development bolus with progress report and cancel option. combo_experimental_split_bolus Experimental split bolus feature - combo_ignore_transient_tbr_errors - Ignore transient TBR errors - combo_experimental_reject_tbr_changes_below_delta - Reject TBR changes below threshold (%) - Don\'t set a TBR if the difference between the new and a running TBR is below this threshold in percent. Specifying 0 disables this option. - Ignore failures when setting a TBR, unless setting the next TBR also fails. - Splits boluses into 2 U parts and waits around 45 after each to slow down bolus delivery (only active with non-experimental bolus). - Enables the in-development bolus with progress report and cancel option. - Unlocks experimental features which are in development and might be broken entirely. + Splits boluses into 2 U parts and waits around 45s after each to slow down bolus delivery (only active with non-experimental bolus). + combo_ignore_transient_tbr_errors + Ignore transient errors + Ignore failures when setting a TBR or reading pump state, unless the next attempt also fails. + combo_experimental_reject_tbr_changes_below_delta + Skip TBR changes below threshold (%). + Don\'t set a TBR if the difference between the new and a running TBR is below this threshold in percent. Specifying 0 disables this option. combo_disable_alerts Dentist appointment mode Ignore all errors encountered while communicating with the pump. diff --git a/app/src/main/res/xml/pref_combo.xml b/app/src/main/res/xml/pref_combo.xml index 9e2927d4cf..052f7e0d49 100644 --- a/app/src/main/res/xml/pref_combo.xml +++ b/app/src/main/res/xml/pref_combo.xml @@ -25,18 +25,18 @@ + android:key="@string/key_combo_experimental_ignore_transient_errors" + android:title="@string/combo_experimental_ignore_transient_errors" + android:summary="@string/combo_experimental_ignore_transient_errors_summary"/> + android:dialogMessage="@string/combo_experimental_skip_tbr_changes_below_delta_summary"/> Date: Wed, 6 Sep 2017 11:02:35 +0200 Subject: [PATCH 20/28] Wait for currentMenu to be != null (cherry picked from commit 13b96ec) --- .../plugins/PumpCombo/scripter/RuffyScripter.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java index d0d126235e..c13242b5c4 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java @@ -474,10 +474,12 @@ public class RuffyScripter { // === pump ops === public Menu getCurrentMenu() { - // TODO workaround, supposedly fixed in latest ruffy? + long timeout = System.currentTimeMillis() + 5 * 1000; while (currentMenu == null) { + if (System.currentTimeMillis() > timeout) { + throw new CommandException().message("Unable to read current menu"); + } log.error("currentMenu == null, waiting"); - SystemClock.sleep(500); waitForMenuUpdate(); } return currentMenu; From 5d10956900b61ec1bc31956e56ab844a5b5d164b Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 6 Sep 2017 11:13:35 +0200 Subject: [PATCH 21/28] Declare RuffyScripter.currentMenu nullable. (cherry picked from commit fb0c829) --- .../PumpCombo/scripter/RuffyScripter.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java index c13242b5c4..b8b818e758 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java @@ -2,6 +2,7 @@ package info.nightscout.androidaps.plugins.PumpCombo.scripter; import android.os.RemoteException; import android.os.SystemClock; +import android.support.annotation.Nullable; import com.google.common.base.Joiner; @@ -36,6 +37,7 @@ public class RuffyScripter { private IRuffyService ruffyService; private String unrecoverableError = null; + @Nullable private volatile Menu currentMenu; private volatile long menuLastUpdated = 0; @@ -194,13 +196,20 @@ public class RuffyScripter { } public void returnToMainMenu() { - // returning to main menu using the 'back' key should not cause a vibration - // TODO this is too brute-force; at least check for WARNING_OR_ERROR menu type - do { + // returning to main menu using the 'back' key does not cause a vibration + while (getCurrentMenu().getType() != MenuType.MAIN_MENU) { + if (getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { + String errorMsg = (String) getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); + confirmAlert(errorMsg, 1000); + // TODO this isn't gonna work out ... this method can't know if something was enacted ... + // gotta keep that state in the command instance + throw new CommandException().success(false).enacted(false) + .message("Warning/error " + errorMsg + " raised while returning to main menu"); + } log.debug("Going back to main menu, currently at " + getCurrentMenu().getType()); pressBackKey(); waitForMenuUpdate(); - } while (getCurrentMenu().getType() != MenuType.MAIN_MENU); + } } private static class Returnable { From 882f400d1ef8d61c0d5ecc203bbd4ce6babb070e Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 6 Sep 2017 12:22:22 +0200 Subject: [PATCH 22/28] Disable incomplete parts in ExperimentalBolusCommand. --- .../scripter/commands/ExperimentalBolusCommand.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java index 951b025edf..d493d95433 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java @@ -118,6 +118,7 @@ public class ExperimentalBolusCommand extends BolusCommand { lastBolusReported = bolusRemaining; } + /* // TODO think through situatiotns where an alarm can be raised, not just when pressing a button, // but a 'low battery' alarm can trigger at any time ... if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { @@ -130,11 +131,14 @@ public class ExperimentalBolusCommand extends BolusCommand { break; } } + */ + SystemClock.sleep(50); bolusRemaining = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_REMAINING); } progressReportCallback.report(DELIVERED, 100, bolus); + /* // wait up to 2s for any possible warning to be raised, if not raised already // TODO what could be raised here, other than those alarms than can ring at any time anyways? long timeout = System.currentTimeMillis() + 2 * 1000; @@ -144,12 +148,12 @@ public class ExperimentalBolusCommand extends BolusCommand { // process warnings (confirm them, report back to AAPS about them) // while (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR || System.currentTimeMillis() < timeout) { - // TODO brute-force hack if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { scripter.confirmAlert(((String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE)), 1000); } // SystemClock.sleep(50); // } + */ // 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? From dc7dd155719d083a47626bca73678a24ba4a20f9 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 6 Sep 2017 12:33:49 +0200 Subject: [PATCH 23/28] Update pref descriptions. --- app/src/main/res/values/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 14ff96af76..e8fb7bf7f4 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -717,7 +717,7 @@ Unlocks experimental features which are in development and might be broken entirely. combo_enable_experimental_bolus Experimental bolus - Enables the in-development bolus with progress report and cancel option. + Enables the in-development bolus with progress report and semi-working cancel option. combo_experimental_split_bolus Experimental split bolus feature Splits boluses into 2 U parts and waits around 45s after each to slow down bolus delivery (only active with non-experimental bolus). @@ -728,7 +728,7 @@ Skip TBR changes below threshold (%). Don\'t set a TBR if the difference between the new and a running TBR is below this threshold in percent. Specifying 0 disables this option. combo_disable_alerts - Dentist appointment mode - Ignore all errors encountered while communicating with the pump. + Disable alerts + Ignore all errors encountered while communicating with the pump. Alerts raised by the pump (including those caused by AAPS) will still be raised. From 09f834d990fa9bcecc41006aa48c7b14284d2dd3 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 6 Sep 2017 12:40:42 +0200 Subject: [PATCH 24/28] Make access to RuffyScripter.currentMenu safer. --- .../PumpCombo/scripter/RuffyScripter.java | 16 ++++++++-------- .../PumpCombo/scripter/commands/BaseCommand.java | 5 ----- .../commands/ExperimentalBolusCommand.java | 1 - 3 files changed, 8 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java index b8b818e758..2066244d3a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java @@ -488,7 +488,7 @@ public class RuffyScripter { if (System.currentTimeMillis() > timeout) { throw new CommandException().message("Unable to read current menu"); } - log.error("currentMenu == null, waiting"); + log.debug("currentMenu == null, waiting"); waitForMenuUpdate(); } return currentMenu; @@ -634,10 +634,10 @@ public class RuffyScripter { } public void navigateToMenu(MenuType desiredMenu) { - MenuType startedFrom = currentMenu.getType(); + MenuType startedFrom = getCurrentMenu().getType(); boolean movedOnce = false; - while (currentMenu.getType() != desiredMenu) { - MenuType currentMenuType = currentMenu.getType(); + while (getCurrentMenu().getType() != desiredMenu) { + MenuType currentMenuType = getCurrentMenu().getType(); log.debug("Navigating to menu " + desiredMenu + ", currenty menu: " + currentMenuType); if (movedOnce && currentMenuType == startedFrom) { throw new CommandException().message("Menu not found searching for " + desiredMenu @@ -652,7 +652,7 @@ public class RuffyScripter { /** Wait till a menu changed has completed, "away" from the menu provided as argument. */ public void waitForMenuToBeLeft(MenuType menuType) { long timeout = System.currentTimeMillis() + 60 * 1000; - while (currentMenu.getType() == menuType) { + while (getCurrentMenu().getType() == menuType) { if (System.currentTimeMillis() > timeout) { throw new CommandException().message("Timeout waiting for menu " + menuType + " to be left"); } @@ -666,7 +666,7 @@ public class RuffyScripter { public void verifyMenuIsDisplayed(MenuType expectedMenu, String failureMessage) { int retries = 600; - while (currentMenu.getType() != expectedMenu) { + while (getCurrentMenu().getType() != expectedMenu) { if (retries > 0) { SystemClock.sleep(100); retries = retries - 1; @@ -682,9 +682,9 @@ public class RuffyScripter { @SuppressWarnings("unchecked") public T readBlinkingValue(Class expectedType, MenuAttribute attribute) { int retries = 5; - Object value = currentMenu.getAttribute(attribute); + Object value = getCurrentMenu().getAttribute(attribute); while (!expectedType.isInstance(value)) { - value = currentMenu.getAttribute(attribute); + value = getCurrentMenu().getAttribute(attribute); waitForScreenUpdate(1000); retries--; if (retries == 0) { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BaseCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BaseCommand.java index 1a145c3efc..d47f654660 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BaseCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BaseCommand.java @@ -1,10 +1,5 @@ package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; -import android.os.SystemClock; - -import org.monkey.d.ruffy.ruffy.driver.display.MenuAttribute; -import org.monkey.d.ruffy.ruffy.driver.display.MenuType; - import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; public abstract class BaseCommand implements Command { diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java index d493d95433..edd5827286 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java @@ -11,7 +11,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.DELIVERED; From f4f91c0b85b0dc7cad7e6deb7400c446857d6bac Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 6 Sep 2017 12:53:47 +0200 Subject: [PATCH 25/28] Add TODO. --- .../androidaps/plugins/PumpCombo/scripter/RuffyScripter.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java index 2066244d3a..f2f08820e0 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java @@ -484,6 +484,9 @@ public class RuffyScripter { // === pump ops === public Menu getCurrentMenu() { 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 + // something to deal with connection loses while (currentMenu == null) { if (System.currentTimeMillis() > timeout) { throw new CommandException().message("Unable to read current menu"); From cb24d13caeb668a6ede18b94e916a71785ae575d Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Thu, 7 Sep 2017 09:25:20 +0200 Subject: [PATCH 26/28] Remove GetReservoirLevelCommand, will be a method in the future. --- .../commands/GetReservoirLevelCommand.java | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java deleted file mode 100644 index 2d61d26fcc..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/GetReservoirLevelCommand.java +++ /dev/null @@ -1,28 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; - -import java.util.List; - -public class GetReservoirLevelCommand extends BaseCommand { - @Override - public CommandResult execute() { - // TODO merge this into GetPumpHistory / GetFullPumpState; or maybe just have - // GetPumpState and parameterize to just read the displayed menu, read reservoir level, read history? - // TODO rough version, no error handling thought out - - // turn into a method; bolus commands needs this as a precheck, parameterize GetPumpState command - // to include reservoir level if desired - scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU); - scripter.pressCheckKey(); - scripter.waitForMenuToBeLeft(MenuType.MAIN_MENU); - scripter.verifyMenuIsDisplayed(MenuType.QUICK_INFO); - int remainingInsulin = ((Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.REMAINING_INSULIN)).intValue(); - scripter.returnToMainMenu(); - return new CommandResult().success(true).enacted(false).reservoirLevel(remainingInsulin); - } - - @Override - public List validateArguments() { - // TODO stub - return null; - } -} From 960586b79d3f8ba38e0ce4f4792e4a14df641905 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Fri, 8 Sep 2017 02:13:35 +0200 Subject: [PATCH 27/28] ExperimentalBolusCommand: update progress when starting to programm the pump. --- .../plugins/PumpCombo/ComboPlugin.java | 17 ++++++++++------- .../commands/ExperimentalBolusCommand.java | 7 ++++++- app/src/main/res/values/strings.xml | 6 ++++++ 3 files changed, 22 insertions(+), 8 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 0203708d87..f0237b2e10 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 @@ -370,23 +370,26 @@ public class ComboPlugin implements PluginBase, PumpInterface { new ExperimentalBolusCommand.ProgressReportCallback() { @Override public void report(ExperimentalBolusCommand.ProgressReportCallback.State state, int percent, double delivered) { - EventOverviewBolusProgress enent = EventOverviewBolusProgress.getInstance(); + EventOverviewBolusProgress event = EventOverviewBolusProgress.getInstance(); switch (state) { + case PROGRAMMING: + event.status = MainApp.sResources.getString(R.string.bolusprogramming); + break; case DELIVERING: - enent.status = String.format(MainApp.sResources.getString(R.string.bolusdelivering), delivered); + event.status = String.format(MainApp.sResources.getString(R.string.bolusdelivering), delivered); break; case DELIVERED: - enent.status = String.format(MainApp.sResources.getString(R.string.bolusdelivered), delivered); + event.status = String.format(MainApp.sResources.getString(R.string.bolusdelivered), delivered); break; case STOPPING: - enent.status = MainApp.sResources.getString(R.string.bolusstopping); + event.status = MainApp.sResources.getString(R.string.bolusstopping); break; case STOPPED: - enent.status = MainApp.sResources.getString(R.string.bolusstopped); + event.status = MainApp.sResources.getString(R.string.bolusstopped); break; } - enent.percent = percent; - MainApp.bus().post(enent); + event.percent = percent; + MainApp.bus().post(event); } }; diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java index edd5827286..9fde35ea5c 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java @@ -15,6 +15,7 @@ import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.DELIVERED; import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.DELIVERING; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.PROGRAMMING; import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.STOPPED; import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.STOPPING; @@ -44,8 +45,11 @@ public class ExperimentalBolusCommand extends BolusCommand { public CommandResult execute() { try { // TODO read reservoir level and reject request if reservoir < bolus - enterBolusMenu(); + // TODO also check if there's a bolus in history we're not aware of + // press check twice to get reservoir level and last bolus quickly + progressReportCallback.report(PROGRAMMING, 0, 0); + enterBolusMenu(); inputBolusAmount(); verifyDisplayedBolusAmount(); @@ -218,6 +222,7 @@ public class ExperimentalBolusCommand extends BolusCommand { public interface ProgressReportCallback { enum State { + PROGRAMMING, DELIVERING, DELIVERED, STOPPING, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e8fb7bf7f4..5d9477c5a5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -730,5 +730,11 @@ combo_disable_alerts Disable alerts Ignore all errors encountered while communicating with the pump. Alerts raised by the pump (including those caused by AAPS) will still be raised. + Programming pump for bolusing + wizard_include_bg + wizard_include_cob + wizard_include_trend_bg + wizard_include_bolus_iob + wizard_include_basal_iob From 60c9a984b53b2247531dd41a2a6ad0bdb1d1c1b5 Mon Sep 17 00:00:00 2001 From: Johannes Mockenhaupt Date: Wed, 11 Oct 2017 14:01:52 +0200 Subject: [PATCH 28/28] Refactor, clean out stuff, add RuffyCommands interface. --- .../plugins/PumpCombo/ComboPlugin.java | 60 ++--- .../PumpCombo/scripter/BasalProfile.java | 4 + .../PumpCombo/scripter/PumpHistory.java | 4 + .../PumpCombo/scripter/RuffyCommands.java | 27 ++ .../PumpCombo/scripter/RuffyScripter.java | 51 +++- .../scripter/commands/BolusCommand.java | 162 ++++++++++-- .../commands/ExperimentalBolusCommand.java | 234 ------------------ .../scripter/commands/ReadBasalProfile.java | 22 ++ .../scripter/commands/ReadHistoryCommand.java | 26 ++ .../commands/ReadReserverLevelCommand.java | 22 ++ .../scripter/commands/SetBasalProfile.java | 27 ++ .../commands/SuperMicroBolusCommand.java | 15 -- app/src/main/res/values/strings.xml | 6 - app/src/main/res/xml/pref_combo.xml | 13 - 14 files changed, 335 insertions(+), 338 deletions(-) create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/BasalProfile.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/PumpHistory.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyCommands.java delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadBasalProfile.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadHistoryCommand.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadReserverLevelCommand.java create mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SetBasalProfile.java delete mode 100644 app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SuperMicroBolusCommand.java 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 f0237b2e10..d79310fbdf 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 @@ -23,15 +23,6 @@ import org.slf4j.LoggerFactory; import java.util.Date; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancelTbrCommand; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.Command; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandResult; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.GetPumpStateCommand; -import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.SetTbrCommand; import info.nightscout.androidaps.BuildConfig; import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.R; @@ -47,6 +38,11 @@ import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress; import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.Command; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandResult; import info.nightscout.utils.DateUtil; import info.nightscout.utils.SP; @@ -54,7 +50,6 @@ import info.nightscout.utils.SP; * Created by mike on 05.08.2016. */ public class ComboPlugin implements PluginBase, PumpInterface { - public static final String COMBO_MAX_TEMP_PERCENT_SP = "combo_maxTempPercent"; private static Logger log = LoggerFactory.getLogger(ComboPlugin.class); private boolean fragmentEnabled = false; @@ -142,11 +137,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { long now = System.currentTimeMillis(); long fiveMinutesSinceLastAlarm = lastAlarmTime + (5 * 60 * 1000) + (15 * 1000); boolean loopEnabled = ConfigBuilderPlugin.getActiveLoop() != null; - boolean ignoreLastFailedTbrCmd = SP.getBoolean(R.string.key_combo_enable_experimental_features, false) - && SP.getBoolean(R.string.key_combo_experimental_ignore_transient_errors, false) - && (localLastCmd instanceof SetTbrCommand || localLastCmd instanceof GetPumpStateCommand) - && ignoreLastSetTbrOrReadStateFailure; - if (now > fiveMinutesSinceLastAlarm && loopEnabled && !ignoreLastFailedTbrCmd) { + if (now > fiveMinutesSinceLastAlarm && loopEnabled) { log.error("Command failed: " + localLastCmd); log.error("Command result: " + localLastCmdResult); PumpState localPumpState = pump.state; @@ -352,7 +343,8 @@ public class ComboPlugin implements PluginBase, PumpInterface { if (notAUserRequest && wasRunAtLeastOnce && ranWithinTheLastMinute) { log.debug("Not fetching state from pump, since we did already within the last 60 seconds"); } else { - runCommand(new GetPumpStateCommand()); + // TODO +// runCommand(new GetPumpStateCommand()); } } @@ -366,10 +358,10 @@ public class ComboPlugin implements PluginBase, PumpInterface { return basal; } - private static ExperimentalBolusCommand.ProgressReportCallback bolusProgressReportCallback = - new ExperimentalBolusCommand.ProgressReportCallback() { + private static BolusCommand.ProgressReportCallback bolusProgressReportCallback = + new BolusCommand.ProgressReportCallback() { @Override - public void report(ExperimentalBolusCommand.ProgressReportCallback.State state, int percent, double delivered) { + public void report(BolusCommand.ProgressReportCallback.State state, int percent, double delivered) { EventOverviewBolusProgress event = EventOverviewBolusProgress.getInstance(); switch (state) { case PROGRAMMING: @@ -467,10 +459,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { @NonNull private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) { - runningBolusCommand = SP.getBoolean(R.string.key_combo_enable_experimental_features, false) - && SP.getBoolean(R.string.key_combo_enable_experimental_bolus, false) - ? new ExperimentalBolusCommand(detailedBolusInfo.insulin, bolusProgressReportCallback) - : new BolusCommand(detailedBolusInfo.insulin); + runningBolusCommand = new BolusCommand(detailedBolusInfo.insulin, bolusProgressReportCallback); CommandResult bolusCmdResult = runCommand(runningBolusCommand); PumpEnactResult pumpEnactResult = new PumpEnactResult(); pumpEnactResult.success = bolusCmdResult.success; @@ -517,19 +506,6 @@ public class ComboPlugin implements PluginBase, PumpInterface { log.error("Exception received from pump", commandResult.exception); } - // error tolerance - if (commandResult.success) ignoreLastSetTbrOrReadStateFailure = false; - - if (command instanceof SetTbrCommand || command instanceof GetPumpStateCommand) { - if (!commandResult.success && !ignoreLastSetTbrOrReadStateFailure) { - // ignore this once - ignoreLastSetTbrOrReadStateFailure = true; - } else { - // second failure in a row - ignoreLastSetTbrOrReadStateFailure = false; - } - } - pump.lastCmd = command; pump.lastCmdTime = new Date(); pump.lastCmdResult = commandResult; @@ -595,7 +571,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { adjustedPercent = rounded.intValue(); } - CommandResult commandResult = runCommand(new SetTbrCommand(adjustedPercent, durationInMinutes)); + CommandResult commandResult = ruffyScripter.setTbr(adjustedPercent, durationInMinutes); if (commandResult.enacted) { TemporaryBasal tempStart = new TemporaryBasal(commandResult.completionTime); @@ -641,7 +617,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { if (activeTemp == null || userRequested) { /* v1 compatibility to sync DB to pump if they diverged (activeTemp == null) */ log.debug("cancelTempBasal: hard-cancelling TBR since user requested"); - commandResult = runCommand(new CancelTbrCommand()); + commandResult = ruffyScripter.cancelTbr(); if (commandResult.enacted) { tempBasal = new TemporaryBasal(commandResult.completionTime); tempBasal.durationInMinutes = 0; @@ -661,14 +637,14 @@ public class ComboPlugin implements PluginBase, PumpInterface { } 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; + int percentage = (activeTemp.percentRate > 100) ? 110 : 90; log.debug("cancelTempBasal: changing tbr to " + percentage + "% for 15 mins."); - commandResult = runCommand(new SetTbrCommand(percentage, 15)); + commandResult = ruffyScripter.setTbr(percentage, 15); if (commandResult.enacted) { tempBasal = new TemporaryBasal(commandResult.completionTime); tempBasal.durationInMinutes = 15; tempBasal.source = Source.USER; - tempBasal.percentRate = (int) percentage; + tempBasal.percentRate = percentage; tempBasal.isAbsolute = false; } } @@ -695,7 +671,7 @@ public class ComboPlugin implements PluginBase, PumpInterface { // TODO v2 add battery, reservoir info when we start reading that and clean up the code @Override public JSONObject getJSONStatus() { - if (true) { //pump.lastCmdTime.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) { + if (pump.lastCmdTime.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) { return null; } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/BasalProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/BasalProfile.java new file mode 100644 index 0000000000..6b927ebc25 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/BasalProfile.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpCombo.scripter; + +public class BasalProfile { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/PumpHistory.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/PumpHistory.java new file mode 100644 index 0000000000..74b3986f48 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/PumpHistory.java @@ -0,0 +1,4 @@ +package info.nightscout.androidaps.plugins.PumpCombo.scripter; + +public class PumpHistory { +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyCommands.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyCommands.java new file mode 100644 index 0000000000..18939c4ba1 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyCommands.java @@ -0,0 +1,27 @@ +package info.nightscout.androidaps.plugins.PumpCombo.scripter; + +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandResult; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand; + +/** + * Main entry point for clients, implemented by RuffyScripter. + */ +public interface RuffyCommands { + CommandResult deliverBolus(double amount, BolusCommand.ProgressReportCallback progressReportCallback); + + void cancelBolus(); + + CommandResult setTbr(int percent, int duraton); + + CommandResult cancelTbr(); + + CommandResult readReservoirLevel(); + + // PumpHistory.fields.*: null=don't care. empty history=we know nothing yet. filled history=this is what we know so far + CommandResult readHistory(PumpHistory knownHistory); + + CommandResult readBasalProfile(); + + CommandResult setBasalProfile(BasalProfile basalProfile); +} + diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java index f2f08820e0..2eb40e26a6 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/RuffyScripter.java @@ -17,10 +17,17 @@ import org.slf4j.LoggerFactory; import java.util.List; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CancelTbrCommand; import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.Command; import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandException; import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandResult; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand; import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.GetPumpStateCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ReadBasalProfile; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ReadHistoryCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ReadReserverLevelCommand; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.SetBasalProfile; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.SetTbrCommand; // TODO regularly read "My data" history (boluses, TBR) to double check all commands ran successfully. // Automatically compare against AAPS db, or log all requests in the PumpInterface (maybe Milos @@ -31,7 +38,7 @@ import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.GetPumpSta * class and inject that into executing commands, so that commands operately solely on * operations and are cleanly separated from the thread management, connection management etc */ -public class RuffyScripter { +public class RuffyScripter implements RuffyCommands { private static final Logger log = LoggerFactory.getLogger(RuffyScripter.class); private IRuffyService ruffyService; @@ -696,4 +703,46 @@ public class RuffyScripter { } return (T) value; } + + @Override + public CommandResult deliverBolus(double amount, BolusCommand.ProgressReportCallback progressReportCallback) { + return runCommand(new BolusCommand(amount, progressReportCallback)); + } + + @Override + public void cancelBolus() { + if (activeCmd instanceof BolusCommand) { + ((BolusCommand) activeCmd).requestCancellation(); + } + } + + @Override + public CommandResult setTbr(int percent, int duraton) { + return runCommand(new SetTbrCommand(percent, duraton)); + } + + @Override + public CommandResult cancelTbr() { + return runCommand(new CancelTbrCommand()); + } + + @Override + public CommandResult readReservoirLevel() { + return runCommand(new ReadReserverLevelCommand()); + } + + @Override + public CommandResult readHistory(PumpHistory knownHistory) { + return runCommand(new ReadHistoryCommand(knownHistory)); + } + + @Override + public CommandResult readBasalProfile() { + return runCommand(new ReadBasalProfile()); + } + + @Override + public CommandResult setBasalProfile(BasalProfile basalProfile) { + return runCommand(new SetBasalProfile(basalProfile)); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BolusCommand.java index 5593974281..e2c177c78b 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BolusCommand.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/BolusCommand.java @@ -11,16 +11,24 @@ import java.util.ArrayList; import java.util.List; import java.util.Locale; -import info.nightscout.androidaps.R; -import info.nightscout.utils.SP; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; + +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand.ProgressReportCallback.State.DELIVERED; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand.ProgressReportCallback.State.DELIVERING; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand.ProgressReportCallback.State.PROGRAMMING; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand.ProgressReportCallback.State.STOPPED; +import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand.ProgressReportCallback.State.STOPPING; public class BolusCommand extends BaseCommand { private static final Logger log = LoggerFactory.getLogger(BolusCommand.class); protected final double bolus; + private final ProgressReportCallback progressReportCallback; + private volatile boolean cancelRequested; - public BolusCommand(double bolus) { + public BolusCommand(double bolus, ProgressReportCallback progressReportCallback) { this.bolus = bolus; + this.progressReportCallback = progressReportCallback; } @Override @@ -37,37 +45,119 @@ public class BolusCommand extends BaseCommand { @Override public CommandResult execute() { try { - enterBolusMenu(); + // TODO read reservoir level and reject request if reservoir < bolus + // TODO also check if there's a bolus in history we're not aware of + // press check twice to get reservoir level and last bolus quickly + progressReportCallback.report(PROGRAMMING, 0, 0); + enterBolusMenu(); inputBolusAmount(); verifyDisplayedBolusAmount(); + if (cancelRequested) { + progressReportCallback.report(STOPPING, 0, 0); + scripter.returnToMainMenu(); + 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 - // and then returns to the main menu - 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 = scripter.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 cleared so we can see the remaining bolus again; while (bolusRemaining != null) { - log.debug("Delivering bolus, remaining: " + bolusRemaining); - SystemClock.sleep(200); - if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { - throw new CommandException().success(false).enacted(true) - .message("Warning/error raised after bolus delivery started. " + - "The treatment has been recorded, please check it against the " + - "pumps records and delete it if it hasn't finished successfully."); + if (cancelRequested) { + // cancel running bolus by pressing up for 3s, while raise a BOLUS CANCELLED + // alert, unless the bolus finished within those 3s. + 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; + } + + /* + // TODO think through situatiotns where an alarm can be raised, not just when pressing a button, + // but a 'low battery' alarm can trigger at any time ... + if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { + String message = (String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); + if (message.equals("LOW CARTRIDGE")) { + lowCartdrigeAlarmTriggered = true; + scripter.confirmAlert("LOW CARTRIDGE", 2000); + } else { + // any other alert + break; + } + } + */ + + SystemClock.sleep(50); bolusRemaining = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_REMAINING); } + progressReportCallback.report(DELIVERED, 100, bolus); + /* + // wait up to 2s for any possible warning to be raised, if not raised already + // TODO what could be raised here, other than those alarms than can ring at any time anyways? + long timeout = System.currentTimeMillis() + 2 * 1000; + while (scripter.getCurrentMenu().getType() != MenuType.WARNING_OR_ERROR && System.currentTimeMillis() < timeout) { + SystemClock.sleep(50); + } + + // process warnings (confirm them, report back to AAPS about them) +// while (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR || System.currentTimeMillis() < timeout) { + if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { + scripter.confirmAlert(((String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE)), 1000); + } +// SystemClock.sleep(50); +// } + */ // 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? @@ -77,6 +167,8 @@ 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); @@ -91,6 +183,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) @@ -99,17 +193,14 @@ public class BolusCommand extends BaseCommand { } log.debug("Bolus record in history confirms delivered bolus"); - if(SP.getBoolean(R.string.key_combo_enable_experimental_features, false)) { - scripter.returnToMainMenu(); - } else { - // leave menu to go back to main menu - scripter.pressCheckKey(); - scripter.waitForMenuToBeLeft(MenuType.BOLUS_DATA); + // TODO how would this call fail? more generally ...... + scripter.returnToMainMenu(); + if (scripter.getCurrentMenu().getType() != MenuType.MAIN_MENU) { + 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."); } - scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU, - "Bolus was correctly delivered and checked against history, but we " - + "did not return the main menu successfully."); return new CommandResult().success(true).enacted(true) .message(String.format(Locale.US, "Delivered %02.1f U", bolus)); @@ -118,7 +209,7 @@ public class BolusCommand extends BaseCommand { } } - protected void enterBolusMenu() { + private void enterBolusMenu() { scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU); scripter.navigateToMenu(MenuType.BOLUS_MENU); scripter.verifyMenuIsDisplayed(MenuType.BOLUS_MENU); @@ -127,7 +218,7 @@ public class BolusCommand extends BaseCommand { scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER); } - protected void inputBolusAmount() { + private void inputBolusAmount() { scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER); // press 'up' once for each 0.1 U increment long steps = Math.round(bolus * 10); @@ -141,7 +232,7 @@ public class BolusCommand extends BaseCommand { SystemClock.sleep(2000); } - protected void verifyDisplayedBolusAmount() { + private void verifyDisplayedBolusAmount() { scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER); // wait up to 5s for any scrolling to finish @@ -168,10 +259,27 @@ public class BolusCommand extends BaseCommand { } } + public void requestCancellation() { + cancelRequested = true; + progressReportCallback.report(STOPPING, 0, 0); + } + @Override public String toString() { return "BolusCommand{" + "bolus=" + bolus + '}'; } + + public interface ProgressReportCallback { + enum State { + PROGRAMMING, + DELIVERING, + DELIVERED, + STOPPING, + STOPPED + } + + void report(State state, int percent, double delivered); + } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java deleted file mode 100644 index 9fde35ea5c..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ExperimentalBolusCommand.java +++ /dev/null @@ -1,234 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; - -import android.os.SystemClock; - -import org.monkey.d.ruffy.ruffy.driver.display.MenuAttribute; -import org.monkey.d.ruffy.ruffy.driver.display.MenuType; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; - -import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.DELIVERED; -import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.DELIVERING; -import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.PROGRAMMING; -import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.STOPPED; -import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.ExperimentalBolusCommand.ProgressReportCallback.State.STOPPING; - -public class ExperimentalBolusCommand extends BolusCommand { - private static final Logger log = LoggerFactory.getLogger(ExperimentalBolusCommand.class); - - private final ProgressReportCallback progressReportCallback; - private volatile boolean cancelRequested; - - public ExperimentalBolusCommand(double bolus, ProgressReportCallback progressReportCallback) { - super(bolus); - this.progressReportCallback = progressReportCallback; - } - - @Override - public List validateArguments() { - List violations = new ArrayList<>(); - - if (bolus <= 0 || bolus > 25) { - violations.add("Requested bolus " + bolus + " out of limits (0-25)"); - } - - return violations; - } - - @Override - public CommandResult execute() { - try { - // TODO read reservoir level and reject request if reservoir < bolus - // TODO also check if there's a bolus in history we're not aware of - // press check twice to get reservoir level and last bolus quickly - - progressReportCallback.report(PROGRAMMING, 0, 0); - enterBolusMenu(); - inputBolusAmount(); - verifyDisplayedBolusAmount(); - - if (cancelRequested) { - progressReportCallback.report(STOPPING, 0, 0); - scripter.returnToMainMenu(); - 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 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 = scripter.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. - // TODO extract into method - - // TODO 'low cartrdige' alarm must be handled inside, since the bolus continues regardless; - // it must be cleared so we can see the remaining bolus again; - while (bolusRemaining != null) { - if (cancelRequested) { - // cancel running bolus by pressing up for 3s, while raise a BOLUS CANCELLED - // alert, unless the bolus finished within those 3s. - 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; - } - - /* - // TODO think through situatiotns where an alarm can be raised, not just when pressing a button, - // but a 'low battery' alarm can trigger at any time ... - if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { - String message = (String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); - if (message.equals("LOW CARTRIDGE")) { - lowCartdrigeAlarmTriggered = true; - scripter.confirmAlert("LOW CARTRIDGE", 2000); - } else { - // any other alert - break; - } - } - */ - - SystemClock.sleep(50); - bolusRemaining = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_REMAINING); - } - progressReportCallback.report(DELIVERED, 100, bolus); - - /* - // wait up to 2s for any possible warning to be raised, if not raised already - // TODO what could be raised here, other than those alarms than can ring at any time anyways? - long timeout = System.currentTimeMillis() + 2 * 1000; - while (scripter.getCurrentMenu().getType() != MenuType.WARNING_OR_ERROR && System.currentTimeMillis() < timeout) { - SystemClock.sleep(50); - } - - // process warnings (confirm them, report back to AAPS about them) -// while (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR || System.currentTimeMillis() < timeout) { - if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { - scripter.confirmAlert(((String) scripter.getCurrentMenu().getAttribute(MenuAttribute.MESSAGE)), 1000); - } -// SystemClock.sleep(50); -// } - */ - - // 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? - - // make sure no alert (occlusion, cartridge empty) has occurred. - scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU, - "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); - scripter.verifyMenuIsDisplayed(MenuType.MY_DATA_MENU); - scripter.pressCheckKey(); - if (scripter.getCurrentMenu().getType() != MenuType.BOLUS_DATA) { - scripter.waitForMenuUpdate(); - } - - if (!scripter.getCurrentMenu().attributes().contains(MenuAttribute.BOLUS)) { - throw new CommandException().success(false).enacted(true) - .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) - .message("Last bolus shows " + lastBolusInHistory - + " U delievered, but " + bolus + " U were requested"); - } - log.debug("Bolus record in history confirms delivered bolus"); - - // TODO how would this call fail? more generally ...... - scripter.returnToMainMenu(); - if (scripter.getCurrentMenu().getType() != MenuType.MAIN_MENU) { - 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."); - } - - - return new CommandResult().success(true).enacted(true) - .message(String.format(Locale.US, "Delivered %02.1f U", bolus)); - } catch (CommandException e) { - return e.toCommandResult(); - } - } - - public void requestCancellation() { - cancelRequested = true; - progressReportCallback.report(STOPPING, 0, 0); - } - - @Override - public String toString() { - return "BolusCommand{" + - "bolus=" + bolus + - '}'; - } - - public interface ProgressReportCallback { - enum State { - PROGRAMMING, - DELIVERING, - DELIVERED, - STOPPING, - STOPPED - } - - void report(State state, int percent, double delivered); - } -} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadBasalProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadBasalProfile.java new file mode 100644 index 0000000000..d360634fe0 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadBasalProfile.java @@ -0,0 +1,22 @@ +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; + +import java.util.List; + +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; + +public class ReadBasalProfile implements Command { + @Override + public CommandResult execute() { + return null; + } + + @Override + public List validateArguments() { + return null; + } + + @Override + public void setScripter(RuffyScripter scripter) { + + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadHistoryCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadHistoryCommand.java new file mode 100644 index 0000000000..97d8d6ed63 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadHistoryCommand.java @@ -0,0 +1,26 @@ +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; + +import java.util.List; + +import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpHistory; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; + +public class ReadHistoryCommand implements Command { + public ReadHistoryCommand(PumpHistory knownHistory) { + } + + @Override + public CommandResult execute() { + return null; + } + + @Override + public List validateArguments() { + return null; + } + + @Override + public void setScripter(RuffyScripter scripter) { + + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadReserverLevelCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadReserverLevelCommand.java new file mode 100644 index 0000000000..ff5787a407 --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/ReadReserverLevelCommand.java @@ -0,0 +1,22 @@ +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; + +import java.util.List; + +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; + +public class ReadReserverLevelCommand implements Command { + @Override + public CommandResult execute() { + return null; + } + + @Override + public List validateArguments() { + return null; + } + + @Override + public void setScripter(RuffyScripter scripter) { + + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SetBasalProfile.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SetBasalProfile.java new file mode 100644 index 0000000000..cdbe4b3aee --- /dev/null +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SetBasalProfile.java @@ -0,0 +1,27 @@ +package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; + +import java.util.List; + +import info.nightscout.androidaps.plugins.PumpCombo.scripter.BasalProfile; +import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter; + +public class SetBasalProfile implements Command { + public SetBasalProfile(BasalProfile basalProfile) { + + } + + @Override + public CommandResult execute() { + return null; + } + + @Override + public List validateArguments() { + return null; + } + + @Override + public void setScripter(RuffyScripter scripter) { + + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SuperMicroBolusCommand.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SuperMicroBolusCommand.java deleted file mode 100644 index a08ea1c595..0000000000 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/scripter/commands/SuperMicroBolusCommand.java +++ /dev/null @@ -1,15 +0,0 @@ -package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands; - -/** - * Draft. - * - * small bolus, don't check reservoir level beforehand ... ?? - * not cancellable - * less of an issue if it fails - * can be retried automatically - */ -public class SuperMicroBolusCommand extends BolusCommand { - public SuperMicroBolusCommand(double bolus) { - super(bolus); - } -} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5d9477c5a5..25020904a5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -715,15 +715,9 @@ combo_enable_experimental_features Enable experimental features Unlocks experimental features which are in development and might be broken entirely. - combo_enable_experimental_bolus - Experimental bolus - Enables the in-development bolus with progress report and semi-working cancel option. combo_experimental_split_bolus Experimental split bolus feature Splits boluses into 2 U parts and waits around 45s after each to slow down bolus delivery (only active with non-experimental bolus). - combo_ignore_transient_tbr_errors - Ignore transient errors - Ignore failures when setting a TBR or reading pump state, unless the next attempt also fails. combo_experimental_reject_tbr_changes_below_delta Skip TBR changes below threshold (%). Don\'t set a TBR if the difference between the new and a running TBR is below this threshold in percent. Specifying 0 disables this option. diff --git a/app/src/main/res/xml/pref_combo.xml b/app/src/main/res/xml/pref_combo.xml index 052f7e0d49..1a73dd3599 100644 --- a/app/src/main/res/xml/pref_combo.xml +++ b/app/src/main/res/xml/pref_combo.xml @@ -9,12 +9,6 @@ android:key="@string/key_combo_enable_experimental_features" android:title="@string/combo_enable_experimental_features" android:summary="@string/combo_enable_experimental_features_summary" /> - - -