2017-07-13 19:50:11 +02:00
|
|
|
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.MenuType;
|
|
|
|
import org.slf4j.Logger;
|
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
|
2017-07-17 10:27:39 +02:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.List;
|
2017-07-13 19:50:11 +02:00
|
|
|
import java.util.Locale;
|
|
|
|
|
2017-07-19 12:52:19 +02:00
|
|
|
import de.jotomo.ruffyscripter.PumpState;
|
2017-07-13 19:50:11 +02:00
|
|
|
import de.jotomo.ruffyscripter.RuffyScripter;
|
|
|
|
|
|
|
|
public class BolusCommand implements Command {
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(BolusCommand.class);
|
|
|
|
|
|
|
|
private final double bolus;
|
|
|
|
|
|
|
|
public BolusCommand(double bolus) {
|
|
|
|
this.bolus = bolus;
|
|
|
|
}
|
|
|
|
|
2017-07-17 10:27:39 +02:00
|
|
|
@Override
|
|
|
|
public List<String> validateArguments() {
|
|
|
|
List<String> violations = new ArrayList<>();
|
|
|
|
|
2017-07-17 15:40:55 +02:00
|
|
|
if (bolus <= 0 || bolus > 25) {
|
2017-07-17 10:27:39 +02:00
|
|
|
violations.add("Requested bolus " + bolus + " out of limits (0-25)");
|
|
|
|
}
|
|
|
|
|
|
|
|
return violations;
|
|
|
|
}
|
|
|
|
|
2017-07-13 19:50:11 +02:00
|
|
|
@Override
|
2017-07-19 12:52:19 +02:00
|
|
|
public CommandResult execute(RuffyScripter scripter, PumpState initialPumpState) {
|
2017-07-13 19:50:11 +02:00
|
|
|
try {
|
|
|
|
enterBolusMenu(scripter);
|
2017-07-18 01:24:13 +02:00
|
|
|
|
2017-07-26 14:46:00 +02:00
|
|
|
inputBolusAmount(scripter);
|
|
|
|
verifyDisplayedBolusAmount(scripter);
|
2017-07-13 19:50:11 +02:00
|
|
|
|
|
|
|
// confirm bolus
|
2017-07-16 14:50:45 +02:00
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
2017-07-13 19:50:11 +02:00
|
|
|
scripter.pressCheckKey();
|
|
|
|
|
|
|
|
// the pump displays the entered bolus and waits a bit to let user check and cancel
|
|
|
|
scripter.waitForMenuToBeLeft(MenuType.BOLUS_ENTER);
|
|
|
|
|
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU,
|
|
|
|
"Pump did not return to MAIN_MEU from BOLUS_ENTER to deliver bolus. "
|
2017-07-17 10:27:39 +02:00
|
|
|
+ "Check pump manually, the bolus might not have been delivered.");
|
2017-07-13 19:50:11 +02:00
|
|
|
|
2017-07-22 11:34:28 +02:00
|
|
|
// wait for bolus delivery to complete; the remaining units to deliver are counted
|
|
|
|
// down and are displayed on the main menu.
|
2017-07-13 19:50:11 +02:00
|
|
|
Double bolusRemaining = (Double) scripter.currentMenu.getAttribute(MenuAttribute.BOLUS_REMAINING);
|
|
|
|
while (bolusRemaining != null) {
|
|
|
|
log.debug("Delivering bolus, remaining: " + bolusRemaining);
|
|
|
|
SystemClock.sleep(200);
|
|
|
|
bolusRemaining = (Double) scripter.currentMenu.getAttribute(MenuAttribute.BOLUS_REMAINING);
|
|
|
|
}
|
|
|
|
|
|
|
|
// TODO what if we hit 'cartridge low' alert here? is it immediately displayed or after the bolus?
|
|
|
|
// TODO how are error states reported back to the caller that occur outside of calls in genal? Low battery, low cartridge?
|
|
|
|
|
|
|
|
// make sure no alert (occlusion, cartridge empty) has occurred.
|
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU,
|
|
|
|
"Bolus delivery did not complete as expected. "
|
2017-07-17 10:27:39 +02:00
|
|
|
+ "Check pump manually, the bolus might not have been delivered.");
|
2017-07-13 19:50:11 +02:00
|
|
|
|
2017-07-27 13:39:23 +02:00
|
|
|
// read last bolus record; those menus display static data and therefore
|
|
|
|
// only a single menu update is sent
|
|
|
|
scripter.navigateToMenu(MenuType.MY_DATA_MENU);
|
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.MY_DATA_MENU);
|
|
|
|
scripter.pressCheckKey();
|
|
|
|
if (scripter.currentMenu.getType() != MenuType.BOLUS_DATA) {
|
|
|
|
scripter.waitForMenuUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!scripter.currentMenu.attributes().contains(MenuAttribute.BOLUS)) {
|
|
|
|
throw new CommandException().success(false).enacted(true)
|
2017-07-27 14:35:56 +02:00
|
|
|
.message("Bolus was delivered, but unable to confirm it with history record");
|
2017-07-27 13:39:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
double lastBolusInHistory = (double) scripter.currentMenu.getAttribute(MenuAttribute.BOLUS);
|
|
|
|
if (Math.abs(bolus - lastBolusInHistory) > 0.05) {
|
|
|
|
throw new CommandException().success(false).enacted(true)
|
|
|
|
.message("Last bolus shows " + lastBolusInHistory
|
|
|
|
+ " U delievered, but " + bolus + " U were requested");
|
|
|
|
}
|
|
|
|
log.debug("Bolus record in history confirms delivered bolus");
|
|
|
|
|
|
|
|
// leave menu to go back to main menu
|
|
|
|
scripter.pressCheckKey();
|
|
|
|
scripter.waitForMenuToBeLeft(MenuType.BOLUS_DATA);
|
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU,
|
|
|
|
"Bolus was correctly delivered and checked against history, but we "
|
|
|
|
+ "did not return the main menu successfully.");
|
|
|
|
|
2017-07-13 19:50:11 +02:00
|
|
|
return new CommandResult().success(true).enacted(true)
|
|
|
|
.message(String.format(Locale.US, "Delivered %02.1f U", bolus));
|
|
|
|
} catch (CommandException e) {
|
|
|
|
return e.toCommandResult();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private void enterBolusMenu(RuffyScripter scripter) {
|
2017-07-16 14:50:45 +02:00
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU);
|
2017-07-13 19:50:11 +02:00
|
|
|
scripter.navigateToMenu(MenuType.BOLUS_MENU);
|
2017-07-16 14:50:45 +02:00
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_MENU);
|
2017-07-13 19:50:11 +02:00
|
|
|
scripter.pressCheckKey();
|
|
|
|
scripter.waitForMenuUpdate();
|
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void inputBolusAmount(RuffyScripter scripter) {
|
2017-07-18 10:24:45 +02:00
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
2017-07-13 19:50:11 +02:00
|
|
|
// press 'up' once for each 0.1 U increment
|
|
|
|
long steps = Math.round(bolus * 10);
|
|
|
|
for (int i = 0; i < steps; i++) {
|
2017-07-16 14:50:45 +02:00
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
2017-07-13 19:50:11 +02:00
|
|
|
scripter.pressUpKey();
|
|
|
|
SystemClock.sleep(100);
|
|
|
|
}
|
2017-07-26 14:46:00 +02:00
|
|
|
// Give the pump time to finish any scrolling that might still be going on, can take
|
2017-07-26 18:02:21 +02:00
|
|
|
// up to 1100ms. Plus some extra time to be sure
|
2017-07-26 14:46:00 +02:00
|
|
|
SystemClock.sleep(2000);
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void verifyDisplayedBolusAmount(RuffyScripter scripter) {
|
2017-07-18 10:24:45 +02:00
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
2017-07-18 01:51:52 +02:00
|
|
|
double displayedBolus = readDisplayedBolusAmount(scripter);
|
2017-07-13 19:50:11 +02:00
|
|
|
log.debug("Final bolus: " + displayedBolus);
|
2017-07-13 20:19:22 +02:00
|
|
|
if (Math.abs(displayedBolus - bolus) > 0.05) {
|
2017-07-13 19:50:11 +02:00
|
|
|
throw new CommandException().message("Failed to set correct bolus. Expected: " + bolus + ", actual: " + displayedBolus);
|
|
|
|
}
|
2017-07-26 14:46:00 +02:00
|
|
|
|
|
|
|
// check again to ensure the displayed value hasn't change due to due scrolling taking extremely long
|
|
|
|
SystemClock.sleep(2000);
|
|
|
|
double refreshedDisplayedBolus = readDisplayedBolusAmount(scripter);
|
|
|
|
if (Math.abs(displayedBolus - refreshedDisplayedBolus) > 0.05) {
|
|
|
|
throw new CommandException().message("Failed to set bolus: bolus changed after input stopped from "
|
|
|
|
+ displayedBolus + " -> " + refreshedDisplayedBolus);
|
|
|
|
}
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|
2017-07-14 15:01:20 +02:00
|
|
|
|
2017-07-18 01:51:52 +02:00
|
|
|
private double readDisplayedBolusAmount(RuffyScripter scripter) {
|
2017-07-22 11:34:28 +02:00
|
|
|
// TODO v2 add timeout? Currently the command execution timeout would trigger if exceeded
|
2017-07-18 01:51:52 +02:00
|
|
|
scripter.verifyMenuIsDisplayed(MenuType.BOLUS_ENTER);
|
2017-07-22 11:34:28 +02:00
|
|
|
// bolus amount is blinking, so we need to make sure we catch it at the right moment
|
2017-07-18 01:51:52 +02:00
|
|
|
Object amountObj = scripter.currentMenu.getAttribute(MenuAttribute.BOLUS);
|
|
|
|
while (!(amountObj instanceof Double)) {
|
|
|
|
scripter.waitForMenuUpdate();
|
|
|
|
amountObj = scripter.currentMenu.getAttribute(MenuAttribute.BOLUS);
|
|
|
|
}
|
|
|
|
return (double) amountObj;
|
|
|
|
}
|
|
|
|
|
2017-07-14 15:01:20 +02:00
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "BolusCommand{" +
|
|
|
|
"bolus=" + bolus +
|
|
|
|
'}';
|
|
|
|
}
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|