diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java index a3320cf61a..76290678e2 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java @@ -98,6 +98,8 @@ import info.nightscout.androidaps.utils.sharedPreferences.SP; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.schedulers.Schedulers; +import static info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants.BASAL_STEP_DURATION; + /** * Created by andy on 23.04.18. * @@ -545,6 +547,10 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface, durationInMinutes, Profile profile, boolean enforceNew) { aapsLogger.info(LTag.PUMP, "setTempBasalAbsolute: rate: {}, duration={}", absoluteRate, durationInMinutes); + if (durationInMinutes <= 0 || durationInMinutes % BASAL_STEP_DURATION.getStandardMinutes() != 0) { + return new PumpEnactResult(getInjector()).success(false).comment(resourceHelper.gs(R.string.omnipod_error_set_temp_basal_failed_validation, BASAL_STEP_DURATION.getStandardMinutes())); + } + // read current TBR TemporaryBasal tbrCurrent = readTBR(); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/OmnipodConstants.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/OmnipodConstants.java index b5b65f0f58..a9504e974f 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/OmnipodConstants.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/OmnipodConstants.java @@ -14,6 +14,7 @@ public class OmnipodConstants { public static final double MAX_RESERVOIR_READING = 50.0; public static final double MAX_BOLUS = 30.0; public static final double MAX_BASAL_RATE = 30.0; + public static final Duration BASAL_STEP_DURATION = Duration.standardMinutes(30); public static final Duration MAX_TEMP_BASAL_DURATION = Duration.standardHours(12); public static final int DEFAULT_ADDRESS = 0xffffffff; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/RateEntry.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/RateEntry.java index e3d5d7cf28..51e6f297d0 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/RateEntry.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/schedule/RateEntry.java @@ -9,6 +9,8 @@ import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.IRawRepresentable; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import static info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants.BASAL_STEP_DURATION; + public class RateEntry implements IRawRepresentable { private final double totalPulses; @@ -21,6 +23,13 @@ public class RateEntry implements IRawRepresentable { } public static List createEntries(double rate, Duration duration) { + if (Duration.ZERO.equals(duration)) { + throw new IllegalArgumentException("Duration may not be 0 minutes."); + } + if (duration.getStandardMinutes() % BASAL_STEP_DURATION.getStandardMinutes() != 0) { + throw new IllegalArgumentException("Duration must be a multiple of " + BASAL_STEP_DURATION.getStandardMinutes() + " minutes."); + } + List entries = new ArrayList<>(); int remainingSegments = (int) Math.round(duration.getStandardSeconds() / 1800.0); double pulsesPerSegment = (int) Math.round(rate / OmnipodConstants.POD_PULSE_SIZE) / 2.0; diff --git a/omnipod/src/main/res/values/strings.xml b/omnipod/src/main/res/values/strings.xml index 7be906aae4..befc1d8233 100644 --- a/omnipod/src/main/res/values/strings.xml +++ b/omnipod/src/main/res/values/strings.xml @@ -105,6 +105,7 @@ Cancelling temp basal might have failed. Please manually refresh the Pod status from the Omnipod tab. Setting temp basal failed. If a temp basal was previously running, it might have been cancelled. Please manually refresh the Pod status from the Omnipod tab. Setting temp might have basal failed. If a temp basal was previously running, it has been cancelled. Please manually refresh the Pod status from the Omnipod tab. + TBR duration must be greater than zero and a multiple of %1$s minutes. Setting time might have failed. Delivery might be suspended! Please manually refresh the Pod status from the Omnipod tab and resume delivery if needed. Setting time failed. Delivery is suspended! Please manually resume delivery from the Omnipod tab. Failed to set basal profile: received an empty profile. Make sure to activate your basal profile. diff --git a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPluginTest.java b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPluginTest.java index 64f7f48728..e2b4cd31ec 100644 --- a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPluginTest.java +++ b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPluginTest.java @@ -89,7 +89,7 @@ public class OmnipodPumpPluginTest { PumpEnactResult result2 = plugin.setTempBasalPercent(5000, 30000, profile, false); PumpEnactResult result3 = plugin.setTempBasalPercent(0, 30, profile, false); PumpEnactResult result4 = plugin.setTempBasalPercent(0, 0, profile, false); - PumpEnactResult result5 = plugin.setTempBasalPercent(-50, -1, profile, false); + PumpEnactResult result5 = plugin.setTempBasalPercent(-50, 60, profile, false); // Then return correct values assertEquals(result1.absolute, 0.4d, 0.01d); assertEquals(result1.duration, 30); @@ -97,22 +97,22 @@ public class OmnipodPumpPluginTest { assertEquals(result2.duration, 30000); assertEquals(result3.absolute, 0d, 0.01d); assertEquals(result3.duration, 30); - assertEquals(result4.absolute, 0d, 0.01d); - assertEquals(result4.duration, 0); + assertEquals(result4.absolute, -1d, 0.01d); + assertEquals(result4.duration, -1); // this is validated downstream, see TempBasalExtraCommand assertEquals(result5.absolute, -0.25d, 0.01d); - assertEquals(result5.duration, -1); + assertEquals(result5.duration, 60); // Given zero basal when(profile.getBasal()).thenReturn(0d); // When - result1 = plugin.setTempBasalPercent(8000, 10, profile, false); - result2 = plugin.setTempBasalPercent(0, 00, profile, false); + result1 = plugin.setTempBasalPercent(8000, 90, profile, false); + result2 = plugin.setTempBasalPercent(0, 0, profile, false); // Then return zero values assertEquals(result1.absolute, 0d, 0.01d); - assertEquals(result1.duration, 10); - assertEquals(result2.absolute, 0d, 0.01d); - assertEquals(result2.duration, 0); + assertEquals(result1.duration, 90); + assertEquals(result2.absolute, -1d, 0.01d); + assertEquals(result2.duration, -1); // Given unhealthy basal when(profile.getBasal()).thenReturn(500d); @@ -125,18 +125,18 @@ public class OmnipodPumpPluginTest { // Given weird basal when(profile.getBasal()).thenReturn(1.234567d); // When treatment - result1 = plugin.setTempBasalPercent(280, 500, profile, false); + result1 = plugin.setTempBasalPercent(280, 600, profile, false); // Then return sane values assertEquals(result1.absolute, 3.4567876, 0.01d); - assertEquals(result1.duration, 500); + assertEquals(result1.duration, 600); // Given negative basal when(profile.getBasal()).thenReturn(-1.234567d); // When treatment - result1 = plugin.setTempBasalPercent(280, 500, profile, false); + result1 = plugin.setTempBasalPercent(280, 510, profile, false); // Then return negative value (this is validated further downstream, see TempBasalExtraCommand) assertEquals(result1.absolute, -3.4567876, 0.01d); - assertEquals(result1.duration, 500); + assertEquals(result1.duration, 510); } }