Misc improvements:
* Make command execution (RuffyScripter/ComoboPlugin.runCommand) more robust (I still suck at threading). * Return all possible states in PumpState * Add absolute TBR to PumpState * Add NoOpCommand to fetch state data from pump * Display returned pump state in Combo fragment/tab.
This commit is contained in:
parent
f251427d1b
commit
8ecf6922f7
|
@ -108,6 +108,7 @@ public class RuffyScripter {
|
|||
private volatile Command activeCmd = null;
|
||||
|
||||
public CommandResult runCommand(final Command cmd) {
|
||||
synchronized (this) {
|
||||
try {
|
||||
if (isPumpBusy()) {
|
||||
return new CommandResult().message("Pump is busy");
|
||||
|
@ -117,8 +118,6 @@ public class RuffyScripter {
|
|||
// TODO reuse thread, scheduler ...
|
||||
Thread cmdThread;
|
||||
|
||||
// TODO make this a safe lock
|
||||
synchronized (this) {
|
||||
cmdResult = null;
|
||||
activeCmd = cmd;
|
||||
// wait till pump is ready for input
|
||||
|
@ -126,7 +125,8 @@ public class RuffyScripter {
|
|||
// check if pump is an an error state
|
||||
if (currentMenu != null && currentMenu.getType() == MenuType.WARNING_OR_ERROR) {
|
||||
try {
|
||||
return new CommandResult().message("Pump is in an error state: " + currentMenu.getAttribute(MenuAttribute.MESSAGE));
|
||||
PumpState pumpState = readPumpState();
|
||||
return new CommandResult().message("Pump is in an error state: " + currentMenu.getAttribute(MenuAttribute.MESSAGE)).state(pumpState);
|
||||
} catch (Exception e) {
|
||||
return new CommandResult().message("Pump is in an error state, reading the error state resulted in the attached exception").exception(e);
|
||||
}
|
||||
|
@ -147,7 +147,6 @@ public class RuffyScripter {
|
|||
}
|
||||
});
|
||||
cmdThread.start();
|
||||
}
|
||||
|
||||
// TODO really?
|
||||
long timeout = System.currentTimeMillis() + 90 * 1000;
|
||||
|
@ -158,7 +157,6 @@ public class RuffyScripter {
|
|||
log.error("Running command " + activeCmd + " timed out");
|
||||
cmdThread.interrupt();
|
||||
activeCmd = null;
|
||||
cmdResult = null;
|
||||
return new CommandResult().success(false).enacted(false).message("Command timed out");
|
||||
}
|
||||
}
|
||||
|
@ -167,13 +165,14 @@ public class RuffyScripter {
|
|||
cmdResult.state = readPumpState();
|
||||
}
|
||||
log.debug("Command result: " + cmdResult);
|
||||
CommandResult r = cmdResult;
|
||||
cmdResult = null;
|
||||
return r;
|
||||
return cmdResult;
|
||||
} catch (CommandException e) {
|
||||
return e.toCommandResult();
|
||||
} catch (Exception e) {
|
||||
return new CommandResult().exception(e).message("Unexpected exception communication with ruffy");
|
||||
} finally {
|
||||
activeCmd = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -288,7 +287,7 @@ public class RuffyScripter {
|
|||
if (System.currentTimeMillis() > timeout) {
|
||||
throw new CommandException().message("Timeout waiting for menu " + menuType + " to be left");
|
||||
}
|
||||
SystemClock.sleep(50);
|
||||
SystemClock.sleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,16 +311,31 @@ public class RuffyScripter {
|
|||
}
|
||||
|
||||
private PumpState readPumpState() {
|
||||
verifyMenuIsDisplayed(MenuType.MAIN_MENU);
|
||||
PumpState state = new PumpState();
|
||||
Double tbrPercentage = (Double) currentMenu.getAttribute(MenuAttribute.TBR);
|
||||
Menu menu = this.currentMenu;
|
||||
MenuType menuType = menu.getType();
|
||||
if (menuType == MenuType.MAIN_MENU) {
|
||||
Double tbrPercentage = (Double) menu.getAttribute(MenuAttribute.TBR);
|
||||
if (tbrPercentage != 100) {
|
||||
state.tbrActive = true;
|
||||
Double displayedTbr = (Double) currentMenu.getAttribute(MenuAttribute.TBR);
|
||||
Double displayedTbr = (Double) menu.getAttribute(MenuAttribute.TBR);
|
||||
state.tbrPercent = displayedTbr.intValue();
|
||||
MenuTime durationMenuTime = ((MenuTime) currentMenu.getAttribute(MenuAttribute.RUNTIME));
|
||||
MenuTime durationMenuTime = ((MenuTime) menu.getAttribute(MenuAttribute.RUNTIME));
|
||||
state.tbrRemainingDuration = durationMenuTime.getHour() * 60 + durationMenuTime.getMinute();
|
||||
state.tbrRate = ((double) currentMenu.getAttribute(MenuAttribute.BASAL_RATE));
|
||||
state.tbrRate = ((double) menu.getAttribute(MenuAttribute.BASAL_RATE));
|
||||
}
|
||||
} else if (menuType == MenuType.WARNING_OR_ERROR) {
|
||||
state.isErrorOrWarning = true;
|
||||
state.errorMsg = (String) menu.getAttribute(MenuAttribute.MESSAGE);
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (MenuAttribute menuAttribute : menu.attributes()) {
|
||||
sb.append(menuAttribute);
|
||||
sb.append(": ");
|
||||
sb.append(menu.getAttribute(menuAttribute));
|
||||
sb.append("\n");
|
||||
}
|
||||
state.errorMsg = "Pump is on menu " + menuType + ", listing attributes: \n" + sb.toString();
|
||||
}
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,15 @@
|
|||
package de.jotomo.ruffyscripter.commands;
|
||||
|
||||
public class NoOpCommand {
|
||||
import de.jotomo.ruffyscripter.RuffyScripter;
|
||||
|
||||
public class NoOpCommand implements Command {
|
||||
@Override
|
||||
public CommandResult execute(RuffyScripter ruffyScripter) {
|
||||
return new CommandResult().success(true).enacted(false).message("Returning pump state only");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "NoOpCommand{}";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ public class PumpState {
|
|||
public Date timestamp = new Date();
|
||||
public boolean tbrActive = false;
|
||||
public int tbrPercent = -1;
|
||||
public double tbrRate = -1;
|
||||
public int tbrRemainingDuration = -1;
|
||||
public boolean isErrorOrWarning = false;
|
||||
public String errorMsg;
|
||||
|
@ -23,6 +24,11 @@ public class PumpState {
|
|||
return this;
|
||||
}
|
||||
|
||||
public PumpState tbrRate(double tbrRate) {
|
||||
this.tbrRate = tbrRate;
|
||||
return this;
|
||||
}
|
||||
|
||||
public PumpState tbrRemainingDuration(int tbrRemainingDuration) {
|
||||
this.tbrRemainingDuration = tbrRemainingDuration;
|
||||
return this;
|
||||
|
@ -43,6 +49,7 @@ public class PumpState {
|
|||
return "PumpState{" +
|
||||
"tbrActive=" + tbrActive +
|
||||
", tbrPercent=" + tbrPercent +
|
||||
", tbrRate=" + tbrRate +
|
||||
", tbrRemainingDuration=" + tbrRemainingDuration +
|
||||
", isErrorOrWarning=" + isErrorOrWarning +
|
||||
", errorMsg=" + errorMsg +
|
||||
|
|
|
@ -9,6 +9,7 @@ import android.support.v4.app.Fragment;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.squareup.otto.Subscribe;
|
||||
|
@ -33,11 +34,15 @@ public class ComboFragment extends Fragment {
|
|||
return comboPlugin;
|
||||
}
|
||||
|
||||
private EditText statusText;
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(R.layout.combopump_fragment, container, false);
|
||||
|
||||
statusText = (EditText) view.findViewById(R.id.comboStatusEditText);
|
||||
|
||||
updateGUI();
|
||||
return view;
|
||||
}
|
||||
|
@ -65,9 +70,17 @@ public class ComboFragment extends Fragment {
|
|||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
// your rendering code here
|
||||
|
||||
if (getPlugin() == null) {
|
||||
statusText.setText("Initializing");
|
||||
} else {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(getPlugin().statusSummary);
|
||||
if (getPlugin().pumpState != null) {
|
||||
sb.append("\n\n");
|
||||
sb.append(getPlugin().pumpState.toString().replaceAll(",", "\n"));
|
||||
}
|
||||
statusText.setText(sb.toString());
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ import de.jotomo.ruffyscripter.commands.BolusCommand;
|
|||
import de.jotomo.ruffyscripter.commands.CancelTbrCommand;
|
||||
import de.jotomo.ruffyscripter.commands.Command;
|
||||
import de.jotomo.ruffyscripter.commands.CommandResult;
|
||||
import de.jotomo.ruffyscripter.commands.ReadStateCommand;
|
||||
import de.jotomo.ruffyscripter.commands.NoOpCommand;
|
||||
import de.jotomo.ruffyscripter.commands.SetTbrCommand;
|
||||
import de.jotomo.ruffyscripter.commands.PumpState;
|
||||
import info.nightscout.androidaps.BuildConfig;
|
||||
|
@ -36,11 +36,11 @@ import info.nightscout.androidaps.data.PumpEnactResult;
|
|||
import info.nightscout.androidaps.db.Source;
|
||||
import info.nightscout.androidaps.db.TemporaryBasal;
|
||||
import info.nightscout.androidaps.events.EventAppExit;
|
||||
import info.nightscout.androidaps.events.EventPumpStatusChanged;
|
||||
import info.nightscout.androidaps.interfaces.PluginBase;
|
||||
import info.nightscout.androidaps.interfaces.PumpDescription;
|
||||
import info.nightscout.androidaps.interfaces.PumpInterface;
|
||||
import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin;
|
||||
import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI;
|
||||
import info.nightscout.utils.DateUtil;
|
||||
|
||||
/**
|
||||
|
@ -59,7 +59,9 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
private ServiceConnection mRuffyServiceConnection;
|
||||
|
||||
@Nullable
|
||||
private volatile PumpState pumpState;
|
||||
volatile PumpState pumpState;
|
||||
|
||||
volatile String statusSummary = "Initializing";
|
||||
|
||||
private static PumpEnactResult OPERATION_NOT_SUPPORTED = new PumpEnactResult();
|
||||
|
||||
|
@ -96,6 +98,12 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||
ruffyScripter = new RuffyScripter(IRuffyService.Stub.asInterface(service));
|
||||
log.debug("ruffy serivce connected");
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runCommand(new NoOpCommand());
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -299,10 +307,14 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
}
|
||||
|
||||
private CommandResult runCommand(Command command) {
|
||||
synchronized (this) {
|
||||
// TODO use this to dispatch methods to a service thread, like DanaRs executionService
|
||||
// will be required when doing multiple commands in sequence.
|
||||
// Alternatively provide 'composite commands' to return everything needed in one go?
|
||||
try {
|
||||
statusSummary = "Busy running " + command;
|
||||
pumpState = null;
|
||||
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||
CommandResult commandResult = ruffyScripter.runCommand(command);
|
||||
if (commandResult.success && commandResult.state != null) {
|
||||
pumpState = commandResult.state;
|
||||
|
@ -310,7 +322,12 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
return commandResult;
|
||||
} finally {
|
||||
lastCmdTime = new Date();
|
||||
statusSummary = pumpState != null && !pumpState.isErrorOrWarning
|
||||
? "Idle"
|
||||
: "Error: " + pumpState.errorMsg;
|
||||
ruffyScripter.disconnect();
|
||||
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -358,7 +375,6 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
log.debug("Rounded requested percentage from " + percent + " to " + rounded);
|
||||
percent = rounded;
|
||||
}
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.settingtempbasal)));
|
||||
CommandResult commandResult = runCommand(new SetTbrCommand(percent, durationInMinutes));
|
||||
if (commandResult.enacted) {
|
||||
TemporaryBasal tempStart = new TemporaryBasal(System.currentTimeMillis());
|
||||
|
@ -387,10 +403,10 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
return OPERATION_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
// TODO untested, probably not working
|
||||
@Override
|
||||
public PumpEnactResult cancelTempBasal() {
|
||||
log.debug("cancelTempBasal called");
|
||||
MainApp.bus().post(new EventPumpStatusChanged(MainApp.sResources.getString(R.string.stoppingtempbasal)));
|
||||
CommandResult commandResult = runCommand(new CancelTbrCommand());
|
||||
if (commandResult.enacted) {
|
||||
TemporaryBasal tempStop = new TemporaryBasal(System.currentTimeMillis());
|
||||
|
@ -422,13 +438,20 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
JSONObject status = new JSONObject();
|
||||
JSONObject extended = new JSONObject();
|
||||
try {
|
||||
status.put("status", "normal");
|
||||
status.put("status", statusSummary);
|
||||
extended.put("Version", BuildConfig.VERSION_NAME + "-" + BuildConfig.BUILDVERSION);
|
||||
try {
|
||||
extended.put("ActiveProfile", MainApp.getConfigBuilder().getProfileName());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
status.put("timestamp", DateUtil.toISOString(new Date()));
|
||||
status.put("timestamp", lastCmdTime);
|
||||
|
||||
if (pumpState != null) {
|
||||
extended.put("TempBasalAbsoluteRate", pumpState.tbrRate);
|
||||
// TODO best guess at this point ...
|
||||
extended.put("TempBasalStart", DateUtil.dateAndTimeString(System.currentTimeMillis() - (pumpState.tbrRemainingDuration - 15 * 60 * 1000)));
|
||||
extended.put("TempBasalRemaining", pumpState.tbrRemainingDuration);
|
||||
}
|
||||
|
||||
// more info here .... look at dana plugin
|
||||
|
||||
|
@ -454,7 +477,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
|||
|
||||
@Override
|
||||
public String shortStatus(boolean veryShort) {
|
||||
return deviceID();
|
||||
return statusSummary;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,4 +17,12 @@
|
|||
|
||||
</ScrollView>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/comboStatusEditText"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:ems="10"
|
||||
android:textAlignment="center"
|
||||
android:layout_gravity="center_horizontal"/>
|
||||
|
||||
</FrameLayout>
|
||||
|
|
Loading…
Reference in a new issue