2017-07-13 19:50:11 +02:00
|
|
|
package de.jotomo.ruffyscripter.commands;
|
|
|
|
|
2017-08-12 13:36:09 +02:00
|
|
|
import android.os.SystemClock;
|
|
|
|
|
2017-07-13 19:50:11 +02:00
|
|
|
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;
|
|
|
|
|
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;
|
|
|
|
|
2017-08-12 00:12:11 +02:00
|
|
|
import static org.monkey.d.ruffy.ruffy.driver.display.MenuType.MAIN_MENU;
|
|
|
|
import static org.monkey.d.ruffy.ruffy.driver.display.MenuType.TBR_DURATION;
|
|
|
|
import static org.monkey.d.ruffy.ruffy.driver.display.MenuType.TBR_MENU;
|
|
|
|
import static org.monkey.d.ruffy.ruffy.driver.display.MenuType.TBR_SET;
|
|
|
|
import static org.monkey.d.ruffy.ruffy.driver.display.MenuType.WARNING_OR_ERROR;
|
2017-08-11 14:19:16 +02:00
|
|
|
|
2017-07-13 19:50:11 +02:00
|
|
|
public class SetTbrCommand implements Command {
|
|
|
|
private static final Logger log = LoggerFactory.getLogger(SetTbrCommand.class);
|
|
|
|
|
|
|
|
private final long percentage;
|
|
|
|
private final long duration;
|
|
|
|
|
|
|
|
public SetTbrCommand(long percentage, long duration) {
|
|
|
|
this.percentage = percentage;
|
|
|
|
this.duration = duration;
|
2017-07-17 10:27:39 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public List<String> validateArguments() {
|
|
|
|
List<String> violations = new ArrayList<>();
|
2017-07-13 19:50:11 +02:00
|
|
|
|
|
|
|
if (percentage % 10 != 0) {
|
2017-07-17 10:27:39 +02:00
|
|
|
violations.add("TBR percentage must be set in 10% steps");
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|
|
|
|
if (percentage < 0 || percentage > 500) {
|
2017-07-17 10:27:39 +02:00
|
|
|
violations.add("TBR percentage must be within 0-500%");
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (percentage != 100) {
|
|
|
|
if (duration % 15 != 0) {
|
2017-07-17 10:27:39 +02:00
|
|
|
violations.add("TBR duration can only be set in 15 minute steps");
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|
|
|
|
if (duration > 60 * 24) {
|
2017-07-17 10:27:39 +02:00
|
|
|
violations.add("Maximum TBR duration is 24 hours");
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (percentage == 0 && duration > 120) {
|
2017-07-17 10:27:39 +02:00
|
|
|
violations.add("Max allowed zero-temp duration is 2h");
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|
2017-07-17 10:27:39 +02:00
|
|
|
|
2017-07-18 01:24:13 +02:00
|
|
|
return violations;
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|
2017-08-12 16:00:05 +02:00
|
|
|
|
2017-08-12 00:12:11 +02:00
|
|
|
@Override
|
|
|
|
public CommandResult execute(RuffyScripter scripter, PumpState initialPumpState) {
|
|
|
|
try {
|
2017-08-12 16:00:05 +02:00
|
|
|
log.debug("1. going from " + scripter.currentMenu + " to TBR_MENU");
|
2017-08-12 00:12:11 +02:00
|
|
|
int retries = 5;
|
2017-08-12 16:00:05 +02:00
|
|
|
while (!scripter.goToMainTypeScreen(TBR_MENU, 3000)) {
|
2017-08-12 00:12:11 +02:00
|
|
|
retries--;
|
2017-08-12 16:00:05 +02:00
|
|
|
if (retries == 0)
|
|
|
|
throw new CommandException().message("not able to find TBR_MENU: stuck in " + scripter.currentMenu);
|
2017-08-12 13:36:09 +02:00
|
|
|
SystemClock.sleep(500);
|
2017-08-12 16:00:05 +02:00
|
|
|
if (scripter.currentMenu.getType() == TBR_MENU)
|
2017-08-12 00:12:11 +02:00
|
|
|
break;
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|
2017-08-12 00:12:11 +02:00
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
if (scripter.currentMenu.getType() != TBR_MENU)
|
|
|
|
throw new CommandException().message("not able to find TBR_MENU: stuck in " + scripter.currentMenu);
|
2017-08-12 00:12:11 +02:00
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
log.debug("2. entering " + scripter.currentMenu);
|
2017-08-12 00:12:11 +02:00
|
|
|
retries = 5;
|
2017-08-12 16:00:05 +02:00
|
|
|
while (!scripter.enterMenu(TBR_MENU, MenuType.TBR_SET, RuffyScripter.Key.CHECK, 2000)) {
|
2017-08-12 00:12:11 +02:00
|
|
|
retries--;
|
2017-08-12 16:00:05 +02:00
|
|
|
if (retries == 0)
|
|
|
|
throw new CommandException().message("not able to find TBR_SET: stuck in " + scripter.currentMenu);
|
2017-08-12 13:36:09 +02:00
|
|
|
SystemClock.sleep(500);
|
2017-08-12 16:00:05 +02:00
|
|
|
if (scripter.currentMenu.getType() == TBR_SET)
|
2017-08-12 00:12:11 +02:00
|
|
|
break;
|
2017-08-12 16:00:05 +02:00
|
|
|
if (scripter.currentMenu.getType() == TBR_DURATION) {
|
2017-08-12 00:12:11 +02:00
|
|
|
scripter.pressMenuKey();
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-11 14:19:16 +02:00
|
|
|
}
|
2017-08-12 00:12:11 +02:00
|
|
|
}
|
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
log.debug("SetTbrCommand: 3. getting/setting basal percentage in " + scripter.currentMenu);
|
2017-08-12 00:12:11 +02:00
|
|
|
retries = 30;
|
|
|
|
|
|
|
|
double currentPercentage = -100;
|
2017-08-12 16:00:05 +02:00
|
|
|
while (currentPercentage != percentage && retries >= 0) {
|
2017-08-12 00:12:11 +02:00
|
|
|
retries--;
|
|
|
|
Object percentageObj = scripter.currentMenu.getAttribute(MenuAttribute.BASAL_RATE);
|
|
|
|
|
|
|
|
if (percentageObj != null && (percentageObj instanceof Double)) {
|
|
|
|
currentPercentage = ((Double) percentageObj).doubleValue();
|
|
|
|
|
|
|
|
if (currentPercentage != percentage) {
|
|
|
|
int requestedPercentage = (int) percentage;
|
|
|
|
int actualPercentage = (int) currentPercentage;
|
|
|
|
int steps = (requestedPercentage - actualPercentage) / 10;
|
2017-08-12 09:29:07 +02:00
|
|
|
log.debug("Adjusting basal(" + requestedPercentage + "/" + actualPercentage + ") with " + steps + " steps and " + retries + " retries left");
|
2017-08-12 00:12:11 +02:00
|
|
|
scripter.step(steps, (steps < 0 ? RuffyScripter.Key.DOWN : RuffyScripter.Key.UP), 500);
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-05 15:33:28 +02:00
|
|
|
}
|
2017-08-12 00:12:11 +02:00
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
} else {
|
|
|
|
currentPercentage = -100;
|
2017-08-05 15:33:28 +02:00
|
|
|
}
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-12 00:12:11 +02:00
|
|
|
}
|
2017-08-12 16:00:05 +02:00
|
|
|
if (currentPercentage < 0 || retries < 0)
|
|
|
|
throw new CommandException().message("unable to set basal percentage");
|
2017-08-12 00:12:11 +02:00
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
log.debug("4. checking basal percentage in " + scripter.currentMenu);
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-12 16:00:05 +02:00
|
|
|
currentPercentage = -1000;
|
|
|
|
retries = 10;
|
|
|
|
while (currentPercentage < 0 && retries >= 0) {
|
2017-08-12 00:12:11 +02:00
|
|
|
retries--;
|
|
|
|
Object percentageObj = scripter.currentMenu.getAttribute(MenuAttribute.BASAL_RATE);
|
|
|
|
|
|
|
|
if (percentageObj != null && (percentageObj instanceof Double)) {
|
|
|
|
currentPercentage = ((Double) percentageObj).doubleValue();
|
2017-08-12 16:00:05 +02:00
|
|
|
} else {
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-12 16:00:05 +02:00
|
|
|
}
|
2017-08-12 00:12:11 +02:00
|
|
|
}
|
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
if (retries < 0 || currentPercentage != percentage)
|
2017-08-12 15:06:30 +02:00
|
|
|
throw new CommandException().message("Unable to set percentage. Requested: " + percentage + ", value displayed on pump: " + currentPercentage);
|
2017-08-12 00:12:11 +02:00
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
if (currentPercentage != 100) {
|
2017-08-12 09:29:07 +02:00
|
|
|
log.debug("5. change to TBR_DURATION from " + scripter.currentMenu);
|
2017-08-12 00:12:11 +02:00
|
|
|
retries = 5;
|
2017-08-12 16:00:05 +02:00
|
|
|
while (retries >= 0 && !scripter.enterMenu(TBR_SET, MenuType.TBR_DURATION, RuffyScripter.Key.MENU, 2000)) {
|
2017-08-05 15:33:28 +02:00
|
|
|
retries--;
|
2017-08-12 00:12:11 +02:00
|
|
|
if (retries == 0)
|
2017-08-12 13:26:05 +02:00
|
|
|
throw new CommandException().message("not able to find TBR_SET: stuck in " + scripter.currentMenu);
|
2017-08-12 13:36:09 +02:00
|
|
|
SystemClock.sleep(500);
|
2017-08-12 00:12:11 +02:00
|
|
|
if (scripter.currentMenu.getType() == TBR_DURATION)
|
|
|
|
break;
|
|
|
|
if (scripter.currentMenu.getType() == TBR_SET) {
|
|
|
|
scripter.pressMenuKey();
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-12 00:12:11 +02:00
|
|
|
}
|
2017-08-05 15:33:28 +02:00
|
|
|
}
|
2017-08-12 00:12:11 +02:00
|
|
|
|
2017-08-12 09:29:07 +02:00
|
|
|
log.debug("6. getting/setting duration in " + scripter.currentMenu);
|
2017-08-12 00:12:11 +02:00
|
|
|
retries = 30;
|
|
|
|
|
|
|
|
double currentDuration = -100;
|
|
|
|
while (currentDuration != duration && retries >= 0) {
|
|
|
|
retries--;
|
2017-08-05 15:33:28 +02:00
|
|
|
Object durationObj = scripter.currentMenu.getAttribute(MenuAttribute.RUNTIME);
|
2017-08-12 09:29:07 +02:00
|
|
|
log.debug("Requested time: " + duration + " actual time: " + durationObj);
|
2017-08-12 00:12:11 +02:00
|
|
|
if (durationObj != null && durationObj instanceof MenuTime) {
|
2017-08-05 15:33:28 +02:00
|
|
|
MenuTime time = (MenuTime) durationObj;
|
2017-08-12 00:12:11 +02:00
|
|
|
currentDuration = (time.getHour() * 60) + time.getMinute();
|
|
|
|
if (currentDuration != duration) {
|
|
|
|
int requestedDuration = (int) duration;
|
|
|
|
int actualDuration = (int) currentDuration;
|
|
|
|
int steps = (requestedDuration - actualDuration) / 15;
|
|
|
|
if (currentDuration + (steps * 15) < requestedDuration)
|
|
|
|
steps++;
|
|
|
|
else if (currentDuration + (steps * 15) > requestedDuration)
|
|
|
|
steps--;
|
2017-08-12 09:29:07 +02:00
|
|
|
log.debug("Adjusting duration(" + requestedDuration + "/" + actualDuration + ") with " + steps + " steps and " + retries + " retries left");
|
2017-08-12 00:12:11 +02:00
|
|
|
scripter.step(steps, (steps > 0 ? RuffyScripter.Key.UP : RuffyScripter.Key.DOWN), 500);
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-05 15:33:28 +02:00
|
|
|
}
|
|
|
|
}
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-05 15:33:28 +02:00
|
|
|
}
|
2017-08-12 00:12:11 +02:00
|
|
|
if (currentDuration < 0 || retries < 0)
|
2017-08-12 14:14:48 +02:00
|
|
|
throw new CommandException().message("unable to set duration, requested:" + duration + ", displayed on pump: " + currentDuration);
|
2017-08-12 00:12:11 +02:00
|
|
|
|
2017-08-12 15:06:30 +02:00
|
|
|
log.debug("7. checking duration in " + scripter.currentMenu);
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-12 00:12:11 +02:00
|
|
|
currentDuration = -1000;
|
|
|
|
retries = 10;
|
|
|
|
while (currentDuration < 0 && retries >= 0) {
|
|
|
|
retries--;
|
|
|
|
Object durationObj = scripter.currentMenu.getAttribute(MenuAttribute.RUNTIME);
|
|
|
|
|
|
|
|
if (durationObj != null && durationObj instanceof MenuTime) {
|
|
|
|
MenuTime time = (MenuTime) durationObj;
|
|
|
|
currentDuration = (time.getHour() * 60) + time.getMinute();
|
2017-08-12 16:00:05 +02:00
|
|
|
} else
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-05 15:33:28 +02:00
|
|
|
}
|
2017-08-12 00:12:11 +02:00
|
|
|
if (retries < 0 || currentDuration != duration)
|
2017-08-12 15:06:30 +02:00
|
|
|
throw new CommandException().message("wrong duration! Requested: " + duration + ", displayed on pump: " + currentDuration);
|
2017-08-12 00:12:11 +02:00
|
|
|
}
|
|
|
|
|
2017-08-12 15:06:30 +02:00
|
|
|
log.debug("8. confirming TBR om " + scripter.currentMenu);
|
2017-08-12 16:00:05 +02:00
|
|
|
retries = 5;
|
|
|
|
while (retries >= 0 && (scripter.currentMenu.getType() == TBR_DURATION || scripter.currentMenu.getType() == TBR_SET)) {
|
2017-08-12 00:12:11 +02:00
|
|
|
retries--;
|
|
|
|
scripter.pressCheckKey();
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-12 00:12:11 +02:00
|
|
|
}
|
2017-08-12 16:00:05 +02:00
|
|
|
if (retries < 0 || scripter.currentMenu.getType() == TBR_DURATION || scripter.currentMenu.getType() == TBR_SET)
|
2017-08-12 13:26:05 +02:00
|
|
|
throw new CommandException().message("failed setting basal!");
|
2017-08-12 16:00:05 +02:00
|
|
|
retries = 10;
|
|
|
|
boolean cancelledError = true;
|
|
|
|
if (percentage == 100)
|
|
|
|
cancelledError = false;
|
|
|
|
while (retries >= 0 && scripter.currentMenu.getType() != MAIN_MENU) {
|
2017-08-12 15:06:30 +02:00
|
|
|
// TODO how probable is it, that a totally unrelated error (like occlusion alert)
|
|
|
|
// is raised at this point, which we'd cancel together with the TBR cancelled alert?
|
2017-08-12 16:00:05 +02:00
|
|
|
if (percentage == 100 && scripter.currentMenu.getType() == WARNING_OR_ERROR) {
|
2017-08-05 15:33:28 +02:00
|
|
|
scripter.pressCheckKey();
|
2017-08-12 00:12:11 +02:00
|
|
|
retries++;
|
2017-08-12 16:00:05 +02:00
|
|
|
cancelledError = true;
|
2017-08-12 14:15:23 +02:00
|
|
|
scripter.waitForScreenUpdate(1000);
|
2017-08-12 16:00:05 +02:00
|
|
|
} else {
|
2017-08-12 00:12:11 +02:00
|
|
|
retries--;
|
2017-08-12 16:00:05 +02:00
|
|
|
if (scripter.currentMenu.getType() == MAIN_MENU && cancelledError)
|
2017-08-12 00:12:11 +02:00
|
|
|
break;
|
2017-08-05 15:33:28 +02:00
|
|
|
}
|
2017-07-15 14:46:58 +02:00
|
|
|
}
|
2017-08-12 14:14:48 +02:00
|
|
|
|
|
|
|
log.debug("9. verifying the main menu display the TBR we just set/cancelled");
|
2017-08-12 16:00:05 +02:00
|
|
|
if (retries < 0 || scripter.currentMenu.getType() != MAIN_MENU)
|
2017-08-12 13:26:05 +02:00
|
|
|
throw new CommandException().message("failed going to main!");
|
2017-08-12 00:12:11 +02:00
|
|
|
|
|
|
|
Object percentageObj = scripter.currentMenu.getAttribute(MenuAttribute.TBR);
|
|
|
|
Object durationObj = scripter.currentMenu.getAttribute(MenuAttribute.RUNTIME);
|
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
if (percentage == 100) {
|
2017-08-15 13:15:37 +02:00
|
|
|
if (durationObj != null)
|
2017-08-12 15:11:19 +02:00
|
|
|
throw new CommandException().message("TBR cancelled, but main menu shows a running TBR");
|
|
|
|
|
|
|
|
return new CommandResult().success(true).enacted(true).message("TBR was cancelled");
|
|
|
|
}
|
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
if (percentageObj == null || !(percentageObj instanceof Double))
|
2017-08-12 13:26:05 +02:00
|
|
|
throw new CommandException().message("not percentage");
|
2017-08-12 00:12:11 +02:00
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
if (((double) percentageObj) != percentage)
|
2017-08-12 13:26:05 +02:00
|
|
|
throw new CommandException().message("wrong percentage set!");
|
2017-08-12 00:12:11 +02:00
|
|
|
|
2017-08-12 16:00:05 +02:00
|
|
|
if (durationObj == null || !(durationObj instanceof MenuTime))
|
2017-08-12 13:26:05 +02:00
|
|
|
throw new CommandException().message("not time");
|
2017-08-12 00:12:11 +02:00
|
|
|
|
|
|
|
MenuTime t = (MenuTime) durationObj;
|
2017-08-12 16:00:05 +02:00
|
|
|
if (t.getMinute() + (60 * t.getHour()) > duration || t.getMinute() + (60 * t.getHour()) < duration - 5)
|
2017-08-12 13:26:05 +02:00
|
|
|
throw new CommandException().message("wrong time set!");
|
2017-08-12 00:12:11 +02:00
|
|
|
|
2017-08-12 15:11:19 +02:00
|
|
|
|
2017-08-11 14:19:16 +02:00
|
|
|
return new CommandResult().success(true).enacted(true).message(
|
|
|
|
String.format(Locale.US, "TBR set to %d%% for %d min", percentage, duration));
|
2017-08-12 00:12:11 +02:00
|
|
|
} catch (Exception e) {
|
2017-08-12 09:29:07 +02:00
|
|
|
log.error("got exception: ", e);
|
2017-08-15 13:15:37 +02:00
|
|
|
return new CommandResult().success(false).message(e.getMessage()).exception(e);
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|
|
|
|
}
|
2017-07-14 15:01:20 +02:00
|
|
|
|
|
|
|
@Override
|
|
|
|
public String toString() {
|
|
|
|
return "SetTbrCommand{" +
|
|
|
|
"percentage=" + percentage +
|
|
|
|
", duration=" + duration +
|
|
|
|
'}';
|
|
|
|
}
|
2017-07-13 19:50:11 +02:00
|
|
|
}
|