Revert merge which was committed due to a misunderstanding.
This commit is contained in:
parent
dbad306766
commit
c524e2a685
|
@ -44,7 +44,7 @@ android {
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 23
|
targetSdkVersion 23
|
||||||
versionCode 1500
|
versionCode 1500
|
||||||
version "1.5f-combo-sandratest"
|
version "1.5f"
|
||||||
buildConfigField "String", "VERSION", '"' + version + '"'
|
buildConfigField "String", "VERSION", '"' + version + '"'
|
||||||
buildConfigField "String", "BUILDVERSION", generateGitBuild()
|
buildConfigField "String", "BUILDVERSION", generateGitBuild()
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class RuffyScripterInstrumentedTest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
ruffyScripter = new RuffyScripter();
|
ruffyScripter = new RuffyScripter(IRuffyService.Stub.asInterface(service));
|
||||||
log.debug("ruffy serivce connected");
|
log.debug("ruffy serivce connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,17 +10,12 @@ interface IRTHandler {
|
||||||
void fail(String message);
|
void fail(String message);
|
||||||
|
|
||||||
void requestBluetooth();
|
void requestBluetooth();
|
||||||
boolean canDisconnect();
|
|
||||||
void rtStopped();
|
void rtStopped();
|
||||||
void rtStarted();
|
void rtStarted();
|
||||||
|
|
||||||
void rtClearDisplay();
|
void rtClearDisplay();
|
||||||
void rtUpdateDisplay(in byte[] quarter, int which);
|
void rtUpdateDisplay(in byte[] quarter, int which);
|
||||||
|
|
||||||
void rtDisplayHandleMenu(in Menu menu, in int sequence);
|
void rtDisplayHandleMenu(in Menu menu);
|
||||||
void rtDisplayHandleNoMenu(in int sequence);
|
void rtDisplayHandleNoMenu();
|
||||||
|
|
||||||
void keySent(in int sequence);
|
|
||||||
|
|
||||||
String getServiceIdentifier();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,10 +13,10 @@ interface IRuffyService {
|
||||||
*
|
*
|
||||||
* @return 0 if successful, -1 otherwise
|
* @return 0 if successful, -1 otherwise
|
||||||
*/
|
*/
|
||||||
int doRTConnect(IRTHandler handler);
|
int doRTConnect();
|
||||||
|
|
||||||
/** Disconnect from the pump */
|
/** Disconnect from the pump */
|
||||||
void doRTDisconnect(IRTHandler handler);
|
void doRTDisconnect();
|
||||||
|
|
||||||
/*What's the meaning of 'changed'?
|
/*What's the meaning of 'changed'?
|
||||||
* changed means if a button state has been changed, like btton pressed is a change and button release another*/
|
* changed means if a button state has been changed, like btton pressed is a change and button release another*/
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package de.jotomo.ruffyscripter;
|
package de.jotomo.ruffyscripter;
|
||||||
|
|
||||||
|
import android.os.DeadObjectException;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
|
||||||
|
@ -15,13 +16,11 @@ import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
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.CommandResult;
|
import de.jotomo.ruffyscripter.commands.CommandResult;
|
||||||
import de.jotomo.ruffyscripter.commands.ReadPumpStateCommand;
|
import de.jotomo.ruffyscripter.commands.ReadPumpStateCommand;
|
||||||
import de.jotomo.ruffyscripter.commands.SetTbrCommand;
|
|
||||||
|
|
||||||
// TODO regularly read "My data" history (boluses, TBR) to double check all commands ran successfully.
|
// TODO regularly read "My data" history (boluses, TBR) to double check all commands ran successfully.
|
||||||
// Automatically compare against AAPS db, or log all requests in the PumpInterface (maybe Milos
|
// Automatically compare against AAPS db, or log all requests in the PumpInterface (maybe Milos
|
||||||
|
@ -36,7 +35,7 @@ public class RuffyScripter {
|
||||||
private static final Logger log = LoggerFactory.getLogger(RuffyScripter.class);
|
private static final Logger log = LoggerFactory.getLogger(RuffyScripter.class);
|
||||||
|
|
||||||
|
|
||||||
private IRuffyService ruffyService;
|
private final IRuffyService ruffyService;
|
||||||
private final long connectionTimeOutMs = 5000;
|
private final long connectionTimeOutMs = 5000;
|
||||||
private String unrecoverableError = null;
|
private String unrecoverableError = null;
|
||||||
|
|
||||||
|
@ -51,41 +50,27 @@ public class RuffyScripter {
|
||||||
|
|
||||||
private boolean started = false;
|
private boolean started = false;
|
||||||
|
|
||||||
private final Object keylock = new Object();
|
public RuffyScripter(final IRuffyService ruffyService) {
|
||||||
private int keynotwait = 0;
|
this.ruffyService = ruffyService;
|
||||||
|
|
||||||
private final Object screenlock = new Object();
|
|
||||||
|
|
||||||
public RuffyScripter() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void start(IRuffyService newService) {
|
public void start() {
|
||||||
try {
|
try {
|
||||||
if(newService!=null) {
|
ruffyService.addHandler(mHandler);
|
||||||
this.ruffyService = newService;
|
idleDisconnectMonitorThread.start();
|
||||||
// TODO this'll be done better in v2 via ConnectionManager
|
started = true;
|
||||||
if (idleDisconnectMonitorThread.getState() == Thread.State.NEW) {
|
} catch (RemoteException e) {
|
||||||
idleDisconnectMonitorThread.start();
|
|
||||||
}
|
|
||||||
started = true;
|
|
||||||
try{newService.addHandler(mHandler);}catch (Exception e){}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() {
|
public void stop() {
|
||||||
if (started) {
|
if (started) {
|
||||||
started=false;
|
try {
|
||||||
// TODO ruffy removes dead handlers automatically by now.
|
|
||||||
// still, check this when going through recovery logic
|
|
||||||
/* try {
|
|
||||||
ruffyService.removeHandler(mHandler);
|
ruffyService.removeHandler(mHandler);
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
log.warn("Removing IRTHandler from Ruffy service failed, ignoring", e);
|
log.warn("Removing IRTHandler from Ruffy service failed, ignoring", e);
|
||||||
}*/
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +78,6 @@ public class RuffyScripter {
|
||||||
return started;
|
return started;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canDisconnect = false;
|
|
||||||
private Thread idleDisconnectMonitorThread = new Thread(new Runnable() {
|
private Thread idleDisconnectMonitorThread = new Thread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
|
@ -107,24 +91,20 @@ public class RuffyScripter {
|
||||||
&& now > lastDisconnect + 15 * 1000) {
|
&& now > lastDisconnect + 15 * 1000) {
|
||||||
log.debug("Disconnecting after " + (connectionTimeOutMs / 1000) + "s inactivity timeout");
|
log.debug("Disconnecting after " + (connectionTimeOutMs / 1000) + "s inactivity timeout");
|
||||||
lastDisconnect = now;
|
lastDisconnect = now;
|
||||||
canDisconnect=true;
|
ruffyService.doRTDisconnect();
|
||||||
ruffyService.doRTDisconnect(mHandler);
|
|
||||||
connected = false;
|
connected = false;
|
||||||
lastDisconnect = System.currentTimeMillis();
|
lastDisconnect = System.currentTimeMillis();
|
||||||
// don't attempt anything fancy in the next 10s, let the pump settle
|
// don't attempt anything fancy in the next 10s, let the pump settle
|
||||||
SystemClock.sleep(10 * 1000);
|
SystemClock.sleep(10 * 1000);
|
||||||
}
|
}
|
||||||
else
|
} catch (DeadObjectException doe) {
|
||||||
{
|
|
||||||
canDisconnect=false;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// TODO do we need to catch this exception somewhere else too? right now it's
|
// 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;
|
// converted into a command failure, but it's not classified as unrecoverable;
|
||||||
// eventually we might try to recover ... check docs, there's also another
|
// eventually we might try to recover ... check docs, there's also another
|
||||||
// execption we should watch interacting with a remote service.
|
// execption we should watch interacting with a remote service.
|
||||||
// SecurityException was the other, when there's an AIDL mismatch;
|
// SecurityException was the other, when there's an AIDL mismatch;
|
||||||
//unrecoverableError = "Ruffy service went away";
|
unrecoverableError = "Ruffy service went away";
|
||||||
|
} catch (RemoteException e) {
|
||||||
log.debug("Exception in idle disconnect monitor thread, carrying on", e);
|
log.debug("Exception in idle disconnect monitor thread, carrying on", e);
|
||||||
}
|
}
|
||||||
SystemClock.sleep(1000);
|
SystemClock.sleep(1000);
|
||||||
|
@ -148,11 +128,6 @@ public class RuffyScripter {
|
||||||
log.trace("Ruffy invoked requestBluetooth callback");
|
log.trace("Ruffy invoked requestBluetooth callback");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean canDisconnect() throws RemoteException {
|
|
||||||
return canDisconnect;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rtStopped() throws RemoteException {
|
public void rtStopped() throws RemoteException {
|
||||||
log.debug("rtStopped callback invoked");
|
log.debug("rtStopped callback invoked");
|
||||||
|
@ -175,18 +150,13 @@ public class RuffyScripter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rtDisplayHandleMenu(Menu menu, int sequence) throws RemoteException {
|
public void rtDisplayHandleMenu(Menu menu) throws RemoteException {
|
||||||
// method is called every ~500ms
|
// method is called every ~500ms
|
||||||
log.debug("rtDisplayHandleMenu: " + menu.getType());
|
log.debug("rtDisplayHandleMenu: " + menu.getType());
|
||||||
|
|
||||||
currentMenu = menu;
|
currentMenu = menu;
|
||||||
menuLastUpdated = System.currentTimeMillis();
|
menuLastUpdated = System.currentTimeMillis();
|
||||||
|
|
||||||
synchronized (screenlock)
|
|
||||||
{
|
|
||||||
screenlock.notifyAll();
|
|
||||||
}
|
|
||||||
|
|
||||||
connected = true;
|
connected = true;
|
||||||
|
|
||||||
// note that a WARNING_OR_ERROR menu can be a valid temporary state (cancelling TBR)
|
// note that a WARNING_OR_ERROR menu can be a valid temporary state (cancelling TBR)
|
||||||
|
@ -197,39 +167,16 @@ public class RuffyScripter {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rtDisplayHandleNoMenu(int sequence) throws RemoteException {
|
public void rtDisplayHandleNoMenu() throws RemoteException {
|
||||||
log.debug("rtDisplayHandleNoMenu callback invoked");
|
log.debug("rtDisplayHandleNoMenu callback invoked");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void keySent(int sequence) throws RemoteException {
|
|
||||||
synchronized (keylock)
|
|
||||||
{
|
|
||||||
if(keynotwait>0)
|
|
||||||
keynotwait--;
|
|
||||||
else
|
|
||||||
keylock.notify();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getServiceIdentifier() throws RemoteException {
|
|
||||||
return this.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public boolean isPumpBusy() {
|
public boolean isPumpBusy() {
|
||||||
return activeCmd != null;
|
return activeCmd != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unbind() {
|
|
||||||
if(ruffyService!=null)
|
|
||||||
try{ruffyService.removeHandler(mHandler);}catch (Exception e){}
|
|
||||||
this.ruffyService = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class Returnable {
|
private static class Returnable {
|
||||||
CommandResult cmdResult;
|
CommandResult cmdResult;
|
||||||
}
|
}
|
||||||
|
@ -377,8 +324,7 @@ public class RuffyScripter {
|
||||||
SystemClock.sleep(10 * 1000);
|
SystemClock.sleep(10 * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
canDisconnect=false;
|
boolean connectInitSuccessful = ruffyService.doRTConnect() == 0;
|
||||||
boolean connectInitSuccessful = ruffyService.doRTConnect(mHandler) == 0;
|
|
||||||
log.debug("Connect init successful: " + connectInitSuccessful);
|
log.debug("Connect init successful: " + connectInitSuccessful);
|
||||||
log.debug("Waiting for first menu update to be sent");
|
log.debug("Waiting for first menu update to be sent");
|
||||||
// Note: there was an 'if(currentMenu == null)' around the next call, since
|
// Note: there was an 'if(currentMenu == null)' around the next call, since
|
||||||
|
@ -390,8 +336,8 @@ public class RuffyScripter {
|
||||||
// if the user just pressed a button on the combo, the screen needs to time first
|
// if the user just pressed a button on the combo, the screen needs to time first
|
||||||
// before a connection is possible. In that case, it takes 45s before the
|
// before a connection is possible. In that case, it takes 45s before the
|
||||||
// connection comes up.
|
// connection comes up.
|
||||||
waitForMenuUpdate(180);
|
waitForMenuUpdate(90);
|
||||||
} catch (Exception e) {
|
} catch (RemoteException e) {
|
||||||
throw new CommandException().exception(e).message("Unexpected exception while initiating/restoring pump connection");
|
throw new CommandException().exception(e).message("Unexpected exception while initiating/restoring pump connection");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -401,95 +347,38 @@ public class RuffyScripter {
|
||||||
// so this class can focus on providing a connection to run commands
|
// so this class can focus on providing a connection to run commands
|
||||||
// (or maybe reconsider putting it into a base class)
|
// (or maybe reconsider putting it into a base class)
|
||||||
|
|
||||||
public static class Key {
|
private static class Key {
|
||||||
public static byte NO_KEY = (byte) 0x00;
|
static byte NO_KEY = (byte) 0x00;
|
||||||
public static byte MENU = (byte) 0x03;
|
static byte MENU = (byte) 0x03;
|
||||||
public static byte CHECK = (byte) 0x0C;
|
static byte CHECK = (byte) 0x0C;
|
||||||
public static byte UP = (byte) 0x30;
|
static byte UP = (byte) 0x30;
|
||||||
public static byte DOWN = (byte) 0xC0;
|
static byte DOWN = (byte) 0xC0;
|
||||||
public static byte BACK = (byte) 0x33;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pressUpKey() {
|
public void pressUpKey() {
|
||||||
log.debug("Pressing up key");
|
log.debug("Pressing up key");
|
||||||
pressKey(Key.UP,2000);
|
pressKey(Key.UP);
|
||||||
log.debug("Releasing up key");
|
log.debug("Releasing up key");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pressDownKey() {
|
public void pressDownKey() {
|
||||||
log.debug("Pressing down key");
|
log.debug("Pressing down key");
|
||||||
pressKey(Key.DOWN,2000);
|
pressKey(Key.DOWN);
|
||||||
log.debug("Releasing down key");
|
log.debug("Releasing down key");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pressCheckKey() {
|
public void pressCheckKey() {
|
||||||
log.debug("Pressing check key");
|
log.debug("Pressing check key");
|
||||||
pressKey(Key.CHECK,2000);
|
pressKey(Key.CHECK);
|
||||||
log.debug("Releasing check key");
|
log.debug("Releasing check key");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pressMenuKey() {
|
public void pressMenuKey() {
|
||||||
log.debug("Pressing menu key");
|
log.debug("Pressing menu key");
|
||||||
pressKey(Key.MENU,2000);
|
pressKey(Key.MENU);
|
||||||
log.debug("Releasing menu key");
|
log.debug("Releasing menu key");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void pressBackKey() {
|
|
||||||
log.debug("Pressing back key");
|
|
||||||
pressKey(Key.BACK,2000);
|
|
||||||
log.debug("Releasing back key");
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean waitScreen(long timeout)
|
|
||||||
{
|
|
||||||
synchronized (screenlock) {
|
|
||||||
try {
|
|
||||||
screenlock.wait(timeout);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean goToMainMenuScreen(MenuType screen, long timeout)
|
|
||||||
{
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
while((currentMenu == null || currentMenu.getType()!=screen) && start+timeout>System.currentTimeMillis())
|
|
||||||
{
|
|
||||||
if(currentMenu!=null && currentMenu.getType()==MenuType.WARNING_OR_ERROR)
|
|
||||||
{
|
|
||||||
//FIXME bad thing to do :D
|
|
||||||
pressCheckKey();
|
|
||||||
}
|
|
||||||
else if(currentMenu!=null && !currentMenu.getType().isMaintype())
|
|
||||||
{
|
|
||||||
pressBackKey();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pressMenuKey();
|
|
||||||
waitScreen(250);
|
|
||||||
}
|
|
||||||
return currentMenu != null && currentMenu.getType()==screen;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean enterMenu(MenuType startType, MenuType targetType, byte key, long timeout)
|
|
||||||
{
|
|
||||||
if(currentMenu==null || currentMenu.getType() != startType)
|
|
||||||
return false;
|
|
||||||
long start = System.currentTimeMillis();
|
|
||||||
pressKey(key,2000);
|
|
||||||
while((currentMenu == null || currentMenu.getType()!=targetType) && start+timeout>System.currentTimeMillis()) {
|
|
||||||
waitScreen(100);
|
|
||||||
}
|
|
||||||
return currentMenu!=null && currentMenu.getType()==targetType;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void step(int steps, byte key, long timeout) {
|
|
||||||
for(int i = 0; i < Math.abs(steps);i++)
|
|
||||||
pressKey(key,timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO v2, rework these two methods: waitForMenuUpdate shoud only be used by commands
|
// TODO v2, rework these two methods: waitForMenuUpdate shoud only be used by commands
|
||||||
// then anything longer than a few seconds is an error;
|
// then anything longer than a few seconds is an error;
|
||||||
// only ensureConnected() uses the method with the timeout parameter; inline that code,
|
// only ensureConnected() uses the method with the timeout parameter; inline that code,
|
||||||
|
@ -498,7 +387,7 @@ public class RuffyScripter {
|
||||||
* Wait until the menu update is in
|
* Wait until the menu update is in
|
||||||
*/
|
*/
|
||||||
public void waitForMenuUpdate() {
|
public void waitForMenuUpdate() {
|
||||||
waitForMenuUpdate(120);
|
waitForMenuUpdate(60);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void waitForMenuUpdate(long timeoutInSeconds) {
|
public void waitForMenuUpdate(long timeoutInSeconds) {
|
||||||
|
@ -512,26 +401,12 @@ public class RuffyScripter {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void pressKey(final byte key, long timeout) {
|
private void pressKey(final byte key) {
|
||||||
try {
|
try {
|
||||||
ruffyService.rtSendKey(key, true);
|
ruffyService.rtSendKey(key, true);
|
||||||
//SystemClock.sleep(200);
|
SystemClock.sleep(100);
|
||||||
ruffyService.rtSendKey(Key.NO_KEY, true);
|
ruffyService.rtSendKey(Key.NO_KEY, true);
|
||||||
if(timeout > 0)
|
} catch (RemoteException e) {
|
||||||
{
|
|
||||||
synchronized (keylock)
|
|
||||||
{
|
|
||||||
keylock.wait(timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
synchronized (keylock)
|
|
||||||
{
|
|
||||||
keynotwait++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new CommandException().exception(e).message("Error while pressing buttons");
|
throw new CommandException().exception(e).message("Error while pressing buttons");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,7 +58,7 @@ public class BolusCommand implements Command {
|
||||||
Double bolusRemaining = (Double) scripter.currentMenu.getAttribute(MenuAttribute.BOLUS_REMAINING);
|
Double bolusRemaining = (Double) scripter.currentMenu.getAttribute(MenuAttribute.BOLUS_REMAINING);
|
||||||
while (bolusRemaining != null) {
|
while (bolusRemaining != null) {
|
||||||
log.debug("Delivering bolus, remaining: " + bolusRemaining);
|
log.debug("Delivering bolus, remaining: " + bolusRemaining);
|
||||||
SystemClock.sleep(300);
|
SystemClock.sleep(200);
|
||||||
bolusRemaining = (Double) scripter.currentMenu.getAttribute(MenuAttribute.BOLUS_REMAINING);
|
bolusRemaining = (Double) scripter.currentMenu.getAttribute(MenuAttribute.BOLUS_REMAINING);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,11 +122,11 @@ public class BolusCommand implements Command {
|
||||||
for (int i = 0; i < steps; i++) {
|
for (int i = 0; i < steps; i++) {
|
||||||
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
||||||
scripter.pressUpKey();
|
scripter.pressUpKey();
|
||||||
SystemClock.sleep(400);
|
SystemClock.sleep(100);
|
||||||
}
|
}
|
||||||
// Give the pump time to finish any scrolling that might still be going on, can take
|
// Give the pump time to finish any scrolling that might still be going on, can take
|
||||||
// up to 1100ms. Plus some extra time to be sure
|
// up to 1100ms. Plus some extra time to be sure
|
||||||
SystemClock.sleep(750);
|
SystemClock.sleep(2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyDisplayedBolusAmount(RuffyScripter scripter) {
|
private void verifyDisplayedBolusAmount(RuffyScripter scripter) {
|
||||||
|
@ -138,7 +138,7 @@ public class BolusCommand implements Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
// check again to ensure the displayed value hasn't change due to due scrolling taking extremely long
|
// check again to ensure the displayed value hasn't change due to due scrolling taking extremely long
|
||||||
SystemClock.sleep(750);
|
SystemClock.sleep(2000);
|
||||||
double refreshedDisplayedBolus = readDisplayedBolusAmount(scripter);
|
double refreshedDisplayedBolus = readDisplayedBolusAmount(scripter);
|
||||||
if (Math.abs(displayedBolus - refreshedDisplayedBolus) > 0.05) {
|
if (Math.abs(displayedBolus - refreshedDisplayedBolus) > 0.05) {
|
||||||
throw new CommandException().message("Failed to set bolus: bolus changed after input stopped from "
|
throw new CommandException().message("Failed to set bolus: bolus changed after input stopped from "
|
||||||
|
|
|
@ -1,191 +0,0 @@
|
||||||
package de.jotomo.ruffyscripter.commands;
|
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
|
|
||||||
import org.monkey.d.ruffy.ruffy.driver.display.MenuAttribute;
|
|
||||||
import org.monkey.d.ruffy.ruffy.driver.display.MenuType;
|
|
||||||
import org.monkey.d.ruffy.ruffy.driver.display.menu.MenuTime;
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
import de.jotomo.ruffyscripter.PumpState;
|
|
||||||
import de.jotomo.ruffyscripter.RuffyScripter;
|
|
||||||
|
|
||||||
import static de.jotomo.ruffyscripter.commands.GetBasalCommand.State.BEFORE;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.GetBasalCommand.State.MAIN;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.GetBasalCommand.State.BASAL_1_MENU;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.GetBasalCommand.State.BASAL_OVERVIEW;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.GetBasalCommand.State.READ_BASAL;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.GetBasalCommand.State.ERROR;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.GetBasalCommand.State.AFTER;
|
|
||||||
|
|
||||||
public class GetBasalCommand implements Command {
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(GetBasalCommand.class);
|
|
||||||
|
|
||||||
private RuffyScripter scripter;
|
|
||||||
|
|
||||||
public GetBasalCommand() {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<String> validateArguments() {
|
|
||||||
List<String> violations = new ArrayList<>();
|
|
||||||
|
|
||||||
return violations;
|
|
||||||
}
|
|
||||||
|
|
||||||
enum State {
|
|
||||||
BEFORE,
|
|
||||||
MAIN,
|
|
||||||
BASAL_1_MENU,
|
|
||||||
BASAL_OVERVIEW,
|
|
||||||
READ_BASAL,
|
|
||||||
ERROR,
|
|
||||||
AFTER,
|
|
||||||
};
|
|
||||||
private State lastState,state;
|
|
||||||
private long last;
|
|
||||||
private long timeout;
|
|
||||||
private Thread timeoutThread = new Thread()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while(state != ERROR && state!=AFTER) {
|
|
||||||
if (timeout + last < System.currentTimeMillis()) {
|
|
||||||
lastState = state;
|
|
||||||
state = ERROR;
|
|
||||||
log.debug("timeout reached -> state:ERROR");
|
|
||||||
}
|
|
||||||
tick();
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tick();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private void updateState(State newState,long timeoutSec)
|
|
||||||
{
|
|
||||||
lastState = state;
|
|
||||||
state = newState;
|
|
||||||
last = System.currentTimeMillis();
|
|
||||||
timeout = timeoutSec*1000;
|
|
||||||
}
|
|
||||||
private MenuType lastMenu;
|
|
||||||
private int retries = 0;
|
|
||||||
private double basalTotal = 0;
|
|
||||||
private Map<Integer,Double> rate = new HashMap<>();
|
|
||||||
|
|
||||||
private void tick()
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case BEFORE:
|
|
||||||
if(scripter.currentMenu!=null && scripter.currentMenu.getType()==MenuType.MAIN_MENU)
|
|
||||||
{
|
|
||||||
updateState(MAIN,120);
|
|
||||||
lastMenu = MenuType.MAIN_MENU;
|
|
||||||
log.debug("found MAIN_MENU -> state:MAIN");
|
|
||||||
retries=3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MAIN:
|
|
||||||
if(retries>0)
|
|
||||||
if(scripter.goToMainMenuScreen(MenuType.BASAL_1_MENU,30000))
|
|
||||||
{
|
|
||||||
if(scripter.enterMenu(MenuType.BASAL_1_MENU,MenuType.BASAL_TOTAL, RuffyScripter.Key.CHECK,2000))
|
|
||||||
{
|
|
||||||
updateState(BASAL_OVERVIEW, 30);
|
|
||||||
retries=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
retries--;
|
|
||||||
else
|
|
||||||
updateState(ERROR,30);
|
|
||||||
break;
|
|
||||||
case BASAL_OVERVIEW:
|
|
||||||
if(scripter.currentMenu.getType()==MenuType.BASAL_TOTAL && scripter.currentMenu.getAttribute(MenuAttribute.BASAL_TOTAL)!=null && (Integer)scripter.currentMenu.getAttribute(MenuAttribute.BASAL_SELECTED)==1)
|
|
||||||
{
|
|
||||||
basalTotal = (Double)scripter.currentMenu.getAttribute(MenuAttribute.BASAL_TOTAL);
|
|
||||||
if(scripter.enterMenu(MenuType.BASAL_TOTAL,MenuType.BASAL_SET, RuffyScripter.Key.MENU,3000))
|
|
||||||
{
|
|
||||||
updateState(READ_BASAL,30);
|
|
||||||
retries = 96;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case READ_BASAL:
|
|
||||||
if(scripter.currentMenu.getType()==MenuType.BASAL_SET && scripter.currentMenu.getAttribute(MenuAttribute.BASAL_START)!=null) {
|
|
||||||
Object rateObj = scripter.currentMenu.getAttribute(MenuAttribute.BASAL_RATE);
|
|
||||||
MenuTime time = (MenuTime) scripter.currentMenu.getAttribute(MenuAttribute.BASAL_START);
|
|
||||||
if (rateObj instanceof Double) {
|
|
||||||
rate.put(time.getHour(), (Double) rateObj);
|
|
||||||
}
|
|
||||||
boolean complete = true;
|
|
||||||
for (int t = 0; t < 24; t++) {
|
|
||||||
if (rate.get(t) == null)
|
|
||||||
complete = false;
|
|
||||||
}
|
|
||||||
if (retries > 0) {
|
|
||||||
if (complete) {
|
|
||||||
scripter.pressBackKey();
|
|
||||||
updateState(AFTER, 30);
|
|
||||||
} else {
|
|
||||||
retries--;
|
|
||||||
scripter.pressMenuKey();
|
|
||||||
scripter.waitScreen(250);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
updateState(ERROR, 30);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ERROR:
|
|
||||||
case AFTER:
|
|
||||||
scripter.goToMainMenuScreen(MenuType.MAIN_MENU,2000);
|
|
||||||
synchronized(GetBasalCommand.this) {
|
|
||||||
GetBasalCommand.this.notify();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public CommandResult execute(RuffyScripter scripter, PumpState initialPumpState) {
|
|
||||||
state = BEFORE;
|
|
||||||
this.scripter = scripter;
|
|
||||||
updateState(BEFORE,120);
|
|
||||||
timeoutThread.start();
|
|
||||||
|
|
||||||
try {
|
|
||||||
synchronized (this) {
|
|
||||||
this.wait();
|
|
||||||
}
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
return new CommandResult().success(false).message("failed to wait: "+e.getMessage());
|
|
||||||
}
|
|
||||||
if(state==AFTER)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < 24;i++)
|
|
||||||
{
|
|
||||||
Log.v("BASAL_RATE","BASAL_RATE from "+String.format("%02d",i)+":00 = "+rate.get(i));
|
|
||||||
}
|
|
||||||
return new CommandResult().success(true).enacted(true).message("Basal Rate was read");
|
|
||||||
}
|
|
||||||
return new CommandResult().success(false).message("failed with state: "+state+" from: "+lastState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "GetTbrCommand{}";
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,5 +1,7 @@
|
||||||
package de.jotomo.ruffyscripter.commands;
|
package de.jotomo.ruffyscripter.commands;
|
||||||
|
|
||||||
|
import android.os.SystemClock;
|
||||||
|
|
||||||
import org.monkey.d.ruffy.ruffy.driver.display.MenuAttribute;
|
import org.monkey.d.ruffy.ruffy.driver.display.MenuAttribute;
|
||||||
import org.monkey.d.ruffy.ruffy.driver.display.MenuType;
|
import org.monkey.d.ruffy.ruffy.driver.display.MenuType;
|
||||||
import org.monkey.d.ruffy.ruffy.driver.display.menu.MenuTime;
|
import org.monkey.d.ruffy.ruffy.driver.display.menu.MenuTime;
|
||||||
|
@ -13,22 +15,11 @@ import java.util.Locale;
|
||||||
import de.jotomo.ruffyscripter.PumpState;
|
import de.jotomo.ruffyscripter.PumpState;
|
||||||
import de.jotomo.ruffyscripter.RuffyScripter;
|
import de.jotomo.ruffyscripter.RuffyScripter;
|
||||||
|
|
||||||
import static de.jotomo.ruffyscripter.commands.SetTbrCommand.State.AFTER;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.SetTbrCommand.State.BEFORE;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.SetTbrCommand.State.ERROR;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.SetTbrCommand.State.MAIN;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.SetTbrCommand.State.SET;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.SetTbrCommand.State.SET_TBR;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.SetTbrCommand.State.SET_TIME;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.SetTbrCommand.State.TBR;
|
|
||||||
import static de.jotomo.ruffyscripter.commands.SetTbrCommand.State.TIME;
|
|
||||||
|
|
||||||
public class SetTbrCommand implements Command {
|
public class SetTbrCommand implements Command {
|
||||||
private static final Logger log = LoggerFactory.getLogger(SetTbrCommand.class);
|
private static final Logger log = LoggerFactory.getLogger(SetTbrCommand.class);
|
||||||
|
|
||||||
private final long percentage;
|
private final long percentage;
|
||||||
private final long duration;
|
private final long duration;
|
||||||
private RuffyScripter scripter;
|
|
||||||
|
|
||||||
public SetTbrCommand(long percentage, long duration) {
|
public SetTbrCommand(long percentage, long duration) {
|
||||||
this.percentage = percentage;
|
this.percentage = percentage;
|
||||||
|
@ -62,233 +53,243 @@ public class SetTbrCommand implements Command {
|
||||||
return violations;
|
return violations;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum State {
|
|
||||||
BEFORE,
|
|
||||||
MAIN,
|
|
||||||
TBR,
|
|
||||||
SET_TBR,
|
|
||||||
TIME,
|
|
||||||
SET_TIME,
|
|
||||||
SET,
|
|
||||||
AFTER,
|
|
||||||
ERROR
|
|
||||||
};
|
|
||||||
private State lastState,state;
|
|
||||||
private long last;
|
|
||||||
private long timeout;
|
|
||||||
private Thread timeoutThread = new Thread()
|
|
||||||
{
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
while(state != ERROR && state!=AFTER) {
|
|
||||||
if (timeout + last < System.currentTimeMillis()) {
|
|
||||||
lastState = state;
|
|
||||||
state = ERROR;
|
|
||||||
log.debug("timeout reached -> state:ERROR");
|
|
||||||
}
|
|
||||||
tick();
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tick();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
private void updateState(State newState,long timeoutSec)
|
|
||||||
{
|
|
||||||
lastState = state;
|
|
||||||
state = newState;
|
|
||||||
last = System.currentTimeMillis();
|
|
||||||
timeout = timeoutSec*1000;
|
|
||||||
}
|
|
||||||
private MenuType lastMenu;
|
|
||||||
private int retries = 0;
|
|
||||||
private void tick()
|
|
||||||
{
|
|
||||||
switch (state)
|
|
||||||
{
|
|
||||||
case BEFORE:
|
|
||||||
if(scripter.currentMenu!=null && scripter.currentMenu.getType()==MenuType.MAIN_MENU)
|
|
||||||
{
|
|
||||||
updateState(MAIN,120);
|
|
||||||
lastMenu = MenuType.MAIN_MENU;
|
|
||||||
log.debug("found MAIN_MENU -> state:MAIN");
|
|
||||||
retries=3;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case MAIN:
|
|
||||||
if(retries>0)
|
|
||||||
if(scripter.goToMainMenuScreen(MenuType.TBR_MENU,30000))
|
|
||||||
{
|
|
||||||
updateState(TBR,30);
|
|
||||||
retries=0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
retries--;
|
|
||||||
else
|
|
||||||
updateState(ERROR,30);
|
|
||||||
break;
|
|
||||||
case TBR:
|
|
||||||
if(scripter.enterMenu(MenuType.TBR_MENU,MenuType.TBR_SET, RuffyScripter.Key.CHECK,20000))
|
|
||||||
{
|
|
||||||
updateState(SET_TBR,60);
|
|
||||||
retries = 10;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
updateState(ERROR,30);
|
|
||||||
break;
|
|
||||||
case SET_TBR:
|
|
||||||
if(scripter.currentMenu!=null && scripter.currentMenu.getType()==MenuType.TBR_SET)
|
|
||||||
{
|
|
||||||
Object percentageObj = scripter.currentMenu.getAttribute(MenuAttribute.BASAL_RATE);
|
|
||||||
if(percentageObj != null && percentageObj instanceof Double)
|
|
||||||
{
|
|
||||||
double currentPercentage = ((Double) percentageObj).doubleValue();
|
|
||||||
|
|
||||||
if(currentPercentage!=percentage)
|
|
||||||
{
|
|
||||||
if(retries>0) {
|
|
||||||
retries--;
|
|
||||||
int steps = (int) ((percentage - currentPercentage) / 10.0);
|
|
||||||
scripter.step(steps,(steps<0? RuffyScripter.Key.DOWN: RuffyScripter.Key.UP), 3000);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
updateState(ERROR,30);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(percentage==100)
|
|
||||||
{
|
|
||||||
scripter.pressCheckKey();
|
|
||||||
updateState(SET,30);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
updateState(TIME, 30);
|
|
||||||
}
|
|
||||||
retries=10;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
updateState(ERROR,30);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TIME:
|
|
||||||
if((scripter.currentMenu!=null && scripter.currentMenu.getType()==MenuType.TBR_DURATION) || scripter.enterMenu(MenuType.TBR_SET,MenuType.TBR_DURATION, RuffyScripter.Key.MENU,20000))
|
|
||||||
{
|
|
||||||
updateState(SET_TIME,60);
|
|
||||||
retries = 10;
|
|
||||||
}
|
|
||||||
else if(retries==0)
|
|
||||||
updateState(ERROR,30);
|
|
||||||
else retries--;
|
|
||||||
break;
|
|
||||||
case SET_TIME:
|
|
||||||
if(scripter.currentMenu!=null && scripter.currentMenu.getType()==MenuType.TBR_DURATION)
|
|
||||||
{
|
|
||||||
Object durationObj = scripter.currentMenu.getAttribute(MenuAttribute.RUNTIME);
|
|
||||||
if(durationObj != null && durationObj instanceof MenuTime)
|
|
||||||
{
|
|
||||||
MenuTime time = (MenuTime) durationObj;
|
|
||||||
double currentDuration = (time.getHour()*60)+time.getMinute();
|
|
||||||
if(currentDuration!=duration)
|
|
||||||
{
|
|
||||||
if(retries>0) {
|
|
||||||
retries--;
|
|
||||||
int steps = (int)((currentDuration - duration)/15.0);
|
|
||||||
if(currentDuration+(steps*15)<duration)
|
|
||||||
steps++;
|
|
||||||
else if(currentDuration+(steps*15)>duration)
|
|
||||||
steps--;
|
|
||||||
scripter.step(steps,(steps>0? RuffyScripter.Key.UP: RuffyScripter.Key.DOWN), 3000);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
updateState(ERROR,30);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
scripter.pressCheckKey();
|
|
||||||
updateState(SET, 30);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
updateState(ERROR,60);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case SET:
|
|
||||||
if(scripter.currentMenu!=null && scripter.currentMenu.getType()==MenuType.WARNING_OR_ERROR)
|
|
||||||
{
|
|
||||||
lastMenu = scripter.currentMenu.getType();
|
|
||||||
scripter.pressCheckKey();
|
|
||||||
updateState(SET, 30);
|
|
||||||
}
|
|
||||||
else if(scripter.currentMenu!=null && scripter.currentMenu.getType()==MenuType.MAIN_MENU) {
|
|
||||||
Object setPercentage = scripter.currentMenu.getAttribute(MenuAttribute.TBR);
|
|
||||||
Object setDuration = scripter.currentMenu.getAttribute(MenuAttribute.RUNTIME);
|
|
||||||
if (setPercentage== null ||setDuration==null) {
|
|
||||||
if(percentage!=100)
|
|
||||||
{
|
|
||||||
updateState(ERROR,10);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(lastMenu==MenuType.WARNING_OR_ERROR)
|
|
||||||
updateState(AFTER,10);
|
|
||||||
else
|
|
||||||
updateState(SET,10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
double mmTbrPercentage = (Double) setPercentage;
|
|
||||||
MenuTime mmTbrDuration = (MenuTime) setDuration;
|
|
||||||
// ... and be the same as what we set
|
|
||||||
// note that displayed duration might have already counted down, e.g. from 30 minutes to
|
|
||||||
// 29 minutes and 59 seconds, so that 29 minutes are displayed
|
|
||||||
int mmTbrDurationInMinutes = mmTbrDuration.getHour() * 60 + mmTbrDuration.getMinute();
|
|
||||||
if (mmTbrPercentage == percentage && mmTbrDurationInMinutes <= duration) {
|
|
||||||
updateState(AFTER, 10);
|
|
||||||
} else {
|
|
||||||
updateState(ERROR, 10);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ERROR:
|
|
||||||
case AFTER:
|
|
||||||
synchronized(SetTbrCommand.this) {
|
|
||||||
SetTbrCommand.this.notify();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
public CommandResult execute(RuffyScripter scripter, PumpState initialPumpState) {
|
public CommandResult execute(RuffyScripter scripter, PumpState initialPumpState) {
|
||||||
state = BEFORE;
|
try {
|
||||||
this.scripter = scripter;
|
enterTbrMenu(scripter);
|
||||||
updateState(BEFORE,120);
|
inputTbrPercentage(scripter);
|
||||||
timeoutThread.start();
|
verifyDisplayedTbrPercentage(scripter);
|
||||||
|
|
||||||
try {
|
if (percentage == 100) {
|
||||||
synchronized (this) {
|
cancelTbrAndConfirmCancellationWarning(scripter);
|
||||||
this.wait();
|
} else {
|
||||||
}
|
// switch to TBR_DURATION menu by pressing menu key
|
||||||
} catch (InterruptedException e) {
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_SET);
|
||||||
e.printStackTrace();
|
scripter.pressMenuKey();
|
||||||
return new CommandResult().success(false).message("failed to wait: "+e.getMessage());
|
scripter.waitForMenuUpdate();
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_DURATION);
|
||||||
|
|
||||||
|
inputTbrDuration(scripter);
|
||||||
|
verifyDisplayedTbrDuration(scripter);
|
||||||
|
|
||||||
|
// confirm TBR
|
||||||
|
scripter.pressCheckKey();
|
||||||
|
scripter.waitForMenuToBeLeft(MenuType.TBR_DURATION);
|
||||||
}
|
}
|
||||||
if(state==AFTER)
|
|
||||||
{
|
|
||||||
if(percentage==100)
|
|
||||||
return new CommandResult().success(true).enacted(true).message("TBR was cancelled");
|
|
||||||
|
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU,
|
||||||
|
"Pump did not return to MAIN_MEU after setting TBR. " +
|
||||||
|
"Check pump manually, the TBR might not have been set/cancelled.");
|
||||||
|
|
||||||
|
// check main menu shows the same values we just set
|
||||||
|
if (percentage == 100) {
|
||||||
|
verifyMainMenuShowsNoActiveTbr(scripter);
|
||||||
|
return new CommandResult().success(true).enacted(true).message("TBR was cancelled");
|
||||||
|
} else {
|
||||||
|
verifyMainMenuShowsExpectedTbrActive(scripter);
|
||||||
return new CommandResult().success(true).enacted(true).message(
|
return new CommandResult().success(true).enacted(true).message(
|
||||||
String.format(Locale.US, "TBR set to %d%% for %d min", percentage, duration));
|
String.format(Locale.US, "TBR set to %d%% for %d min", percentage, duration));
|
||||||
}
|
}
|
||||||
return new CommandResult().success(false).message("failed with state: "+state+" from: "+lastState);
|
|
||||||
|
} catch (CommandException e) {
|
||||||
|
return e.toCommandResult();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void enterTbrMenu(RuffyScripter scripter) {
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU);
|
||||||
|
scripter.navigateToMenu(MenuType.TBR_MENU);
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_MENU);
|
||||||
|
scripter.pressCheckKey();
|
||||||
|
scripter.waitForMenuUpdate();
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inputTbrPercentage(RuffyScripter scripter) {
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_SET);
|
||||||
|
long currentPercent = readDisplayedTbrPercentage(scripter);
|
||||||
|
log.debug("Current TBR %: " + currentPercent);
|
||||||
|
long percentageChange = percentage - currentPercent;
|
||||||
|
long percentageSteps = percentageChange / 10;
|
||||||
|
boolean increasePercentage = true;
|
||||||
|
if (percentageSteps < 0) {
|
||||||
|
increasePercentage = false;
|
||||||
|
percentageSteps = Math.abs(percentageSteps);
|
||||||
|
}
|
||||||
|
log.debug("Pressing " + (increasePercentage ? "up" : "down") + " " + percentageSteps + " times");
|
||||||
|
for (int i = 0; i < percentageSteps; i++) {
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_SET);
|
||||||
|
if (increasePercentage) scripter.pressUpKey();
|
||||||
|
else scripter.pressDownKey();
|
||||||
|
SystemClock.sleep(100);
|
||||||
|
log.debug("Push #" + (i + 1));
|
||||||
|
}
|
||||||
|
// Give the pump time to finish any scrolling that might still be going on, can take
|
||||||
|
// up to 1100ms. Plus some extra time to be sure
|
||||||
|
SystemClock.sleep(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyDisplayedTbrPercentage(RuffyScripter scripter) {
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_SET);
|
||||||
|
long displayedPercentage = readDisplayedTbrPercentage(scripter);
|
||||||
|
if (displayedPercentage != percentage) {
|
||||||
|
log.debug("Final displayed TBR percentage: " + displayedPercentage);
|
||||||
|
throw new CommandException().message("Failed to set TBR percentage");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check again to ensure the displayed value hasn't change due to due scrolling taking extremely long
|
||||||
|
SystemClock.sleep(2000);
|
||||||
|
long refreshedDisplayedTbrPecentage = readDisplayedTbrPercentage(scripter);
|
||||||
|
if (displayedPercentage != refreshedDisplayedTbrPecentage) {
|
||||||
|
throw new CommandException().message("Failed to set TBR percentage: " +
|
||||||
|
"percentage changed after input stopped from "
|
||||||
|
+ displayedPercentage + " -> " + refreshedDisplayedTbrPecentage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long readDisplayedTbrPercentage(RuffyScripter scripter) {
|
||||||
|
// TODO v2 add timeout? Currently the command execution timeout would trigger if exceeded
|
||||||
|
Object percentageObj = scripter.currentMenu.getAttribute(MenuAttribute.BASAL_RATE);
|
||||||
|
// this as a bit hacky, the display value is blinking, so we might catch that, so
|
||||||
|
// keep trying till we get the Double we want
|
||||||
|
while (!(percentageObj instanceof Double)) {
|
||||||
|
scripter.waitForMenuUpdate();
|
||||||
|
percentageObj = scripter.currentMenu.getAttribute(MenuAttribute.BASAL_RATE);
|
||||||
|
}
|
||||||
|
return ((Double) percentageObj).longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void inputTbrDuration(RuffyScripter scripter) {
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_DURATION);
|
||||||
|
long currentDuration = readDisplayedTbrDuration(scripter);
|
||||||
|
if (currentDuration % 15 != 0) {
|
||||||
|
// The duration displayed is how long an active TBR will still run,
|
||||||
|
// which might be something like 0:13, hence not in 15 minute steps.
|
||||||
|
// Pressing up will go to the next higher 15 minute step.
|
||||||
|
// Don't press down, from 0:13 it can't go down, so press up.
|
||||||
|
// Pressing up from 23:59 works to go to 24:00.
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_DURATION);
|
||||||
|
scripter.pressUpKey();
|
||||||
|
scripter.waitForMenuUpdate();
|
||||||
|
currentDuration = readDisplayedTbrDuration(scripter);
|
||||||
|
}
|
||||||
|
log.debug("Current TBR duration: " + currentDuration);
|
||||||
|
long durationChange = duration - currentDuration;
|
||||||
|
long durationSteps = durationChange / 15;
|
||||||
|
boolean increaseDuration = true;
|
||||||
|
if (durationSteps < 0) {
|
||||||
|
increaseDuration = false;
|
||||||
|
durationSteps = Math.abs(durationSteps);
|
||||||
|
}
|
||||||
|
log.debug("Pressing " + (increaseDuration ? "up" : "down") + " " + durationSteps + " times");
|
||||||
|
for (int i = 0; i < durationSteps; i++) {
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_DURATION);
|
||||||
|
if (increaseDuration) scripter.pressUpKey();
|
||||||
|
else scripter.pressDownKey();
|
||||||
|
SystemClock.sleep(100);
|
||||||
|
log.debug("Push #" + (i + 1));
|
||||||
|
}
|
||||||
|
// Give the pump time to finish any scrolling that might still be going on, can take
|
||||||
|
// up to 1100ms. Plus some extra time to be sure
|
||||||
|
SystemClock.sleep(2000);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyDisplayedTbrDuration(RuffyScripter scripter) {
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_DURATION);
|
||||||
|
long displayedDuration = readDisplayedTbrDuration(scripter);
|
||||||
|
if (displayedDuration != duration) {
|
||||||
|
log.debug("Final displayed TBR duration: " + displayedDuration);
|
||||||
|
throw new CommandException().message("Failed to set TBR duration");
|
||||||
|
}
|
||||||
|
|
||||||
|
// check again to ensure the displayed value hasn't change due to due scrolling taking extremely long
|
||||||
|
SystemClock.sleep(2000);
|
||||||
|
long refreshedDisplayedTbrDuration = readDisplayedTbrDuration(scripter);
|
||||||
|
if (displayedDuration != refreshedDisplayedTbrDuration) {
|
||||||
|
throw new CommandException().message("Failed to set TBR duration: " +
|
||||||
|
"duration changed after input stopped from "
|
||||||
|
+ displayedDuration + " -> " + refreshedDisplayedTbrDuration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private long readDisplayedTbrDuration(RuffyScripter scripter) {
|
||||||
|
// TODO v2 add timeout? Currently the command execution timeout would trigger if exceeded
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_DURATION);
|
||||||
|
Object durationObj = scripter.currentMenu.getAttribute(MenuAttribute.RUNTIME);
|
||||||
|
// this as a bit hacky, the display value is blinking, so we might catch that, so
|
||||||
|
// keep trying till we get the Double we want
|
||||||
|
while (!(durationObj instanceof MenuTime)) {
|
||||||
|
scripter.waitForMenuUpdate();
|
||||||
|
durationObj = scripter.currentMenu.getAttribute(MenuAttribute.RUNTIME);
|
||||||
|
}
|
||||||
|
MenuTime duration = (MenuTime) durationObj;
|
||||||
|
return duration.getHour() * 60 + duration.getMinute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void cancelTbrAndConfirmCancellationWarning(RuffyScripter scripter) {
|
||||||
|
// confirm entered TBR
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.TBR_SET);
|
||||||
|
scripter.pressCheckKey();
|
||||||
|
|
||||||
|
// A "TBR CANCELLED alert" is only raised by the pump when the remaining time is
|
||||||
|
// greater than 60s (displayed as 0:01, the pump goes from there to finished.
|
||||||
|
// We could read the remaining duration from MAIN_MENU, but by the time we're here,
|
||||||
|
// the pumup could have moved from 0:02 to 0:01, so instead, check if a "TBR CANCELLED" alert
|
||||||
|
// is raised and if so dismiss it
|
||||||
|
long inFiveSeconds = System.currentTimeMillis() + 5 * 1000;
|
||||||
|
boolean alertProcessed = false;
|
||||||
|
while (System.currentTimeMillis() < inFiveSeconds && !alertProcessed) {
|
||||||
|
if (scripter.currentMenu.getType() == MenuType.WARNING_OR_ERROR) {
|
||||||
|
// Check the raised alarm is TBR CANCELLED, so we're not accidentally cancelling
|
||||||
|
// a different alarm that might be raised at the same time.
|
||||||
|
// Note that the message is permanently displayed, while the error code is blinking.
|
||||||
|
// A wait till the error code can be read results in the code hanging, despite
|
||||||
|
// menu updates coming in, so just check the message.
|
||||||
|
// TODO v2 this only works when the pump's language is English
|
||||||
|
String errorMsg = (String) scripter.currentMenu.getAttribute(MenuAttribute.MESSAGE);
|
||||||
|
if (!errorMsg.equals("TBR CANCELLED")) {
|
||||||
|
throw new CommandException().success(false).enacted(false)
|
||||||
|
.message("An alert other than the expected TBR CANCELLED was raised by the pump: "
|
||||||
|
+ errorMsg + ". Please check the pump.");
|
||||||
|
}
|
||||||
|
// confirm "TBR CANCELLED" alert
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR);
|
||||||
|
scripter.pressCheckKey();
|
||||||
|
// dismiss "TBR CANCELLED" alert
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.WARNING_OR_ERROR);
|
||||||
|
scripter.pressCheckKey();
|
||||||
|
scripter.waitForMenuToBeLeft(MenuType.WARNING_OR_ERROR);
|
||||||
|
alertProcessed = true;
|
||||||
|
}
|
||||||
|
SystemClock.sleep(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyMainMenuShowsNoActiveTbr(RuffyScripter scripter) {
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU);
|
||||||
|
Double tbrPercentage = (Double) scripter.currentMenu.getAttribute(MenuAttribute.TBR);
|
||||||
|
boolean runtimeDisplayed = scripter.currentMenu.attributes().contains(MenuAttribute.RUNTIME);
|
||||||
|
if (tbrPercentage != 100 || runtimeDisplayed) {
|
||||||
|
throw new CommandException().message("Cancelling TBR failed, TBR is still set according to MAIN_MENU");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyMainMenuShowsExpectedTbrActive(RuffyScripter scripter) {
|
||||||
|
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU);
|
||||||
|
// new TBR set; percentage and duration must be displayed ...
|
||||||
|
if (!scripter.currentMenu.attributes().contains(MenuAttribute.TBR) ||
|
||||||
|
!scripter.currentMenu.attributes().contains(MenuAttribute.RUNTIME)) {
|
||||||
|
throw new CommandException().message("Setting TBR failed, according to MAIN_MENU no TBR is active");
|
||||||
|
}
|
||||||
|
Double mmTbrPercentage = (Double) scripter.currentMenu.getAttribute(MenuAttribute.TBR);
|
||||||
|
MenuTime mmTbrDuration = (MenuTime) scripter.currentMenu.getAttribute(MenuAttribute.RUNTIME);
|
||||||
|
// ... and be the same as what we set
|
||||||
|
// note that displayed duration might have already counted down, e.g. from 30 minutes to
|
||||||
|
// 29 minutes and 59 seconds, so that 29 minutes are displayed
|
||||||
|
int mmTbrDurationInMinutes = mmTbrDuration.getHour() * 60 + mmTbrDuration.getMinute();
|
||||||
|
if (mmTbrPercentage != percentage || (mmTbrDurationInMinutes != duration && mmTbrDurationInMinutes + 1 != duration)) {
|
||||||
|
throw new CommandException().message("Setting TBR failed, TBR in MAIN_MENU differs from expected");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -85,7 +85,6 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
MainApp.bus().register(this);
|
MainApp.bus().register(this);
|
||||||
bindRuffyService();
|
bindRuffyService();
|
||||||
startAlerter();
|
startAlerter();
|
||||||
ruffyScripter = new RuffyScripter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void definePumpCapabilities() {
|
private void definePumpCapabilities() {
|
||||||
|
@ -158,10 +157,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
mgr.notify(id, notificationBuilder.build());
|
mgr.notify(id, notificationBuilder.build());
|
||||||
lastAlarmTime = now;
|
lastAlarmTime = now;
|
||||||
} else {
|
} else {
|
||||||
// TODO would it be useful to have a 'last error' field in the ui showing the most recent
|
|
||||||
// failed command? the next command that runs successful with will override this error
|
|
||||||
log.warn("Pump still in error state, but alarm raised recently, so not triggering again: " + localLastCmdResult.message);
|
log.warn("Pump still in error state, but alarm raised recently, so not triggering again: " + localLastCmdResult.message);
|
||||||
refreshDataFromPump("from Error Recovery");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
SystemClock.sleep(5 * 1000);
|
SystemClock.sleep(5 * 1000);
|
||||||
|
@ -170,8 +166,7 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
}, "combo-alerter").start();
|
}, "combo-alerter").start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean bindRuffyService() {
|
private void bindRuffyService() {
|
||||||
|
|
||||||
Context context = MainApp.instance().getApplicationContext();
|
Context context = MainApp.instance().getApplicationContext();
|
||||||
boolean boundSucceeded = false;
|
boolean boundSucceeded = false;
|
||||||
|
|
||||||
|
@ -184,7 +179,6 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
// full path to the driver
|
// full path to the driver
|
||||||
// in the logs this service is mentioned as (note the slash)
|
// in the logs this service is mentioned as (note the slash)
|
||||||
// "org.monkey.d.ruffy.ruffy/.driver.Ruffy"
|
// "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"
|
"org.monkey.d.ruffy.ruffy.driver.Ruffy"
|
||||||
));
|
));
|
||||||
context.startService(intent);
|
context.startService(intent);
|
||||||
|
@ -193,22 +187,16 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServiceConnected(ComponentName name, IBinder service) {
|
public void onServiceConnected(ComponentName name, IBinder service) {
|
||||||
keepUnbound=false;
|
ruffyScripter = new RuffyScripter(IRuffyService.Stub.asInterface(service));
|
||||||
ruffyScripter.start(IRuffyService.Stub.asInterface(service));
|
ruffyScripter.start();
|
||||||
log.debug("ruffy serivce connected");
|
log.debug("ruffy serivce connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onServiceDisconnected(ComponentName name) {
|
public void onServiceDisconnected(ComponentName name) {
|
||||||
ruffyScripter.stop();
|
ruffyScripter.stop();
|
||||||
|
ruffyScripter = null;
|
||||||
log.debug("ruffy service disconnected");
|
log.debug("ruffy service disconnected");
|
||||||
if(!keepUnbound) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(250);
|
|
||||||
} catch (Exception e) {
|
|
||||||
}
|
|
||||||
bindRuffyService();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
boundSucceeded = context.bindService(intent, mRuffyServiceConnection, Context.BIND_AUTO_CREATE);
|
boundSucceeded = context.bindService(intent, mRuffyServiceConnection, Context.BIND_AUTO_CREATE);
|
||||||
|
@ -219,13 +207,9 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
if (!boundSucceeded) {
|
if (!boundSucceeded) {
|
||||||
statusSummary = "No connection to ruffy. Pump control not available.";
|
statusSummary = "No connection to ruffy. Pump control not available.";
|
||||||
}
|
}
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean keepUnbound = false;
|
|
||||||
private void unbindRuffyService() {
|
private void unbindRuffyService() {
|
||||||
keepUnbound = true;
|
|
||||||
ruffyScripter.unbind();
|
|
||||||
MainApp.instance().getApplicationContext().unbindService(mRuffyServiceConnection);
|
MainApp.instance().getApplicationContext().unbindService(mRuffyServiceConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +407,6 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
MainApp.bus().post(new EventComboPumpUpdateGUI());
|
||||||
|
|
||||||
CommandResult commandResult = ruffyScripter.runCommand(command);
|
CommandResult commandResult = ruffyScripter.runCommand(command);
|
||||||
// TODO extract this into a recovery method and check the logic of restarting and rebinding ruffy
|
|
||||||
if (!commandResult.success && commandResult.exception != null) {
|
if (!commandResult.success && commandResult.exception != null) {
|
||||||
log.error("CommandResult has exception, rebinding ruffy service", commandResult.exception);
|
log.error("CommandResult has exception, rebinding ruffy service", commandResult.exception);
|
||||||
|
|
||||||
|
@ -431,12 +414,6 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
try {
|
try {
|
||||||
unbindRuffyService();
|
unbindRuffyService();
|
||||||
SystemClock.sleep(5000);
|
SystemClock.sleep(5000);
|
||||||
} catch (Exception e) {
|
|
||||||
/*String msg = "No connection to ruffy. Pump control not available.";
|
|
||||||
statusSummary = msg;
|
|
||||||
return new CommandResult().message(msg);*/
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
bindRuffyService();
|
bindRuffyService();
|
||||||
SystemClock.sleep(5000);
|
SystemClock.sleep(5000);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -548,60 +525,22 @@ public class ComboPlugin implements PluginBase, PumpInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PumpEnactResult cancelTempBasal(boolean userRequested) {
|
public PumpEnactResult cancelTempBasal() {
|
||||||
log.debug("cancelTempBasal called");
|
log.debug("cancelTempBasal called");
|
||||||
|
CommandResult commandResult = runCommand(new CancelTbrCommand());
|
||||||
CommandResult commandResult = null;
|
if (commandResult.enacted) {
|
||||||
TemporaryBasal tempBasal = null;
|
TemporaryBasal tempStop = new TemporaryBasal(commandResult.completionTime);
|
||||||
PumpEnactResult pumpEnactResult = new PumpEnactResult();
|
tempStop.durationInMinutes = 0; // ending temp basal
|
||||||
|
tempStop.source = Source.USER;
|
||||||
final TemporaryBasal activeTemp = MainApp.getConfigBuilder().getTempBasalFromHistory(System.currentTimeMillis());
|
|
||||||
|
|
||||||
if (activeTemp == null || userRequested) {
|
|
||||||
/* v1 compatibility to sync DB to pump if they diverged (activeTemp == null) */
|
|
||||||
log.debug("cancelTempBasal: hard-cancelling TBR since user requested");
|
|
||||||
commandResult = runCommand(new CancelTbrCommand());
|
|
||||||
if (commandResult.enacted) {
|
|
||||||
tempBasal = new TemporaryBasal(commandResult.completionTime);
|
|
||||||
tempBasal.durationInMinutes = 0;
|
|
||||||
tempBasal.source = Source.USER;
|
|
||||||
pumpEnactResult.isTempCancel = true;
|
|
||||||
}
|
|
||||||
} else if ((activeTemp.percentRate >= 90 && activeTemp.percentRate <= 110) && activeTemp.getPlannedRemainingMinutes() <= 15 ) {
|
|
||||||
// Let fake neutral temp keep running (see below)
|
|
||||||
log.debug("cancelTempBasal: skipping changing tbr since it already is at " + activeTemp.percentRate + "% and running for another " + activeTemp.getPlannedRemainingMinutes() + " mins.");
|
|
||||||
pumpEnactResult.comment = "cancelTempBasal skipping changing tbr since it already is at " + activeTemp.percentRate + "% and running for another " + activeTemp.getPlannedRemainingMinutes() + " mins.";
|
|
||||||
// TODO check what AAPS does with this; no DB update is required;
|
|
||||||
// looking at info/nightscout/androidaps/plugins/Loop/LoopPlugin.java:280
|
|
||||||
// both values are used as one:
|
|
||||||
// if (applyResult.enacted || applyResult.success) { ...
|
|
||||||
pumpEnactResult.enacted = true; // all fine though...
|
|
||||||
pumpEnactResult.success = true; // just roll with it...
|
|
||||||
} else {
|
|
||||||
// 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%.
|
|
||||||
long percentage = (activeTemp.percentRate > 100) ? 110:90;
|
|
||||||
log.debug("cancelTempBasal: changing tbr to " + percentage + "% for 15 mins.");
|
|
||||||
commandResult = runCommand(new SetTbrCommand(percentage, 15));
|
|
||||||
if (commandResult.enacted) {
|
|
||||||
tempBasal = new TemporaryBasal(commandResult.completionTime);
|
|
||||||
tempBasal.durationInMinutes = 15;
|
|
||||||
tempBasal.source = Source.USER;
|
|
||||||
tempBasal.percentRate = (int) percentage;
|
|
||||||
tempBasal.isAbsolute = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tempBasal != null) {
|
|
||||||
ConfigBuilderPlugin treatmentsInterface = MainApp.getConfigBuilder();
|
ConfigBuilderPlugin treatmentsInterface = MainApp.getConfigBuilder();
|
||||||
treatmentsInterface.addToHistoryTempBasal(tempBasal);
|
treatmentsInterface.addToHistoryTempBasal(tempStop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commandResult != null) {
|
PumpEnactResult pumpEnactResult = new PumpEnactResult();
|
||||||
pumpEnactResult.success = commandResult.success;
|
pumpEnactResult.success = commandResult.success;
|
||||||
pumpEnactResult.enacted = commandResult.enacted;
|
pumpEnactResult.enacted = commandResult.enacted;
|
||||||
pumpEnactResult.comment = commandResult.message;
|
pumpEnactResult.comment = commandResult.message;
|
||||||
}
|
pumpEnactResult.isTempCancel = true;
|
||||||
return pumpEnactResult;
|
return pumpEnactResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,32 +35,30 @@ public class Menu implements Parcelable{
|
||||||
String clas = in.readString();
|
String clas = in.readString();
|
||||||
String value = in.readString();
|
String value = in.readString();
|
||||||
|
|
||||||
if(attr!=null && clas!=null && value!=null) {
|
MenuAttribute a = MenuAttribute.valueOf(attr);
|
||||||
MenuAttribute a = MenuAttribute.valueOf(attr);
|
Object o = null;
|
||||||
Object o = null;
|
if (Integer.class.toString().equals(clas)) {
|
||||||
if (Integer.class.toString().equals(clas)) {
|
o = new Integer(value);
|
||||||
o = new Integer(value);
|
} else if (Double.class.toString().equals(clas)) {
|
||||||
} else if (Double.class.toString().equals(clas)) {
|
o = new Double(value);
|
||||||
o = new Double(value);
|
} else if (Boolean.class.toString().equals(clas)) {
|
||||||
} else if (Boolean.class.toString().equals(clas)) {
|
o = new Boolean(value);
|
||||||
o = new Boolean(value);
|
} else if (MenuDate.class.toString().equals(clas)) {
|
||||||
} else if (MenuDate.class.toString().equals(clas)) {
|
o = new MenuDate(value);
|
||||||
o = new MenuDate(value);
|
} else if (MenuTime.class.toString().equals(clas)) {
|
||||||
} else if (MenuTime.class.toString().equals(clas)) {
|
o = new MenuTime(value);
|
||||||
o = new MenuTime(value);
|
} else if (MenuBlink.class.toString().equals(clas)) {
|
||||||
} else if (MenuBlink.class.toString().equals(clas)) {
|
o = new MenuBlink();
|
||||||
o = new MenuBlink();
|
} else if (BolusType.class.toString().equals(clas)) {
|
||||||
} else if (BolusType.class.toString().equals(clas)) {
|
o = BolusType.valueOf(value);
|
||||||
o = BolusType.valueOf(value);
|
} else if (String.class.toString().equals(clas)) {
|
||||||
} else if (String.class.toString().equals(clas)) {
|
o = new String(value);
|
||||||
o = new String(value);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (o != null) {
|
if (o != null) {
|
||||||
attributes.put(a, o);
|
attributes.put(a, o);
|
||||||
} else {
|
} else {
|
||||||
Log.e("MenuIn", "failed to parse: " + attr + " / " + clas + " / " + value);
|
Log.e("MenuIn", "failed to parse: " + attr + " / " + clas + " / " + value);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}catch(Exception e)
|
}catch(Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,47 +5,38 @@ package org.monkey.d.ruffy.ruffy.driver.display;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public enum MenuType {
|
public enum MenuType {
|
||||||
MAIN_MENU(true),
|
MAIN_MENU,
|
||||||
STOP_MENU(true),
|
STOP_MENU,
|
||||||
BOLUS_MENU(true),
|
BOLUS_MENU,
|
||||||
BOLUS_ENTER(false),
|
BOLUS_ENTER,
|
||||||
EXTENDED_BOLUS_MENU(true),
|
EXTENDED_BOLUS_MENU,
|
||||||
BOLUS_DURATION(false),
|
BOLUS_DURATION,
|
||||||
MULTIWAVE_BOLUS_MENU(true),
|
MULTIWAVE_BOLUS_MENU,
|
||||||
IMMEDIATE_BOLUS(false),
|
IMMEDIATE_BOLUS,
|
||||||
TBR_MENU(true),
|
TBR_MENU,
|
||||||
MY_DATA_MENU(true),
|
MY_DATA_MENU,
|
||||||
BASAL_MENU(true),
|
BASAL_MENU,
|
||||||
BASAL_1_MENU(true),
|
BASAL_1_MENU,
|
||||||
BASAL_2_MENU(true),
|
BASAL_2_MENU,
|
||||||
BASAL_3_MENU(true),
|
BASAL_3_MENU,
|
||||||
BASAL_4_MENU(true),
|
BASAL_4_MENU,
|
||||||
BASAL_5_MENU(true),
|
BASAL_5_MENU,
|
||||||
DATE_AND_TIME_MENU(true),
|
DATE_AND_TIME_MENU,
|
||||||
ALARM_MENU(true),
|
ALARM_MENU,
|
||||||
MENU_SETTINGS_MENU(true),
|
MENU_SETTINGS_MENU,
|
||||||
BLUETOOTH_MENU(true),
|
BLUETOOTH_MENU,
|
||||||
THERAPY_MENU(true),
|
THERAPY_MENU,
|
||||||
PUMP_MENU(true),
|
PUMP_MENU,
|
||||||
QUICK_INFO(false),
|
QUICK_INFO,
|
||||||
BOLUS_DATA(false),
|
BOLUS_DATA,
|
||||||
DAILY_DATA(false),
|
DAILY_DATA,
|
||||||
TBR_DATA(false),
|
TBR_DATA,
|
||||||
ERROR_DATA(false),
|
ERROR_DATA,
|
||||||
TBR_SET(false),
|
TBR_SET,
|
||||||
TBR_DURATION(false),
|
TBR_DURATION,
|
||||||
STOP(false),
|
STOP,
|
||||||
START_MENU(false),
|
START_MENU,
|
||||||
BASAL_TOTAL(false),
|
BASAL_TOTAL,
|
||||||
BASAL_SET(false),
|
BASAL_SET,
|
||||||
WARNING_OR_ERROR(false),;
|
WARNING_OR_ERROR,
|
||||||
|
|
||||||
private boolean maintype = false;
|
|
||||||
MenuType(boolean b) {
|
|
||||||
maintype=b;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isMaintype() {
|
|
||||||
return maintype;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue