diff --git a/app/src/main/java/de/jotomo/ruffyscripter/PumpCapabilities.java b/app/src/main/java/de/jotomo/ruffyscripter/PumpCapabilities.java new file mode 100644 index 0000000000..1270851ea0 --- /dev/null +++ b/app/src/main/java/de/jotomo/ruffyscripter/PumpCapabilities.java @@ -0,0 +1,23 @@ +package de.jotomo.ruffyscripter; + +/** + * Created by adrian on 26/07/17. + * + * Contains the capabilities of the current pump model. + */ + +public class PumpCapabilities { + public long maxTempPercent; + + public PumpCapabilities maxTempPercent(long maxTempPercent) { + this.maxTempPercent = maxTempPercent; + return this; + } + + @Override + public String toString() { + return "PumpCapabilities{" + + "maxTempPercent=" + maxTempPercent + + '}'; + } +} diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java index baba5e5216..296f61f056 100644 --- a/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/CommandResult.java @@ -3,6 +3,7 @@ package de.jotomo.ruffyscripter.commands; import java.util.Date; import de.jotomo.ruffyscripter.History; +import de.jotomo.ruffyscripter.PumpCapabilities; import de.jotomo.ruffyscripter.PumpState; public class CommandResult { @@ -13,6 +14,7 @@ public class CommandResult { public String message; public PumpState state; public History history; + public PumpCapabilities capabilities; public CommandResult() { } @@ -52,6 +54,11 @@ public class CommandResult { return this; } + public CommandResult capabilities(PumpCapabilities capabilities) { + this.capabilities = capabilities; + return this; + } + @Override public String toString() { return "CommandResult{" + diff --git a/app/src/main/java/de/jotomo/ruffyscripter/commands/DetermineCapabilitiesCommand.java b/app/src/main/java/de/jotomo/ruffyscripter/commands/DetermineCapabilitiesCommand.java new file mode 100644 index 0000000000..e78bd2f01c --- /dev/null +++ b/app/src/main/java/de/jotomo/ruffyscripter/commands/DetermineCapabilitiesCommand.java @@ -0,0 +1,165 @@ +package de.jotomo.ruffyscripter.commands; + +import android.os.SystemClock; + +import com.j256.ormlite.stmt.query.In; + +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.Collections; +import java.util.List; +import java.util.Locale; + +import de.jotomo.ruffyscripter.PumpCapabilities; +import de.jotomo.ruffyscripter.PumpState; +import de.jotomo.ruffyscripter.RuffyScripter; + + +public class DetermineCapabilitiesCommand implements Command { + private static final Logger log = LoggerFactory.getLogger(DetermineCapabilitiesCommand.class); + public static final int UP_STEPS = 75; + + @Override + public List validateArguments() { + return Collections.emptyList(); + } + + @Override + public CommandResult execute(RuffyScripter scripter, PumpState initialPumpState) { + try { + + //read main menu 100% or TBR? Read remaining duration. + long durationBefore = readDisplayedTbrDurationMainMenu(scripter); + long percentageBefore = readDisplayedTbrPercentageMainMenu(scripter); + + enterTbrMenu(scripter); + long maxTbrPercentage = findMaxTbrPercentage(scripter); + + // TODO v2 this can probably be removed by now + SystemClock.sleep(750); + + scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU, + "Pump did not return to MAIN_MEU after finding max tbr. " + + "Check pump manually, the TBR might be wrong."); + + + //TODO: check if TBR is still the same or duration was less than 5 minutes + long durationAfter = readDisplayedTbrDurationMainMenu(scripter); + long percentageAfter = readDisplayedTbrPercentageMainMenu(scripter); + + if(Math.abs(durationBefore-durationAfter) > 5){ + throw new CommandException().message("Duration jump during DetermineCapabilities"); + } + if(percentageAfter != percentageBefore){ + if(durationBefore<5 && percentageAfter == 100){ + log.debug("(percentageBefore != percentageAfter) - ignoring as tbr is now 100% and had a very short duration left"); + } + throw new CommandException().message("TBR changed while determining maxTBR."); + } + + //TODO return Result + return new CommandResult().success(true).enacted(false).message("Capablities: {maxTbrPercentage = " + maxTbrPercentage + ", success=" + "success }").capabilities((new PumpCapabilities()).maxTempPercent(maxTbrPercentage)); + } 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 long findMaxTbrPercentage(RuffyScripter scripter) { + scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); + long activeTempBasal = readDisplayedTbrPercentage(scripter); + + // pretend to increase the TBR to more than 500% + log.debug("Pressing up " + UP_STEPS + " times to get to maximum"); + for (int i = 0; i < UP_STEPS; i++) { + scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); + scripter.pressUpKey(); + SystemClock.sleep(100); + log.debug("Push #" + (i + 1)); + } + + //read the displayed maximum value + scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); + long maximumTempBasal = readDisplayedTbrPercentage(scripter); + + //reset the TBR in a controlled manner + long percentageChange = maximumTempBasal - activeTempBasal; + long percentageSteps = percentageChange / 10; + log.debug("Pressing down " + percentageSteps + " times to get to previous value"); + for (int i = 0; i < percentageSteps; i++) { + scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); + scripter.pressDownKey(); + SystemClock.sleep(100); + log.debug("Push #" + (i + 1)); + } + + + //do the rest if button-presses failed. + scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); + int i= 0; + while (readDisplayedTbrPercentage(scripter) > activeTempBasal && i < percentageSteps) { + scripter.verifyMenuIsDisplayed(MenuType.TBR_SET); + scripter.pressDownKey(); + SystemClock.sleep(100); + log.debug("Push again as previous buttons failed: #" + i); + i++; + } + + //exit menu + scripter.pressCheckKey(); + scripter.waitForMenuToBeLeft(MenuType.TBR_SET); + return maximumTempBasal; + } + + + private long readDisplayedTbrPercentage(RuffyScripter scripter) { + SystemClock.sleep(250); + // 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 int readDisplayedTbrDurationMainMenu(RuffyScripter scripter) { + scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU); + if(scripter.currentMenu.attributes().contains(MenuAttribute.RUNTIME)){ + // TODO v2 add timeout? Currently the command execution timeout would trigger if exceeded + Object durationObj = scripter.currentMenu.getAttribute(MenuAttribute.RUNTIME); + MenuTime duration = (MenuTime) durationObj; + return duration.getHour() * 60 + duration.getMinute(); + } else { + return 0; + } + } + + private int readDisplayedTbrPercentageMainMenu(RuffyScripter scripter) { + scripter.verifyMenuIsDisplayed(MenuType.MAIN_MENU); + if(scripter.currentMenu.attributes().contains(MenuAttribute.TBR)){ + return (int)((Double) scripter.currentMenu.getAttribute(MenuAttribute.TBR)).doubleValue(); + } else { + return 100; + } + } + + @Override + public String toString() { + return "DetermineCapabilitiesCommand{}"; + } +} diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java index 569f57bb25..0c331b8eb7 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboFragment.java @@ -33,6 +33,8 @@ public class ComboFragment extends Fragment implements View.OnClickListener { } private Button refresh; + private Button testButton; + private TextView statusText; private TextView tbrPercentageText; @@ -50,6 +52,8 @@ public class ComboFragment extends Fragment implements View.OnClickListener { View view = inflater.inflate(R.layout.combopump_fragment, container, false); refresh = (Button) view.findViewById(R.id.combo_refresh); + testButton = (Button) view.findViewById(R.id.combo_testaction); + statusText = (TextView) view.findViewById(R.id.combo_status); tbrPercentageText = (TextView) view.findViewById(R.id.combo_tbr_percentage); @@ -62,6 +66,7 @@ public class ComboFragment extends Fragment implements View.OnClickListener { lastCmdResultText = (TextView) view.findViewById(R.id.combo_last_command_result); refresh.setOnClickListener(this); + testButton.setOnClickListener(this); updateGUI(); return view; @@ -97,6 +102,14 @@ public class ComboFragment extends Fragment implements View.OnClickListener { }); thread.start(); break; + case R.id.combo_testaction: + (new Thread(new Runnable() { + @Override + public void run() { + getPlugin().doTestAction(); + } + })).start(); + break; } } diff --git a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java index 956e40449c..ce76f7df8a 100644 --- a/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java +++ b/app/src/main/java/info/nightscout/androidaps/plugins/PumpCombo/ComboPlugin.java @@ -29,6 +29,7 @@ import de.jotomo.ruffyscripter.commands.BolusCommand; import de.jotomo.ruffyscripter.commands.CancelTbrCommand; import de.jotomo.ruffyscripter.commands.Command; import de.jotomo.ruffyscripter.commands.CommandResult; +import de.jotomo.ruffyscripter.commands.DetermineCapabilitiesCommand; import de.jotomo.ruffyscripter.commands.ReadPumpStateCommand; import de.jotomo.ruffyscripter.commands.SetTbrCommand; import de.jotomo.ruffyscripter.PumpState; @@ -47,6 +48,7 @@ import info.nightscout.androidaps.interfaces.PumpInterface; import info.nightscout.androidaps.plugins.ConfigBuilder.ConfigBuilderPlugin; import info.nightscout.androidaps.plugins.PumpCombo.events.EventComboPumpUpdateGUI; import info.nightscout.utils.DateUtil; +import info.nightscout.utils.ToastUtils; /** * Created by mike on 05.08.2016. @@ -617,6 +619,27 @@ public class ComboPlugin implements PluginBase, PumpInterface { public void onStatusEvent(final EventAppExit e) { unbindRuffyService(); } + + + public void doTestAction() { + ToastUtils.showToastInUiThread(MainApp.instance(), "TestAction called"); + + // if Android is sluggish this might get called before ruffy is bound + if (ruffyScripter == null) { + log.warn("Rejecting call to RefreshDataFromPump: ruffy service not bound (yet)"); + ToastUtils.showToastInUiThread(MainApp.instance(), "Rejecting call to RefreshDataFromPump: ruffy service not bound (yet)"); + + return; + } + CommandResult result = runCommand(new DetermineCapabilitiesCommand()); + if (result.success){ + ToastUtils.showToastInUiThread(MainApp.instance(), "max%: " + result.capabilities.maxTempPercent); + } else { + ToastUtils.showToastInUiThread(MainApp.instance(), "No success with test Command."); + } + } + + } diff --git a/app/src/main/res/layout/combopump_fragment.xml b/app/src/main/res/layout/combopump_fragment.xml index a0d85fb849..d076925740 100644 --- a/app/src/main/res/layout/combopump_fragment.xml +++ b/app/src/main/res/layout/combopump_fragment.xml @@ -20,6 +20,12 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Refresh" /> +