Extract SPI.

This commit is contained in:
Johannes Mockenhaupt 2017-10-17 16:34:24 +02:00
parent 5131b8b62f
commit 142f9cf6a3
No known key found for this signature in database
GPG key ID: 9E1EA6AF7BBBB0D1
26 changed files with 224 additions and 213 deletions

View file

@ -17,9 +17,8 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.plugins.PumpCombo.spi.PumpState;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R;
import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI;
@ -112,7 +111,7 @@ public class ComboFragment extends Fragment implements View.OnClickListener {
@Override
public void run() {
ComboPlugin plugin = ComboPlugin.getPlugin();
statusText.setText(plugin.getPump().stateSummary);
statusText.setText(plugin.getPump().state.getStateSummary());
if (plugin.isInitialized()) {
PumpState ps = plugin.getPump().state;
if (ps != null) {
@ -147,19 +146,19 @@ public class ComboFragment extends Fragment implements View.OnClickListener {
}
}
Command lastCmd = plugin.getPump().lastCmd;
CommandResult lastCmdResult1 = plugin.getPump().lastCmdResult;
String lastCmd = lastCmdResult1.request;
if (lastCmd != null) {
lastCmdText.setText(lastCmd.toString());
lastCmdText.setText(lastCmd);
lastCmdTimeText.setText(plugin.getPump().lastCmdTime.toLocaleString());
} else {
lastCmdText.setText("");
lastCmdTimeText.setText("");
}
CommandResult lastCmdResult = plugin.getPump().lastCmdResult;
if (lastCmdResult != null && lastCmdResult.message != null) {
lastCmdResultText.setText(lastCmdResult.message);
lastCmdDurationText.setText(lastCmdResult.duration);
if (lastCmdResult1.message != null) {
lastCmdResultText.setText(lastCmdResult1.message);
lastCmdDurationText.setText(lastCmdResult1.duration);
} else {
lastCmdResultText.setText("");
lastCmdDurationText.setText("");

View file

@ -11,7 +11,6 @@ import android.net.Uri;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
import com.squareup.otto.Subscribe;
@ -38,11 +37,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.spi.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.androidaps.plugins.PumpCombo.spi.CommandResult;
import info.nightscout.androidaps.plugins.PumpCombo.spi.BolusProgressReporter;
import info.nightscout.androidaps.plugins.PumpCombo.spi.RuffyCommands;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.SP;
@ -57,9 +56,10 @@ public class ComboPlugin implements PluginBase, PumpInterface {
private PumpDescription pumpDescription = new PumpDescription();
private RuffyScripter ruffyScripter;
private RuffyCommands ruffyScripter;
private ServiceConnection mRuffyServiceConnection;
// TODO access to pump (and its members) is chaotic and needs an update
private ComboPump pump = new ComboPump();
private static ComboPlugin plugin = null;
@ -70,9 +70,6 @@ public class ComboPlugin implements PluginBase, PumpInterface {
return plugin;
}
@Nullable
private volatile BolusCommand runningBolusCommand;
private static PumpEnactResult OPERATION_NOT_SUPPORTED = new PumpEnactResult();
static {
@ -81,7 +78,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
OPERATION_NOT_SUPPORTED.comment = "Requested operation not supported by pump";
}
public ComboPlugin() {
private ComboPlugin() {
definePumpCapabilities();
MainApp.bus().register(this);
bindRuffyService();
@ -136,7 +133,6 @@ public class ComboPlugin implements PluginBase, PumpInterface {
int id = 1000;
long lastAlarmTime = 0;
while (true) {
Command localLastCmd = pump.lastCmd;
CommandResult localLastCmdResult = pump.lastCmdResult;
if (!SP.getBoolean(R.string.combo_disable_alerts, false) &&
localLastCmdResult != null && !localLastCmdResult.success) {
@ -144,7 +140,6 @@ public class ComboPlugin implements PluginBase, PumpInterface {
long fiveMinutesSinceLastAlarm = lastAlarmTime + (5 * 60 * 1000) + (15 * 1000);
boolean loopEnabled = ConfigBuilderPlugin.getActiveLoop() != null;
if (now > fiveMinutesSinceLastAlarm && loopEnabled) {
log.error("Command failed: " + localLastCmd);
log.error("Command result: " + localLastCmdResult);
PumpState localPumpState = pump.state;
if (localPumpState != null && localPumpState.errorMsg != null) {
@ -202,7 +197,9 @@ public class ComboPlugin implements PluginBase, PumpInterface {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
keepUnbound = false;
ruffyScripter.start(IRuffyService.Stub.asInterface(service));
// TODO fine until we know whether the impl will be an Android service or not
// and binds things and what not.
((RuffyScripter) ruffyScripter).start(IRuffyService.Stub.asInterface(service));
log.debug("ruffy serivce connected");
}
@ -224,7 +221,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
}
if (!boundSucceeded) {
pump.stateSummary = "No connection to ruffy. Pump control unavailable.";
pump.state.errorMsg = "No connection to ruffy. Pump control unavailable.";
}
return true;
}
@ -233,7 +230,8 @@ public class ComboPlugin implements PluginBase, PumpInterface {
private void unbindRuffyService() {
keepUnbound = true;
ruffyScripter.unbind();
// TODO fine until we know whether the impl will be an Android service or not
((RuffyScripter) ruffyScripter).unbind();
MainApp.instance().getApplicationContext().unbindService(mRuffyServiceConnection);
}
@ -338,7 +336,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
log.debug("RefreshDataFromPump called");
// if Android is sluggish this might get called before ruffy is bound
if (!ruffyScripter.isRunning()) {
if (!ruffyScripter.isPumpAvailable()) {
log.warn("Rejecting call to RefreshDataFromPump: scripter not ready yet.");
return;
}
@ -364,10 +362,11 @@ public class ComboPlugin implements PluginBase, PumpInterface {
return basal;
}
private static BolusCommand.ProgressReportCallback bolusProgressReportCallback =
new BolusCommand.ProgressReportCallback() {
// TODO remove dep on BolusCommand
private static BolusProgressReporter bolusProgressReporter =
new BolusProgressReporter() {
@Override
public void report(BolusCommand.ProgressReportCallback.State state, int percent, double delivered) {
public void report(BolusProgressReporter.State state, int percent, double delivered) {
EventOverviewBolusProgress event = EventOverviewBolusProgress.getInstance();
switch (state) {
case PROGRAMMING:
@ -394,79 +393,82 @@ public class ComboPlugin implements PluginBase, PumpInterface {
/** Updates Treatment records with carbs and boluses and delivers a bolus if needed */
@Override
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
if (detailedBolusInfo.insulin > 0 || detailedBolusInfo.carbs > 0) {
if (detailedBolusInfo.insulin > 0) {
// bolus needed, ask pump to deliver it
if (!(SP.getBoolean(R.string.key_combo_enable_experimental_features, false)
&& SP.getBoolean(R.string.key_combo_enable_experimental_split_bolus, false))) {
return deliverBolus(detailedBolusInfo);
try {
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_features, false)
&& SP.getBoolean(R.string.key_combo_enable_experimental_split_bolus, false))) {
return deliverBolus(detailedBolusInfo);
} else {
// split up bolus into 2 U parts
PumpEnactResult pumpEnactResult = new PumpEnactResult();
pumpEnactResult.success = true;
pumpEnactResult.enacted = true;
pumpEnactResult.bolusDelivered = 0d;
pumpEnactResult.carbsDelivered = detailedBolusInfo.carbs;
double remainingBolus = detailedBolusInfo.insulin;
int split = 1;
while (remainingBolus > 0.05) {
double bolus = remainingBolus > 2 ? 2 : remainingBolus;
DetailedBolusInfo bolusInfo = new DetailedBolusInfo();
bolusInfo.insulin = bolus;
bolusInfo.isValid = false;
log.debug("Delivering split bolus #" + split + " with " + bolus + " U");
PumpEnactResult bolusResult = deliverBolus(bolusInfo);
if (!bolusResult.success) {
return bolusResult;
}
pumpEnactResult.bolusDelivered += bolus;
remainingBolus -= 2;
split++;
// Programming the pump for 2 U takes ~20, so wait 20s more so the
// boluses are spaced 40s apart.
SystemClock.sleep(20 * 1000);
}
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
return pumpEnactResult;
}
} else {
// split up bolus into 2 U parts
// no bolus required, carb only treatment
// TODO the ui freezes when the calculator issues a carb-only treatment
// so just wait, yeah, this is dumb. for now; proper fix via GL#10
// info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog.scheduleDismiss()
SystemClock.sleep(6000);
PumpEnactResult pumpEnactResult = new PumpEnactResult();
pumpEnactResult.success = true;
pumpEnactResult.enacted = true;
pumpEnactResult.bolusDelivered = 0d;
pumpEnactResult.carbsDelivered = detailedBolusInfo.carbs;
double remainingBolus = detailedBolusInfo.insulin;
int split = 1;
while (remainingBolus > 0.05) {
double bolus = remainingBolus > 2 ? 2 : remainingBolus;
DetailedBolusInfo bolusInfo = new DetailedBolusInfo();
bolusInfo.insulin = bolus;
bolusInfo.isValid = false;
log.debug("Delivering split bolus #" + split + " with " + bolus + " U");
PumpEnactResult bolusResult = deliverBolus(bolusInfo);
if (!bolusResult.success) {
return bolusResult;
}
pumpEnactResult.bolusDelivered += bolus;
remainingBolus -= 2;
split++;
// Programming the pump for 2 U takes ~20, so wait 20s more so the
// boluses are spaced 40s apart.
SystemClock.sleep(20 * 1000);
}
pumpEnactResult.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance();
bolusingEvent.percent = 100;
MainApp.bus().post(bolusingEvent);
return pumpEnactResult;
}
} else {
// no bolus required, carb only treatment
// TODO the ui freezes when the calculator issues a carb-only treatment
// so just wait, yeah, this is dumb. for now; proper fix via GL#10
// info.nightscout.androidaps.plugins.Overview.Dialogs.BolusProgressDialog.scheduleDismiss()
SystemClock.sleep(6000);
// neither carbs nor bolus requested
PumpEnactResult pumpEnactResult = new PumpEnactResult();
pumpEnactResult.success = true;
pumpEnactResult.enacted = true;
pumpEnactResult.success = false;
pumpEnactResult.enacted = false;
pumpEnactResult.bolusDelivered = 0d;
pumpEnactResult.carbsDelivered = detailedBolusInfo.carbs;
pumpEnactResult.comment = MainApp.instance().getString(R.string.virtualpump_resultok);
MainApp.getConfigBuilder().addToHistoryTreatment(detailedBolusInfo);
EventOverviewBolusProgress bolusingEvent = EventOverviewBolusProgress.getInstance();
bolusingEvent.percent = 100;
MainApp.bus().post(bolusingEvent);
pumpEnactResult.carbsDelivered = 0d;
pumpEnactResult.comment = MainApp.instance().getString(R.string.danar_invalidinput);
log.error("deliverTreatment: Invalid input");
return pumpEnactResult;
}
} else {
// neither carbs nor bolus requested
PumpEnactResult pumpEnactResult = new PumpEnactResult();
pumpEnactResult.success = false;
pumpEnactResult.enacted = false;
pumpEnactResult.bolusDelivered = 0d;
pumpEnactResult.carbsDelivered = 0d;
pumpEnactResult.comment = MainApp.instance().getString(R.string.danar_invalidinput);
log.error("deliverTreatment: Invalid input");
return pumpEnactResult;
} finally {
MainApp.bus().post(new EventComboPumpUpdateGUI());
}
}
@NonNull
private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) {
runningBolusCommand = new BolusCommand(detailedBolusInfo.insulin, bolusProgressReportCallback);
CommandResult bolusCmdResult = runCommand(runningBolusCommand);
CommandResult bolusCmdResult = ruffyScripter.deliverBolus(detailedBolusInfo.insulin, bolusProgressReporter);
PumpEnactResult pumpEnactResult = new PumpEnactResult();
pumpEnactResult.success = bolusCmdResult.success;
pumpEnactResult.enacted = bolusCmdResult.enacted;
@ -492,41 +494,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
@Override
public void stopBolusDelivering() {
BolusCommand localRunningBolusCommand = runningBolusCommand;
if (localRunningBolusCommand != null) localRunningBolusCommand.requestCancellation();
}
private CommandResult runCommand(Command command) {
if (ruffyScripter == null) {
String msg = "No connection to ruffy. Pump control not available.";
pump.stateSummary = msg;
return new CommandResult().message(msg);
}
pump.stateSummary = "Executing " + command;
MainApp.bus().post(new EventComboPumpUpdateGUI());
CommandResult commandResult = ruffyScripter.runCommand(command);
log.debug("RuffyScripter returned from command invocation, result: " + commandResult);
if (commandResult.exception != null) {
log.error("Exception received from pump", commandResult.exception);
}
pump.lastCmd = command;
pump.lastCmdTime = new Date();
pump.lastCmdResult = commandResult;
pump.state = commandResult.state;
if (commandResult.success && commandResult.state.suspended) {
pump.stateSummary = "Suspended";
} else if (commandResult.success) {
pump.stateSummary = "Idle";
} else {
pump.stateSummary = "Error";
}
MainApp.bus().post(new EventComboPumpUpdateGUI());
return commandResult;
ruffyScripter.cancelBolus();
}
// Note: AAPS calls this only to enact OpenAPS recommendations
@ -593,6 +561,8 @@ public class ComboPlugin implements PluginBase, PumpInterface {
treatmentsInterface.addToHistoryTempBasal(tempStart);
}
MainApp.bus().post(new EventComboPumpUpdateGUI());
PumpEnactResult pumpEnactResult = new PumpEnactResult();
pumpEnactResult.success = commandResult.success;
pumpEnactResult.enacted = commandResult.enacted;
@ -602,6 +572,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
// have the command return this anyways ...
pumpEnactResult.percent = adjustedPercent;
pumpEnactResult.duration = durationInMinutes;
return pumpEnactResult;
}
@ -685,7 +656,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
JSONObject pumpJson = new JSONObject();
JSONObject statusJson = new JSONObject();
JSONObject extendedJson = new JSONObject();
statusJson.put("status", pump.stateSummary);
statusJson.put("status", pump.state.getStateSummary());
extendedJson.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION);
try {
extendedJson.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName());
@ -734,7 +705,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
@Override
public String shortStatus(boolean veryShort) {
// TODO trim for wear if veryShort==true
return pump.stateSummary;
return pump.state.getStateSummary();
}
@Override

View file

@ -5,15 +5,10 @@ import android.support.annotation.Nullable;
import java.util.Date;
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.plugins.PumpCombo.spi.PumpState;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
class ComboPump {
@NonNull
volatile String stateSummary = "Initializing";
@Nullable
volatile Command lastCmd;
@Nullable
volatile CommandResult lastCmdResult;
@NonNull

View file

@ -1,4 +0,0 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter;
public class BasalProfile {
}

View file

@ -1,4 +0,0 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter;
public class PumpHistory {
}

View file

@ -15,19 +15,25 @@ import org.monkey.d.ruffy.ruffy.driver.display.menu.MenuTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Date;
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;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.CancelTbrCommand;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.Command;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.CommandException;
import info.nightscout.androidaps.plugins.PumpCombo.spi.BasalProfile;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.BolusCommand;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.GetPumpStateCommand;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.ReadBasalProfileCommand;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.ReadHistoryCommand;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.ReadReserverLevelCommand;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.SetBasalProfileCommand;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.SetTbrCommand;
import info.nightscout.androidaps.plugins.PumpCombo.spi.BolusProgressReporter;
import info.nightscout.androidaps.plugins.PumpCombo.spi.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.spi.PumpState;
import info.nightscout.androidaps.plugins.PumpCombo.spi.RuffyCommands;
// 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
@ -81,7 +87,8 @@ public class RuffyScripter implements RuffyCommands {
}
}
public boolean isRunning() {
@Override
public boolean isPumpAvailable() {
return started;
}
@ -186,6 +193,7 @@ public class RuffyScripter implements RuffyCommands {
}
};
@Override
public boolean isPumpBusy() {
return activeCmd != null;
}
@ -243,6 +251,7 @@ public class RuffyScripter implements RuffyCommands {
ensureConnected();
final RuffyScripter scripter = this;
final Returnable returnable = new Returnable();
returnable.cmdResult.request = cmd.toString();
Thread cmdThread = new Thread(new Runnable() {
@Override
public void run() {
@ -705,8 +714,8 @@ public class RuffyScripter implements RuffyCommands {
}
@Override
public CommandResult deliverBolus(double amount, BolusCommand.ProgressReportCallback progressReportCallback) {
return runCommand(new BolusCommand(amount, progressReportCallback));
public CommandResult deliverBolus(double amount, BolusProgressReporter bolusProgressReporter) {
return runCommand(new BolusCommand(amount, bolusProgressReporter));
}
@Override
@ -738,11 +747,17 @@ public class RuffyScripter implements RuffyCommands {
@Override
public CommandResult readBasalProfile() {
return runCommand(new ReadBasalProfile());
return runCommand(new ReadBasalProfileCommand());
}
@Override
public CommandResult setBasalProfile(BasalProfile basalProfile) {
return runCommand(new SetBasalProfile(basalProfile));
return runCommand(new SetBasalProfileCommand(basalProfile));
}
@Override
public CommandResult setDateAndTime(Date date) {
// TODO I'm a faker!
return new CommandResult().success(true).enacted(false);
}
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter;

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import android.os.SystemClock;
@ -12,23 +12,21 @@ import java.util.List;
import java.util.Locale;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.spi.BolusProgressReporter;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
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;
import static info.nightscout.androidaps.plugins.PumpCombo.spi.BolusProgressReporter.State.*;
public class BolusCommand extends BaseCommand {
private static final Logger log = LoggerFactory.getLogger(BolusCommand.class);
protected final double bolus;
private final ProgressReportCallback progressReportCallback;
private final BolusProgressReporter bolusProgressReporter;
private volatile boolean cancelRequested;
public BolusCommand(double bolus, ProgressReportCallback progressReportCallback) {
public BolusCommand(double bolus, BolusProgressReporter bolusProgressReporter) {
this.bolus = bolus;
this.progressReportCallback = progressReportCallback;
this.bolusProgressReporter = bolusProgressReporter;
}
@Override
@ -49,15 +47,15 @@ public class BolusCommand extends BaseCommand {
// 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);
bolusProgressReporter.report(PROGRAMMING, 0, 0);
enterBolusMenu();
inputBolusAmount();
verifyDisplayedBolusAmount();
if (cancelRequested) {
progressReportCallback.report(STOPPING, 0, 0);
bolusProgressReporter.report(STOPPING, 0, 0);
scripter.returnToMainMenu();
progressReportCallback.report(STOPPED, 0, 0);
bolusProgressReporter.report(STOPPED, 0, 0);
return new CommandResult().success(true).enacted(false)
.message("Bolus cancelled as per user request with no insulin delivered");
}
@ -69,13 +67,13 @@ public class BolusCommand extends BaseCommand {
// 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);
bolusProgressReporter.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);
bolusProgressReporter.report(STOPPED, 0, 0);
return new CommandResult().success(true).enacted(false)
.message("Bolus cancelled as per user request with no insulin delivered");
}
@ -86,7 +84,7 @@ public class BolusCommand extends BaseCommand {
"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);
bolusProgressReporter.report(DELIVERING, 0, 0);
Double bolusRemaining = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_REMAINING);
double lastBolusReported = 0;
boolean lowCartdrigeAlarmTriggered = false;
@ -100,9 +98,9 @@ public class BolusCommand extends BaseCommand {
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);
bolusProgressReporter.report(STOPPING, 0, 0);
scripter.pressKeyMs(RuffyScripter.Key.UP, 3000);
progressReportCallback.report(STOPPED, 0, 0);
bolusProgressReporter.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) {
@ -118,7 +116,7 @@ public class BolusCommand extends BaseCommand {
if (lastBolusReported != bolusRemaining) {
log.debug("Delivering bolus, remaining: " + bolusRemaining);
int percentDelivered = (int) (100 - (bolusRemaining / bolus * 100));
progressReportCallback.report(DELIVERING, percentDelivered, bolus - bolusRemaining);
bolusProgressReporter.report(DELIVERING, percentDelivered, bolus - bolusRemaining);
lastBolusReported = bolusRemaining;
}
@ -140,7 +138,7 @@ public class BolusCommand extends BaseCommand {
SystemClock.sleep(50);
bolusRemaining = (Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.BOLUS_REMAINING);
}
progressReportCallback.report(DELIVERED, 100, bolus);
bolusProgressReporter.report(DELIVERED, 100, bolus);
/*
// wait up to 2s for any possible warning to be raised, if not raised already
@ -261,7 +259,7 @@ public class BolusCommand extends BaseCommand {
public void requestCancellation() {
cancelRequested = true;
progressReportCallback.report(STOPPING, 0, 0);
bolusProgressReporter.report(STOPPING, 0, 0);
}
@Override
@ -270,16 +268,4 @@ public class BolusCommand extends BaseCommand {
"bolus=" + bolus +
'}';
}
public interface ProgressReportCallback {
enum State {
PROGRAMMING,
DELIVERING,
DELIVERED,
STOPPING,
STOPPED
}
void report(State state, int percent, double delivered);
}
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import org.monkey.d.ruffy.ruffy.driver.display.MenuType;
import org.slf4j.Logger;
@ -7,8 +7,9 @@ import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState;
import info.nightscout.androidaps.plugins.PumpCombo.spi.PumpState;
import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
// TODO robustness: can a TBR run out, whilst we're trying to cancel it?
// Hm, we could just ignore TBRs that run out within the next 60s (0:01 or even 0:02

View file

@ -1,8 +1,9 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
/**
* Interface for all commands to be executed by the pump.

View file

@ -1,4 +1,6 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
public class CommandException extends RuntimeException {
public boolean success = false;

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import android.util.Log;
@ -11,6 +11,7 @@ import java.util.List;
import java.util.Map;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
public class GetBasalRateProfileCommand extends BaseCommand {
private static final Logger log = LoggerFactory.getLogger(GetBasalRateProfileCommand.class);

View file

@ -1,11 +1,13 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import org.monkey.d.ruffy.ruffy.driver.display.MenuType;
import java.util.Collections;
import java.util.List;
import static info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.GetPumpStateCommand.Stepper.runStep;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
import static info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands.GetPumpStateCommand.Stepper.runStep;
public class GetPumpStateCommand extends BaseCommand {
interface Step {

View file

@ -1,10 +1,11 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
public class ReadBasalProfile implements Command {
public class ReadBasalProfileCommand implements Command {
@Override
public CommandResult execute() {
return null;

View file

@ -1,9 +1,10 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.spi.PumpHistory;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
public class ReadHistoryCommand implements Command {
public ReadHistoryCommand(PumpHistory knownHistory) {

View file

@ -1,8 +1,9 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
public class ReadReserverLevelCommand implements Command {
@Override

View file

@ -1,12 +1,13 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.BasalProfile;
import info.nightscout.androidaps.plugins.PumpCombo.spi.BasalProfile;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.RuffyScripter;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
public class SetBasalProfile implements Command {
public SetBasalProfile(BasalProfile basalProfile) {
public class SetBasalProfileCommand implements Command {
public SetBasalProfileCommand(BasalProfile basalProfile) {
}

View file

@ -1,7 +1,9 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import java.util.List;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
public class SetBasalRateProfileCommand extends BaseCommand {
@Override
public CommandResult execute() {

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.scripter.internal.commands;
import android.os.SystemClock;
@ -12,6 +12,8 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import info.nightscout.androidaps.plugins.PumpCombo.spi.CommandResult;
public class SetTbrCommand extends BaseCommand {
private static final Logger log = LoggerFactory.getLogger(SetTbrCommand.class);

View file

@ -0,0 +1,4 @@
package info.nightscout.androidaps.plugins.PumpCombo.spi;
public class BasalProfile {
}

View file

@ -0,0 +1,13 @@
package info.nightscout.androidaps.plugins.PumpCombo.spi;
public interface BolusProgressReporter {
enum State {
PROGRAMMING,
DELIVERING,
DELIVERED,
STOPPING,
STOPPED
}
void report(State state, int percent, double delivered);
}

View file

@ -1,11 +1,9 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter.commands;
package info.nightscout.androidaps.plugins.PumpCombo.spi;
import java.util.Date;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.History;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.PumpState;
public class CommandResult {
public String request;
public boolean success;
public boolean enacted;
public long completionTime;
@ -18,6 +16,11 @@ public class CommandResult {
public CommandResult() {
}
public CommandResult request(String request) {
this.request = request;
return this;
}
public CommandResult success(boolean success) {
this.success = success;
return this;
@ -61,7 +64,8 @@ public class CommandResult {
@Override
public String toString() {
return "CommandResult{" +
"success=" + success +
"request=" + request +
", success=" + success +
", enacted=" + enacted +
", completionTime=" + completionTime + "(" + new Date(completionTime) + ")" +
"' duration=" + duration +

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter;
package info.nightscout.androidaps.plugins.PumpCombo.spi;
/**
* The history data read from "My data"

View file

@ -0,0 +1,4 @@
package info.nightscout.androidaps.plugins.PumpCombo.spi;
public class PumpHistory {
}

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter;
package info.nightscout.androidaps.plugins.PumpCombo.spi;
import java.util.Date;
@ -69,6 +69,14 @@ public class PumpState {
return this;
}
public String getStateSummary() {
if (suspended)
return "Suspended";
else if (errorMsg != null)
return errorMsg;
return "Normal";
}
@Override
public String toString() {
return "PumpState{" +

View file

@ -1,13 +1,12 @@
package info.nightscout.androidaps.plugins.PumpCombo.scripter;
package info.nightscout.androidaps.plugins.PumpCombo.spi;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.CommandResult;
import info.nightscout.androidaps.plugins.PumpCombo.scripter.commands.BolusCommand;
import java.util.Date;
/**
* Main entry point for clients, implemented by RuffyScripter.
*/
public interface RuffyCommands {
CommandResult deliverBolus(double amount, BolusCommand.ProgressReportCallback progressReportCallback);
CommandResult deliverBolus(double amount, BolusProgressReporter bolusProgressReporter);
void cancelBolus();
@ -15,6 +14,10 @@ public interface RuffyCommands {
CommandResult cancelTbr();
boolean isPumpAvailable();
boolean isPumpBusy();
CommandResult readReservoirLevel();
// PumpHistory.fields.*: null=don't care. empty history=we know nothing yet. filled history=this is what we know so far
@ -23,5 +26,7 @@ public interface RuffyCommands {
CommandResult readBasalProfile();
CommandResult setBasalProfile(BasalProfile basalProfile);
CommandResult setDateAndTime(Date date);
}