SetBasalProfileCommand: step calculation for all ranges.
This commit is contained in:
parent
e216bfcb12
commit
9698863f90
|
@ -42,9 +42,9 @@ public class SetBasalProfileCommand extends BaseCommand {
|
||||||
scripter.verifyMenuIsDisplayed(MenuType.BASAL_SET);
|
scripter.verifyMenuIsDisplayed(MenuType.BASAL_SET);
|
||||||
|
|
||||||
double requestedRate = basalProfile.hourlyRates[i];
|
double requestedRate = basalProfile.hourlyRates[i];
|
||||||
Boolean increasing = inputBasalRate(requestedRate);
|
long change = inputBasalRate(requestedRate);
|
||||||
if (increasing != null) {
|
if (change != 0) {
|
||||||
verifyDisplayedRate(requestedRate, increasing);
|
verifyDisplayedRate(requestedRate, change);
|
||||||
}
|
}
|
||||||
|
|
||||||
log.debug("Set basal profile, hour " + i + ": " + requestedRate);
|
log.debug("Set basal profile, hour " + i + ": " + requestedRate);
|
||||||
|
@ -60,7 +60,7 @@ public class SetBasalProfileCommand extends BaseCommand {
|
||||||
for (int i = 0; i < 24; i++) {
|
for (int i = 0; i < 24; i++) {
|
||||||
requestedTotal += basalProfile.hourlyRates[i];
|
requestedTotal += basalProfile.hourlyRates[i];
|
||||||
}
|
}
|
||||||
if (Math.abs(pumpTotal - requestedTotal) > 0.05) { // TODO leniency actually needed?
|
if (Math.abs(pumpTotal - requestedTotal) > 0.001) {
|
||||||
throw new CommandException("Basal total of " + pumpTotal + " differs from requested total of " + requestedTotal);
|
throw new CommandException("Basal total of " + pumpTotal + " differs from requested total of " + requestedTotal);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,46 +73,61 @@ public class SetBasalProfileCommand extends BaseCommand {
|
||||||
result.success(true).basalProfile(basalProfile);
|
result.success(true).basalProfile(basalProfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO boolean to indicate, up, down or neither? yikes
|
private long inputBasalRate(double requestedRate) {
|
||||||
private Boolean inputBasalRate(double requestedRate) {
|
|
||||||
// 0.05 steps; jumps to 0.10 steps if buttons are kept pressed, so there's room for optimization
|
|
||||||
double currentRate = scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE);
|
double currentRate = scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE);
|
||||||
if (Math.abs(currentRate - requestedRate) < 0.01) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
log.debug("Current rate: " + currentRate + ", requested: " + requestedRate);
|
log.debug("Current rate: " + currentRate + ", requested: " + requestedRate);
|
||||||
long steps = stepsUpToOne(currentRate) - stepsUpToOne(requestedRate);
|
long steps = calculateRequiredSteps(currentRate, requestedRate);
|
||||||
boolean increasing = steps > 0;
|
if (steps == 0) {
|
||||||
log.debug("Pressing " + (increasing ? "up" : "down") + " " + Math.abs(steps) + " times");
|
return 0;
|
||||||
|
}
|
||||||
|
log.debug("Pressing " + (steps > 0 ? "up" : "down") + " " + Math.abs(steps) + " times");
|
||||||
for (int i = 0; i < Math.abs(steps); i++) {
|
for (int i = 0; i < Math.abs(steps); i++) {
|
||||||
scripter.verifyMenuIsDisplayed(MenuType.BASAL_SET);
|
scripter.verifyMenuIsDisplayed(MenuType.BASAL_SET);
|
||||||
log.debug("Push #" + (i + 1) + "/" + Math.abs(steps));
|
log.debug("Push #" + (i + 1) + "/" + Math.abs(steps));
|
||||||
if (increasing) scripter.pressUpKey();
|
if (steps > 0) scripter.pressUpKey();
|
||||||
else scripter.pressDownKey();
|
else scripter.pressDownKey();
|
||||||
SystemClock.sleep(50);
|
SystemClock.sleep(50);
|
||||||
}
|
}
|
||||||
return increasing;
|
return steps;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Steps UP to 1.0
|
long calculateRequiredSteps(double currentRate, double requestedRate) {
|
||||||
* May return a negative value for steps down*/
|
long steps;
|
||||||
private long stepsUpToOne(double rate){
|
if (currentRate < 1 && requestedRate > 1) {
|
||||||
double change = (1.0-rate);
|
// going from below 1 to above 1, need both granularities
|
||||||
if (rate > 1) return Math.round(change/0.05);
|
// calculate steps 0.x -> 1.0, calculate 1.0 -> 1+
|
||||||
return Math.round(change/0.01);
|
long smallSteps = Math.round((1 - currentRate) / 0.01);
|
||||||
|
long bigSteps = Math.round((requestedRate - 1) / 0.05);
|
||||||
|
steps = smallSteps + bigSteps;
|
||||||
|
} else if (currentRate > 1 && requestedRate < 1) {
|
||||||
|
// going from above 1 to below 1, need both granularities
|
||||||
|
// calculate +1 -> 1.0, calculate 1.0 -> 0.x
|
||||||
|
long bigSteps = Math.round((currentRate - 1) / 0.05);
|
||||||
|
long smallSteps = Math.round((1 - requestedRate) / 0.01);
|
||||||
|
steps = (bigSteps + smallSteps) * -1;
|
||||||
|
} else if (currentRate < 1 && requestedRate <= 1) {
|
||||||
|
// staying below 1, finer granularity only
|
||||||
|
steps = Math.round((requestedRate - currentRate) / 0.01);
|
||||||
|
} else if (currentRate >= 1 && requestedRate >= 1) {
|
||||||
|
// staying above 1, coarser granularity only
|
||||||
|
steps = Math.round((requestedRate - currentRate) / 0.05);
|
||||||
|
} else {
|
||||||
|
throw new CommandException("Programmer doesn't know what he's doing");
|
||||||
|
}
|
||||||
|
return steps;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyDisplayedRate(double requestedRate, boolean increasingPercentage) {
|
private void verifyDisplayedRate(double requestedRate, long change) {
|
||||||
scripter.verifyMenuIsDisplayed(MenuType.BASAL_SET);
|
scripter.verifyMenuIsDisplayed(MenuType.BASAL_SET);
|
||||||
// wait up to 5s for any scrolling to finish
|
// wait up to 5s for any scrolling to finish
|
||||||
double displayedRate = scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE);
|
double displayedRate = scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE);
|
||||||
long timeout = System.currentTimeMillis() + 10 * 1000;
|
long timeout = System.currentTimeMillis() + 10 * 1000;
|
||||||
while (timeout > System.currentTimeMillis()
|
while (timeout > System.currentTimeMillis()
|
||||||
&& ((increasingPercentage && displayedRate < requestedRate)
|
&& ((change > 0 && displayedRate < requestedRate)
|
||||||
|| (!increasingPercentage && displayedRate > requestedRate))) {
|
|| (change < 0 && displayedRate > requestedRate))) {
|
||||||
log.debug("Waiting for pump to process scrolling input for rate, current: "
|
log.debug("Waiting for pump to process scrolling input for rate, current: "
|
||||||
+ displayedRate + ", desired: " + requestedRate + ", scrolling "
|
+ displayedRate + ", desired: " + requestedRate + ", scrolling "
|
||||||
+ (increasingPercentage ? "up" : "down"));
|
+ (change > 0 ? "up" : "down"));
|
||||||
scripter.waitForScreenUpdate();
|
scripter.waitForScreenUpdate();
|
||||||
displayedRate = scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE);
|
displayedRate = scripter.readBlinkingValue(Double.class, MenuAttribute.BASAL_RATE);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
package de.jotomo.ruffyscripter.commands;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.jotomo.ruffy.spi.BasalProfile;
|
||||||
|
|
||||||
|
import static org.hamcrest.CoreMatchers.equalTo;
|
||||||
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
public class SetBasalProfileCommandTest {
|
||||||
|
private SetBasalProfileCommand setBasalProfileCommand = new SetBasalProfileCommand(new BasalProfile());
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void belowOneToAboveOne() {
|
||||||
|
assertThat(
|
||||||
|
// 0.85 -> 1.00 = 15 + 1.00 -> 1.25 = 5 == 20
|
||||||
|
setBasalProfileCommand.calculateRequiredSteps(0.85, 1.25),
|
||||||
|
is(equalTo(20L)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void aboveOneToBelowOne() {
|
||||||
|
assertThat(
|
||||||
|
// 2.85 -> 1.00 = 37 + 1.00 -> 0.25 = 75 == -112
|
||||||
|
setBasalProfileCommand.calculateRequiredSteps(2.85, 0.25),
|
||||||
|
is(equalTo(-112L)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void belowOneToBelowOne() {
|
||||||
|
assertThat(
|
||||||
|
setBasalProfileCommand.calculateRequiredSteps(0.85, 0.25),
|
||||||
|
is(equalTo(-60L)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void aboveOneToAboveOne() {
|
||||||
|
assertThat(
|
||||||
|
setBasalProfileCommand.calculateRequiredSteps(2.85, 3.25),
|
||||||
|
is(equalTo(8L)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void greaterOrEqualIssuesAroundOne() {
|
||||||
|
assertThat(
|
||||||
|
setBasalProfileCommand.calculateRequiredSteps(0.99, 1.00),
|
||||||
|
is(equalTo(1L)));
|
||||||
|
assertThat(
|
||||||
|
setBasalProfileCommand.calculateRequiredSteps(1.00, 1.05),
|
||||||
|
is(equalTo(1L)));
|
||||||
|
assertThat(
|
||||||
|
setBasalProfileCommand.calculateRequiredSteps(1.10, 1.00),
|
||||||
|
is(equalTo(-2L)));
|
||||||
|
assertThat(
|
||||||
|
setBasalProfileCommand.calculateRequiredSteps(1.00, 1.10),
|
||||||
|
is(equalTo(2L)));
|
||||||
|
assertThat(
|
||||||
|
setBasalProfileCommand.calculateRequiredSteps(1.10, 0.98),
|
||||||
|
is(equalTo(-4L)));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue