Support pump suspend status (and misc other ...).

This commit is contained in:
Johannes Mockenhaupt 2017-10-19 19:08:48 +02:00
parent 523de96c8c
commit c29b4d13a3
No known key found for this signature in database
GPG key ID: 9E1EA6AF7BBBB0D1
21 changed files with 541 additions and 557 deletions

View file

@ -1,5 +1,7 @@
package info.nightscout.androidaps.interfaces; package info.nightscout.androidaps.interfaces;
import android.support.annotation.NonNull;
import org.json.JSONObject; import org.json.JSONObject;
import java.util.Date; import java.util.Date;
@ -24,6 +26,7 @@ public interface PumpInterface {
int setNewBasalProfile(Profile profile); int setNewBasalProfile(Profile profile);
boolean isThisProfileSet(Profile profile); boolean isThisProfileSet(Profile profile);
@NonNull
Date lastDataTime(); Date lastDataTime();
void refreshDataFromPump(String reason); void refreshDataFromPump(String reason);

View file

@ -189,7 +189,7 @@ public class ActionsFragment extends SubscriberFragment implements View.OnClickL
@Override @Override
public void onClick(View view) { public void onClick(View view) {
FragmentManager manager = getFragmentManager(); FragmentManager manager = getChildFragmentManager();
final PumpInterface pump = MainApp.getConfigBuilder(); final PumpInterface pump = MainApp.getConfigBuilder();
switch (view.getId()) { switch (view.getId()) {
case R.id.actions_profileswitch: case R.id.actions_profileswitch:

View file

@ -4,7 +4,7 @@ package info.nightscout.androidaps.plugins.PumpCombo;
import android.app.Activity; import android.app.Activity;
import android.graphics.Color; import android.graphics.Color;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment; import android.os.SystemClock;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
@ -16,87 +16,67 @@ import com.squareup.otto.Subscribe;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.Date;
import de.jotomo.ruffy.spi.CommandResult; import de.jotomo.ruffy.spi.CommandResult;
import de.jotomo.ruffy.spi.PumpState; import de.jotomo.ruffy.spi.PumpState;
import de.jotomo.ruffy.spi.history.Bolus;
import info.nightscout.androidaps.MainApp; import info.nightscout.androidaps.MainApp;
import info.nightscout.androidaps.R; import info.nightscout.androidaps.R;
import info.nightscout.androidaps.db.TemporaryBasal;
import info.nightscout.androidaps.plugins.Common.SubscriberFragment;
import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI; import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI;
import info.nightscout.utils.DateUtil;
import info.nightscout.utils.DecimalFormatter;
public class ComboFragment extends Fragment implements View.OnClickListener { public class ComboFragment extends SubscriberFragment implements View.OnClickListener {
private static Logger log = LoggerFactory.getLogger(ComboFragment.class); private static Logger log = LoggerFactory.getLogger(ComboFragment.class);
// TODO rename to sync, shall sync everything, purge an ongoing alert and raise an AAPS notification for it private TextView statusView;
private TextView batteryView;
private TextView reservoirView;
private TextView lastConnectionView;
private TextView lastBolusView;
private TextView basaBasalRateView;
private TextView tempBasalText;
private Button refresh; private Button refresh;
// TODO create tabs: Status/Overview (like Dana), Errors, Stats (TDD)
// boluses, tbrs, refills, battery change ... all covered already by Treatments, CP,
// boluses & tbrs are synced from pump;
// profile: will also be viewable already, no need to duplicate;
private TextView statusText;
private TextView tbrPercentageText;
private TextView tbrDurationText;
private TextView tbrRateText;
private TextView pumpErrorText;
private TextView lastCmdText;
private TextView lastCmdTimeText;
private TextView lastCmdResultText;
private TextView lastCmdDurationText;
private TextView pumpstateBatteryText;
private TextView insulinstateText;
@Override @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) { Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.combopump_fragment, container, false); View view = inflater.inflate(R.layout.combopump_fragment, container, false);
statusView = (TextView) view.findViewById(R.id.combo_status);
batteryView = (TextView) view.findViewById(R.id.combo_pumpstate_battery);
reservoirView = (TextView) view.findViewById(R.id.combo_insulinstate);
lastConnectionView = (TextView) view.findViewById(R.id.combo_lastconnection);
lastBolusView = (TextView) view.findViewById(R.id.combo_lastbolus);
basaBasalRateView = (TextView) view.findViewById(R.id.combo_basabasalrate);
tempBasalText = (TextView) view.findViewById(R.id.combo_temp_basal);
refresh = (Button) view.findViewById(R.id.combo_refresh); refresh = (Button) view.findViewById(R.id.combo_refresh);
statusText = (TextView) view.findViewById(R.id.combo_status);
tbrPercentageText = (TextView) view.findViewById(R.id.combo_tbr_percentage);
tbrDurationText = (TextView) view.findViewById(R.id.combo_tbr_duration);
tbrRateText = (TextView) view.findViewById(R.id.combo_tbr_rate);
pumpErrorText = (TextView) view.findViewById(R.id.combo_pump_error);
lastCmdText = (TextView) view.findViewById(R.id.combo_last_command);
lastCmdTimeText = (TextView) view.findViewById(R.id.combo_last_command_time);
lastCmdResultText = (TextView) view.findViewById(R.id.combo_last_command_result);
lastCmdDurationText = (TextView) view.findViewById(R.id.combo_last_command_duration);
pumpstateBatteryText = (TextView) view.findViewById(R.id.combo_pumpstate_battery);
insulinstateText = (TextView) view.findViewById(R.id.combo_insulinstate);
refresh.setOnClickListener(this); refresh.setOnClickListener(this);
updateGUI(); updateGUI();
return view; return view;
} }
@Override
public void onPause() {
super.onPause();
MainApp.bus().unregister(this);
}
@Override
public void onResume() {
super.onResume();
MainApp.bus().register(this);
updateGUI();
}
@Subscribe
public void onStatusEvent(final EventComboPumpUpdateGUI ev) {
updateGUI();
}
@Override @Override
public void onClick(View view) { public void onClick(View view) {
switch (view.getId()) { switch (view.getId()) {
case R.id.combo_refresh: case R.id.combo_refresh:
/* Activity activity = getActivity();
if (activity != null) {
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
statusView.setText("Refreshing");
}
});
}*/
Thread thread = new Thread(new Runnable() { Thread thread = new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
@ -108,6 +88,22 @@ public class ComboFragment extends Fragment implements View.OnClickListener {
} }
} }
@Subscribe
public void onStatusEvent(final EventComboPumpUpdateGUI ev) {
if (ev.status != null) {
Activity activity = getActivity();
if (activity != null)
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
statusView.setText(ev.status);
}
});
} else {
updateGUI();
}
}
public void updateGUI() { public void updateGUI() {
Activity activity = getActivity(); Activity activity = getActivity();
if (activity != null) if (activity != null)
@ -115,63 +111,108 @@ public class ComboFragment extends Fragment implements View.OnClickListener {
@Override @Override
public void run() { public void run() {
ComboPlugin plugin = ComboPlugin.getPlugin(); ComboPlugin plugin = ComboPlugin.getPlugin();
if (plugin.getPump().lastCmdResult != null) if (plugin.getPump().lastCmdResult == null) {
statusText.setText(plugin.getPump().state.getStateSummary()); statusView.setText("Initializing");
} else {
statusView.setText(plugin.getPump().state.getStateSummary());
}
if (plugin.getPump().state.errorMsg != null) {
statusView.setTextColor(Color.RED);
} else {
statusView.setTextColor(Color.WHITE);
}
// ???
if (plugin.isInitialized()) { if (plugin.isInitialized()) {
PumpState ps = plugin.getPump().state; PumpState ps = plugin.getPump().state;
if (ps != null) { if (ps != null) {
boolean tbrActive = ps.tbrPercent != -1 && ps.tbrPercent != 100; boolean tbrActive = ps.tbrPercent != -1 && ps.tbrPercent != 100;
if (tbrActive) { if (tbrActive) {
tbrPercentageText.setText("" + ps.tbrPercent + "%"); // tbrPercentageText.setText("" + ps.tbrPercent + "%");
tbrDurationText.setText("" + ps.tbrRemainingDuration + " min"); // tbrDurationText.setText("" + ps.tbrRemainingDuration + " min");
tbrRateText.setText("" + ps.tbrRate + " U/h"); // tbrRateText.setText("" + ps.tbrRate + " U/h");
} else { } else {
tbrPercentageText.setText("Default basal rate running"); // tbrPercentageText.setText("Default basal rate running");
tbrDurationText.setText(""); // tbrDurationText.setText("");
tbrRateText.setText(""); // tbrRateText.setText("");
} }
pumpErrorText.setText(ps.errorMsg != null ? ps.errorMsg : ""); // pumpErrorText.setText(ps.errorMsg != null ? ps.errorMsg : "");
if(ps.batteryState == PumpState.EMPTY){ if (ps.batteryState == PumpState.EMPTY) {
pumpstateBatteryText.setText("{fa-battery-empty}"); batteryView.setText("{fa-battery-empty}");
pumpstateBatteryText.setTextColor(Color.RED); batteryView.setTextColor(Color.RED);
} else if(ps.batteryState == PumpState.LOW){ } else if (ps.batteryState == PumpState.LOW) {
pumpstateBatteryText.setText("{fa-battery-quarter}"); batteryView.setText("{fa-battery-quarter}");
pumpstateBatteryText.setTextColor(Color.YELLOW); batteryView.setTextColor(Color.YELLOW);
} else { } else {
pumpstateBatteryText.setText("{fa-battery-full}"); batteryView.setText("{fa-battery-full}");
pumpstateBatteryText.setTextColor(Color.WHITE); batteryView.setTextColor(Color.WHITE);
} }
switch (ps.insulinState){ switch (ps.insulinState) {
case 0: insulinstateText.setText("ok"); case 0:
insulinstateText.setTextColor(Color.WHITE); reservoirView.setText("ok");
break; break;
case 1: insulinstateText.setText("low"); case 1:
insulinstateText.setTextColor(Color.YELLOW); reservoirView.setText("low");
break; break;
case 2: insulinstateText.setText("empty"); case 2:
insulinstateText.setTextColor(Color.RED); reservoirView.setText("empty");
break; break;
} }
int reservoirLevel = plugin.getPump().history.reservoirLevel; int reservoirLevel = plugin.getPump().history.reservoirLevel;
insulinstateText.setText(reservoirLevel == - 1 ? "" : "" + reservoirLevel + " U"); reservoirView.setText(reservoirLevel == -1 ? "" : "" + reservoirLevel + " U");
} }
if (plugin.getPump().lastCmdResult != null) {
CommandResult lastCmdResult = plugin.getPump().lastCmdResult;
lastConnectionView.setText(
"4 m ago (18:58)"
// new Date(lastCmdResult.completionTime).toLocaleString()
);
}
plugin.getPump().history.bolusHistory.add(new Bolus(System.currentTimeMillis() - 7 * 60 * 1000, 12.8d));
if (!plugin.getPump().history.bolusHistory.isEmpty()) {
Bolus bolus = plugin.getPump().history.bolusHistory.get(0);
// double agoHours = agoMsec / 60d / 60d / 1000d;
// if (agoHours < 6) // max 6h back
if (bolus.timestamp + 6 * 60 * 60 * 1000 < System.currentTimeMillis()) {
lastBolusView.setText("");
} else {
// TODO only if !SMB; also: bolus history: should only be used to sync to DB;
// remember that datum someplace else?
long agoMsc = System.currentTimeMillis() - bolus.timestamp;
double agoHours = agoMsc / 60d / 60d / 1000d;
lastBolusView.setText(DateUtil.timeString(bolus.timestamp) +
" (" + DecimalFormatter.to1Decimal(agoHours) + " " + MainApp.sResources.getString(R.string.hoursago) + ") " +
DecimalFormatter.to2Decimal(bolus.amount) + " U");
lastBolusView.setText("12.80 U (15 m ago, 19:04)"); // (19:04)");
}
}
basaBasalRateView.setText(DecimalFormatter.to2Decimal(plugin.getBaseBasalRate()) + " U/h");
TemporaryBasal temporaryBasal = new TemporaryBasal(System.currentTimeMillis());
temporaryBasal.percentRate = 420;
temporaryBasal.durationInMinutes = 20;
tempBasalText.setText(temporaryBasal.toStringFull());
tempBasalText.setText("420% 5/20' (18:45)");
CommandResult lastCmdResult1 = plugin.getPump().lastCmdResult; CommandResult lastCmdResult1 = plugin.getPump().lastCmdResult;
String lastCmd = lastCmdResult1.request; String lastCmd = lastCmdResult1.request;
if (lastCmd != null) { if (lastCmd != null) {
lastCmdText.setText(lastCmd); // lastCmdText.setText(lastCmd);
lastCmdTimeText.setText(plugin.getPump().lastCmdTime.toLocaleString()); // lastCmdTimeText.setText(plugin.getPump().lastCmdTime.toLocaleString());
} else { } else {
lastCmdText.setText(""); // lastCmdText.setText("");
lastCmdTimeText.setText(""); // lastCmdTimeText.setText("");
} }
if (lastCmdResult1.message != null) { if (lastCmdResult1.message != null) {
lastCmdResultText.setText(lastCmdResult1.message); // lastCmdResultText.setText(lastCmdResult1.message);
lastCmdDurationText.setText(lastCmdResult1.duration); // lastCmdDurationText.setText(lastCmdResult1.duration);
} else { } else {
lastCmdResultText.setText(""); // lastCmdResultText.setText("");
lastCmdDurationText.setText(""); // lastCmdDurationText.setText("");
} }
} }
} }

View file

@ -15,7 +15,12 @@ import org.slf4j.LoggerFactory;
import java.util.Date; import java.util.Date;
import de.jotomo.ruffy.spi.BolusProgressReporter;
import de.jotomo.ruffy.spi.CommandResult;
import de.jotomo.ruffy.spi.PumpState;
import de.jotomo.ruffy.spi.RuffyCommands;
import de.jotomo.ruffy.spi.history.PumpHistoryRequest; import de.jotomo.ruffy.spi.history.PumpHistoryRequest;
import de.jotomo.ruffyscripter.RuffyCommandsV1Impl;
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;
@ -30,11 +35,6 @@ 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 de.jotomo.ruffyscripter.RuffyCommandsV1Impl;
import de.jotomo.ruffy.spi.BolusProgressReporter;
import de.jotomo.ruffy.spi.CommandResult;
import de.jotomo.ruffy.spi.PumpState;
import de.jotomo.ruffy.spi.RuffyCommands;
import info.nightscout.utils.DateUtil; import info.nightscout.utils.DateUtil;
import info.nightscout.utils.SP; import info.nightscout.utils.SP;
@ -226,19 +226,17 @@ public class ComboPlugin implements PluginBase, PumpInterface {
@Override @Override
public boolean isInitialized() { public boolean isInitialized() {
// consider initialized when the pump's state was initially fetched, return pump.lastCmdResult != null;
// after that lastCmd* variables will have values
return pump.lastCmdTime.getTime() > 0;
} }
@Override @Override
public boolean isSuspended() { public boolean isSuspended() {
return pump.state != null && pump.state.suspended; return pump.state.suspended;
} }
@Override @Override
public boolean isBusy() { public boolean isBusy() {
return ruffyScripter.isPumpBusy(); return ruffyScripter.isPumpBusy() && !pump.state.suspended;
} }
// TODO // TODO
@ -255,7 +253,8 @@ public class ComboPlugin implements PluginBase, PumpInterface {
@Override @Override
public Date lastDataTime() { public Date lastDataTime() {
return pump.lastCmdTime; CommandResult lastCmdResult = pump.lastCmdResult;
return lastCmdResult != null ? new Date(lastCmdResult.completionTime) : new Date(0);
} }
// this method is regularly called from info.nightscout.androidaps.receivers.KeepAliveReceiver // this method is regularly called from info.nightscout.androidaps.receivers.KeepAliveReceiver
@ -271,18 +270,19 @@ public class ComboPlugin implements PluginBase, PumpInterface {
return; return;
} }
// TODO
boolean notAUserRequest = !reason.toLowerCase().contains("user"); boolean notAUserRequest = !reason.toLowerCase().contains("user");
boolean wasRunAtLeastOnce = pump.lastCmdTime.getTime() > 0; boolean wasRunAtLeastOnce = pump.lastCmdResult != null;
boolean ranWithinTheLastMinute = System.currentTimeMillis() < pump.lastCmdTime.getTime() + 60 * 1000; boolean ranWithinTheLastMinute = wasRunAtLeastOnce && System.currentTimeMillis() < pump.lastCmdResult.completionTime + 60 * 1000;
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 {
CommandResult commandResult = ruffyScripter.readPumpState(); runCommand("Refreshing", new CommandExecution() {
pump.lastCmdResult = commandResult; @Override
pump.lastCmdTime = new Date(commandResult.completionTime); public CommandResult execute() {
CommandResult reservoirQueryResult = ruffyScripter.readHistory(new PumpHistoryRequest().reservoirLevel(true)); return ruffyScripter.readHistory(new PumpHistoryRequest().reservoirLevel(true));
pump.history = reservoirQueryResult.history; }
MainApp.bus().post(new EventComboPumpUpdateGUI()); });
} }
} }
@ -299,32 +299,34 @@ public class ComboPlugin implements PluginBase, PumpInterface {
// TODO remove dep on BolusCommand // TODO remove dep on BolusCommand
private static BolusProgressReporter bolusProgressReporter = private static BolusProgressReporter bolusProgressReporter =
new BolusProgressReporter() { new BolusProgressReporter() {
@Override @Override
public void report(BolusProgressReporter.State state, int percent, double delivered) { public void report(BolusProgressReporter.State state, int percent, double delivered) {
EventOverviewBolusProgress event = EventOverviewBolusProgress.getInstance(); EventOverviewBolusProgress event = EventOverviewBolusProgress.getInstance();
switch (state) { switch (state) {
case PROGRAMMING: case PROGRAMMING:
event.status = MainApp.sResources.getString(R.string.bolusprogramming); event.status = MainApp.sResources.getString(R.string.bolusprogramming);
break; break;
case DELIVERING: case DELIVERING:
event.status = String.format(MainApp.sResources.getString(R.string.bolusdelivering), delivered); event.status = String.format(MainApp.sResources.getString(R.string.bolusdelivering), delivered);
break; break;
case DELIVERED: case DELIVERED:
event.status = String.format(MainApp.sResources.getString(R.string.bolusdelivered), delivered); event.status = String.format(MainApp.sResources.getString(R.string.bolusdelivered), delivered);
break; break;
case STOPPING: case STOPPING:
event.status = MainApp.sResources.getString(R.string.bolusstopping); event.status = MainApp.sResources.getString(R.string.bolusstopping);
break; break;
case STOPPED: case STOPPED:
event.status = MainApp.sResources.getString(R.string.bolusstopped); event.status = MainApp.sResources.getString(R.string.bolusstopped);
break; break;
} }
event.percent = percent; event.percent = percent;
MainApp.bus().post(event); MainApp.bus().post(event);
} }
}; };
/** Updates Treatment records with carbs and boluses and delivers a bolus if needed */ /**
* Updates Treatment records with carbs and boluses and delivers a bolus if needed
*/
@Override @Override
public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) { public PumpEnactResult deliverTreatment(DetailedBolusInfo detailedBolusInfo) {
try { try {
@ -369,11 +371,13 @@ public class ComboPlugin implements PluginBase, PumpInterface {
} }
@NonNull @NonNull
private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) { private PumpEnactResult deliverBolus(final DetailedBolusInfo detailedBolusInfo) {
CommandResult bolusCmdResult = ruffyScripter.deliverBolus(detailedBolusInfo.insulin, bolusProgressReporter); CommandResult bolusCmdResult = runCommand("Bolusing", new CommandExecution() {
pump.lastCmdResult = bolusCmdResult; @Override
pump.lastCmdTime = new Date(bolusCmdResult.completionTime); public CommandResult execute() {
MainApp.bus().post(new EventComboPumpUpdateGUI()); return ruffyScripter.deliverBolus(detailedBolusInfo.insulin, bolusProgressReporter);
}
});
PumpEnactResult pumpEnactResult = new PumpEnactResult(); PumpEnactResult pumpEnactResult = new PumpEnactResult();
pumpEnactResult.success = bolusCmdResult.success; pumpEnactResult.success = bolusCmdResult.success;
@ -422,7 +426,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
// Note: AAPS calls this only for setting a temp basal issued by the user // Note: AAPS calls this only for setting a temp basal issued by the user
@Override @Override
public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes) { public PumpEnactResult setTempBasalPercent(Integer percent, final Integer durationInMinutes) {
log.debug("setTempBasalPercent called with " + percent + "% for " + durationInMinutes + "min"); log.debug("setTempBasalPercent called with " + percent + "% for " + durationInMinutes + "min");
int adjustedPercent = percent; int adjustedPercent = percent;
@ -438,10 +442,14 @@ public class ComboPlugin implements PluginBase, PumpInterface {
adjustedPercent = rounded.intValue(); adjustedPercent = rounded.intValue();
} }
CommandResult commandResult = ruffyScripter.setTbr(adjustedPercent, durationInMinutes); final int finalAdjustedPercent = adjustedPercent;
pump.lastCmdResult = commandResult; CommandResult commandResult = runCommand("Setting TBR", new CommandExecution() {
pump.lastCmdTime = new Date(commandResult.completionTime); @Override
MainApp.bus().post(new EventComboPumpUpdateGUI()); public CommandResult execute() {
return ruffyScripter.setTbr(finalAdjustedPercent, durationInMinutes);
}
}
);
if (commandResult.enacted) { if (commandResult.enacted) {
TemporaryBasal tempStart = new TemporaryBasal(commandResult.completionTime); TemporaryBasal tempStart = new TemporaryBasal(commandResult.completionTime);
@ -488,10 +496,12 @@ 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 = ruffyScripter.cancelTbr(); commandResult = runCommand("Cancelling TBR", new CommandExecution() {
pump.lastCmdResult = commandResult; @Override
pump.lastCmdTime = new Date(commandResult.completionTime); public CommandResult execute() {
MainApp.bus().post(new EventComboPumpUpdateGUI()); return ruffyScripter.cancelTbr();
}
});
if (commandResult.enacted) { if (commandResult.enacted) {
tempBasal = new TemporaryBasal(commandResult.completionTime); tempBasal = new TemporaryBasal(commandResult.completionTime);
@ -512,12 +522,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%.
int percentage = (activeTemp.percentRate > 100) ? 110 : 90; final 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 = ruffyScripter.setTbr(percentage, 15); commandResult = runCommand("Setting TBR", new CommandExecution() {
pump.lastCmdResult = commandResult; @Override
pump.lastCmdTime = new Date(commandResult.completionTime); public CommandResult execute() {
MainApp.bus().post(new EventComboPumpUpdateGUI()); return ruffyScripter.setTbr(percentage, 15);
}
});
if (commandResult.enacted) { if (commandResult.enacted) {
tempBasal = new TemporaryBasal(commandResult.completionTime); tempBasal = new TemporaryBasal(commandResult.completionTime);
@ -541,6 +553,23 @@ public class ComboPlugin implements PluginBase, PumpInterface {
return pumpEnactResult; return pumpEnactResult;
} }
interface CommandExecution {
CommandResult execute();
}
private CommandResult runCommand(String status, CommandExecution commandExecution) {
MainApp.bus().post(new EventComboPumpUpdateGUI(status));
// TODO handle running into WARNING_OR_ERROR ... or scripter? purge it
CommandResult commandResult = commandExecution.execute();
pump.lastCmdResult = commandResult;
pump.state = commandResult.state;
// TOOD
if (commandResult.history != null)
pump.history = commandResult.history;
MainApp.bus().post(new EventComboPumpUpdateGUI());
return commandResult;
}
@Override @Override
public PumpEnactResult cancelExtendedBolus() { public PumpEnactResult cancelExtendedBolus() {
return OPERATION_NOT_SUPPORTED; return OPERATION_NOT_SUPPORTED;
@ -550,7 +579,8 @@ 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 (pump.lastCmdTime.getTime() + 5 * 60 * 1000L < System.currentTimeMillis()) { CommandResult lastCmdResult = pump.lastCmdResult;
if (lastCmdResult == null || lastCmdResult.completionTime + 5 * 60 * 1000L < System.currentTimeMillis()) {
return null; return null;
} }
@ -564,7 +594,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
extendedJson.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName()); extendedJson.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName());
} catch (Exception e) { } catch (Exception e) {
} }
statusJson.put("timestamp", pump.lastCmdTime); statusJson.put("timestamp", lastCmdResult.completionTime);
PumpState ps = pump.state; PumpState ps = pump.state;
if (ps != null) { if (ps != null) {
@ -582,7 +612,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
pumpJson.put("status", statusJson); pumpJson.put("status", statusJson);
pumpJson.put("extended", extendedJson); pumpJson.put("extended", extendedJson);
pumpJson.put("clock", DateUtil.toISOString(pump.lastCmdTime)); pumpJson.put("clock", DateUtil.toISOString(lastCmdResult.completionTime));
return pumpJson; return pumpJson;
} catch (Exception e) { } catch (Exception e) {

View file

@ -13,7 +13,7 @@ class ComboPump {
@Nullable @Nullable
volatile CommandResult lastCmdResult; volatile CommandResult lastCmdResult;
@NonNull @NonNull
volatile Date lastCmdTime = new Date(0);
volatile PumpState state = new PumpState(); volatile PumpState state = new PumpState();
@NonNull
volatile PumpHistory history = new PumpHistory(); volatile PumpHistory history = new PumpHistory();
} }

View file

@ -5,4 +5,11 @@ package info.nightscout.androidaps.plugins.PumpCombo.events;
*/ */
public class EventComboPumpUpdateGUI { public class EventComboPumpUpdateGUI {
public EventComboPumpUpdateGUI() {}
public EventComboPumpUpdateGUI(String status) {
this.status = status;
}
public String status;
} }

View file

@ -4,6 +4,10 @@
android:layout_height="match_parent" android:layout_height="match_parent"
tools:context=".plugins.PumpCombo.ComboFragment"> tools:context=".plugins.PumpCombo.ComboFragment">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<ScrollView <ScrollView
android:id="@+id/scrollView" android:id="@+id/scrollView"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -14,12 +18,6 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical"> android:orientation="vertical">
<Button
android:id="@+id/combo_refresh"
style="?android:attr/buttonStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Refresh" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
@ -28,7 +26,7 @@
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="2" android:layout_weight="1.5"
android:gravity="end" android:gravity="end"
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="Status" android:text="Status"
@ -52,7 +50,7 @@
android:gravity="start" android:gravity="start"
android:paddingLeft="5dp" android:paddingLeft="5dp"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:text="Initializing" android:text=""
android:textSize="14sp" /> android:textSize="14sp" />
</LinearLayout> </LinearLayout>
@ -74,369 +72,7 @@
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="2" android:layout_weight="1.5"
android:gravity="end"
android:paddingRight="5dp"
android:text="TBR percentage"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_tbr_percentage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="TBR duration"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_tbr_duration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="TBR rate"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_tbr_rate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="Pump error"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_pump_error"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="Last command"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_last_command"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="Command time"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_last_command_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="Command result"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_last_command_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end"
android:paddingRight="5dp"
android:text="Command duration"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_last_command_duration"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="2"
android:gravity="end" android:gravity="end"
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="Battery" android:text="Battery"
@ -458,7 +94,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textColor="@android:color/white" android:textColor="@android:color/white"
android:textSize="20sp" android:textSize="14sp"
android:paddingLeft="5dp" android:paddingLeft="5dp"
android:gravity="start" android:gravity="start"
android:text="" /> android:text="" />
@ -482,7 +118,7 @@
<TextView <TextView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_weight="2" android:layout_weight="1.5"
android:gravity="end" android:gravity="end"
android:paddingRight="5dp" android:paddingRight="5dp"
android:text="Reservoir" android:text="Reservoir"
@ -519,7 +155,239 @@
android:layout_marginTop="5dp" android:layout_marginTop="5dp"
android:background="@color/listdelimiter" /> android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/pump_lastconnection_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_lastconnection"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/pump_lastbolus_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_lastbolus"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/pump_basebasalrate_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_basabasalrate"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1.5"
android:gravity="end"
android:paddingRight="5dp"
android:text="@string/pump_tempbasal_label"
android:textSize="14sp" />
<TextView
android:layout_width="5dp"
android:layout_height="wrap_content"
android:layout_weight="0"
android:gravity="center_horizontal"
android:paddingEnd="2dp"
android:paddingStart="2dp"
android:text=":"
android:textSize="14sp" />
<TextView
android:id="@+id/combo_temp_basal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="start"
android:paddingLeft="5dp"
android:textColor="@android:color/white"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="fill_parent"
android:layout_height="2dip"
android:layout_marginBottom="5dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginTop="5dp"
android:background="@color/listdelimiter" />
</LinearLayout> </LinearLayout>
</ScrollView> </ScrollView>
<LinearLayout
android:id="@+id/combo_buttons"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/combo_refresh"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableTop="@drawable/icon_actions_refill"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/combo_refresh" />
<Button
android:id="@+id/combo_history"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableTop="@drawable/icon_danarhistory"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/pump_history" />
<Button
android:id="@+id/combo_stats"
style="@style/ButtonSmallFontStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:drawableTop="@drawable/icon_danarstats"
android:paddingLeft="0dp"
android:paddingRight="0dp"
android:text="@string/combo_stats" />
</LinearLayout>
</LinearLayout>
</RelativeLayout>
</FrameLayout> </FrameLayout>

View file

@ -761,5 +761,7 @@
<string name="combo_disable_alarms">Disable alarms</string> <string name="combo_disable_alarms">Disable alarms</string>
<string name="combo_disable_alarms_summary">Ignore all errors encountered while communicating with the pump. Alarms raised by the pump (including those caused by AndroidAPS) will still be raised on the pump.</string> <string name="combo_disable_alarms_summary">Ignore all errors encountered while communicating with the pump. Alarms raised by the pump (including those caused by AndroidAPS) will still be raised on the pump.</string>
<string name="bolusprogramming">Programming pump for bolusing</string> <string name="bolusprogramming">Programming pump for bolusing</string>
<string name="combo_refresh">Refresh</string>
<string name="combo_stats">Stats</string>
</resources> </resources>

View file

@ -81,7 +81,7 @@ public class PumpState {
return "Suspended"; return "Suspended";
else if (errorMsg != null) else if (errorMsg != null)
return errorMsg; return errorMsg;
return "Normal"; return "Running";
} }
@Override @Override

View file

@ -2,19 +2,20 @@ package de.jotomo.ruffy.spi.history;
import android.support.annotation.NonNull; import android.support.annotation.NonNull;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
public class PumpHistory { public class PumpHistory {
public int reservoirLevel = -1; public int reservoirLevel = -1;
@NonNull @NonNull
public List<Bolus> bolusHistory = Collections.emptyList(); public List<Bolus> bolusHistory = new ArrayList<>();
@NonNull @NonNull
public List<Tbr> tbrHistory = Collections.emptyList(); public List<Tbr> tbrHistory = new ArrayList<>();
@NonNull @NonNull
public List<Error> errorHistory = Collections.emptyList(); public List<Error> errorHistory = new ArrayList<>();
@NonNull @NonNull
public List<Tdd> tddHistory = Collections.emptyList(); public List<Tdd> tddHistory = new ArrayList<>();
public PumpHistory reservoirLevel(int reservoirLevel) { public PumpHistory reservoirLevel(int reservoirLevel) {
this.reservoirLevel = reservoirLevel this.reservoirLevel = reservoirLevel

View file

@ -8,6 +8,7 @@ public class PumpHistoryRequest {
Either the timestamp of the last known record to fetch all newer records, Either the timestamp of the last known record to fetch all newer records,
or one of the constants to read no history or all of it. or one of the constants to read no history or all of it.
*/ */
public static final long LAST = -2;
public static final long SKIP = -1; public static final long SKIP = -1;
public static final long FULL = 0; public static final long FULL = 0;

View file

@ -34,7 +34,6 @@ import de.jotomo.ruffyscripter.commands.BolusCommand;
import de.jotomo.ruffyscripter.commands.CancelTbrCommand; import de.jotomo.ruffyscripter.commands.CancelTbrCommand;
import de.jotomo.ruffyscripter.commands.Command; import de.jotomo.ruffyscripter.commands.Command;
import de.jotomo.ruffyscripter.commands.CommandException; import de.jotomo.ruffyscripter.commands.CommandException;
import de.jotomo.ruffyscripter.commands.GetPumpStateCommand;
import de.jotomo.ruffyscripter.commands.ReadBasalProfileCommand; import de.jotomo.ruffyscripter.commands.ReadBasalProfileCommand;
import de.jotomo.ruffyscripter.commands.ReadHistoryCommand; import de.jotomo.ruffyscripter.commands.ReadHistoryCommand;
import de.jotomo.ruffyscripter.commands.ReadPumpStateCommand; import de.jotomo.ruffyscripter.commands.ReadPumpStateCommand;
@ -219,9 +218,9 @@ public class RuffyScripter implements RuffyCommands {
return runCommand(new ReadPumpStateCommand()); return runCommand(new ReadPumpStateCommand());
} }
public void returnToMainMenu() { public void returnToRootMenu() {
// returning to main menu using the 'back' key does not cause a vibration // returning to main menu using the 'back' key does not cause a vibration
while (getCurrentMenu().getType() != MenuType.MAIN_MENU) { while (getCurrentMenu().getType() != MenuType.MAIN_MENU && getCurrentMenu().getType() != MenuType.STOP) {
if (getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) { if (getCurrentMenu().getType() == MenuType.WARNING_OR_ERROR) {
String errorMsg = (String) getCurrentMenu().getAttribute(MenuAttribute.MESSAGE); String errorMsg = (String) getCurrentMenu().getAttribute(MenuAttribute.MESSAGE);
confirmAlert(errorMsg, 1000); confirmAlert(errorMsg, 1000);
@ -293,12 +292,10 @@ public class RuffyScripter implements RuffyCommands {
// level to handle state and logic. // level to handle state and logic.
// For now, when changing cartridges and such: tell AAPS to stop the loop, change cartridge and resume the loop. // For now, when changing cartridges and such: tell AAPS to stop the loop, change cartridge and resume the loop.
if (currentMenu == null || currentMenu.getType() == MenuType.STOP) { if (currentMenu == null || currentMenu.getType() == MenuType.STOP) {
if (cmd instanceof GetPumpStateCommand) { if (cmd.needsRunMode()) {
returnable.cmdResult = new CommandResult().success(true).enacted(false);
} else {
returnable.cmdResult = new CommandResult().success(false).enacted(false).message("Pump is suspended"); returnable.cmdResult = new CommandResult().success(false).enacted(false).message("Pump is suspended");
return;
} }
return;
} }
log.debug("Connection ready to execute cmd " + cmd); log.debug("Connection ready to execute cmd " + cmd);
PumpState pumpState = readPumpStateInternal(); PumpState pumpState = readPumpStateInternal();
@ -718,6 +715,18 @@ public class RuffyScripter implements RuffyCommands {
} }
} }
public void verifyRootMenuIsDisplayed() {
int retries = 600;
while (getCurrentMenu().getType() != MenuType.MAIN_MENU && getCurrentMenu().getType() != MenuType.STOP) {
if (retries > 0) {
SystemClock.sleep(100);
retries = retries - 1;
} else {
throw new CommandException().message("Invalid pump state, expected to be in menu MAIN or STOP but current menu is " + currentMenu.getType());
}
}
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T readBlinkingValue(Class<T> expectedType, MenuAttribute attribute) { public <T> T readBlinkingValue(Class<T> expectedType, MenuAttribute attribute) {
int retries = 5; int retries = 5;

View file

@ -22,4 +22,9 @@ public abstract class BaseCommand implements Command {
public boolean isCancellable() { public boolean isCancellable() {
return canBeCancelled; return canBeCancelled;
} }
@Override
public boolean needsRunMode() {
return false;
}
} }

View file

@ -54,7 +54,7 @@ public class BolusCommand extends BaseCommand {
if (cancelRequested) { if (cancelRequested) {
bolusProgressReporter.report(STOPPING, 0, 0); bolusProgressReporter.report(STOPPING, 0, 0);
scripter.returnToMainMenu(); scripter.returnToRootMenu();
bolusProgressReporter.report(STOPPED, 0, 0); bolusProgressReporter.report(STOPPED, 0, 0);
return new CommandResult().success(true).enacted(false) return new CommandResult().success(true).enacted(false)
.message("Bolus cancelled as per user request with no insulin delivered"); .message("Bolus cancelled as per user request with no insulin delivered");
@ -192,7 +192,7 @@ public class BolusCommand extends BaseCommand {
log.debug("Bolus record in history confirms delivered bolus"); log.debug("Bolus record in history confirms delivered bolus");
// TODO how would this call fail? more generally ...... // TODO how would this call fail? more generally ......
scripter.returnToMainMenu(); scripter.returnToRootMenu();
if (scripter.getCurrentMenu().getType() != MenuType.MAIN_MENU) { if (scripter.getCurrentMenu().getType() != MenuType.MAIN_MENU) {
throw new CommandException().success(false).enacted(true) throw new CommandException().success(false).enacted(true)
.message("Bolus was correctly delivered and checked against history, but we " .message("Bolus was correctly delivered and checked against history, but we "
@ -262,6 +262,11 @@ public class BolusCommand extends BaseCommand {
bolusProgressReporter.report(STOPPING, 0, 0); bolusProgressReporter.report(STOPPING, 0, 0);
} }
@Override
public boolean needsRunMode() {
return true;
}
@Override @Override
public String toString() { public String toString() {
return "BolusCommand{" + return "BolusCommand{" +

View file

@ -57,6 +57,11 @@ public class CancelTbrCommand extends BaseCommand {
} }
} }
@Override
public boolean needsRunMode() {
return true;
}
@Override @Override
public String toString() { public String toString() {
return "CancelTbrCommand{}"; return "CancelTbrCommand{}";

View file

@ -16,4 +16,5 @@ public interface Command {
CommandResult execute(); CommandResult execute();
List<String> validateArguments(); List<String> validateArguments();
void setScripter(RuffyScripter scripter); void setScripter(RuffyScripter scripter);
boolean needsRunMode();
} }

View file

@ -6,7 +6,7 @@ import java.util.List;
import de.jotomo.ruffyscripter.RuffyScripter; import de.jotomo.ruffyscripter.RuffyScripter;
import de.jotomo.ruffy.spi.CommandResult; import de.jotomo.ruffy.spi.CommandResult;
public class ReadBasalProfileCommand implements Command { public class ReadBasalProfileCommand extends BaseCommand {
private final int number; private final int number;
public ReadBasalProfileCommand(int number) { public ReadBasalProfileCommand(int number) {

View file

@ -16,6 +16,7 @@ import de.jotomo.ruffy.spi.history.PumpHistoryRequest;
public class ReadHistoryCommand extends BaseCommand { public class ReadHistoryCommand extends BaseCommand {
private final PumpHistoryRequest request; private final PumpHistoryRequest request;
private final PumpHistory history = new PumpHistory();
public ReadHistoryCommand(PumpHistoryRequest request) { public ReadHistoryCommand(PumpHistoryRequest request) {
this.request = request; this.request = request;
@ -23,11 +24,10 @@ public class ReadHistoryCommand extends BaseCommand {
@Override @Override
public CommandResult execute() { public CommandResult execute() {
PumpHistory history = new PumpHistory(); if (request.reservoirLevel) {
if (request.reservoirLevel) readReservoirLevel();
readReservoirLevel(history); }
if (request.bolusHistory != PumpHistoryRequest.SKIP if (request.bolusHistory != PumpHistoryRequest.SKIP
|| request.bolusHistory != PumpHistoryRequest.SKIP
|| request.tbrHistory != PumpHistoryRequest.SKIP || request.tbrHistory != PumpHistoryRequest.SKIP
|| request.errorHistory != PumpHistoryRequest.SKIP || request.errorHistory != PumpHistoryRequest.SKIP
|| request.tddHistory != PumpHistoryRequest.SKIP) { || request.tddHistory != PumpHistoryRequest.SKIP) {
@ -81,19 +81,20 @@ public class ReadHistoryCommand extends BaseCommand {
// TODO start or end time? // TODO start or end time?
MenuTime time = (MenuTime) scripter.getCurrentMenu().getAttribute(MenuAttribute.TIME); MenuTime time = (MenuTime) scripter.getCurrentMenu().getAttribute(MenuAttribute.TIME);
} }
scripter.returnToMainMenu(); scripter.returnToRootMenu();
} }
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU); scripter.verifyRootMenuIsDisplayed();
return new CommandResult().success(true).enacted(false).history(history); return new CommandResult().success(true).enacted(false).history(history);
} }
private void readReservoirLevel(PumpHistory history) { private void readReservoirLevel() {
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU); scripter.verifyRootMenuIsDisplayed();
scripter.pressCheckKey(); scripter.pressCheckKey();
scripter.waitForMenuToBeLeft(MenuType.MAIN_MENU); scripter.waitForMenuToBeLeft(MenuType.MAIN_MENU);
scripter.waitForMenuToBeLeft(MenuType.STOP);
scripter.verifyMenuIsDisplayed(MenuType.QUICK_INFO); scripter.verifyMenuIsDisplayed(MenuType.QUICK_INFO);
int remainingInsulin = ((Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.REMAINING_INSULIN)).intValue(); int remainingInsulin = ((Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.REMAINING_INSULIN)).intValue();
scripter.returnToMainMenu(); scripter.returnToRootMenu();
history.reservoirLevel = remainingInsulin; history.reservoirLevel = remainingInsulin;
} }

View file

@ -6,10 +6,10 @@ import java.util.List;
import de.jotomo.ruffy.spi.CommandResult; import de.jotomo.ruffy.spi.CommandResult;
import de.jotomo.ruffyscripter.RuffyScripter; import de.jotomo.ruffyscripter.RuffyScripter;
public class ReadPumpStateCommand implements Command { public class ReadPumpStateCommand extends BaseCommand {
@Override @Override
public CommandResult execute() { public CommandResult execute() {
return new CommandResult().success(true).enacted(false); return new CommandResult().success(true).enacted(false).state(scripter.readPumpStateInternal());
} }
@Override @Override

View file

@ -6,7 +6,7 @@ import de.jotomo.ruffy.spi.BasalProfile;
import de.jotomo.ruffyscripter.RuffyScripter; import de.jotomo.ruffyscripter.RuffyScripter;
import de.jotomo.ruffy.spi.CommandResult; import de.jotomo.ruffy.spi.CommandResult;
public class SetBasalProfileCommand implements Command { public class SetBasalProfileCommand extends BaseCommand {
public SetBasalProfileCommand(BasalProfile basalProfile) { public SetBasalProfileCommand(BasalProfile basalProfile) {
} }

View file

@ -267,6 +267,11 @@ public class SetTbrCommand extends BaseCommand {
return scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE).longValue(); return scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE).longValue();
} }
@Override
public boolean needsRunMode() {
return true;
}
@Override @Override
public String toString() { public String toString() {
return "SetTbrCommand{" + return "SetTbrCommand{" +