Refactor, clean out stuff, add RuffyCommands interface.
This commit is contained in:
parent
960586b79d
commit
60c9a984b5
|
@ -23,15 +23,6 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Date;
|
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.BuildConfig;
|
||||||
import info.nightscout.androidaps.MainApp;
|
import info.nightscout.androidaps.MainApp;
|
||||||
import info.nightscout.androidaps.R;
|
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.ConfigBuilder.ConfigBuilderPlugin;
|
||||||
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
|
import info.nightscout.androidaps.plugins.Overview.events.EventOverviewBolusProgress;
|
||||||
import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI;
|
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.DateUtil;
|
||||||
import info.nightscout.utils.SP;
|
import info.nightscout.utils.SP;
|
||||||
|
|
||||||
|
@ -54,7 +50,6 @@ import info.nightscout.utils.SP;
|
||||||
* Created by mike on 05.08.2016.
|
* Created by mike on 05.08.2016.
|
||||||
*/
|
*/
|
||||||
public class ComboPlugin implements PluginBase, PumpInterface {
|
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 static Logger log = LoggerFactory.getLogger(ComboPlugin.class);
|
||||||
|
|
||||||
private boolean fragmentEnabled = false;
|
private boolean fragmentEnabled = false;
|
||||||
|
@ -142,11 +137,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
long fiveMinutesSinceLastAlarm = lastAlarmTime + (5 * 60 * 1000) + (15 * 1000);
|
long fiveMinutesSinceLastAlarm = lastAlarmTime + (5 * 60 * 1000) + (15 * 1000);
|
||||||
boolean loopEnabled = ConfigBuilderPlugin.getActiveLoop() != null;
|
boolean loopEnabled = ConfigBuilderPlugin.getActiveLoop() != null;
|
||||||
boolean ignoreLastFailedTbrCmd = SP.getBoolean(R.string.key_combo_enable_experimental_features, false)
|
if (now > fiveMinutesSinceLastAlarm && loopEnabled) {
|
||||||
&& 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 failed: " + localLastCmd);
|
||||||
log.error("Command result: " + localLastCmdResult);
|
log.error("Command result: " + localLastCmdResult);
|
||||||
PumpState localPumpState = pump.state;
|
PumpState localPumpState = pump.state;
|
||||||
|
@ -352,7 +343,8 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
if (notAUserRequest && wasRunAtLeastOnce && ranWithinTheLastMinute) {
|
if (notAUserRequest && wasRunAtLeastOnce && ranWithinTheLastMinute) {
|
||||||
log.debug("Not fetching state from pump, since we did already within the last 60 seconds");
|
log.debug("Not fetching state from pump, since we did already within the last 60 seconds");
|
||||||
} else {
|
} else {
|
||||||
runCommand(new GetPumpStateCommand());
|
// TODO
|
||||||
|
// runCommand(new GetPumpStateCommand());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -366,10 +358,10 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
return basal;
|
return basal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ExperimentalBolusCommand.ProgressReportCallback bolusProgressReportCallback =
|
private static BolusCommand.ProgressReportCallback bolusProgressReportCallback =
|
||||||
new ExperimentalBolusCommand.ProgressReportCallback() {
|
new BolusCommand.ProgressReportCallback() {
|
||||||
@Override
|
@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();
|
EventOverviewBolusProgress event = EventOverviewBolusProgress.getInstance();
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PROGRAMMING:
|
case PROGRAMMING:
|
||||||
|
@ -467,10 +459,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
|
|
||||||
@NonNull
|
@NonNull
|
||||||
private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) {
|
private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) {
|
||||||
runningBolusCommand = SP.getBoolean(R.string.key_combo_enable_experimental_features, false)
|
runningBolusCommand = new BolusCommand(detailedBolusInfo.insulin, bolusProgressReportCallback);
|
||||||
&& SP.getBoolean(R.string.key_combo_enable_experimental_bolus, false)
|
|
||||||
? new ExperimentalBolusCommand(detailedBolusInfo.insulin, bolusProgressReportCallback)
|
|
||||||
: new BolusCommand(detailedBolusInfo.insulin);
|
|
||||||
CommandResult bolusCmdResult = runCommand(runningBolusCommand);
|
CommandResult bolusCmdResult = runCommand(runningBolusCommand);
|
||||||
PumpEnactResult pumpEnactResult = new PumpEnactResult();
|
PumpEnactResult pumpEnactResult = new PumpEnactResult();
|
||||||
pumpEnactResult.success = bolusCmdResult.success;
|
pumpEnactResult.success = bolusCmdResult.success;
|
||||||
|
@ -517,19 +506,6 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
log.error("Exception received from pump", commandResult.exception);
|
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.lastCmd = command;
|
||||||
pump.lastCmdTime = new Date();
|
pump.lastCmdTime = new Date();
|
||||||
pump.lastCmdResult = commandResult;
|
pump.lastCmdResult = commandResult;
|
||||||
|
@ -595,7 +571,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
adjustedPercent = rounded.intValue();
|
adjustedPercent = rounded.intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandResult commandResult = runCommand(new SetTbrCommand(adjustedPercent, durationInMinutes));
|
CommandResult commandResult = ruffyScripter.setTbr(adjustedPercent, durationInMinutes);
|
||||||
|
|
||||||
if (commandResult.enacted) {
|
if (commandResult.enacted) {
|
||||||
TemporaryBasal tempStart = new TemporaryBasal(commandResult.completionTime);
|
TemporaryBasal tempStart = new TemporaryBasal(commandResult.completionTime);
|
||||||
|
@ -641,7 +617,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
if (activeTemp == null || userRequested) {
|
if (activeTemp == null || userRequested) {
|
||||||
/* v1 compatibility to sync DB to pump if they diverged (activeTemp == null) */
|
/* v1 compatibility to sync DB to pump if they diverged (activeTemp == null) */
|
||||||
log.debug("cancelTempBasal: hard-cancelling TBR since user requested");
|
log.debug("cancelTempBasal: hard-cancelling TBR since user requested");
|
||||||
commandResult = runCommand(new CancelTbrCommand());
|
commandResult = ruffyScripter.cancelTbr();
|
||||||
if (commandResult.enacted) {
|
if (commandResult.enacted) {
|
||||||
tempBasal = new TemporaryBasal(commandResult.completionTime);
|
tempBasal = new TemporaryBasal(commandResult.completionTime);
|
||||||
tempBasal.durationInMinutes = 0;
|
tempBasal.durationInMinutes = 0;
|
||||||
|
@ -661,14 +637,14 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
} else {
|
} else {
|
||||||
// Set a fake neutral temp to avoid TBR cancel alert. Decide 90% vs 110% based on
|
// 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%.
|
// 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.");
|
log.debug("cancelTempBasal: changing tbr to " + percentage + "% for 15 mins.");
|
||||||
commandResult = runCommand(new SetTbrCommand(percentage, 15));
|
commandResult = ruffyScripter.setTbr(percentage, 15);
|
||||||
if (commandResult.enacted) {
|
if (commandResult.enacted) {
|
||||||
tempBasal = new TemporaryBasal(commandResult.completionTime);
|
tempBasal = new TemporaryBasal(commandResult.completionTime);
|
||||||
tempBasal.durationInMinutes = 15;
|
tempBasal.durationInMinutes = 15;
|
||||||
tempBasal.source = Source.USER;
|
tempBasal.source = Source.USER;
|
||||||
tempBasal.percentRate = (int) percentage;
|
tempBasal.percentRate = percentage;
|
||||||
tempBasal.isAbsolute = false;
|
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
|
// TODO v2 add battery, reservoir info when we start reading that and clean up the code
|
||||||
@Override
|
@Override
|
||||||
public JSONObject getJSONStatus() {
|
public JSONObject getJSONStatus() {
|
||||||
if (true) { //pump.lastCmdTime.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) {
|
if (pump.lastCmdTime.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
package info.nightscout.androidaps.plugins.PumpCombo.scripter;
|
||||||
|
|
||||||
|
public class BasalProfile {
|
||||||
|
}
|
|
@ -0,0 +1,4 @@
|
||||||
|
package info.nightscout.androidaps.plugins.PumpCombo.scripter;
|
||||||
|
|
||||||
|
public class PumpHistory {
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
|
@ -17,10 +17,17 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.List;
|
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.Command;
|
||||||
import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandException;
|
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.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.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.
|
// 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
|
// 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
|
* 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
|
* 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 static final Logger log = LoggerFactory.getLogger(RuffyScripter.class);
|
||||||
|
|
||||||
private IRuffyService ruffyService;
|
private IRuffyService ruffyService;
|
||||||
|
@ -696,4 +703,46 @@ public class RuffyScripter {
|
||||||
}
|
}
|
||||||
return (T) value;
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,16 +11,24 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
import info.nightscout.androidaps.R;
|
import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter;
|
||||||
import info.nightscout.utils.SP;
|
|
||||||
|
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 {
|
public class BolusCommand extends BaseCommand {
|
||||||
private static final Logger log = LoggerFactory.getLogger(BolusCommand.class);
|
private static final Logger log = LoggerFactory.getLogger(BolusCommand.class);
|
||||||
|
|
||||||
protected final double bolus;
|
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.bolus = bolus;
|
||||||
|
this.progressReportCallback = progressReportCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -37,37 +45,119 @@ public class BolusCommand extends BaseCommand {
|
||||||
@Override
|
@Override
|
||||||
public CommandResult execute() {
|
public CommandResult execute() {
|
||||||
try {
|
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();
|
inputBolusAmount();
|
||||||
verifyDisplayedBolusAmount();
|
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
|
// confirm bolus
|
||||||
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
||||||
scripter.pressCheckKey();
|
scripter.pressCheckKey();
|
||||||
|
|
||||||
// the pump displays the entered bolus and waits a bit to let user check and cancel
|
// the pump displays the entered bolus and waits a few seconds to let user check and cancel
|
||||||
// and then returns to the main menu
|
while (scripter.getCurrentMenu().getType() == MenuType.BOLUS_ENTER) {
|
||||||
scripter.waitForMenuToBeLeft(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,
|
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU,
|
||||||
"Pump did not return to MAIN_MEU from BOLUS_ENTER to deliver bolus. "
|
"Pump did not return to MAIN_MEU from BOLUS_ENTER to deliver bolus. "
|
||||||
+ "Check pump manually, the bolus might not have been delivered.");
|
+ "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
|
// wait for bolus delivery to complete; the remaining units to deliver are counted
|
||||||
// down and are displayed on the main menu.
|
// 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) {
|
while (bolusRemaining != null) {
|
||||||
log.debug("Delivering bolus, remaining: " + bolusRemaining);
|
if (cancelRequested) {
|
||||||
SystemClock.sleep(200);
|
// cancel running bolus by pressing up for 3s, while raise a BOLUS CANCELLED
|
||||||
if (scripter.getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) {
|
// alert, unless the bolus finished within those 3s.
|
||||||
throw new CommandException().success(false).enacted(true)
|
progressReportCallback.report(STOPPING, 0, 0);
|
||||||
.message("Warning/error raised after bolus delivery started. " +
|
scripter.pressKeyMs(RuffyScripter.Key.UP, 3000);
|
||||||
"The treatment has been recorded, please check it against the " +
|
progressReportCallback.report(STOPPED, 0, 0);
|
||||||
"pumps records and delete it if it hasn't finished successfully.");
|
// 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);
|
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 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?
|
// 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. "
|
"Bolus delivery did not complete as expected. "
|
||||||
+ "Check pump manually, the bolus might not have been delivered.");
|
+ "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
|
// read last bolus record; those menus display static data and therefore
|
||||||
// only a single menu update is sent
|
// only a single menu update is sent
|
||||||
scripter.navigateToMenu(MenuType.MY_DATA_MENU);
|
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");
|
.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);
|
double lastBolusInHistory = (double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS);
|
||||||
if (Math.abs(bolus - lastBolusInHistory) > 0.05) {
|
if (Math.abs(bolus - lastBolusInHistory) > 0.05) {
|
||||||
throw new CommandException().success(false).enacted(true)
|
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");
|
log.debug("Bolus record in history confirms delivered bolus");
|
||||||
|
|
||||||
if(SP.getBoolean(R.string.key_combo_enable_experimental_features, false)) {
|
// TODO how would this call fail? more generally ......
|
||||||
scripter.returnToMainMenu();
|
scripter.returnToMainMenu();
|
||||||
} else {
|
if (scripter.getCurrentMenu().getType() != MenuType.MAIN_MENU) {
|
||||||
// leave menu to go back to main menu
|
throw new CommandException().success(false).enacted(true)
|
||||||
scripter.pressCheckKey();
|
.message("Bolus was correctly delivered and checked against history, but we "
|
||||||
scripter.waitForMenuToBeLeft(MenuType.BOLUS_DATA);
|
+ "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)
|
return new CommandResult().success(true).enacted(true)
|
||||||
.message(String.format(Locale.US, "Delivered %02.1f U", bolus));
|
.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.verifyMenuIsDisplayed(MenuType.MAIN_MENU);
|
||||||
scripter.navigateToMenu(MenuType.BOLUS_MENU);
|
scripter.navigateToMenu(MenuType.BOLUS_MENU);
|
||||||
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_MENU);
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_MENU);
|
||||||
|
@ -127,7 +218,7 @@ public class BolusCommand extends BaseCommand {
|
||||||
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void inputBolusAmount() {
|
private void inputBolusAmount() {
|
||||||
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
||||||
// press 'up' once for each 0.1 U increment
|
// press 'up' once for each 0.1 U increment
|
||||||
long steps = Math.round(bolus * 10);
|
long steps = Math.round(bolus * 10);
|
||||||
|
@ -141,7 +232,7 @@ public class BolusCommand extends BaseCommand {
|
||||||
SystemClock.sleep(2000);
|
SystemClock.sleep(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void verifyDisplayedBolusAmount() {
|
private void verifyDisplayedBolusAmount() {
|
||||||
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
||||||
|
|
||||||
// wait up to 5s for any scrolling to finish
|
// 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
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "BolusCommand{" +
|
return "BolusCommand{" +
|
||||||
"bolus=" + bolus +
|
"bolus=" + bolus +
|
||||||
'}';
|
'}';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public interface ProgressReportCallback {
|
||||||
|
enum State {
|
||||||
|
PROGRAMMING,
|
||||||
|
DELIVERING,
|
||||||
|
DELIVERED,
|
||||||
|
STOPPING,
|
||||||
|
STOPPED
|
||||||
|
}
|
||||||
|
|
||||||
|
void report(State state, int percent, double delivered);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<String> validateArguments() {
|
|
||||||
List<String> 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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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<String> validateArguments() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setScripter(RuffyScripter scripter) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<String> validateArguments() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setScripter(RuffyScripter scripter) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<String> validateArguments() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setScripter(RuffyScripter scripter) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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<String> validateArguments() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setScripter(RuffyScripter scripter) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -715,15 +715,9 @@
|
||||||
<string name="key_combo_enable_experimental_features">combo_enable_experimental_features</string>
|
<string name="key_combo_enable_experimental_features">combo_enable_experimental_features</string>
|
||||||
<string name="combo_enable_experimental_features">Enable experimental features</string>
|
<string name="combo_enable_experimental_features">Enable experimental features</string>
|
||||||
<string name="combo_enable_experimental_features_summary">Unlocks experimental features which are in development and might be broken entirely.</string>
|
<string name="combo_enable_experimental_features_summary">Unlocks experimental features which are in development and might be broken entirely.</string>
|
||||||
<string name="key_combo_enable_experimental_bolus">combo_enable_experimental_bolus</string>
|
|
||||||
<string name="combo_enable_experimental_bolus">Experimental bolus</string>
|
|
||||||
<string name="combo_enable_experimental_bolus_summary">Enables the in-development bolus with progress report and semi-working cancel option.</string>
|
|
||||||
<string name="key_combo_enable_experimental_split_bolus">combo_experimental_split_bolus</string>
|
<string name="key_combo_enable_experimental_split_bolus">combo_experimental_split_bolus</string>
|
||||||
<string name="combo_enable_experimental_split_bolus">Experimental split bolus feature</string>
|
<string name="combo_enable_experimental_split_bolus">Experimental split bolus feature</string>
|
||||||
<string name="combo_enable_experimental_split_bolus_summary">Splits boluses into 2 U parts and waits around 45s after each to slow down bolus delivery (only active with non-experimental bolus).</string>
|
<string name="combo_enable_experimental_split_bolus_summary">Splits boluses into 2 U parts and waits around 45s after each to slow down bolus delivery (only active with non-experimental bolus).</string>
|
||||||
<string name="key_combo_experimental_ignore_transient_errors">combo_ignore_transient_tbr_errors</string>
|
|
||||||
<string name="combo_experimental_ignore_transient_errors">Ignore transient errors</string>
|
|
||||||
<string name="combo_experimental_ignore_transient_errors_summary">Ignore failures when setting a TBR or reading pump state, unless the next attempt also fails.</string>
|
|
||||||
<string name="key_combo_experimental_skip_tbr_changes_below_delta">combo_experimental_reject_tbr_changes_below_delta</string>
|
<string name="key_combo_experimental_skip_tbr_changes_below_delta">combo_experimental_reject_tbr_changes_below_delta</string>
|
||||||
<string name="combo_experimental_skip_tbr_changes_below_delta">Skip TBR changes below threshold (%).</string>
|
<string name="combo_experimental_skip_tbr_changes_below_delta">Skip TBR changes below threshold (%).</string>
|
||||||
<string name="combo_experimental_skip_tbr_changes_below_delta_summary">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.</string>
|
<string name="combo_experimental_skip_tbr_changes_below_delta_summary">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.</string>
|
||||||
|
|
|
@ -9,12 +9,6 @@
|
||||||
android:key="@string/key_combo_enable_experimental_features"
|
android:key="@string/key_combo_enable_experimental_features"
|
||||||
android:title="@string/combo_enable_experimental_features"
|
android:title="@string/combo_enable_experimental_features"
|
||||||
android:summary="@string/combo_enable_experimental_features_summary" />
|
android:summary="@string/combo_enable_experimental_features_summary" />
|
||||||
<SwitchPreference
|
|
||||||
android:dependency="@string/key_combo_enable_experimental_features"
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:key="@string/key_combo_enable_experimental_bolus"
|
|
||||||
android:title="@string/combo_enable_experimental_bolus"
|
|
||||||
android:summary="@string/combo_enable_experimental_bolus_summary" />
|
|
||||||
<SwitchPreference
|
<SwitchPreference
|
||||||
android:dependency="@string/key_combo_enable_experimental_features"
|
android:dependency="@string/key_combo_enable_experimental_features"
|
||||||
android:defaultValue="false"
|
android:defaultValue="false"
|
||||||
|
@ -22,13 +16,6 @@
|
||||||
android:title="@string/combo_enable_experimental_split_bolus"
|
android:title="@string/combo_enable_experimental_split_bolus"
|
||||||
android:summary="@string/combo_enable_experimental_split_bolus_summary"/>
|
android:summary="@string/combo_enable_experimental_split_bolus_summary"/>
|
||||||
|
|
||||||
<SwitchPreference
|
|
||||||
android:dependency="@string/key_combo_enable_experimental_features"
|
|
||||||
android:defaultValue="false"
|
|
||||||
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"/>
|
|
||||||
|
|
||||||
<!-- TODO add validation, to restrict values to rang 0-100, see pref_absorption_oref0.xml -->
|
<!-- TODO add validation, to restrict values to rang 0-100, see pref_absorption_oref0.xml -->
|
||||||
<EditTextPreference
|
<EditTextPreference
|
||||||
android:dependency="@string/key_combo_enable_experimental_features"
|
android:dependency="@string/key_combo_enable_experimental_features"
|
||||||
|
|
Loading…
Reference in a new issue