Fix initializing ruffy service, read reservoir level on init.
This commit is contained in:
parent
31a1811323
commit
dca219d900
9 changed files with 222 additions and 142 deletions
|
@ -147,6 +147,8 @@ public class ComboFragment extends Fragment implements View.OnClickListener {
|
||||||
insulinstateText.setTextColor(Color.RED);
|
insulinstateText.setTextColor(Color.RED);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
int reservoirLevel = plugin.getPump().history.reservoirLevel;
|
||||||
|
insulinstateText.setText(reservoirLevel == - 1 ? "" : "" + reservoirLevel);
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandResult lastCmdResult1 = plugin.getPump().lastCmdResult;
|
CommandResult lastCmdResult1 = plugin.getPump().lastCmdResult;
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
|
import de.jotomo.ruffy.spi.history.PumpHistoryRequest;
|
||||||
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;
|
||||||
|
@ -258,6 +259,8 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
// this method is regularly called from info.nightscout.androidaps.receivers.KeepAliveReceiver
|
// this method is regularly called from info.nightscout.androidaps.receivers.KeepAliveReceiver
|
||||||
|
// TODO check this is eithor called regularly even with other commansd being fired; if not,
|
||||||
|
// request this periodically
|
||||||
@Override
|
@Override
|
||||||
public void refreshDataFromPump(String reason) {
|
public void refreshDataFromPump(String reason) {
|
||||||
log.debug("RefreshDataFromPump called");
|
log.debug("RefreshDataFromPump called");
|
||||||
|
@ -269,12 +272,19 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean notAUserRequest = !reason.toLowerCase().contains("user");
|
boolean notAUserRequest = !reason.toLowerCase().contains("user");
|
||||||
|
if (notAUserRequest) SystemClock.sleep(2000);
|
||||||
boolean wasRunAtLeastOnce = pump.lastCmdTime.getTime() > 0;
|
boolean wasRunAtLeastOnce = pump.lastCmdTime.getTime() > 0;
|
||||||
boolean ranWithinTheLastMinute = System.currentTimeMillis() < pump.lastCmdTime.getTime() + 60 * 1000;
|
boolean ranWithinTheLastMinute = System.currentTimeMillis() < pump.lastCmdTime.getTime() + 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 {
|
||||||
ruffyScripter.readPumpState();
|
CommandResult commandResult = ruffyScripter.readPumpState();
|
||||||
|
pump.lastCmdResult = commandResult;
|
||||||
|
pump.lastCmdTime = new Date(commandResult.completionTime);
|
||||||
|
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||||
|
|
||||||
|
CommandResult reservoirQueryResult = ruffyScripter.readHistory(new PumpHistoryRequest().reservoirLevel(true));
|
||||||
|
pump.history = reservoirQueryResult.history;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,6 +373,10 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
@NonNull
|
@NonNull
|
||||||
private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) {
|
private PumpEnactResult deliverBolus(DetailedBolusInfo detailedBolusInfo) {
|
||||||
CommandResult bolusCmdResult = ruffyScripter.deliverBolus(detailedBolusInfo.insulin, bolusProgressReporter);
|
CommandResult bolusCmdResult = ruffyScripter.deliverBolus(detailedBolusInfo.insulin, bolusProgressReporter);
|
||||||
|
pump.lastCmdResult = bolusCmdResult;
|
||||||
|
pump.lastCmdTime = new Date(bolusCmdResult.completionTime);
|
||||||
|
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||||
|
|
||||||
PumpEnactResult pumpEnactResult = new PumpEnactResult();
|
PumpEnactResult pumpEnactResult = new PumpEnactResult();
|
||||||
pumpEnactResult.success = bolusCmdResult.success;
|
pumpEnactResult.success = bolusCmdResult.success;
|
||||||
pumpEnactResult.enacted = bolusCmdResult.enacted;
|
pumpEnactResult.enacted = bolusCmdResult.enacted;
|
||||||
|
@ -427,6 +441,9 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandResult commandResult = ruffyScripter.setTbr(adjustedPercent, durationInMinutes);
|
CommandResult commandResult = ruffyScripter.setTbr(adjustedPercent, durationInMinutes);
|
||||||
|
pump.lastCmdResult = commandResult;
|
||||||
|
pump.lastCmdTime = new Date(commandResult.completionTime);
|
||||||
|
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||||
|
|
||||||
if (commandResult.enacted) {
|
if (commandResult.enacted) {
|
||||||
TemporaryBasal tempStart = new TemporaryBasal(commandResult.completionTime);
|
TemporaryBasal tempStart = new TemporaryBasal(commandResult.completionTime);
|
||||||
|
@ -442,8 +459,6 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
treatmentsInterface.addToHistoryTempBasal(tempStart);
|
treatmentsInterface.addToHistoryTempBasal(tempStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
|
||||||
|
|
||||||
PumpEnactResult pumpEnactResult = new PumpEnactResult();
|
PumpEnactResult pumpEnactResult = new PumpEnactResult();
|
||||||
pumpEnactResult.success = commandResult.success;
|
pumpEnactResult.success = commandResult.success;
|
||||||
pumpEnactResult.enacted = commandResult.enacted;
|
pumpEnactResult.enacted = commandResult.enacted;
|
||||||
|
@ -476,6 +491,10 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
/* 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 = ruffyScripter.cancelTbr();
|
||||||
|
pump.lastCmdResult = commandResult;
|
||||||
|
pump.lastCmdTime = new Date(commandResult.completionTime);
|
||||||
|
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||||
|
|
||||||
if (commandResult.enacted) {
|
if (commandResult.enacted) {
|
||||||
tempBasal = new TemporaryBasal(commandResult.completionTime);
|
tempBasal = new TemporaryBasal(commandResult.completionTime);
|
||||||
tempBasal.durationInMinutes = 0;
|
tempBasal.durationInMinutes = 0;
|
||||||
|
@ -498,6 +517,10 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
int percentage = (activeTemp.percentRate > 100) ? 110 : 90;
|
int percentage = (activeTemp.percentRate > 100) ? 110 : 90;
|
||||||
log.debug("cancelTempBasal: changing tbr to " + percentage + "% for 15 mins.");
|
log.debug("cancelTempBasal: changing tbr to " + percentage + "% for 15 mins.");
|
||||||
commandResult = ruffyScripter.setTbr(percentage, 15);
|
commandResult = ruffyScripter.setTbr(percentage, 15);
|
||||||
|
pump.lastCmdResult = commandResult;
|
||||||
|
pump.lastCmdTime = new Date(commandResult.completionTime);
|
||||||
|
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||||
|
|
||||||
if (commandResult.enacted) {
|
if (commandResult.enacted) {
|
||||||
tempBasal = new TemporaryBasal(commandResult.completionTime);
|
tempBasal = new TemporaryBasal(commandResult.completionTime);
|
||||||
tempBasal.durationInMinutes = 15;
|
tempBasal.durationInMinutes = 15;
|
||||||
|
|
|
@ -7,6 +7,7 @@ import java.util.Date;
|
||||||
|
|
||||||
import de.jotomo.ruffy.spi.PumpState;
|
import de.jotomo.ruffy.spi.PumpState;
|
||||||
import de.jotomo.ruffy.spi.CommandResult;
|
import de.jotomo.ruffy.spi.CommandResult;
|
||||||
|
import de.jotomo.ruffy.spi.history.PumpHistory;
|
||||||
|
|
||||||
class ComboPump {
|
class ComboPump {
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -14,4 +15,5 @@ class ComboPump {
|
||||||
@NonNull
|
@NonNull
|
||||||
volatile Date lastCmdTime = new Date(0);
|
volatile Date lastCmdTime = new Date(0);
|
||||||
volatile PumpState state = new PumpState();
|
volatile PumpState state = new PumpState();
|
||||||
|
volatile PumpHistory history = new PumpHistory();
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:id="@+id/objectives_fake_layout"
|
android:id="@+id/objectives_fake_layout"
|
||||||
android:visibility="gone">
|
android:visibility="visible">
|
||||||
|
|
||||||
<CheckBox
|
<CheckBox
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|
|
@ -2,25 +2,54 @@ package de.jotomo.ruffy.spi.history;
|
||||||
|
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class PumpHistory {
|
public class PumpHistory {
|
||||||
public final int reservoirLevel;
|
public int reservoirLevel = -1;
|
||||||
@NonNull
|
@NonNull
|
||||||
public final List<Bolus> bolusHistory;
|
public List<Bolus> bolusHistory = Collections.emptyList();
|
||||||
@NonNull
|
@NonNull
|
||||||
public final List<Tbr> tbrHistory;
|
public List<Tbr> tbrHistory = Collections.emptyList();
|
||||||
@NonNull
|
@NonNull
|
||||||
public final List<java.lang.Error> errorHistory;
|
public List<Error> errorHistory = Collections.emptyList();
|
||||||
@NonNull
|
@NonNull
|
||||||
public final List<Tdd> tddHistory;
|
public List<Tdd> tddHistory = Collections.emptyList();
|
||||||
|
|
||||||
public PumpHistory(int reservoirLevel, List<Bolus> bolusHistory, List<Tbr> tbrHistory, List<java.lang.Error> errorHistory, List<Tdd> tddHistory) {
|
public PumpHistory reservoirLevel(int reservoirLevel) {
|
||||||
this.reservoirLevel = reservoirLevel;
|
this.reservoirLevel = reservoirLevel
|
||||||
this.bolusHistory = Objects.requireNonNull(bolusHistory);
|
;
|
||||||
this.tbrHistory = Objects.requireNonNull(tbrHistory);
|
return this;
|
||||||
this.errorHistory = Objects.requireNonNull(errorHistory);
|
}
|
||||||
this.tddHistory = Objects.requireNonNull(tddHistory);
|
|
||||||
|
public PumpHistory bolusHistory(List<Bolus> bolusHistory) {
|
||||||
|
this.bolusHistory = bolusHistory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PumpHistory tbrHistory(List<Tbr> tbrHistory) {
|
||||||
|
this.tbrHistory = tbrHistory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PumpHistory errorHistory(List<Error> errorHistory) {
|
||||||
|
this.errorHistory = errorHistory;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "PumpHistory{" +
|
||||||
|
"reservoirLevel=" + reservoirLevel +
|
||||||
|
", bolusHistory=" + bolusHistory +
|
||||||
|
", tbrHistory=" + tbrHistory +
|
||||||
|
", errorHistory=" + errorHistory +
|
||||||
|
", tddHistory=" + tddHistory +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
public PumpHistory tddHistory(List<Tdd> tddHistory) {
|
||||||
|
this.tddHistory = tddHistory;
|
||||||
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ public class PumpHistoryRequest {
|
||||||
public static final long SKIP = -1;
|
public static final long SKIP = -1;
|
||||||
public static final long FULL = 0;
|
public static final long FULL = 0;
|
||||||
|
|
||||||
public long bolusHistory;
|
public long bolusHistory = SKIP;
|
||||||
public long tbrHistory;
|
public long tbrHistory = SKIP;
|
||||||
public long errorHistory;
|
public long errorHistory = SKIP;
|
||||||
|
|
||||||
public PumpHistoryRequest reservoirLevel(boolean reservoirLevel) {
|
public PumpHistoryRequest reservoirLevel(boolean reservoirLevel) {
|
||||||
this.reservoirLevel = reservoirLevel;
|
this.reservoirLevel = reservoirLevel;
|
||||||
|
|
|
@ -20,29 +20,25 @@ import org.monkey.d.ruffy.ruffy.driver.display.menu.MenuTime;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import de.jotomo.ruffy.spi.BasalProfile;
|
||||||
|
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.ruffyscripter.commands.BolusCommand;
|
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.GetPumpStateCommand;
|
||||||
import de.jotomo.ruffyscripter.commands.ReadBasalProfileCommand;
|
import de.jotomo.ruffyscripter.commands.ReadBasalProfileCommand;
|
||||||
|
import de.jotomo.ruffyscripter.commands.ReadHistoryCommand;
|
||||||
import de.jotomo.ruffyscripter.commands.ReadPumpStateCommand;
|
import de.jotomo.ruffyscripter.commands.ReadPumpStateCommand;
|
||||||
import de.jotomo.ruffyscripter.commands.SetBasalProfileCommand;
|
import de.jotomo.ruffyscripter.commands.SetBasalProfileCommand;
|
||||||
import de.jotomo.ruffyscripter.commands.SetTbrCommand;
|
import de.jotomo.ruffyscripter.commands.SetTbrCommand;
|
||||||
import de.jotomo.ruffy.spi.BasalProfile;
|
|
||||||
import de.jotomo.ruffy.spi.BolusProgressReporter;
|
|
||||||
import de.jotomo.ruffy.spi.CommandResult;
|
|
||||||
import de.jotomo.ruffy.spi.history.Bolus;
|
|
||||||
import de.jotomo.ruffy.spi.history.PumpHistory;
|
|
||||||
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.Tbr;
|
|
||||||
import de.jotomo.ruffy.spi.history.Tdd;
|
|
||||||
|
|
||||||
// TODO regularly read "My data" history (boluses, TBR) to double check all commands ran successfully.
|
// TODO regularly read "My data" history (boluses, TBR) to double check all commands ran successfully.
|
||||||
// Automatically compare against AAPS db, or log all requests in the PumpInterface (maybe Milos
|
// Automatically compare against AAPS db, or log all requests in the PumpInterface (maybe Milos
|
||||||
|
@ -70,91 +66,6 @@ public class RuffyScripter implements RuffyCommands {
|
||||||
|
|
||||||
private final Object screenlock = new Object();
|
private final Object screenlock = new Object();
|
||||||
|
|
||||||
private ServiceConnection mRuffyServiceConnection;
|
|
||||||
|
|
||||||
public RuffyScripter(Context context) {
|
|
||||||
boolean boundSucceeded = false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Intent intent = new Intent()
|
|
||||||
.setComponent(new ComponentName(
|
|
||||||
// this must be the base package of the app (check package attribute in
|
|
||||||
// manifest element in the manifest file of the providing app)
|
|
||||||
"org.monkey.d.ruffy.ruffy",
|
|
||||||
// full path to the driver;
|
|
||||||
// in the logs this service is mentioned as (note the slash)
|
|
||||||
// "org.monkey.d.ruffy.ruffy/.driver.Ruffy";
|
|
||||||
// org.monkey.d.ruffy.ruffy is the base package identifier
|
|
||||||
// and /.driver.Ruffy the service within the package
|
|
||||||
"org.monkey.d.ruffy.ruffy.driver.Ruffy"
|
|
||||||
));
|
|
||||||
context.startService(intent);
|
|
||||||
|
|
||||||
mRuffyServiceConnection = new ServiceConnection() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
|
||||||
ruffyService = IRuffyService.Stub.asInterface(service);
|
|
||||||
log.debug("ruffy serivce connected");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
|
||||||
log.debug("ruffy service disconnected");
|
|
||||||
}
|
|
||||||
};
|
|
||||||
boundSucceeded = context.bindService(intent, mRuffyServiceConnection, Context.BIND_AUTO_CREATE);
|
|
||||||
} catch (Exception e) {
|
|
||||||
log.error("Binding to ruffy service failed", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!boundSucceeded) {
|
|
||||||
log.error("No connection to ruffy. Pump control unavailable.");
|
|
||||||
} else {
|
|
||||||
started = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isPumpAvailable() {
|
|
||||||
return started;
|
|
||||||
}
|
|
||||||
|
|
||||||
private volatile boolean connected = false;
|
|
||||||
private volatile long lastDisconnected = 0;
|
|
||||||
|
|
||||||
private Thread idleDisconnectMonitorThread = new Thread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while (unrecoverableError == null) {
|
|
||||||
try {
|
|
||||||
long now = System.currentTimeMillis();
|
|
||||||
long connectionTimeOutMs = 5000;
|
|
||||||
if (connected && activeCmd == null
|
|
||||||
&& now > lastCmdExecutionTime + connectionTimeOutMs
|
|
||||||
// don't disconnect too frequently, confuses ruffy?
|
|
||||||
&& now > lastDisconnected + 15 * 1000) {
|
|
||||||
log.debug("Disconnecting after " + (connectionTimeOutMs / 1000) + "s inactivity timeout");
|
|
||||||
lastDisconnected = now;
|
|
||||||
ruffyService.doRTDisconnect();
|
|
||||||
connected = false;
|
|
||||||
// don't attempt anything fancy in the next 10s, let the pump settle
|
|
||||||
SystemClock.sleep(10 * 1000);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// TODO do we need to catch this exception somewhere else too? right now it's
|
|
||||||
// converted into a command failure, but it's not classified as unrecoverable;
|
|
||||||
// eventually we might try to recover ... check docs, there's also another
|
|
||||||
// execption we should watch interacting with a remote service.
|
|
||||||
// SecurityException was the other, when there's an AIDL mismatch;
|
|
||||||
//unrecoverableError = "Ruffy service went away";
|
|
||||||
log.debug("Exception in idle disconnect monitor thread, carrying on", e);
|
|
||||||
}
|
|
||||||
SystemClock.sleep(1000);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, "idle-disconnect-monitor");
|
|
||||||
|
|
||||||
private IRTHandler mHandler = new IRTHandler.Stub() {
|
private IRTHandler mHandler = new IRTHandler.Stub() {
|
||||||
@Override
|
@Override
|
||||||
public void log(String message) throws RemoteException {
|
public void log(String message) throws RemoteException {
|
||||||
|
@ -221,6 +132,93 @@ public class RuffyScripter implements RuffyCommands {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public RuffyScripter(Context context) {
|
||||||
|
boolean boundSucceeded = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent()
|
||||||
|
.setComponent(new ComponentName(
|
||||||
|
// this must be the base package of the app (check package attribute in
|
||||||
|
// manifest element in the manifest file of the providing app)
|
||||||
|
"org.monkey.d.ruffy.ruffy",
|
||||||
|
// full path to the driver;
|
||||||
|
// in the logs this service is mentioned as (note the slash)
|
||||||
|
// "org.monkey.d.ruffy.ruffy/.driver.Ruffy";
|
||||||
|
// org.monkey.d.ruffy.ruffy is the base package identifier
|
||||||
|
// and /.driver.Ruffy the service within the package
|
||||||
|
"org.monkey.d.ruffy.ruffy.driver.Ruffy"
|
||||||
|
));
|
||||||
|
context.startService(intent);
|
||||||
|
|
||||||
|
ServiceConnection mRuffyServiceConnection = new ServiceConnection() {
|
||||||
|
@Override
|
||||||
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
|
log.debug("ruffy service connected");
|
||||||
|
ruffyService = IRuffyService.Stub.asInterface(service);
|
||||||
|
try {
|
||||||
|
ruffyService.setHandler(mHandler);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Ruffy handler has issues", e);
|
||||||
|
}
|
||||||
|
idleDisconnectMonitorThread.start();
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
|
log.debug("ruffy service disconnected");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
boundSucceeded = context.bindService(intent, mRuffyServiceConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Binding to ruffy service failed", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!boundSucceeded) {
|
||||||
|
log.error("No connection to ruffy. Pump control unavailable.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPumpAvailable() {
|
||||||
|
return started;
|
||||||
|
}
|
||||||
|
|
||||||
|
private volatile boolean connected = false;
|
||||||
|
private volatile long lastDisconnected = 0;
|
||||||
|
|
||||||
|
private Thread idleDisconnectMonitorThread = new Thread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
while (unrecoverableError == null) {
|
||||||
|
try {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
long connectionTimeOutMs = 5000;
|
||||||
|
if (connected && activeCmd == null
|
||||||
|
&& now > lastCmdExecutionTime + connectionTimeOutMs
|
||||||
|
// don't disconnect too frequently, confuses ruffy?
|
||||||
|
&& now > lastDisconnected + 15 * 1000) {
|
||||||
|
log.debug("Disconnecting after " + (connectionTimeOutMs / 1000) + "s inactivity timeout");
|
||||||
|
lastDisconnected = now;
|
||||||
|
ruffyService.doRTDisconnect();
|
||||||
|
connected = false;
|
||||||
|
// don't attempt anything fancy in the next 10s, let the pump settle
|
||||||
|
SystemClock.sleep(10 * 1000);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
// TODO do we need to catch this exception somewhere else too? right now it's
|
||||||
|
// converted into a command failure, but it's not classified as unrecoverable;
|
||||||
|
// eventually we might try to recover ... check docs, there's also another
|
||||||
|
// execption we should watch interacting with a remote service.
|
||||||
|
// SecurityException was the other, when there's an AIDL mismatch;
|
||||||
|
//unrecoverableError = "Ruffy service went away";
|
||||||
|
log.debug("Exception in idle disconnect monitor thread, carrying on", e);
|
||||||
|
}
|
||||||
|
SystemClock.sleep(1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, "idle-disconnect-monitor");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isPumpBusy() {
|
public boolean isPumpBusy() {
|
||||||
return activeCmd != null;
|
return activeCmd != null;
|
||||||
|
@ -266,14 +264,13 @@ public class RuffyScripter implements RuffyCommands {
|
||||||
return new CommandResult().message(Joiner.on("\n").join(violations)).state(readPumpStateInternal());
|
return new CommandResult().message(Joiner.on("\n").join(violations)).state(readPumpStateInternal());
|
||||||
}
|
}
|
||||||
|
|
||||||
// synchronized (RuffyScripter.class) {
|
synchronized (RuffyScripter.class) {
|
||||||
try {
|
try {
|
||||||
activeCmd = cmd;
|
activeCmd = cmd;
|
||||||
long connectStart = System.currentTimeMillis();
|
long connectStart = System.currentTimeMillis();
|
||||||
ensureConnected();
|
ensureConnected();
|
||||||
final RuffyScripter scripter = this;
|
final RuffyScripter scripter = this;
|
||||||
final Returnable returnable = new Returnable();
|
final Returnable returnable = new Returnable();
|
||||||
returnable.cmdResult.request = cmd.toString();
|
|
||||||
Thread cmdThread = new Thread(new Runnable() {
|
Thread cmdThread = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -370,6 +367,7 @@ public class RuffyScripter implements RuffyCommands {
|
||||||
long connectDurationSec = (executionStart - connectStart) / 1000;
|
long connectDurationSec = (executionStart - connectStart) / 1000;
|
||||||
long executionDurationSec = (System.currentTimeMillis() - executionStart) / 1000;
|
long executionDurationSec = (System.currentTimeMillis() - executionStart) / 1000;
|
||||||
returnable.cmdResult.duration = "Connect: " + connectDurationSec + "s, execution: " + executionDurationSec + "s";
|
returnable.cmdResult.duration = "Connect: " + connectDurationSec + "s, execution: " + executionDurationSec + "s";
|
||||||
|
returnable.cmdResult.request = cmd.toString();
|
||||||
log.debug("Command result: " + returnable.cmdResult);
|
log.debug("Command result: " + returnable.cmdResult);
|
||||||
return returnable.cmdResult;
|
return returnable.cmdResult;
|
||||||
} catch (CommandException e) {
|
} catch (CommandException e) {
|
||||||
|
@ -381,7 +379,7 @@ public class RuffyScripter implements RuffyCommands {
|
||||||
} finally {
|
} finally {
|
||||||
activeCmd = null;
|
activeCmd = null;
|
||||||
}
|
}
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -431,8 +429,10 @@ public class RuffyScripter implements RuffyCommands {
|
||||||
// TODO v2 add remaining info we can extract from the main menu, low battery and low
|
// TODO v2 add remaining info we can extract from the main menu, low battery and low
|
||||||
// cartridge warnings, running extended bolus (how does that look if a TBR is active as well?)
|
// cartridge warnings, running extended bolus (how does that look if a TBR is active as well?)
|
||||||
|
|
||||||
/** This reads the state of the, which is whatever is currently displayed on the display,
|
/**
|
||||||
* no actions are performed. */
|
* This reads the state of the, which is whatever is currently displayed on the display,
|
||||||
|
* no actions are performed.
|
||||||
|
*/
|
||||||
public PumpState readPumpStateInternal() {
|
public PumpState readPumpStateInternal() {
|
||||||
PumpState state = new PumpState();
|
PumpState state = new PumpState();
|
||||||
Menu menu = currentMenu;
|
Menu menu = currentMenu;
|
||||||
|
@ -611,7 +611,9 @@ public class RuffyScripter implements RuffyCommands {
|
||||||
|
|
||||||
// TODO confirmAlarms? and report back which were cancelled?
|
// TODO confirmAlarms? and report back which were cancelled?
|
||||||
|
|
||||||
/** Confirms and dismisses the given alert if it's raised before the timeout */
|
/**
|
||||||
|
* Confirms and dismisses the given alert if it's raised before the timeout
|
||||||
|
*/
|
||||||
public boolean confirmAlert(String alertMessage, int maxWaitMs) {
|
public boolean confirmAlert(String alertMessage, int maxWaitMs) {
|
||||||
long inFiveSeconds = System.currentTimeMillis() + maxWaitMs;
|
long inFiveSeconds = System.currentTimeMillis() + maxWaitMs;
|
||||||
boolean alertProcessed = false;
|
boolean alertProcessed = false;
|
||||||
|
@ -641,7 +643,9 @@ public class RuffyScripter implements RuffyCommands {
|
||||||
return alertProcessed;
|
return alertProcessed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Wait until the menu is updated */
|
/**
|
||||||
|
* Wait until the menu is updated
|
||||||
|
*/
|
||||||
public void waitForMenuUpdate() {
|
public void waitForMenuUpdate() {
|
||||||
waitForMenuUpdate(60, "Timeout waiting for menu update");
|
waitForMenuUpdate(60, "Timeout waiting for menu update");
|
||||||
}
|
}
|
||||||
|
@ -692,7 +696,9 @@ public class RuffyScripter implements RuffyCommands {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Wait till a menu changed has completed, "away" from the menu provided as argument. */
|
/**
|
||||||
|
* Wait till a menu changed has completed, "away" from the menu provided as argument.
|
||||||
|
*/
|
||||||
public void waitForMenuToBeLeft(MenuType menuType) {
|
public void waitForMenuToBeLeft(MenuType menuType) {
|
||||||
long timeout = System.currentTimeMillis() + 60 * 1000;
|
long timeout = System.currentTimeMillis() + 60 * 1000;
|
||||||
while (getCurrentMenu().getType() == menuType) {
|
while (getCurrentMenu().getType() == menuType) {
|
||||||
|
@ -761,12 +767,7 @@ public class RuffyScripter implements RuffyCommands {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandResult readHistory(PumpHistoryRequest request) {
|
public CommandResult readHistory(PumpHistoryRequest request) {
|
||||||
return new CommandResult().history(
|
return runCommand(new ReadHistoryCommand(request));
|
||||||
new PumpHistory(50,
|
|
||||||
Collections.<Bolus>emptyList(),
|
|
||||||
Collections.<Tbr>emptyList(),
|
|
||||||
Collections.<Error>emptyList(),
|
|
||||||
Collections.<Tdd>emptyList()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -1,27 +1,45 @@
|
||||||
package de.jotomo.ruffyscripter.commands;
|
package de.jotomo.ruffyscripter.commands;
|
||||||
|
|
||||||
|
import org.monkey.d.ruffy.ruffy.driver.display.MenuAttribute;
|
||||||
|
import org.monkey.d.ruffy.ruffy.driver.display.MenuType;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.jotomo.ruffy.spi.history.PumpHistory;
|
import de.jotomo.ruffy.spi.history.PumpHistory;
|
||||||
import de.jotomo.ruffyscripter.RuffyScripter;
|
import de.jotomo.ruffy.spi.history.PumpHistoryRequest;
|
||||||
import de.jotomo.ruffy.spi.CommandResult;
|
import de.jotomo.ruffy.spi.CommandResult;
|
||||||
|
|
||||||
public class ReadHistoryCommand implements Command {
|
public class ReadHistoryCommand extends BaseCommand {
|
||||||
public ReadHistoryCommand(PumpHistory knownHistory) {
|
private final PumpHistoryRequest request;
|
||||||
|
|
||||||
|
public ReadHistoryCommand(PumpHistoryRequest request) {
|
||||||
|
this.request = request;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CommandResult execute() {
|
public CommandResult execute() {
|
||||||
return null;
|
PumpHistory history = new PumpHistory();
|
||||||
|
if (request.reservoirLevel) readReservoirLevel(history);
|
||||||
|
if (request.bolusHistory != PumpHistoryRequest.SKIP) readBolusHistory(history, request.bolusHistory);
|
||||||
|
return new CommandResult().success(true).enacted(false).history(history);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readBolusHistory(PumpHistory history, long bolusHistory) {
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readReservoirLevel(PumpHistory history) {
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU);
|
||||||
|
scripter.pressCheckKey();
|
||||||
|
scripter.waitForMenuToBeLeft(MenuType.MAIN_MENU);
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.QUICK_INFO);
|
||||||
|
int remainingInsulin = ((Double) scripter.getCurrentMenu().getAttribute(MenuAttribute.REMAINING_INSULIN)).intValue();
|
||||||
|
scripter.returnToMainMenu();
|
||||||
|
history.reservoirLevel = remainingInsulin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> validateArguments() {
|
public List<String> validateArguments() {
|
||||||
return null;
|
return Collections.emptyList();
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setScripter(RuffyScripter scripter) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,4 +19,9 @@ public class ReadPumpStateCommand implements Command {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setScripter(RuffyScripter scripter) {}
|
public void setScripter(RuffyScripter scripter) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "ReadPumpStateCommand{}";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue