From 6fa01f88e34ba3b927381ed86729f7d4428edad0 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Fri, 2 Oct 2020 00:56:54 +0200 Subject: [PATCH 01/15] Add FIXME --- .../message/response/podinfo/PodInfoFaultEvent.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java index 13a782fdf7..2ec60af9a5 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java @@ -71,7 +71,15 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons faultAccessingTables = encodedData[16] == 0x02; int i = ByteUtil.convertUnsignedByteToInt(encodedData[17]); byte value = (byte) (i >>> 4); + + // FIXME below line DOES NOT MATCH the OpenOmni Wiki description of the type 2 pod info response + // See https://github.com/openaps/openomni/wiki/Command-02-Pod-Information-Response#type-2 + // Example of an observed message from the Pod that makes below line throw an IllegalArgumentException: + // 1F0F038F20180216020D00000000000012FFFF03FF00160000879A070000012E + // the LogEventErrorCode class doesn't make any sense and should be removed. Instead, the a, bb and c bits in byte 17 + // should be decoded independently as per the response description on the OpenOmni Wiki logEventErrorType = LogEventErrorCode.fromByte(value); + logEventErrorPodProgressStatus = PodProgressStatus.fromByte((byte) (encodedData[17] & 0x0f)); receiverLowGain = (byte) (ByteUtil.convertUnsignedByteToInt(encodedData[18]) >>> 6); radioRSSI = (byte) (encodedData[18] & 0x3f); From e93a9eb34e8967b789c2ecc6445004744a3d6f5f Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Fri, 2 Oct 2020 02:51:16 +0200 Subject: [PATCH 02/15] Properly decode pod info response type 02 --- .../response/podinfo/PodInfoFaultEvent.java | 52 ++++++++++-------- .../driver/definition/LogEventErrorCode.java | 24 --------- .../podinfo/PodInfoFaultEventTest.java | 53 +++++++++++++++---- .../response/podinfo/PodInfoResponseTest.java | 3 +- 4 files changed, 72 insertions(+), 60 deletions(-) delete mode 100644 omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/LogEventErrorCode.java diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java index 2ec60af9a5..4432670239 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java @@ -2,12 +2,13 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mes import org.joda.time.Duration; +import java.util.Arrays; + import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.LogEventErrorCode; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; @@ -27,8 +28,10 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons private final Duration timeActive; private final AlertSet unacknowledgedAlerts; private final boolean faultAccessingTables; - private final LogEventErrorCode logEventErrorType; - private final PodProgressStatus logEventErrorPodProgressStatus; + private final boolean loggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging; + private final byte loggedFaultEventInternal2bitMainLoopRoutinesVariable; + private final boolean loggedFaultEventImmediateBolusInProgressDuringError; + private final PodProgressStatus loggedFaultEventErrorPodProgressStatus; private final byte receiverLowGain; private final byte radioRSSI; private final PodProgressStatus podProgressStatusAtTimeOfFirstLoggedFaultEvent; @@ -69,18 +72,11 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons unacknowledgedAlerts = new AlertSet(encodedData[15]); faultAccessingTables = encodedData[16] == 0x02; - int i = ByteUtil.convertUnsignedByteToInt(encodedData[17]); - byte value = (byte) (i >>> 4); - - // FIXME below line DOES NOT MATCH the OpenOmni Wiki description of the type 2 pod info response - // See https://github.com/openaps/openomni/wiki/Command-02-Pod-Information-Response#type-2 - // Example of an observed message from the Pod that makes below line throw an IllegalArgumentException: - // 1F0F038F20180216020D00000000000012FFFF03FF00160000879A070000012E - // the LogEventErrorCode class doesn't make any sense and should be removed. Instead, the a, bb and c bits in byte 17 - // should be decoded independently as per the response description on the OpenOmni Wiki - logEventErrorType = LogEventErrorCode.fromByte(value); - - logEventErrorPodProgressStatus = PodProgressStatus.fromByte((byte) (encodedData[17] & 0x0f)); + int loggedFaultEventInfo = ByteUtil.convertUnsignedByteToInt(encodedData[17]); + loggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging = (loggedFaultEventInfo & 0x80) == 0x80; + loggedFaultEventInternal2bitMainLoopRoutinesVariable = (byte) ((loggedFaultEventInfo >>> 5) & 0x03); + loggedFaultEventImmediateBolusInProgressDuringError = (loggedFaultEventInfo & 0x10) == 0x10; + loggedFaultEventErrorPodProgressStatus = PodProgressStatus.fromByte((byte) (loggedFaultEventInfo & 0x0f)); receiverLowGain = (byte) (ByteUtil.convertUnsignedByteToInt(encodedData[18]) >>> 6); radioRSSI = (byte) (encodedData[18] & 0x3f); podProgressStatusAtTimeOfFirstLoggedFaultEvent = PodProgressStatus.fromByte((byte) (encodedData[19] & 0x0f)); @@ -140,12 +136,20 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons return faultAccessingTables; } - public LogEventErrorCode getLogEventErrorType() { - return logEventErrorType; + public boolean isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging() { + return loggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging; } - public PodProgressStatus getLogEventErrorPodProgressStatus() { - return logEventErrorPodProgressStatus; + public byte getLoggedFaultEventInternal2bitMainLoopRoutinesVariable() { + return loggedFaultEventInternal2bitMainLoopRoutinesVariable; + } + + public boolean isLoggedFaultEventImmediateBolusInProgressDuringError() { + return loggedFaultEventImmediateBolusInProgressDuringError; + } + + public PodProgressStatus getLoggedFaultEventErrorPodProgressStatus() { + return loggedFaultEventErrorPodProgressStatus; } public byte getReceiverLowGain() { @@ -156,7 +160,7 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons return radioRSSI; } - public PodProgressStatus getPodProgressStatusAtTimeOfFirstLoggedFaultEvent() { + public PodProgressStatus getLoggedFaultEventPodProgressStatus() { return podProgressStatusAtTimeOfFirstLoggedFaultEvent; } @@ -178,12 +182,14 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons ", timeActive=" + timeActive + ", unacknowledgedAlerts=" + unacknowledgedAlerts + ", faultAccessingTables=" + faultAccessingTables + - ", logEventErrorType=" + logEventErrorType + - ", logEventErrorPodProgressStatus=" + logEventErrorPodProgressStatus + + ", loggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging=" + loggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging + + ", loggedFaultEventInternal2bitMainLoopRoutinesVariable=" + loggedFaultEventInternal2bitMainLoopRoutinesVariable + + ", loggedFaultEventImmediateBolusInProgressDuringError=" + loggedFaultEventImmediateBolusInProgressDuringError + + ", loggedFaultEventErrorPodProgressStatus=" + loggedFaultEventErrorPodProgressStatus + ", receiverLowGain=" + receiverLowGain + ", radioRSSI=" + radioRSSI + ", podProgressStatusAtTimeOfFirstLoggedFaultEvent=" + podProgressStatusAtTimeOfFirstLoggedFaultEvent + - ", unknownValue=" + ByteUtil.shortHexString(unknownValue) + + ", unknownValue=" + Arrays.toString(unknownValue) + '}'; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/LogEventErrorCode.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/LogEventErrorCode.java deleted file mode 100644 index eb7223b4f0..0000000000 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/LogEventErrorCode.java +++ /dev/null @@ -1,24 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; - -public enum LogEventErrorCode { - NONE((byte) 0x00), - IMMEDIATE_BOLUS_IN_PROGRESS((byte) 0x01), - INTERNAL_2_BIT_VARIABLE_SET_AND_MANIPULATED_IN_MAIN_LOOP_ROUTINES_2((byte) 0x02), - INTERNAL_2_BIT_VARIABLE_SET_AND_MANIPULATED_IN_MAIN_LOOP_ROUTINES_3((byte) 0x03), - INSULIN_STATE_TABLE_CORRUPTION((byte) 0x04); - - private final byte value; - - LogEventErrorCode(byte value) { - this.value = value; - } - - public static LogEventErrorCode fromByte(byte value) { - for (LogEventErrorCode type : values()) { - if (type.value == value) { - return type; - } - } - throw new IllegalArgumentException("Unknown LogEventErrorCode: " + value); - } -} diff --git a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEventTest.java b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEventTest.java index 5731123724..1ceb53cf59 100644 --- a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEventTest.java +++ b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEventTest.java @@ -6,7 +6,6 @@ import org.junit.Test; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.LogEventErrorCode; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; import static org.junit.Assert.assertEquals; @@ -30,8 +29,10 @@ public class PodInfoFaultEventTest { assertTrue(Duration.standardSeconds(8100).isEqual(podInfoFaultEvent.getTimeActive())); assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertEquals(LogEventErrorCode.NONE, podInfoFaultEvent.getLogEventErrorType()); - assertEquals(PodProgressStatus.INACTIVE, podInfoFaultEvent.getPodProgressStatusAtTimeOfFirstLoggedFaultEvent()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); + assertEquals(0x00, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); + assertEquals(PodProgressStatus.INACTIVE, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); assertEquals(2, podInfoFaultEvent.getReceiverLowGain()); assertEquals(21, podInfoFaultEvent.getRadioRSSI()); } @@ -50,8 +51,10 @@ public class PodInfoFaultEventTest { assertTrue(Duration.standardSeconds(60).isEqual(podInfoFaultEvent.getTimeActive())); assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertEquals(LogEventErrorCode.NONE, podInfoFaultEvent.getLogEventErrorType()); - assertEquals(PodProgressStatus.PRIMING_COMPLETED, podInfoFaultEvent.getPodProgressStatusAtTimeOfFirstLoggedFaultEvent()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); + assertEquals(0x00, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); + assertEquals(PodProgressStatus.PRIMING_COMPLETED, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); assertEquals(2, podInfoFaultEvent.getReceiverLowGain()); assertEquals(46, podInfoFaultEvent.getRadioRSSI()); } @@ -71,8 +74,10 @@ public class PodInfoFaultEventTest { assertNull(podInfoFaultEvent.getReservoirLevel()); assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertEquals(LogEventErrorCode.NONE, podInfoFaultEvent.getLogEventErrorType()); - assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getPodProgressStatusAtTimeOfFirstLoggedFaultEvent()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); + assertEquals(0x00, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); + assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); assertEquals(0, podInfoFaultEvent.getReceiverLowGain()); assertEquals(35, podInfoFaultEvent.getRadioRSSI()); } @@ -92,8 +97,10 @@ public class PodInfoFaultEventTest { assertNull(podInfoFaultEvent.getReservoirLevel()); assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertEquals(LogEventErrorCode.INTERNAL_2_BIT_VARIABLE_SET_AND_MANIPULATED_IN_MAIN_LOOP_ROUTINES_2, podInfoFaultEvent.getLogEventErrorType()); - assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getPodProgressStatusAtTimeOfFirstLoggedFaultEvent()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); + assertEquals(0x01, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); + assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); assertEquals(2, podInfoFaultEvent.getReceiverLowGain()); assertEquals(39, podInfoFaultEvent.getRadioRSSI()); } @@ -113,9 +120,33 @@ public class PodInfoFaultEventTest { assertNull(podInfoFaultEvent.getReservoirLevel()); assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertEquals(LogEventErrorCode.INTERNAL_2_BIT_VARIABLE_SET_AND_MANIPULATED_IN_MAIN_LOOP_ROUTINES_2, podInfoFaultEvent.getLogEventErrorType()); - assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getPodProgressStatusAtTimeOfFirstLoggedFaultEvent()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); + assertEquals(0x01, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); + assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); assertEquals(2, podInfoFaultEvent.getReceiverLowGain()); assertEquals(39, podInfoFaultEvent.getRadioRSSI()); } + + @Test + public void testPodInfoFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging() { + PodInfoFaultEvent podInfoFaultEvent = new PodInfoFaultEvent(ByteUtil.fromHexString("020D00000000000012FFFF03FF00160000879A070000")); + + assertEquals(PodProgressStatus.FAULT_EVENT_OCCURRED, podInfoFaultEvent.getPodProgressStatus()); + assertEquals(DeliveryStatus.SUSPENDED, podInfoFaultEvent.getDeliveryStatus()); + assertEquals(0, podInfoFaultEvent.getBolusNotDelivered(), 0.000001); + assertEquals(0x00, podInfoFaultEvent.getPodMessageCounter()); + assertEquals(FaultEventCode.RESET_DUE_TO_LVD, podInfoFaultEvent.getFaultEventCode()); + assertTrue(Duration.ZERO.isEqual(podInfoFaultEvent.getFaultEventTime())); + assertNull(podInfoFaultEvent.getReservoirLevel()); + assertTrue(Duration.standardSeconds(1320).isEqual(podInfoFaultEvent.getTimeActive())); + assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); + assertFalse(podInfoFaultEvent.isFaultAccessingTables()); + assertTrue(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); + assertEquals(0x00, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); + assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); + assertEquals(PodProgressStatus.INSERTING_CANNULA, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); + assertEquals(2, podInfoFaultEvent.getReceiverLowGain()); + assertEquals(26, podInfoFaultEvent.getRadioRSSI()); + } } diff --git a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponseTest.java b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponseTest.java index 821143ecd4..f82674acfc 100644 --- a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponseTest.java +++ b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponseTest.java @@ -5,7 +5,6 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.LogEventErrorCode; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; import static org.junit.Assert.assertArrayEquals; @@ -43,7 +42,7 @@ public class PodInfoResponseTest { PodInfoFaultEvent podInfo = (PodInfoFaultEvent) podInfoResponse.getPodInfo(); assertFalse(podInfo.isFaultAccessingTables()); - assertEquals(LogEventErrorCode.INTERNAL_2_BIT_VARIABLE_SET_AND_MANIPULATED_IN_MAIN_LOOP_ROUTINES_2, podInfo.getLogEventErrorType()); + assertEquals(0x01, podInfo.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); } @Test From fa84cbd513b754777c4a92cea4dab9ac718d1aad Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Fri, 2 Oct 2020 03:00:51 +0200 Subject: [PATCH 03/15] Replace Arrays.toString() with ByteUtil.shortHexString() in PodInfo.toString() --- .../message/response/podinfo/PodInfoActiveAlerts.java | 3 +-- .../message/response/podinfo/PodInfoFaultEvent.java | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java index 6723a0a0da..36e1b1a213 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoActiveAlerts.java @@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mes import org.joda.time.Duration; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; @@ -54,7 +53,7 @@ public class PodInfoActiveAlerts extends PodInfo { @Override public String toString() { return "PodInfoActiveAlerts{" + - "word278=" + Arrays.toString(word278) + + "word278=" + ByteUtil.shortHexString(word278) + ", alertActivations=" + alertActivations + '}'; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java index 4432670239..227206943b 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java @@ -2,8 +2,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mes import org.joda.time.Duration; -import java.util.Arrays; - import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; @@ -189,7 +187,7 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons ", receiverLowGain=" + receiverLowGain + ", radioRSSI=" + radioRSSI + ", podProgressStatusAtTimeOfFirstLoggedFaultEvent=" + podProgressStatusAtTimeOfFirstLoggedFaultEvent + - ", unknownValue=" + Arrays.toString(unknownValue) + + ", unknownValue=" + ByteUtil.shortHexString(unknownValue) + '}'; } } From 04f5efca0b3d19e00fd9dfd0f5e3bb7cf48e2c79 Mon Sep 17 00:00:00 2001 From: Sam Spycher Date: Fri, 2 Oct 2020 12:17:19 +0200 Subject: [PATCH 04/15] Implement setting TBR value as percentages, see AAPS-Omnipod/AndroidAPS#10 --- .../plugins/pump/omnipod/OmnipodPumpPlugin.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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 6e1c85314b..7e04c2d33c 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 @@ -895,8 +895,14 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface, @NonNull @Override public PumpEnactResult setTempBasalPercent(Integer percent, Integer durationInMinutes, Profile profile, boolean enforceNew) { - aapsLogger.debug(LTag.PUMP, "setTempBasalPercent [OmnipodPumpPlugin] - Not implemented."); - return getOperationNotSupportedWithCustomText(info.nightscout.androidaps.core.R.string.pump_operation_not_supported_by_pump_driver); + if (percent == 0) { + return setTempBasalAbsolute(0.0d, durationInMinutes, profile, enforceNew); + } else { + double absoluteValue = profile.getBasal() * (percent / 100.0d); + absoluteValue = pumpDescription.pumpType.determineCorrectBasalSize(absoluteValue); + aapsLogger.warn(LTag.PUMP, "setTempBasalPercent [MedtronicPumpPlugin] - You are trying to use setTempBasalPercent with percent other then 0% (" + percent + "). This will start setTempBasalAbsolute, with calculated value (" + absoluteValue + "). Result might not be 100% correct."); + return setTempBasalAbsolute(absoluteValue, durationInMinutes, profile, enforceNew); + } } @NonNull @Override public PumpEnactResult setExtendedBolus(Double insulin, Integer From f1ee6c2757d47397c4df5e7f4a3c12cd56b421d5 Mon Sep 17 00:00:00 2001 From: Sam Spycher Date: Sat, 3 Oct 2020 13:59:32 +0200 Subject: [PATCH 05/15] replace text referring to Medtronic with text referring to Omnipod --- .../androidaps/plugins/pump/omnipod/OmnipodPumpPlugin.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 7e04c2d33c..8d2e1bf50e 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 @@ -900,7 +900,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface, } else { double absoluteValue = profile.getBasal() * (percent / 100.0d); absoluteValue = pumpDescription.pumpType.determineCorrectBasalSize(absoluteValue); - aapsLogger.warn(LTag.PUMP, "setTempBasalPercent [MedtronicPumpPlugin] - You are trying to use setTempBasalPercent with percent other then 0% (" + percent + "). This will start setTempBasalAbsolute, with calculated value (" + absoluteValue + "). Result might not be 100% correct."); + aapsLogger.warn(LTag.PUMP, "setTempBasalPercent [OmnipodPumpPlugin] - You are trying to use setTempBasalPercent with percent other then 0% (" + percent + "). This will start setTempBasalAbsolute, with calculated value (" + absoluteValue + "). Result might not be 100% correct."); return setTempBasalAbsolute(absoluteValue, durationInMinutes, profile, enforceNew); } } From badfba2993f3084c5b82e6778d1d15855a82b0a0 Mon Sep 17 00:00:00 2001 From: Sam Spycher Date: Mon, 5 Oct 2020 13:32:22 +0200 Subject: [PATCH 06/15] Unit test for setting temporary basal rate with percentages --- .../pump/omnipod/OmnipodPumpPluginTest.java | 141 ++++++++++++++++++ 1 file changed, 141 insertions(+) create mode 100644 omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPluginTest.java 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 new file mode 100644 index 0000000000..ed76eb2621 --- /dev/null +++ b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/OmnipodPumpPluginTest.java @@ -0,0 +1,141 @@ +package info.nightscout.androidaps.plugins.pump.omnipod; + +import android.os.Looper; + +import org.joda.time.DateTimeZone; +import org.joda.time.tz.UTCProvider; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Answers; +import org.mockito.Mock; +import org.powermock.api.mockito.PowerMockito; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; + +import java.util.ArrayList; + +import dagger.android.AndroidInjector; +import dagger.android.HasAndroidInjector; +import info.nightscout.androidaps.data.Profile; +import info.nightscout.androidaps.data.PumpEnactResult; +import info.nightscout.androidaps.interfaces.ActivePluginProvider; +import info.nightscout.androidaps.interfaces.CommandQueueProvider; +import info.nightscout.androidaps.logging.AAPSLogger; +import info.nightscout.androidaps.logging.AAPSLoggerTest; +import info.nightscout.androidaps.plugins.bus.RxBusWrapper; +import info.nightscout.androidaps.plugins.pump.common.data.TempBasalPair; +import info.nightscout.androidaps.plugins.pump.common.defs.PumpType; +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.RileyLinkUtil; +import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager; +import info.nightscout.androidaps.utils.resources.ResourceHelper; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyLong; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + + +@RunWith(PowerMockRunner.class) +public class OmnipodPumpPluginTest { + + @Mock HasAndroidInjector injector; + AAPSLogger aapsLogger = new AAPSLoggerTest(); + RxBusWrapper rxBusWrapper = new RxBusWrapper(); + @Mock ResourceHelper resourceHelper; + @Mock(answer = Answers.RETURNS_DEEP_STUBS) ActivePluginProvider activePluginProvider; + @Mock AapsOmnipodManager aapsOmnipodManager; + @Mock CommandQueueProvider commandQueueProvider; + @Mock RileyLinkUtil rileyLinkUtil; + + + @Test + @PrepareForTest(Looper.class) + public void testSetTempBasalPercent() { + + DateTimeZone.setProvider(new UTCProvider()); + + // mock all the things + PowerMockito.mockStatic(Looper.class); + OmnipodPumpPlugin plugin = new OmnipodPumpPlugin(injector, aapsLogger, rxBusWrapper, null, + resourceHelper, activePluginProvider, null, null, aapsOmnipodManager, commandQueueProvider, + null, null, null, null, null, + rileyLinkUtil, null, null + ); + when(activePluginProvider.getActiveTreatments().getTempBasalFromHistory(anyLong())).thenReturn(null); + when(rileyLinkUtil.getRileyLinkHistory()).thenReturn(new ArrayList<>()); + when(injector.androidInjector()).thenReturn(new AndroidInjector() { + @Override public void inject(Object instance) {} + }); + Profile profile = mock(Profile.class); + + + // always return a PumpEnactResult containing same rate and duration as input + when(aapsOmnipodManager.setTemporaryBasal(any(TempBasalPair.class))).thenAnswer( + invocation -> { + TempBasalPair pair = invocation.getArgument(0); + PumpEnactResult result = new PumpEnactResult(injector); + result.absolute(pair.getInsulinRate()); + result.duration(pair.getDurationMinutes()); + return result; + }); + + + // Given standard basal + when(profile.getBasal()).thenReturn(0.5d); + // When + PumpEnactResult result1 = plugin.setTempBasalPercent(80, 30, profile, false); + 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); + // Then return correct values + assertEquals(result1.absolute, 0.4d, 0.01d); + assertEquals(result1.duration, 30); + assertEquals(result2.absolute, 25d, 0.01d); + assertEquals(result2.duration, 30000); + assertEquals(result3.absolute, 0d, 0.01d); + assertEquals(result3.duration, 30); + assertEquals(result4.absolute, 0d, 0.01d); + assertEquals(result4.duration, 0); + // this is validated downstream, see TempBasalExtraCommand + assertEquals(result5.absolute, -0.25d, 0.01d); + assertEquals(result5.duration, -1); + + // Given zero basal + when(profile.getBasal()).thenReturn(0d); + // When + result1 = plugin.setTempBasalPercent(8000, 10, profile, false); + result2 = plugin.setTempBasalPercent(0, 00, 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); + + // Given unhealthy basal + when(profile.getBasal()).thenReturn(500d); + // When treatment + result1 = plugin.setTempBasalPercent(80, 30, profile, false); + // Then return sane values + assertEquals(result1.absolute, PumpType.Insulet_Omnipod.determineCorrectBasalSize(500d * 0.8), 0.01d); + assertEquals(result1.duration, 30); + + // Given weird basal + when(profile.getBasal()).thenReturn(1.234567d); + // When treatment + result1 = plugin.setTempBasalPercent(280, 500, profile, false); + // Then return sane values + assertEquals(result1.absolute, 3.4567876, 0.01d); + assertEquals(result1.duration, 500); + + // Given negative basal + when(profile.getBasal()).thenReturn(-1.234567d); + // When treatment + result1 = plugin.setTempBasalPercent(280, 500, profile, false); + // Then return negative value (this is validated further downstream, see TempBasalExtraCommand) + assertEquals(result1.absolute, -3.4567876, 0.01d); + assertEquals(result1.duration, 500); + } + +} From 3a6d1f286c823f85627b1174ff8e452f4fd64dfc Mon Sep 17 00:00:00 2001 From: Sam Spycher Date: Mon, 5 Oct 2020 13:45:13 +0200 Subject: [PATCH 07/15] throw IllegalArgumentException for zero or negative durations --- .../communication/message/command/TempBasalExtraCommand.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/TempBasalExtraCommand.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/TempBasalExtraCommand.java index baac0f9305..8f5cf5053b 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/TempBasalExtraCommand.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/TempBasalExtraCommand.java @@ -27,7 +27,10 @@ public class TempBasalExtraCommand extends MessageBlock { } else if (rate > OmnipodConstants.MAX_BASAL_RATE) { throw new IllegalArgumentException("Rate exceeds max basal rate"); } - if (duration.isLongerThan(OmnipodConstants.MAX_TEMP_BASAL_DURATION)) { + + if (duration.isShorterThan(Duration.ZERO) || duration.equals(Duration.ZERO)) { + throw new IllegalArgumentException("Duration should be > 0"); + } else if (duration.isLongerThan(OmnipodConstants.MAX_TEMP_BASAL_DURATION)) { throw new IllegalArgumentException("Duration exceeds max temp basal duration"); } From 26e0df11829781f1a78566bb22f3fab8b5c3fb7e Mon Sep 17 00:00:00 2001 From: Sam Spycher Date: Thu, 8 Oct 2020 11:53:15 +0200 Subject: [PATCH 08/15] Return programmed duration and rate when setting TBR, fixes AAPS-Omnipod/AndroidAPS#12 --- .../plugins/pump/omnipod/manager/AapsOmnipodManager.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java index cddf3b2692..dca84bd3ba 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java @@ -481,7 +481,10 @@ public class AapsOmnipodManager { addTempBasalTreatment(System.currentTimeMillis(), pumpId, tempBasalPair); - return new PumpEnactResult(injector).success(true).enacted(true); + return new PumpEnactResult(injector) + .duration(tempBasalPair.getDurationMinutes()) + .absolute(PumpType.Insulet_Omnipod.determineCorrectBasalSize(tempBasalPair.getInsulinRate())) + .success(true).enacted(true); } public PumpEnactResult cancelTemporaryBasal() { From 2fcae4b19ab3ca83423fde52d04b6592a8f71ea7 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 17 Oct 2020 10:45:28 +0200 Subject: [PATCH 09/15] - Rename and refactor PodInfoFaultEvent to PodInfoDetailedStatus - introduce ActivationTimeExceededException --- .../action/AssignAddressAction.java | 5 + .../communication/action/SetupPodAction.java | 5 + .../message/response/ErrorResponse.java | 18 +- ...tEvent.java => PodInfoDetailedStatus.java} | 72 ++++---- .../driver/definition/ErrorEventInfo.java | 52 ++++++ .../driver/definition/FaultEventCode.java | 4 +- .../driver/definition/PodInfoType.java | 8 +- .../ActivationTimeExceededException.java | 7 + .../driver/exception/PodFaultException.java | 14 +- .../driver/manager/OmnipodManager.java | 69 +++++--- .../driver/manager/PodStateManager.java | 63 ++++--- .../omnipod/manager/AapsOmnipodManager.java | 15 +- .../OmnipodRileyLinkCommunicationManager.java | 25 ++- .../omnipod/ui/OmnipodOverviewFragment.kt | 6 +- .../pump/omnipod/ui/PodManagementActivity.kt | 2 +- .../PodActivationActionFragmentBase.kt | 5 +- .../pump/omnipod/OmnipodPumpPluginTest.java | 5 +- .../message/command/GetStatusCommandTest.java | 2 +- .../podinfo/PodInfoDetailedStatusTest.java | 162 ++++++++++++++++++ .../podinfo/PodInfoFaultEventTest.java | 152 ---------------- .../response/podinfo/PodInfoResponseTest.java | 8 +- 21 files changed, 407 insertions(+), 292 deletions(-) rename omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/{PodInfoFaultEvent.java => PodInfoDetailedStatus.java} (67%) create mode 100644 omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/ErrorEventInfo.java create mode 100644 omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/ActivationTimeExceededException.java create mode 100644 omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatusTest.java delete mode 100644 omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEventTest.java diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java index 9f8fc4296a..dbea17fde2 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java @@ -10,6 +10,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; @@ -52,6 +53,10 @@ public class AssignAddressAction implements OmnipodAction { podStateManager.setInitializationParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), // assignAddressResponse.getPiVersion(), assignAddressResponse.getPmVersion(), DateTimeZone.getDefault(), assignAddressResponse.getPodProgressStatus()); + if (podStateManager.isPodActivationTimeExceeded()) { + throw new ActivationTimeExceededException(); + } + return assignAddressResponse; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java index f811e711db..dc4c06abe2 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java @@ -9,6 +9,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; @@ -47,6 +48,10 @@ public class SetupPodAction implements OmnipodAction { throw new IllegalMessageAddressException(podStateManager.getAddress(), setupPodResponse.getAddress()); } + if (podStateManager.isPodActivationTimeExceeded()) { + throw new ActivationTimeExceededException(); + } + return setupPodResponse; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/ErrorResponse.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/ErrorResponse.java index 2ef230ba2f..58f68ca6fd 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/ErrorResponse.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/ErrorResponse.java @@ -12,9 +12,11 @@ public class ErrorResponse extends MessageBlock { private static final int MESSAGE_LENGTH = 5; private final byte errorResponseCode; - private Integer nonceSearchKey; // only valid for BAD_NONCE - private FaultEventCode faultEventCode; // valid for all but BAD_NONCE - private PodProgressStatus podProgressStatus; // valid for all but BAD_NONCE + + private final Integer nonceSearchKey; // only valid for BAD_NONCE + private final FaultEventCode faultEventCode; // valid for all but BAD_NONCE + + private final PodProgressStatus podProgressStatus; // valid for all but BAD_NONCE public ErrorResponse(byte[] encodedData) { if (encodedData.length < MESSAGE_LENGTH) { @@ -24,11 +26,16 @@ public class ErrorResponse extends MessageBlock { errorResponseCode = encodedData[2]; - if (this.errorResponseCode == ERROR_RESPONSE_CODE_BAD_NONCE) { + if (errorResponseCode == ERROR_RESPONSE_CODE_BAD_NONCE) { nonceSearchKey = ByteUtil.makeUnsignedShort(encodedData[3], encodedData[4]); + + faultEventCode = null; + podProgressStatus = null; } else { faultEventCode = FaultEventCode.fromByte(encodedData[3]); podProgressStatus = PodProgressStatus.fromByte(encodedData[4]); + + nonceSearchKey = null; } } @@ -53,8 +60,7 @@ public class ErrorResponse extends MessageBlock { return nonceSearchKey; } - @Override - public String toString() { + @Override public String toString() { return "ErrorResponse{" + "errorResponseCode=" + errorResponseCode + ", nonceSearchKey=" + nonceSearchKey + diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java similarity index 67% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java index 227206943b..123a352f03 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEvent.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java @@ -2,16 +2,19 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mes import org.joda.time.Duration; +import java.util.Arrays; + import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ErrorEventInfo; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; -public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableResponse { +public class PodInfoDetailedStatus extends PodInfo implements StatusUpdatableResponse { private static final int MINIMUM_MESSAGE_LENGTH = 21; private final PodProgressStatus podProgressStatus; @@ -26,16 +29,13 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons private final Duration timeActive; private final AlertSet unacknowledgedAlerts; private final boolean faultAccessingTables; - private final boolean loggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging; - private final byte loggedFaultEventInternal2bitMainLoopRoutinesVariable; - private final boolean loggedFaultEventImmediateBolusInProgressDuringError; - private final PodProgressStatus loggedFaultEventErrorPodProgressStatus; + private final ErrorEventInfo errorEventInfo; private final byte receiverLowGain; private final byte radioRSSI; - private final PodProgressStatus podProgressStatusAtTimeOfFirstLoggedFaultEvent; + private final PodProgressStatus previousPodProgressStatus; private final byte[] unknownValue; - public PodInfoFaultEvent(byte[] encodedData) { + public PodInfoDetailedStatus(byte[] encodedData) { super(encodedData); if (encodedData.length < MINIMUM_MESSAGE_LENGTH) { @@ -70,20 +70,33 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons unacknowledgedAlerts = new AlertSet(encodedData[15]); faultAccessingTables = encodedData[16] == 0x02; - int loggedFaultEventInfo = ByteUtil.convertUnsignedByteToInt(encodedData[17]); - loggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging = (loggedFaultEventInfo & 0x80) == 0x80; - loggedFaultEventInternal2bitMainLoopRoutinesVariable = (byte) ((loggedFaultEventInfo >>> 5) & 0x03); - loggedFaultEventImmediateBolusInProgressDuringError = (loggedFaultEventInfo & 0x10) == 0x10; - loggedFaultEventErrorPodProgressStatus = PodProgressStatus.fromByte((byte) (loggedFaultEventInfo & 0x0f)); + byte rawErrorEventInfo = encodedData[17]; + if (rawErrorEventInfo == 0x00) { + errorEventInfo = null; + } else { + errorEventInfo = ErrorEventInfo.fromByte(rawErrorEventInfo); + } receiverLowGain = (byte) (ByteUtil.convertUnsignedByteToInt(encodedData[18]) >>> 6); radioRSSI = (byte) (encodedData[18] & 0x3f); - podProgressStatusAtTimeOfFirstLoggedFaultEvent = PodProgressStatus.fromByte((byte) (encodedData[19] & 0x0f)); + if (ByteUtil.convertUnsignedByteToInt(encodedData[19]) == 0xff) { // this byte is not valid (no fault has occurred) + previousPodProgressStatus = null; + } else { + previousPodProgressStatus = PodProgressStatus.fromByte((byte) (encodedData[19] & 0x0f)); + } unknownValue = ByteUtil.substring(encodedData, 20, 2); } @Override public PodInfoType getType() { - return PodInfoType.FAULT_EVENT; + return PodInfoType.DETAILED_STATUS; + } + + public boolean isFaulted() { + return faultEventCode != null; + } + + public boolean isActivationTimeExceeded() { + return podProgressStatus == PodProgressStatus.ACTIVATION_TIME_EXCEEDED; } @Override public PodProgressStatus getPodProgressStatus() { @@ -134,20 +147,8 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons return faultAccessingTables; } - public boolean isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging() { - return loggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging; - } - - public byte getLoggedFaultEventInternal2bitMainLoopRoutinesVariable() { - return loggedFaultEventInternal2bitMainLoopRoutinesVariable; - } - - public boolean isLoggedFaultEventImmediateBolusInProgressDuringError() { - return loggedFaultEventImmediateBolusInProgressDuringError; - } - - public PodProgressStatus getLoggedFaultEventErrorPodProgressStatus() { - return loggedFaultEventErrorPodProgressStatus; + public ErrorEventInfo getErrorEventInfo() { + return errorEventInfo; } public byte getReceiverLowGain() { @@ -158,8 +159,8 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons return radioRSSI; } - public PodProgressStatus getLoggedFaultEventPodProgressStatus() { - return podProgressStatusAtTimeOfFirstLoggedFaultEvent; + public PodProgressStatus getPreviousPodProgressStatus() { + return previousPodProgressStatus; } public byte[] getUnknownValue() { @@ -167,7 +168,7 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons } @Override public String toString() { - return "PodInfoFaultEvent{" + + return "PodInfoDetailedStatus{" + "podProgressStatus=" + podProgressStatus + ", deliveryStatus=" + deliveryStatus + ", bolusNotDelivered=" + bolusNotDelivered + @@ -180,14 +181,11 @@ public class PodInfoFaultEvent extends PodInfo implements StatusUpdatableRespons ", timeActive=" + timeActive + ", unacknowledgedAlerts=" + unacknowledgedAlerts + ", faultAccessingTables=" + faultAccessingTables + - ", loggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging=" + loggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging + - ", loggedFaultEventInternal2bitMainLoopRoutinesVariable=" + loggedFaultEventInternal2bitMainLoopRoutinesVariable + - ", loggedFaultEventImmediateBolusInProgressDuringError=" + loggedFaultEventImmediateBolusInProgressDuringError + - ", loggedFaultEventErrorPodProgressStatus=" + loggedFaultEventErrorPodProgressStatus + + ", errorEventInfo=" + errorEventInfo + ", receiverLowGain=" + receiverLowGain + ", radioRSSI=" + radioRSSI + - ", podProgressStatusAtTimeOfFirstLoggedFaultEvent=" + podProgressStatusAtTimeOfFirstLoggedFaultEvent + - ", unknownValue=" + ByteUtil.shortHexString(unknownValue) + + ", previousPodProgressStatus=" + previousPodProgressStatus + + ", unknownValue=" + Arrays.toString(unknownValue) + '}'; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/ErrorEventInfo.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/ErrorEventInfo.java new file mode 100644 index 0000000000..2f3e064d36 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/ErrorEventInfo.java @@ -0,0 +1,52 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; + +import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; + +public final class ErrorEventInfo { + private final boolean insulinStateTableCorruption; + private final byte internalVariable; + private final boolean immediateBolusInProgress; + private final PodProgressStatus podProgressStatus; + + private ErrorEventInfo(boolean insulinStateTableCorruption, byte internalVariable, boolean immediateBolusInProgress, PodProgressStatus podProgressStatus) { + this.insulinStateTableCorruption = insulinStateTableCorruption; + this.internalVariable = internalVariable; + this.immediateBolusInProgress = immediateBolusInProgress; + this.podProgressStatus = podProgressStatus; + } + + public static ErrorEventInfo fromByte(byte faultEventInfo) { + int loggedFaultEventInfo = ByteUtil.convertUnsignedByteToInt(faultEventInfo); + boolean insulinStateTableCorruption = (loggedFaultEventInfo & 0x80) == 0x80; + byte internalVariable = (byte) ((loggedFaultEventInfo >>> 5) & 0x03); + boolean immediateBolusInProgress = (loggedFaultEventInfo & 0x10) == 0x10; + PodProgressStatus podProgressStatus = PodProgressStatus.fromByte((byte) (loggedFaultEventInfo & 0x0f)); + + return new ErrorEventInfo(insulinStateTableCorruption, internalVariable, immediateBolusInProgress, podProgressStatus); + } + + public boolean isInsulinStateTableCorruption() { + return insulinStateTableCorruption; + } + + public byte getInternalVariable() { + return internalVariable; + } + + public boolean isImmediateBolusInProgress() { + return immediateBolusInProgress; + } + + public PodProgressStatus getPodProgressStatus() { + return podProgressStatus; + } + + @Override public String toString() { + return "ErrorEventInfo{" + + "insulinStateTableCorruption=" + insulinStateTableCorruption + + ", internalVariable=" + internalVariable + + ", immediateBolusInProgress=" + immediateBolusInProgress + + ", podProgressStatus=" + podProgressStatus + + '}'; + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/FaultEventCode.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/FaultEventCode.java index a6fac508db..0a42811848 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/FaultEventCode.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/FaultEventCode.java @@ -3,7 +3,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; import java.util.Locale; public enum FaultEventCode { - NO_FAULTS((byte) 0x00), FAILED_FLASH_ERASE((byte) 0x01), FAILED_FLASH_STORE((byte) 0x02), TABLE_CORRUPTION_BASAL_SUBCOMMAND((byte) 0x03), @@ -129,6 +128,9 @@ public enum FaultEventCode { } public static FaultEventCode fromByte(byte value) { + if (value == 0x00) { // No faults + return null; + } for (FaultEventCode type : values()) { if (type.value == value) { return type; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PodInfoType.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PodInfoType.java index d85ee9bd3f..4198810aa1 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PodInfoType.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/PodInfoType.java @@ -3,15 +3,15 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfo; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoActiveAlerts; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoDataLog; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoDetailedStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoFaultAndInitializationTime; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoFaultEvent; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoOlderPulseLog; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog; public enum PodInfoType { NORMAL((byte) 0x00), ACTIVE_ALERTS((byte) 0x01), - FAULT_EVENT((byte) 0x02), + DETAILED_STATUS((byte) 0x02), DATA_LOG((byte) 0x03), // Similar to types $50 & $51. Returns up to the last 60 dwords of data. FAULT_AND_INITIALIZATION_TIME((byte) 0x05), RECENT_PULSE_LOG((byte) 0x50), // Starting at $4200 @@ -44,8 +44,8 @@ public enum PodInfoType { throw new UnsupportedOperationException("Cannot decode PodInfoType.NORMAL"); case ACTIVE_ALERTS: return new PodInfoActiveAlerts(encodedData); - case FAULT_EVENT: - return new PodInfoFaultEvent(encodedData); + case DETAILED_STATUS: + return new PodInfoDetailedStatus(encodedData); case DATA_LOG: return new PodInfoDataLog(encodedData, bodyLength); case FAULT_AND_INITIALIZATION_TIME: diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/ActivationTimeExceededException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/ActivationTimeExceededException.java new file mode 100644 index 0000000000..91e4c4bab3 --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/ActivationTimeExceededException.java @@ -0,0 +1,7 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; + +public class ActivationTimeExceededException extends OmnipodException { + public ActivationTimeExceededException() { + super("The Pod's activation time has been exceeded", true); + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/PodFaultException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/PodFaultException.java index 884e7481eb..4786f241c7 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/PodFaultException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/PodFaultException.java @@ -1,16 +1,16 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoFaultEvent; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoDetailedStatus; public class PodFaultException extends OmnipodException { - private final PodInfoFaultEvent faultEvent; + private final PodInfoDetailedStatus detailedStatus; - public PodFaultException(PodInfoFaultEvent faultEvent) { - super(faultEvent.getFaultEventCode().toString(), true); - this.faultEvent = faultEvent; + public PodFaultException(PodInfoDetailedStatus detailedStatus) { + super(detailedStatus.getFaultEventCode().toString(), true); + this.detailedStatus = detailedStatus; } - public PodInfoFaultEvent getFaultEvent() { - return faultEvent; + public PodInfoDetailedStatus getDetailedStatus() { + return detailedStatus; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java index e642fd1f71..bd87de7499 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java @@ -40,6 +40,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketT import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException; @@ -88,11 +89,18 @@ public class OmnipodManager { } public synchronized Single pairAndPrime() { + if (podStateManager.isPodActivationTimeExceeded()) { + throw new ActivationTimeExceededException(); + } + if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.PRIMING)) { + return Single.just(true); + } + logStartingCommandExecution("pairAndPrime"); try { + // Always send both 0x07 and 0x03 on retries if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PAIRING_COMPLETED)) { - // Always send both 0x07 and 0x03 on retries try { communicationService.executeAction( new AssignAddressAction(podStateManager)); @@ -109,28 +117,29 @@ public class OmnipodManager { communicationService.executeAction(new SetupPodAction(podStateManager)); } catch (IllegalPacketTypeException ex) { if (PacketType.ACK.equals(ex.getActual())) { - // TODO is this true for the SetupPodCommand? // Pod is already configured aapsLogger.debug("Received ACK instead of response in SetupPodAction. Ignoring"); } } - } else if (podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.PRIMING)) { - throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, podStateManager.getPodProgressStatus()); + } else { + // Make sure we have an up to date PodProgressStatus + getPodStatus(); + + if (podStateManager.isPodActivationTimeExceeded()) { + throw new ActivationTimeExceededException(); + } } - // Make sure we have an up to date PodProgressStatus - getPodStatus(); - communicationService.executeAction(new PrimeAction(new PrimeService(), podStateManager)); + + long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_PRIME_BOLUS_UNITS, OmnipodConstants.POD_PRIMING_DELIVERY_RATE).getMillis(); + + return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // + .map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED)) // + .subscribeOn(Schedulers.io()); } finally { logCommandExecutionFinished("pairAndPrime"); } - - long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_PRIME_BOLUS_UNITS, OmnipodConstants.POD_PRIMING_DELIVERY_RATE).getMillis(); - - return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // - .map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED)) // - .subscribeOn(Schedulers.io()); } public synchronized Single insertCannula( @@ -139,26 +148,30 @@ public class OmnipodManager { throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, !podStateManager.isPodInitialized() ? null : podStateManager.getPodProgressStatus()); } - // Make sure we have the latest PodProgressStatus - getPodStatus(); - - if (podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.INSERTING_CANNULA)) { - throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, podStateManager.getPodProgressStatus()); - } - logStartingCommandExecution("insertCannula [basalSchedule=" + basalSchedule + "]"); try { + // Make sure we have the latest PodProgressStatus + getPodStatus(); + + if (podStateManager.isPodActivationTimeExceeded()) { + throw new ActivationTimeExceededException(); + } + if (podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.INSERTING_CANNULA)) { + return Single.just(true); + } + communicationService.executeAction(new InsertCannulaAction(podStateManager, basalSchedule, expirationReminderTimeBeforeShutdown, lowReservoirAlertUnits)); + + long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConstants.POD_CANNULA_INSERTION_DELIVERY_RATE).getMillis(); + + return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // + .map(o -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS)) // + .subscribeOn(Schedulers.io()); + } finally { logCommandExecutionFinished("insertCannula"); } - - long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConstants.POD_CANNULA_INSERTION_DELIVERY_RATE).getMillis(); - - return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // - .map(o -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS)) // - .subscribeOn(Schedulers.io()); } public synchronized StatusResponse getPodStatus() { @@ -437,7 +450,7 @@ public class OmnipodManager { break; } catch (PodFaultException ex) { // Subtract units not delivered in case of a Pod failure - bolusNotDelivered = ex.getFaultEvent().getBolusNotDelivered(); + bolusNotDelivered = ex.getDetailedStatus().getBolusNotDelivered(); aapsLogger.debug(LTag.PUMPCOMM, "Caught PodFaultException in bolus completion verification", ex); break; @@ -473,7 +486,7 @@ public class OmnipodManager { StatusResponse statusResponse = cancelDelivery(EnumSet.of(DeliveryType.BOLUS), acknowledgementBeep); discardActiveBolusData(statusResponse.getBolusNotDelivered()); } catch (PodFaultException ex) { - discardActiveBolusData(ex.getFaultEvent().getBolusNotDelivered()); + discardActiveBolusData(ex.getDetailedStatus().getBolusNotDelivered()); throw ex; } finally { logCommandExecutionFinished("cancelBolus"); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java index f7fa1ee694..91ab82edfe 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java @@ -21,11 +21,12 @@ import java.util.function.Supplier; import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoFaultEvent; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoDetailedStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FirmwareVersion; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodCrc; @@ -79,7 +80,7 @@ public abstract class PodStateManager { * @return true if we have a Pod state and the Pod activation has been completed. The pod could also be dead at this point */ public final boolean isPodActivationCompleted() { - return isPodInitialized() && podState.getPodProgressStatus().isAtLeast(PodProgressStatus.ABOVE_FIFTY_UNITS) && podState.getPodProgressStatus() != PodProgressStatus.ACTIVATION_TIME_EXCEEDED; + return isPodInitialized() && podState.getPodProgressStatus().isAtLeast(PodProgressStatus.ABOVE_FIFTY_UNITS) && !isPodActivationTimeExceeded(); } /** @@ -97,6 +98,13 @@ public abstract class PodStateManager { return isPodInitialized() && podState.getPodProgressStatus().equals(PodProgressStatus.FAULT_EVENT_OCCURRED); } + /** + * @return true if the Pod's activation time has been exceeded + */ + public boolean isPodActivationTimeExceeded() { + return isPodInitialized() && getPodProgressStatus() == PodProgressStatus.ACTIVATION_TIME_EXCEEDED; + } + /** * @return true if we have a Pod state and the Pod is dead, meaning it is either in a fault state or activation time has been exceeded or it is deactivated */ @@ -232,16 +240,12 @@ public abstract class PodStateManager { * a fault event, this does NOT necessarily mean that the Pod is not faulted. For a reliable * indication on whether or not the pod is faulted, see {@link #isPodFaulted() isPodFaulted()} */ - public final boolean hasFaultEvent() { - return podState != null && podState.getFaultEvent() != null; + public final boolean isFaulted() { + return podState != null && podState.getFaultEventCode() != null; } - public final PodInfoFaultEvent getFaultEvent() { - return getSafe(() -> podState.getFaultEvent()); - } - - public final void setFaultEvent(PodInfoFaultEvent faultEvent) { - setAndStore(() -> podState.setFaultEvent(faultEvent)); + public final FaultEventCode getFaultEventCode() { + return getSafe(() -> podState.getFaultEventCode()); } public final AlertType getConfiguredAlertType(AlertSlot alertSlot) { @@ -513,20 +517,20 @@ public abstract class PodStateManager { /** * Does not automatically store pod state in order to decrease I/O load */ - public final void updateFromResponse(StatusUpdatableResponse statusResponse) { + public final void updateFromResponse(StatusUpdatableResponse status) { setSafe(() -> { if (podState.getActivatedAt() == null) { - DateTime activatedAtCalculated = DateTime.now().withZone(podState.getTimeZone()).minus(statusResponse.getTimeActive()); + DateTime activatedAtCalculated = DateTime.now().withZone(podState.getTimeZone()).minus(status.getTimeActive()); podState.setActivatedAt(activatedAtCalculated); } - podState.setSuspended(statusResponse.getDeliveryStatus() == DeliveryStatus.SUSPENDED); - podState.setActiveAlerts(statusResponse.getUnacknowledgedAlerts()); - podState.setLastDeliveryStatus(statusResponse.getDeliveryStatus()); - podState.setReservoirLevel(statusResponse.getReservoirLevel()); - podState.setTotalTicksDelivered(statusResponse.getTicksDelivered()); - podState.setPodProgressStatus(statusResponse.getPodProgressStatus()); - podState.setTimeActive(statusResponse.getTimeActive()); - if (statusResponse.getDeliveryStatus().isTbrRunning()) { + podState.setSuspended(status.getDeliveryStatus() == DeliveryStatus.SUSPENDED); + podState.setActiveAlerts(status.getUnacknowledgedAlerts()); + podState.setLastDeliveryStatus(status.getDeliveryStatus()); + podState.setReservoirLevel(status.getReservoirLevel()); + podState.setTotalTicksDelivered(status.getTicksDelivered()); + podState.setPodProgressStatus(status.getPodProgressStatus()); + podState.setTimeActive(status.getTimeActive()); + if (status.getDeliveryStatus().isTbrRunning()) { if (!isTempBasalCertain() && isTempBasalRunning()) { podState.setTempBasalCertain(true); } @@ -535,6 +539,13 @@ public abstract class PodStateManager { setTempBasal(null, null, null, true, false); } podState.setLastUpdatedFromResponse(DateTime.now()); + + if (status instanceof PodInfoDetailedStatus) { + PodInfoDetailedStatus detailedStatus = (PodInfoDetailedStatus) status; + if (detailedStatus.isFaulted()) { + podState.setFaultEventCode(detailedStatus.getFaultEventCode()); + } + } }); } @@ -626,7 +637,7 @@ public abstract class PodStateManager { private DateTimeZone timeZone; private DateTime activatedAt; private Duration timeActive; - private PodInfoFaultEvent faultEvent; + private FaultEventCode faultEventCode; private Double reservoirLevel; private Integer totalTicksDelivered; private boolean suspended; @@ -751,12 +762,12 @@ public abstract class PodStateManager { this.timeActive = timeActive; } - PodInfoFaultEvent getFaultEvent() { - return faultEvent; + FaultEventCode getFaultEventCode() { + return faultEventCode; } - void setFaultEvent(PodInfoFaultEvent faultEvent) { - this.faultEvent = faultEvent; + void setFaultEventCode(FaultEventCode faultEventCode) { + this.faultEventCode = faultEventCode; } Double getReservoirLevel() { @@ -930,7 +941,7 @@ public abstract class PodStateManager { ", timeZone=" + timeZone + ", activatedAt=" + activatedAt + ", timeActive=" + timeActive + - ", faultEvent=" + faultEvent + + ", faultEvent=" + faultEventCode + ", reservoirLevel=" + reservoirLevel + ", totalTicksDelivered=" + totalTicksDelivered + ", suspended=" + suspended + diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java index cddf3b2692..f50c09edcf 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java @@ -50,9 +50,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.Deliver import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalScheduleEntry; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CrcMismatchException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException; @@ -755,10 +755,8 @@ public class AapsOmnipodManager { if (ex instanceof OmnipodException) { aapsLogger.error(LTag.PUMP, String.format("Caught OmnipodException[certainFailure=%s] from OmnipodManager", ((OmnipodException) ex).isCertainFailure()), ex); if (ex instanceof PodFaultException) { - FaultEventCode faultEventCode = ((PodFaultException) ex).getFaultEvent().getFaultEventCode(); - if (!(faultEventCode == FaultEventCode.NO_FAULTS && podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus() == PodProgressStatus.ACTIVATION_TIME_EXCEEDED)) { - showPodFaultNotification(faultEventCode); - } + FaultEventCode faultEventCode = ((PodFaultException) ex).getDetailedStatus().getFaultEventCode(); + showPodFaultNotification(faultEventCode); } } else { aapsLogger.error(LTag.PUMP, "Caught an unexpected non-OmnipodException from OmnipodManager", ex); @@ -791,8 +789,10 @@ public class AapsOmnipodManager { } else if (ex instanceof NotEnoughDataException) { comment = getStringResource(R.string.omnipod_error_not_enough_data); } else if (ex instanceof PodFaultException) { - FaultEventCode faultEventCode = ((PodFaultException) ex).getFaultEvent().getFaultEventCode(); + FaultEventCode faultEventCode = ((PodFaultException) ex).getDetailedStatus().getFaultEventCode(); comment = createPodFaultErrorMessage(faultEventCode); + } else if (ex instanceof ActivationTimeExceededException) { + comment = getStringResource(R.string.omnipod_error_pod_fault_activation_time_exceeded); } else if (ex instanceof PodReturnedErrorResponseException) { comment = getStringResource(R.string.omnipod_error_pod_returned_error_response); } else if (ex instanceof RileyLinkUnreachableException) { @@ -813,9 +813,6 @@ public class AapsOmnipodManager { } private String createPodFaultErrorMessage(FaultEventCode faultEventCode) { - if (faultEventCode == FaultEventCode.NO_FAULTS && podStateManager.getPodProgressStatus() == PodProgressStatus.ACTIVATION_TIME_EXCEEDED) { - return getStringResource(R.string.omnipod_error_pod_fault_activation_time_exceeded); - } return getStringResource(R.string.omnipod_error_pod_fault, ByteUtil.convertUnsignedByteToInt(faultEventCode.getValue()), faultEventCode.name()); } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/rileylink/manager/OmnipodRileyLinkCommunicationManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/rileylink/manager/OmnipodRileyLinkCommunicationManager.java index adb9e97e69..822228d949 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/rileylink/manager/OmnipodRileyLinkCommunicationManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/rileylink/manager/OmnipodRileyLinkCommunicationManager.java @@ -23,12 +23,13 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.ErrorResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfo; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoFaultEvent; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoDetailedStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.MessageBlockType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageSequenceNumberException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; @@ -156,12 +157,21 @@ public class OmnipodRileyLinkCommunicationManager extends RileyLinkCommunication podStateManager.setLastFailedCommunication(DateTime.now()); throw new PodReturnedErrorResponseException(error); } - } else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.FAULT_EVENT) { - PodInfoFaultEvent faultEvent = (PodInfoFaultEvent) ((PodInfoResponse) responseMessageBlock).getPodInfo(); - podStateManager.setFaultEvent(faultEvent); - // Treat as successful communication as the user will get notified and can work with this response - podStateManager.setLastSuccessfulCommunication(DateTime.now()); - throw new PodFaultException(faultEvent); + } else if (responseMessageBlock.getType() == MessageBlockType.POD_INFO_RESPONSE && ((PodInfoResponse) responseMessageBlock).getSubType() == PodInfoType.DETAILED_STATUS) { + PodInfoDetailedStatus detailedStatus = (PodInfoDetailedStatus) ((PodInfoResponse) responseMessageBlock).getPodInfo(); + if (detailedStatus.isFaulted()) { + // Treat as successful communication in order to prevent false positive pump unreachable alarms + podStateManager.setLastSuccessfulCommunication(DateTime.now()); + throw new PodFaultException(detailedStatus); + } else if (detailedStatus.isActivationTimeExceeded()) { + // Treat as successful communication in order to prevent false positive pump unreachable alarms + podStateManager.setLastSuccessfulCommunication(DateTime.now()); + throw new ActivationTimeExceededException(); + } else { + // Shouldn't happen + podStateManager.setLastFailedCommunication(DateTime.now()); + throw new IllegalResponseException(responseClass.getSimpleName(), responseMessageBlock.getType()); + } } else { podStateManager.setLastFailedCommunication(DateTime.now()); throw new IllegalResponseException(responseClass.getSimpleName(), responseMessageBlock.getType()); @@ -174,6 +184,7 @@ public class OmnipodRileyLinkCommunicationManager extends RileyLinkCommunication } finally { podStateManager.storePodState(); } + } private MessageBlock transportMessages(PodStateManager podStateManager, OmnipodMessage message, Integer addressOverride, Integer ackAddressOverride) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt index 055e7550d2..168f96180f 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt @@ -272,8 +272,8 @@ class OmnipodOverviewFragment : DaggerFragment() { }) } - if (podStateManager.hasFaultEvent()) { - val faultEventCode = podStateManager.faultEvent.faultEventCode + if (podStateManager.isFaulted) { + val faultEventCode = podStateManager.faultEventCode errors.add(resourceHelper.gs(R.string.omnipod_pod_status_pod_fault_description, faultEventCode.value, faultEventCode.name)) } @@ -345,7 +345,7 @@ class OmnipodOverviewFragment : DaggerFragment() { if (!podStateManager.isPodInitialized) { resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation) } else { - if (PodProgressStatus.ACTIVATION_TIME_EXCEEDED == podStateManager.podProgressStatus) { + if (podStateManager.isPodActivationTimeExceeded) { resourceHelper.gs(R.string.omnipod_pod_status_activation_time_exceeded) } else if (podStateManager.podProgressStatus.isBefore(PodProgressStatus.PRIMING_COMPLETED)) { resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation) diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt index 03ee8035ae..1732c6e204 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt @@ -93,7 +93,7 @@ class PodManagementActivity : NoSplashAppCompatActivity() { omnipod_pod_management_waiting_for_rl_layout.visibility = (!rileyLinkServiceData.rileyLinkServiceState.isReady).toVisibility() if (rileyLinkServiceData.rileyLinkServiceState.isReady) { - omnipod_pod_management_button_activate_pod.isEnabled = !podStateManager.isPodActivationCompleted + omnipod_pod_management_button_activate_pod.isEnabled = !podStateManager.isPodActivationCompleted && !podStateManager.isPodActivationTimeExceeded omnipod_pod_management_button_deactivate_pod.isEnabled = podStateManager.isPodInitialized if (discardButtonEnabled) { omnipod_pod_management_button_discard_pod.isEnabled = true diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt index 2055d895e0..cb064bebcf 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt @@ -3,8 +3,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation.fra import android.content.Intent import android.os.Bundle import android.view.View -import info.nightscout.androidaps.plugins.pump.omnipod.R -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.fragment.ActionFragmentBase import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.deactivation.PodDeactivationWizardActivity @@ -27,8 +25,7 @@ abstract class PodActivationActionFragmentBase : ActionFragmentBase() { } override fun onActionFailure() { - if (podStateManager.isPodInitialized && podStateManager.podProgressStatus == PodProgressStatus.ACTIVATION_TIME_EXCEEDED) { - omnipod_wizard_action_error.setText(R.string.omnipod_error_pod_fault_activation_time_exceeded) + if (podStateManager.isPodActivationTimeExceeded) { omnipod_wizard_button_retry.visibility = View.GONE omnipod_wizard_button_deactivate_pod.visibility = View.VISIBLE } 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 ed76eb2621..64f7f48728 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 @@ -65,7 +65,8 @@ public class OmnipodPumpPluginTest { when(activePluginProvider.getActiveTreatments().getTempBasalFromHistory(anyLong())).thenReturn(null); when(rileyLinkUtil.getRileyLinkHistory()).thenReturn(new ArrayList<>()); when(injector.androidInjector()).thenReturn(new AndroidInjector() { - @Override public void inject(Object instance) {} + @Override public void inject(Object instance) { + } }); Profile profile = mock(Profile.class); @@ -118,7 +119,7 @@ public class OmnipodPumpPluginTest { // When treatment result1 = plugin.setTempBasalPercent(80, 30, profile, false); // Then return sane values - assertEquals(result1.absolute, PumpType.Insulet_Omnipod.determineCorrectBasalSize(500d * 0.8), 0.01d); + assertEquals(result1.absolute, PumpType.Insulet_Omnipod.determineCorrectBasalSize(500d * 0.8), 0.01d); assertEquals(result1.duration, 30); // Given weird basal diff --git a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/GetStatusCommandTest.java b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/GetStatusCommandTest.java index aa7d168a7c..65d8e9d7c2 100644 --- a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/GetStatusCommandTest.java +++ b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/command/GetStatusCommandTest.java @@ -24,7 +24,7 @@ public class GetStatusCommandTest { @Test public void testPodInfoTypeFaultEvents() { - GetStatusCommand getStatusCommand = new GetStatusCommand(PodInfoType.FAULT_EVENT); + GetStatusCommand getStatusCommand = new GetStatusCommand(PodInfoType.DETAILED_STATUS); assertArrayEquals(ByteUtil.fromHexString("0e0102"), getStatusCommand.getRawData()); } diff --git a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatusTest.java b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatusTest.java new file mode 100644 index 0000000000..1b3d5ed816 --- /dev/null +++ b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatusTest.java @@ -0,0 +1,162 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo; + +import org.joda.time.Duration; +import org.junit.Test; + +import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ErrorEventInfo; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +// From https://github.com/ps2/rileylink_ios/blob/omnipod-testing/OmniKitTests/PodInfoTests.swift +public class PodInfoDetailedStatusTest { + @Test + public void testPodInfoFaultEventNoFaultAlerts() { + PodInfoDetailedStatus podInfoDetailedStatus = new PodInfoDetailedStatus(ByteUtil.fromHexString("02080100000a003800000003ff008700000095ff0000")); + + assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoDetailedStatus.getPodProgressStatus()); + assertEquals(DeliveryStatus.NORMAL, podInfoDetailedStatus.getDeliveryStatus()); + assertEquals(0, podInfoDetailedStatus.getBolusNotDelivered(), 0.000001); + assertEquals(0x0a, podInfoDetailedStatus.getPodMessageCounter()); + assertNull(podInfoDetailedStatus.getFaultEventCode()); + assertTrue(Duration.ZERO.isEqual(podInfoDetailedStatus.getFaultEventTime())); + assertNull(podInfoDetailedStatus.getReservoirLevel()); + assertTrue(Duration.standardSeconds(8100).isEqual(podInfoDetailedStatus.getTimeActive())); + assertEquals(0, podInfoDetailedStatus.getUnacknowledgedAlerts().getRawValue()); + assertFalse(podInfoDetailedStatus.isFaultAccessingTables()); + ErrorEventInfo errorEventInfo = podInfoDetailedStatus.getErrorEventInfo(); + assertNull(errorEventInfo); + assertNull(podInfoDetailedStatus.getPreviousPodProgressStatus()); + assertEquals(2, podInfoDetailedStatus.getReceiverLowGain()); + assertEquals(21, podInfoDetailedStatus.getRadioRSSI()); + } + + @Test + public void testPodInfoFaultEventDeliveryErrorDuringPriming() { + PodInfoDetailedStatus podInfoDetailedStatus = new PodInfoDetailedStatus(ByteUtil.fromHexString("020f0000000900345c000103ff0001000005ae056029")); + + assertEquals(PodProgressStatus.INACTIVE, podInfoDetailedStatus.getPodProgressStatus()); + assertEquals(DeliveryStatus.SUSPENDED, podInfoDetailedStatus.getDeliveryStatus()); + assertEquals(0, podInfoDetailedStatus.getBolusNotDelivered(), 0.000001); + assertEquals(0x09, podInfoDetailedStatus.getPodMessageCounter()); + assertEquals(FaultEventCode.PRIME_OPEN_COUNT_TOO_LOW, podInfoDetailedStatus.getFaultEventCode()); + assertTrue(Duration.standardSeconds(60).isEqual(podInfoDetailedStatus.getFaultEventTime())); + assertNull(podInfoDetailedStatus.getReservoirLevel()); + assertTrue(Duration.standardSeconds(60).isEqual(podInfoDetailedStatus.getTimeActive())); + assertEquals(0, podInfoDetailedStatus.getUnacknowledgedAlerts().getRawValue()); + assertFalse(podInfoDetailedStatus.isFaultAccessingTables()); + ErrorEventInfo errorEventInfo = podInfoDetailedStatus.getErrorEventInfo(); + assertFalse(errorEventInfo.isInsulinStateTableCorruption()); + assertEquals(0x00, errorEventInfo.getInternalVariable()); + assertFalse(errorEventInfo.isImmediateBolusInProgress()); + assertEquals(PodProgressStatus.PRIMING_COMPLETED, errorEventInfo.getPodProgressStatus()); + assertEquals(PodProgressStatus.PRIMING_COMPLETED, podInfoDetailedStatus.getPreviousPodProgressStatus()); + assertEquals(2, podInfoDetailedStatus.getReceiverLowGain()); + assertEquals(46, podInfoDetailedStatus.getRadioRSSI()); + } + + @Test + public void testPodInfoFaultEventErrorShuttingDown() { + PodInfoDetailedStatus podInfoDetailedStatus = new PodInfoDetailedStatus(ByteUtil.fromHexString("020d0000000407f28609ff03ff0a0200000823080000")); + + assertEquals(PodProgressStatus.FAULT_EVENT_OCCURRED, podInfoDetailedStatus.getPodProgressStatus()); + assertEquals(DeliveryStatus.SUSPENDED, podInfoDetailedStatus.getDeliveryStatus()); + assertEquals(2034, podInfoDetailedStatus.getTicksDelivered()); + assertEquals(101.7, podInfoDetailedStatus.getInsulinDelivered(), 0.000001); + assertEquals(0, podInfoDetailedStatus.getBolusNotDelivered(), 0.000001); + assertEquals(0x04, podInfoDetailedStatus.getPodMessageCounter()); + assertEquals(FaultEventCode.BASAL_OVER_INFUSION_PULSE, podInfoDetailedStatus.getFaultEventCode()); + assertTrue(Duration.standardMinutes(2559).isEqual(podInfoDetailedStatus.getFaultEventTime())); + assertNull(podInfoDetailedStatus.getReservoirLevel()); + assertEquals(0, podInfoDetailedStatus.getUnacknowledgedAlerts().getRawValue()); + assertFalse(podInfoDetailedStatus.isFaultAccessingTables()); + ErrorEventInfo errorEventInfo = podInfoDetailedStatus.getErrorEventInfo(); + assertFalse(errorEventInfo.isInsulinStateTableCorruption()); + assertEquals(0x00, errorEventInfo.getInternalVariable()); + assertFalse(errorEventInfo.isImmediateBolusInProgress()); + assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, errorEventInfo.getPodProgressStatus()); + assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoDetailedStatus.getPreviousPodProgressStatus()); + assertEquals(0, podInfoDetailedStatus.getReceiverLowGain()); + assertEquals(35, podInfoDetailedStatus.getRadioRSSI()); + } + + @Test + public void testPodInfoFaultEventInsulinNotDelivered() { + PodInfoDetailedStatus podInfoDetailedStatus = new PodInfoDetailedStatus(ByteUtil.fromHexString("020f0000010200ec6a026803ff026b000028a7082023")); + + assertEquals(PodProgressStatus.INACTIVE, podInfoDetailedStatus.getPodProgressStatus()); + assertEquals(DeliveryStatus.SUSPENDED, podInfoDetailedStatus.getDeliveryStatus()); + assertEquals(236, podInfoDetailedStatus.getTicksDelivered()); + assertEquals(11.8, podInfoDetailedStatus.getInsulinDelivered(), 0.000001); + assertEquals(0.05, podInfoDetailedStatus.getBolusNotDelivered(), 0.000001); + assertEquals(0x02, podInfoDetailedStatus.getPodMessageCounter()); + assertEquals(FaultEventCode.OCCLUSION_CHECK_ABOVE_THRESHOLD, podInfoDetailedStatus.getFaultEventCode()); + assertTrue(Duration.standardMinutes(616).isEqual(podInfoDetailedStatus.getFaultEventTime())); + assertNull(podInfoDetailedStatus.getReservoirLevel()); + assertEquals(0, podInfoDetailedStatus.getUnacknowledgedAlerts().getRawValue()); + assertFalse(podInfoDetailedStatus.isFaultAccessingTables()); + ErrorEventInfo errorEventInfo = podInfoDetailedStatus.getErrorEventInfo(); + assertFalse(errorEventInfo.isInsulinStateTableCorruption()); + assertEquals(0x01, errorEventInfo.getInternalVariable()); + assertFalse(errorEventInfo.isImmediateBolusInProgress()); + assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, errorEventInfo.getPodProgressStatus()); + assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoDetailedStatus.getPreviousPodProgressStatus()); + assertEquals(2, podInfoDetailedStatus.getReceiverLowGain()); + assertEquals(39, podInfoDetailedStatus.getRadioRSSI()); + } + + @Test + public void testPodInfoFaultEventMaxBolusNotDelivered() { + PodInfoDetailedStatus podInfoDetailedStatus = new PodInfoDetailedStatus(ByteUtil.fromHexString("020f00ffff0200ec6a026803ff026b000028a7082023")); + + assertEquals(PodProgressStatus.INACTIVE, podInfoDetailedStatus.getPodProgressStatus()); + assertEquals(DeliveryStatus.SUSPENDED, podInfoDetailedStatus.getDeliveryStatus()); + assertEquals(236, podInfoDetailedStatus.getTicksDelivered()); + assertEquals(11.8, podInfoDetailedStatus.getInsulinDelivered(), 0.000001); + assertEquals(3276.75, podInfoDetailedStatus.getBolusNotDelivered(), 0.000001); // Insane and will not happen, but this verifies that we convert it to an unsigned int + assertEquals(0x02, podInfoDetailedStatus.getPodMessageCounter()); + assertEquals(FaultEventCode.OCCLUSION_CHECK_ABOVE_THRESHOLD, podInfoDetailedStatus.getFaultEventCode()); + assertTrue(Duration.standardMinutes(616).isEqual(podInfoDetailedStatus.getFaultEventTime())); + assertNull(podInfoDetailedStatus.getReservoirLevel()); + assertEquals(0, podInfoDetailedStatus.getUnacknowledgedAlerts().getRawValue()); + assertFalse(podInfoDetailedStatus.isFaultAccessingTables()); + ErrorEventInfo errorEventInfo = podInfoDetailedStatus.getErrorEventInfo(); + assertFalse(errorEventInfo.isInsulinStateTableCorruption()); + assertEquals(0x01, errorEventInfo.getInternalVariable()); + assertFalse(errorEventInfo.isImmediateBolusInProgress()); + assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, errorEventInfo.getPodProgressStatus()); + assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoDetailedStatus.getPreviousPodProgressStatus()); + assertEquals(2, podInfoDetailedStatus.getReceiverLowGain()); + assertEquals(39, podInfoDetailedStatus.getRadioRSSI()); + } + + @Test + public void testPodInfoFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging() { + PodInfoDetailedStatus podInfoDetailedStatus = new PodInfoDetailedStatus(ByteUtil.fromHexString("020D00000000000012FFFF03FF00160000879A070000")); + + assertEquals(PodProgressStatus.FAULT_EVENT_OCCURRED, podInfoDetailedStatus.getPodProgressStatus()); + assertEquals(DeliveryStatus.SUSPENDED, podInfoDetailedStatus.getDeliveryStatus()); + assertEquals(0, podInfoDetailedStatus.getBolusNotDelivered(), 0.000001); + assertEquals(0x00, podInfoDetailedStatus.getPodMessageCounter()); + assertEquals(FaultEventCode.RESET_DUE_TO_LVD, podInfoDetailedStatus.getFaultEventCode()); + assertTrue(Duration.ZERO.isEqual(podInfoDetailedStatus.getFaultEventTime())); + assertNull(podInfoDetailedStatus.getReservoirLevel()); + assertTrue(Duration.standardSeconds(1320).isEqual(podInfoDetailedStatus.getTimeActive())); + assertEquals(0, podInfoDetailedStatus.getUnacknowledgedAlerts().getRawValue()); + assertFalse(podInfoDetailedStatus.isFaultAccessingTables()); + ErrorEventInfo errorEventInfo = podInfoDetailedStatus.getErrorEventInfo(); + assertTrue(errorEventInfo.isInsulinStateTableCorruption()); + assertEquals(0x00, errorEventInfo.getInternalVariable()); + assertFalse(errorEventInfo.isImmediateBolusInProgress()); + assertEquals(PodProgressStatus.INSERTING_CANNULA, errorEventInfo.getPodProgressStatus()); + assertEquals(PodProgressStatus.INSERTING_CANNULA, podInfoDetailedStatus.getPreviousPodProgressStatus()); + assertEquals(2, podInfoDetailedStatus.getReceiverLowGain()); + assertEquals(26, podInfoDetailedStatus.getRadioRSSI()); + } +} diff --git a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEventTest.java b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEventTest.java deleted file mode 100644 index 1ceb53cf59..0000000000 --- a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoFaultEventTest.java +++ /dev/null @@ -1,152 +0,0 @@ -package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo; - -import org.joda.time.Duration; -import org.junit.Test; - -import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.FaultEventCode; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; - -// From https://github.com/ps2/rileylink_ios/blob/omnipod-testing/OmniKitTests/PodInfoTests.swift -public class PodInfoFaultEventTest { - @Test - public void testPodInfoFaultEventNoFaultAlerts() { - PodInfoFaultEvent podInfoFaultEvent = new PodInfoFaultEvent(ByteUtil.fromHexString("02080100000a003800000003ff008700000095ff0000")); - - assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getPodProgressStatus()); - assertEquals(DeliveryStatus.NORMAL, podInfoFaultEvent.getDeliveryStatus()); - assertEquals(0, podInfoFaultEvent.getBolusNotDelivered(), 0.000001); - assertEquals(0x0a, podInfoFaultEvent.getPodMessageCounter()); - assertEquals(FaultEventCode.NO_FAULTS, podInfoFaultEvent.getFaultEventCode()); - assertTrue(Duration.ZERO.isEqual(podInfoFaultEvent.getFaultEventTime())); - assertNull(podInfoFaultEvent.getReservoirLevel()); - assertTrue(Duration.standardSeconds(8100).isEqual(podInfoFaultEvent.getTimeActive())); - assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); - assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); - assertEquals(0x00, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); - assertEquals(PodProgressStatus.INACTIVE, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); - assertEquals(2, podInfoFaultEvent.getReceiverLowGain()); - assertEquals(21, podInfoFaultEvent.getRadioRSSI()); - } - - @Test - public void testPodInfoFaultEventDeliveryErrorDuringPriming() { - PodInfoFaultEvent podInfoFaultEvent = new PodInfoFaultEvent(ByteUtil.fromHexString("020f0000000900345c000103ff0001000005ae056029")); - - assertEquals(PodProgressStatus.INACTIVE, podInfoFaultEvent.getPodProgressStatus()); - assertEquals(DeliveryStatus.SUSPENDED, podInfoFaultEvent.getDeliveryStatus()); - assertEquals(0, podInfoFaultEvent.getBolusNotDelivered(), 0.000001); - assertEquals(0x09, podInfoFaultEvent.getPodMessageCounter()); - assertEquals(FaultEventCode.PRIME_OPEN_COUNT_TOO_LOW, podInfoFaultEvent.getFaultEventCode()); - assertTrue(Duration.standardSeconds(60).isEqual(podInfoFaultEvent.getFaultEventTime())); - assertNull(podInfoFaultEvent.getReservoirLevel()); - assertTrue(Duration.standardSeconds(60).isEqual(podInfoFaultEvent.getTimeActive())); - assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); - assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); - assertEquals(0x00, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); - assertEquals(PodProgressStatus.PRIMING_COMPLETED, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); - assertEquals(2, podInfoFaultEvent.getReceiverLowGain()); - assertEquals(46, podInfoFaultEvent.getRadioRSSI()); - } - - @Test - public void testPodInfoFaultEventErrorShuttingDown() { - PodInfoFaultEvent podInfoFaultEvent = new PodInfoFaultEvent(ByteUtil.fromHexString("020d0000000407f28609ff03ff0a0200000823080000")); - - assertEquals(PodProgressStatus.FAULT_EVENT_OCCURRED, podInfoFaultEvent.getPodProgressStatus()); - assertEquals(DeliveryStatus.SUSPENDED, podInfoFaultEvent.getDeliveryStatus()); - assertEquals(2034, podInfoFaultEvent.getTicksDelivered()); - assertEquals(101.7, podInfoFaultEvent.getInsulinDelivered(), 0.000001); - assertEquals(0, podInfoFaultEvent.getBolusNotDelivered(), 0.000001); - assertEquals(0x04, podInfoFaultEvent.getPodMessageCounter()); - assertEquals(FaultEventCode.BASAL_OVER_INFUSION_PULSE, podInfoFaultEvent.getFaultEventCode()); - assertTrue(Duration.standardMinutes(2559).isEqual(podInfoFaultEvent.getFaultEventTime())); - assertNull(podInfoFaultEvent.getReservoirLevel()); - assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); - assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); - assertEquals(0x00, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); - assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); - assertEquals(0, podInfoFaultEvent.getReceiverLowGain()); - assertEquals(35, podInfoFaultEvent.getRadioRSSI()); - } - - @Test - public void testPodInfoFaultEventInsulinNotDelivered() { - PodInfoFaultEvent podInfoFaultEvent = new PodInfoFaultEvent(ByteUtil.fromHexString("020f0000010200ec6a026803ff026b000028a7082023")); - - assertEquals(PodProgressStatus.INACTIVE, podInfoFaultEvent.getPodProgressStatus()); - assertEquals(DeliveryStatus.SUSPENDED, podInfoFaultEvent.getDeliveryStatus()); - assertEquals(236, podInfoFaultEvent.getTicksDelivered()); - assertEquals(11.8, podInfoFaultEvent.getInsulinDelivered(), 0.000001); - assertEquals(0.05, podInfoFaultEvent.getBolusNotDelivered(), 0.000001); - assertEquals(0x02, podInfoFaultEvent.getPodMessageCounter()); - assertEquals(FaultEventCode.OCCLUSION_CHECK_ABOVE_THRESHOLD, podInfoFaultEvent.getFaultEventCode()); - assertTrue(Duration.standardMinutes(616).isEqual(podInfoFaultEvent.getFaultEventTime())); - assertNull(podInfoFaultEvent.getReservoirLevel()); - assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); - assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); - assertEquals(0x01, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); - assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); - assertEquals(2, podInfoFaultEvent.getReceiverLowGain()); - assertEquals(39, podInfoFaultEvent.getRadioRSSI()); - } - - @Test - public void testPodInfoFaultEventMaxBolusNotDelivered() { - PodInfoFaultEvent podInfoFaultEvent = new PodInfoFaultEvent(ByteUtil.fromHexString("020f00ffff0200ec6a026803ff026b000028a7082023")); - - assertEquals(PodProgressStatus.INACTIVE, podInfoFaultEvent.getPodProgressStatus()); - assertEquals(DeliveryStatus.SUSPENDED, podInfoFaultEvent.getDeliveryStatus()); - assertEquals(236, podInfoFaultEvent.getTicksDelivered()); - assertEquals(11.8, podInfoFaultEvent.getInsulinDelivered(), 0.000001); - assertEquals(3276.75, podInfoFaultEvent.getBolusNotDelivered(), 0.000001); // Insane and will not happen, but this verifies that we convert it to an unsigned int - assertEquals(0x02, podInfoFaultEvent.getPodMessageCounter()); - assertEquals(FaultEventCode.OCCLUSION_CHECK_ABOVE_THRESHOLD, podInfoFaultEvent.getFaultEventCode()); - assertTrue(Duration.standardMinutes(616).isEqual(podInfoFaultEvent.getFaultEventTime())); - assertNull(podInfoFaultEvent.getReservoirLevel()); - assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); - assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); - assertEquals(0x01, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); - assertEquals(PodProgressStatus.ABOVE_FIFTY_UNITS, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); - assertEquals(2, podInfoFaultEvent.getReceiverLowGain()); - assertEquals(39, podInfoFaultEvent.getRadioRSSI()); - } - - @Test - public void testPodInfoFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging() { - PodInfoFaultEvent podInfoFaultEvent = new PodInfoFaultEvent(ByteUtil.fromHexString("020D00000000000012FFFF03FF00160000879A070000")); - - assertEquals(PodProgressStatus.FAULT_EVENT_OCCURRED, podInfoFaultEvent.getPodProgressStatus()); - assertEquals(DeliveryStatus.SUSPENDED, podInfoFaultEvent.getDeliveryStatus()); - assertEquals(0, podInfoFaultEvent.getBolusNotDelivered(), 0.000001); - assertEquals(0x00, podInfoFaultEvent.getPodMessageCounter()); - assertEquals(FaultEventCode.RESET_DUE_TO_LVD, podInfoFaultEvent.getFaultEventCode()); - assertTrue(Duration.ZERO.isEqual(podInfoFaultEvent.getFaultEventTime())); - assertNull(podInfoFaultEvent.getReservoirLevel()); - assertTrue(Duration.standardSeconds(1320).isEqual(podInfoFaultEvent.getTimeActive())); - assertEquals(0, podInfoFaultEvent.getUnacknowledgedAlerts().getRawValue()); - assertFalse(podInfoFaultEvent.isFaultAccessingTables()); - assertTrue(podInfoFaultEvent.isLoggedFaultEventInsulinStateTableCorruptionFoundDuringErrorLogging()); - assertEquals(0x00, podInfoFaultEvent.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); - assertFalse(podInfoFaultEvent.isLoggedFaultEventImmediateBolusInProgressDuringError()); - assertEquals(PodProgressStatus.INSERTING_CANNULA, podInfoFaultEvent.getLoggedFaultEventPodProgressStatus()); - assertEquals(2, podInfoFaultEvent.getReceiverLowGain()); - assertEquals(26, podInfoFaultEvent.getRadioRSSI()); - } -} diff --git a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponseTest.java b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponseTest.java index f82674acfc..99d05b7d03 100644 --- a/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponseTest.java +++ b/omnipod/src/test/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoResponseTest.java @@ -38,18 +38,18 @@ public class PodInfoResponseTest { public void testMessageDecoding() { PodInfoResponse podInfoResponse = new PodInfoResponse(ByteUtil.fromHexString("0216020d0000000000ab6a038403ff03860000285708030d")); - assertEquals(PodInfoType.FAULT_EVENT, podInfoResponse.getSubType()); + assertEquals(PodInfoType.DETAILED_STATUS, podInfoResponse.getSubType()); - PodInfoFaultEvent podInfo = (PodInfoFaultEvent) podInfoResponse.getPodInfo(); + PodInfoDetailedStatus podInfo = (PodInfoDetailedStatus) podInfoResponse.getPodInfo(); assertFalse(podInfo.isFaultAccessingTables()); - assertEquals(0x01, podInfo.getLoggedFaultEventInternal2bitMainLoopRoutinesVariable()); + assertEquals(0x01, podInfo.getErrorEventInfo().getInternalVariable()); } @Test public void testInvalidPodInfoTypeMessageDecoding() { PodInfoResponse podInfoResponse = new PodInfoResponse(ByteUtil.fromHexString("0216020d0000000000ab6a038403ff03860000285708030d")); - assertEquals(PodInfoType.FAULT_EVENT, podInfoResponse.getSubType()); + assertEquals(PodInfoType.DETAILED_STATUS, podInfoResponse.getSubType()); thrown.expect(ClassCastException.class); PodInfoActiveAlerts podInfo = (PodInfoActiveAlerts) podInfoResponse.getPodInfo(); From b3933e510d5c2d1bcd2e69c7ce41c1e71a30dd1d Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 17 Oct 2020 12:50:08 +0200 Subject: [PATCH 10/15] Re-introduce SetupProgress in order to be able to correctly handle Activation Time Exceeded errors --- .../pump/omnipod/OmnipodPumpPlugin.java | 10 +- .../action/AssignAddressAction.java | 69 ++-- .../action/InsertCannulaAction.java | 35 +- .../communication/action/PrimeAction.java | 37 +- .../communication/action/SetupPodAction.java | 64 ++-- .../driver/definition/SetupProgress.java | 66 ++++ .../IllegalPodProgressException.java | 2 +- .../IllegalSetupProgressException.java | 24 ++ .../driver/manager/OmnipodManager.java | 361 ++++++------------ .../driver/manager/PodStateManager.java | 27 +- .../omnipod/manager/AapsOmnipodManager.java | 4 +- .../omnipod/ui/OmnipodOverviewFragment.kt | 7 +- .../pump/omnipod/ui/PodManagementActivity.kt | 5 +- .../activation/PodActivationWizardActivity.kt | 4 +- .../PodActivationActionFragmentBase.kt | 3 +- 15 files changed, 384 insertions(+), 334 deletions(-) create mode 100644 omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/SetupProgress.java create mode 100644 omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalSetupProgressException.java 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 8d2e1bf50e..6ce16cb71f 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 @@ -74,6 +74,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.acti import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged; import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodTbrChanged; @@ -254,6 +255,13 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface, // When PodStateManager is created, which causes an IllegalArgumentException for DateTimeZones not being recognized podStateManager.loadPodState(); + // BS @ 2020-10-17 FIXME: for backwards compatibility; remove before release + if (podStateManager.isPodInitialized() && + podStateManager.getSetupProgress() == SetupProgress.NONE && + podStateManager.getPodProgressStatus().isAtLeast(PodProgressStatus.ABOVE_FIFTY_UNITS)) { + podStateManager.setSetupProgress(SetupProgress.COMPLETED); + } + lastConnectionTimeMillis = sp.getLong( RileyLinkConst.Prefs.LastGoodDeviceCommunicationTime, 0L); @@ -922,7 +930,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface, } private void initializeAfterRileyLinkConnection() { - if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAtLeast(PodProgressStatus.PAIRING_COMPLETED)) { + if (podStateManager.getSetupProgress().isAtLeast(SetupProgress.PAIRING_COMPLETED)) { for (int i = 0; STARTUP_STATUS_REQUEST_TRIES > i; i++) { PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus); if (result.success) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java index dbea17fde2..a16c69163a 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java @@ -5,59 +5,68 @@ import org.joda.time.DateTimeZone; import java.util.Collections; import java.util.Random; +import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.AssignAddressCommand; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; -public class AssignAddressAction implements OmnipodAction { +public class AssignAddressAction implements OmnipodAction { private final PodStateManager podStateManager; + private final AAPSLogger aapsLogger; - public AssignAddressAction(PodStateManager podStateManager) { + public AssignAddressAction(PodStateManager podStateManager, AAPSLogger aapsLogger) { if (podStateManager == null) { throw new IllegalArgumentException("podStateManager can not be null"); } + if (aapsLogger == null) { + throw new IllegalArgumentException("Logger can not be null"); + } this.podStateManager = podStateManager; + this.aapsLogger = aapsLogger; } @Override - public VersionResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { + public Void execute(OmnipodRileyLinkCommunicationManager communicationService) { if (!podStateManager.hasPodState()) { podStateManager.initState(generateRandomAddress()); } - if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.REMINDER_INITIALIZED)) { - throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.getPodProgressStatus()); + + if (podStateManager.getSetupProgress().needsPairing()) { + AssignAddressCommand assignAddress = new AssignAddressCommand(podStateManager.getAddress()); + OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS, + Collections.singletonList(assignAddress), podStateManager.getMessageNumber()); + + try { + VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, assignAddressMessage, + OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress()); + + if (!assignAddressResponse.isAssignAddressVersionResponse()) { + throw new IllegalVersionResponseTypeException("assignAddress", "setupPod"); + } + if (assignAddressResponse.getAddress() != podStateManager.getAddress()) { + throw new IllegalMessageAddressException(podStateManager.getAddress(), assignAddressResponse.getAddress()); + } + + podStateManager.setInitializationParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), // + assignAddressResponse.getPiVersion(), assignAddressResponse.getPmVersion(), DateTimeZone.getDefault(), assignAddressResponse.getPodProgressStatus()); + } catch (IllegalPacketTypeException ex) { + if (ex.getActual() == PacketType.ACK && podStateManager.isPodInitialized()) { + // When we already assigned the address before, it's possible to only get an ACK here + aapsLogger.debug("Received ACK instead of response in AssignAddressAction. Ignoring because we already assigned the address successfully"); + } else { + throw ex; + } + } } - AssignAddressCommand assignAddress = new AssignAddressCommand(podStateManager.getAddress()); - OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS, - Collections.singletonList(assignAddress), podStateManager.getMessageNumber()); - - VersionResponse assignAddressResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, assignAddressMessage, - OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress()); - - if (!assignAddressResponse.isAssignAddressVersionResponse()) { - throw new IllegalVersionResponseTypeException("assignAddress", "setupPod"); - } - if (assignAddressResponse.getAddress() != podStateManager.getAddress()) { - throw new IllegalMessageAddressException(podStateManager.getAddress(), assignAddressResponse.getAddress()); - } - - podStateManager.setInitializationParameters(assignAddressResponse.getLot(), assignAddressResponse.getTid(), // - assignAddressResponse.getPiVersion(), assignAddressResponse.getPmVersion(), DateTimeZone.getDefault(), assignAddressResponse.getPodProgressStatus()); - - if (podStateManager.isPodActivationTimeExceeded()) { - throw new ActivationTimeExceededException(); - } - - return assignAddressResponse; + return null; } private static int generateRandomAddress() { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java index 7dae20fea9..b1adbc1f68 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java @@ -6,16 +6,15 @@ import java.util.List; import java.util.Optional; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.ExpirationReminderBuilder; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; -public class InsertCannulaAction implements OmnipodAction { +public class InsertCannulaAction implements OmnipodAction { private final PodStateManager podStateManager; private final BasalSchedule initialBasalSchedule; @@ -37,31 +36,33 @@ public class InsertCannulaAction implements OmnipodAction { } @Override - public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { - if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) { - throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); + public Void execute(OmnipodRileyLinkCommunicationManager communicationService) { + if (podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_COMPLETED)) { + throw new IllegalSetupProgressException(SetupProgress.PRIMING_COMPLETED, podStateManager.getSetupProgress()); } - if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.BASAL_INITIALIZED)) { + if (podStateManager.getSetupProgress().needsBasalSchedule()) { podStateManager.setBasalSchedule(initialBasalSchedule); communicationService.executeAction(new SetBasalScheduleAction(podStateManager, initialBasalSchedule, true, podStateManager.getScheduleOffset(), false)); + podStateManager.setSetupProgress(SetupProgress.BASAL_INITIALIZED); } - if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.INSERTING_CANNULA)) { + if (podStateManager.getSetupProgress().needsExpirationReminders()) { communicationService.executeAction(new ConfigureAlertsAction(podStateManager, buildAlertConfigurations())); podStateManager.setExpirationAlertTimeBeforeShutdown(expirationReminderTimeBeforeShutdown); podStateManager.setLowReservoirAlertUnits(lowReservoirAlertUnits); - - return communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, - Duration.standardSeconds(1), false, false)); - } else if (podStateManager.getPodProgressStatus().equals(PodProgressStatus.INSERTING_CANNULA)) { - // Check status - return communicationService.executeAction(new GetStatusAction(podStateManager)); - } else { - throw new IllegalPodProgressException(null, podStateManager.getPodProgressStatus()); + podStateManager.setSetupProgress(SetupProgress.EXPIRATION_REMINDERS_SET); } + + if (podStateManager.getSetupProgress().needsCannulaInsertion()) { + communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, + Duration.standardSeconds(1), false, false)); + podStateManager.setSetupProgress(SetupProgress.INSERTING_CANNULA); + } + + return null; } private List buildAlertConfigurations() { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java index 44c50e1a38..6f748e9962 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java @@ -1,13 +1,12 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.PrimeService; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; -public class PrimeAction implements OmnipodAction { +public class PrimeAction implements OmnipodAction { private final PrimeService service; private final PodStateManager podStateManager; @@ -24,21 +23,27 @@ public class PrimeAction implements OmnipodAction { } @Override - public StatusResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { - if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PAIRING_COMPLETED)) { - throw new IllegalPodProgressException(PodProgressStatus.PAIRING_COMPLETED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); + public Void execute(OmnipodRileyLinkCommunicationManager communicationService) { + if (podStateManager.getSetupProgress().isBefore(SetupProgress.PAIRING_COMPLETED)) { + throw new IllegalSetupProgressException(SetupProgress.PAIRING_COMPLETED, podStateManager.getSetupProgress()); } - if (podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING)) { + + if (podStateManager.getSetupProgress().needsDisableTab5Sub16And17()) { // FaultConfigCommand sets internal pod variables to effectively disable $6x faults which occur more often with a 0 TBR service.executeDisableTab5Sub16And17FaultConfigCommand(communicationService, podStateManager); - - service.executeFinishSetupReminderAlertCommand(communicationService, podStateManager); - return service.executePrimeBolusCommand(communicationService, podStateManager); - } else if (podStateManager.getPodProgressStatus().equals(PodProgressStatus.PRIMING)) { - // Check status - return communicationService.executeAction(new GetStatusAction(podStateManager)); - } else { - throw new IllegalPodProgressException(null, podStateManager.getPodProgressStatus()); + podStateManager.setSetupProgress(SetupProgress.TAB_5_SUB_16_AND_17_DISABLED); } + + if (podStateManager.getSetupProgress().needsSetupReminders()) { + service.executeFinishSetupReminderAlertCommand(communicationService, podStateManager); + podStateManager.setSetupProgress(SetupProgress.SETUP_REMINDERS_SET); + } + + if (podStateManager.getSetupProgress().needsPriming()) { + service.executePrimeBolusCommand(communicationService, podStateManager); + podStateManager.setSetupProgress(SetupProgress.PRIMING); + } + + return null; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java index dc4c06abe2..498e285b0b 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java @@ -4,54 +4,72 @@ import org.joda.time.DateTime; import java.util.Collections; +import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetupPodCommand; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; -public class SetupPodAction implements OmnipodAction { +public class SetupPodAction implements OmnipodAction { private final PodStateManager podStateManager; + private final AAPSLogger aapsLogger; - public SetupPodAction(PodStateManager podStateManager) { + public SetupPodAction(PodStateManager podStateManager, AAPSLogger aapsLogger) { if (podStateManager == null) { throw new IllegalArgumentException("Pod state manager can not be null"); } + if (aapsLogger == null) { + throw new IllegalArgumentException("Logger can not be null"); + } this.podStateManager = podStateManager; + this.aapsLogger = aapsLogger; } @Override - public VersionResponse execute(OmnipodRileyLinkCommunicationManager communicationService) { - if (!podStateManager.isPodInitialized() || !podStateManager.getPodProgressStatus().equals(PodProgressStatus.REMINDER_INITIALIZED)) { + public Void execute(OmnipodRileyLinkCommunicationManager communicationService) { + if (!podStateManager.isPodInitialized()) { throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); } - DateTime activationDate = DateTime.now(podStateManager.getTimeZone()); - SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate, - podStateManager.getLot(), podStateManager.getTid()); - OmnipodMessage message = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS, - Collections.singletonList(setupPodCommand), podStateManager.getMessageNumber()); - VersionResponse setupPodResponse; - setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, - message, OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress()); + if (podStateManager.getSetupProgress().needsPairing()) { + DateTime activationDate = DateTime.now(podStateManager.getTimeZone()); - if (!setupPodResponse.isSetupPodVersionResponse()) { - throw new IllegalVersionResponseTypeException("setupPod", "assignAddress"); - } - if (setupPodResponse.getAddress() != podStateManager.getAddress()) { - throw new IllegalMessageAddressException(podStateManager.getAddress(), setupPodResponse.getAddress()); + SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate, + podStateManager.getLot(), podStateManager.getTid()); + OmnipodMessage message = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS, + Collections.singletonList(setupPodCommand), podStateManager.getMessageNumber()); + + try { + VersionResponse setupPodResponse = communicationService.exchangeMessages(VersionResponse.class, podStateManager, + message, OmnipodConstants.DEFAULT_ADDRESS, podStateManager.getAddress()); + + if (!setupPodResponse.isSetupPodVersionResponse()) { + throw new IllegalVersionResponseTypeException("setupPod", "assignAddress"); + } + if (setupPodResponse.getAddress() != podStateManager.getAddress()) { + throw new IllegalMessageAddressException(podStateManager.getAddress(), setupPodResponse.getAddress()); + } + } catch (IllegalPacketTypeException ex) { + if (PacketType.ACK.equals(ex.getActual())) { + // Pod is already configured + aapsLogger.debug("Received ACK instead of response in SetupPodAction. Ignoring"); + } else { + throw ex; + } + } + + podStateManager.setSetupProgress(SetupProgress.PAIRING_COMPLETED); } - if (podStateManager.isPodActivationTimeExceeded()) { - throw new ActivationTimeExceededException(); - } - - return setupPodResponse; + return null; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/SetupProgress.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/SetupProgress.java new file mode 100644 index 0000000000..874b9a2d3e --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/SetupProgress.java @@ -0,0 +1,66 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; + +public enum SetupProgress { + NONE, + PAIRING_COMPLETED, + TAB_5_SUB_16_AND_17_DISABLED, + SETUP_REMINDERS_SET, + PRIMING, + PRIMING_COMPLETED, + BASAL_INITIALIZED, + EXPIRATION_REMINDERS_SET, + INSERTING_CANNULA, + COMPLETED; + + public boolean needsPairing() { + return this == NONE; + } + + public boolean needsDisableTab5Sub16And17() { + return this == PAIRING_COMPLETED; + } + + public boolean needsSetupReminders() { + return this == TAB_5_SUB_16_AND_17_DISABLED; + } + + public boolean needsPriming() { + return this == SETUP_REMINDERS_SET; + } + + public boolean needsPrimingVerification() { + return this == PRIMING; + } + + public boolean needsBasalSchedule() { + return this == PRIMING_COMPLETED; + } + + public boolean needsExpirationReminders() { + return this == BASAL_INITIALIZED; + } + + public boolean needsCannulaInsertion() { + return this == EXPIRATION_REMINDERS_SET; + } + + public boolean needsCannulaInsertionVerification() { + return this == INSERTING_CANNULA; + } + + public boolean isCompleted() { + return this == COMPLETED; + } + + public boolean isBefore(SetupProgress other) { + return ordinal() < other.ordinal(); + } + + public boolean isAtLeast(SetupProgress other) { + return ordinal() >= other.ordinal(); + } + + public boolean isAfter(SetupProgress other) { + return ordinal() > other.ordinal(); + } +} \ No newline at end of file diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalPodProgressException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalPodProgressException.java index da319d5d83..18719fa1ce 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalPodProgressException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalPodProgressException.java @@ -9,7 +9,7 @@ public class IllegalPodProgressException extends OmnipodException { private final PodProgressStatus actual; public IllegalPodProgressException(PodProgressStatus expected, PodProgressStatus actual) { - super(String.format(Locale.getDefault(), "Illegal setup state: %s, expected: %s", actual, expected), true); + super(String.format(Locale.getDefault(), "Illegal Pod progress: %s, expected: %s", actual, expected), true); this.expected = expected; this.actual = actual; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalSetupProgressException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalSetupProgressException.java new file mode 100644 index 0000000000..42744496ea --- /dev/null +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalSetupProgressException.java @@ -0,0 +1,24 @@ +package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; + +import java.util.Locale; + +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; + +public class IllegalSetupProgressException extends OmnipodException { + private final SetupProgress expected; + private final SetupProgress actual; + + public IllegalSetupProgressException(SetupProgress expected, SetupProgress actual) { + super(String.format(Locale.getDefault(), "Illegal setup progress: %s, expected: %s", actual, expected), true); + this.expected = expected; + this.actual = actual; + } + + public SetupProgress getExpected() { + return expected; + } + + public SetupProgress getActual() { + return actual; + } +} diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java index bd87de7499..1f8593eb67 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java @@ -36,16 +36,15 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepTyp import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.ActivationTimeExceededException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodFaultException; @@ -89,89 +88,54 @@ public class OmnipodManager { } public synchronized Single pairAndPrime() { - if (podStateManager.isPodActivationTimeExceeded()) { - throw new ActivationTimeExceededException(); - } - if (podStateManager.isPodInitialized() && podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.PRIMING)) { - return Single.just(true); - } - - logStartingCommandExecution("pairAndPrime"); - - try { - // Always send both 0x07 and 0x03 on retries - if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PAIRING_COMPLETED)) { - try { - communicationService.executeAction( - new AssignAddressAction(podStateManager)); - } catch (IllegalPacketTypeException ex) { - if (ex.getActual() == PacketType.ACK && podStateManager.isPodInitialized()) { - // When we already assigned the address before, it's possible to only get an ACK here - aapsLogger.debug("Received ACK instead of response in AssignAddressAction. Ignoring because we already assigned the address successfully"); - } else { - throw ex; - } - } - - try { - communicationService.executeAction(new SetupPodAction(podStateManager)); - } catch (IllegalPacketTypeException ex) { - if (PacketType.ACK.equals(ex.getActual())) { - // Pod is already configured - aapsLogger.debug("Received ACK instead of response in SetupPodAction. Ignoring"); - } - } - } else { - // Make sure we have an up to date PodProgressStatus - getPodStatus(); - - if (podStateManager.isPodActivationTimeExceeded()) { - throw new ActivationTimeExceededException(); - } + if (podStateManager.isPodInitialized()) { + if (podStateManager.getSetupProgress().isAfter(SetupProgress.PRIMING)) { + return Single.just(true); + } + if (podStateManager.getSetupProgress().needsPrimingVerification()) { + return Single.fromCallable(() -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, SetupProgress.PRIMING_COMPLETED)); } - - communicationService.executeAction(new PrimeAction(new PrimeService(), podStateManager)); - - long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_PRIME_BOLUS_UNITS, OmnipodConstants.POD_PRIMING_DELIVERY_RATE).getMillis(); - - return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // - .map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED)) // - .subscribeOn(Schedulers.io()); - } finally { - logCommandExecutionFinished("pairAndPrime"); } + + // Always send both 0x07 and 0x03 on retries + if (podStateManager.getSetupProgress().isBefore(SetupProgress.PAIRING_COMPLETED)) { + communicationService.executeAction( + new AssignAddressAction(podStateManager, aapsLogger)); + + communicationService.executeAction(new SetupPodAction(podStateManager, aapsLogger)); + } + + communicationService.executeAction(new PrimeAction(new PrimeService(), podStateManager)); + + long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_PRIME_BOLUS_UNITS, OmnipodConstants.POD_PRIMING_DELIVERY_RATE).getMillis(); + + return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // + .map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, SetupProgress.PRIMING_COMPLETED)) // + .subscribeOn(Schedulers.io()); } public synchronized Single insertCannula( BasalSchedule basalSchedule, Duration expirationReminderTimeBeforeShutdown, Integer lowReservoirAlertUnits) { - if (!podStateManager.isPodInitialized() || podStateManager.getPodProgressStatus().isBefore(PodProgressStatus.PRIMING_COMPLETED)) { - throw new IllegalPodProgressException(PodProgressStatus.PRIMING_COMPLETED, !podStateManager.isPodInitialized() ? null : podStateManager.getPodProgressStatus()); + if (podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_COMPLETED)) { + throw new IllegalSetupProgressException(SetupProgress.PRIMING_COMPLETED, podStateManager.getSetupProgress()); } - logStartingCommandExecution("insertCannula [basalSchedule=" + basalSchedule + "]"); - - try { - // Make sure we have the latest PodProgressStatus - getPodStatus(); - - if (podStateManager.isPodActivationTimeExceeded()) { - throw new ActivationTimeExceededException(); - } - if (podStateManager.getPodProgressStatus().isAfter(PodProgressStatus.INSERTING_CANNULA)) { + if (podStateManager.isPodInitialized()) { + if (podStateManager.getSetupProgress().isCompleted()) { return Single.just(true); } - - communicationService.executeAction(new InsertCannulaAction(podStateManager, basalSchedule, expirationReminderTimeBeforeShutdown, lowReservoirAlertUnits)); - - long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConstants.POD_CANNULA_INSERTION_DELIVERY_RATE).getMillis(); - - return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // - .map(o -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS)) // - .subscribeOn(Schedulers.io()); - - } finally { - logCommandExecutionFinished("insertCannula"); + if (podStateManager.getSetupProgress().needsCannulaInsertionVerification()) { + return Single.fromCallable(() -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS, SetupProgress.COMPLETED)); + } } + + communicationService.executeAction(new InsertCannulaAction(podStateManager, basalSchedule, expirationReminderTimeBeforeShutdown, lowReservoirAlertUnits)); + + long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConstants.POD_CANNULA_INSERTION_DELIVERY_RATE).getMillis(); + + return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // + .map(o -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS, SetupProgress.COMPLETED)) // + .subscribeOn(Schedulers.io()); } public synchronized StatusResponse getPodStatus() { @@ -179,49 +143,29 @@ public class OmnipodManager { throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null); } - logStartingCommandExecution("getPodStatus"); + return communicationService.executeAction(new GetStatusAction(podStateManager)); - try { - return communicationService.executeAction(new GetStatusAction(podStateManager)); - } finally { - logCommandExecutionFinished("getPodStatus"); - } } public synchronized PodInfoResponse getPodInfo(PodInfoType podInfoType) { assertReadyForDelivery(); - logStartingCommandExecution("getPodInfo"); - - try { - return communicationService.executeAction(new GetPodInfoAction(podStateManager, podInfoType)); - } finally { - logCommandExecutionFinished("getPodInfo"); - } + return communicationService.executeAction(new GetPodInfoAction(podStateManager, podInfoType)); } public synchronized StatusResponse configureAlerts(List alertConfigurations) { assertReadyForDelivery(); - logStartingCommandExecution("configureAlerts"); - try { - StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new ConfigureAlertsAction(podStateManager, alertConfigurations))); - ConfigureAlertsAction.updateConfiguredAlerts(podStateManager, alertConfigurations); - return statusResponse; - } finally { - logCommandExecutionFinished("configureAlerts"); - } + + StatusResponse statusResponse = executeAndVerify(() -> communicationService.executeAction(new ConfigureAlertsAction(podStateManager, alertConfigurations))); + ConfigureAlertsAction.updateConfiguredAlerts(podStateManager, alertConfigurations); + return statusResponse; + } public synchronized StatusResponse acknowledgeAlerts() { assertReadyForDelivery(); - logStartingCommandExecution("acknowledgeAlerts"); - - try { - return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podStateManager, podStateManager.getActiveAlerts()))); - } finally { - logCommandExecutionFinished("acknowledgeAlerts"); - } + return executeAndVerify(() -> communicationService.executeAction(new AcknowledgeAlertsAction(podStateManager, podStateManager.getActiveAlerts()))); } // CAUTION: cancels all delivery @@ -229,41 +173,33 @@ public class OmnipodManager { public synchronized void setBasalSchedule(BasalSchedule schedule, boolean acknowledgementBeep) { assertReadyForDelivery(); - logStartingCommandExecution("setBasalSchedule [basalSchedule=" + schedule + ", acknowledgementBeep=" + acknowledgementBeep + "]"); + boolean wasSuspended = podStateManager.isSuspended(); + if (!wasSuspended) { + suspendDelivery(acknowledgementBeep); + } try { - boolean wasSuspended = podStateManager.isSuspended(); - if (!wasSuspended) { - suspendDelivery(acknowledgementBeep); + executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, schedule, + false, podStateManager.getScheduleOffset(), acknowledgementBeep))); + podStateManager.setBasalSchedule(schedule); + } catch (OmnipodException ex) { + if (ex.isCertainFailure()) { + if (!wasSuspended) { + throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but setting the new basal schedule did not", ex); + } + throw ex; } - try { - executeAndVerify(() -> communicationService.executeAction(new SetBasalScheduleAction(podStateManager, schedule, - false, podStateManager.getScheduleOffset(), acknowledgementBeep))); + // verifyDeliveryStatus will throw an exception if verification fails + if (verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) { podStateManager.setBasalSchedule(schedule); - } catch (OmnipodException ex) { - if (ex.isCertainFailure()) { - if (!wasSuspended) { - throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but setting the new basal schedule did not", ex); - } - throw ex; - } - - // verifyDeliveryStatus will throw an exception if verification fails - if (verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) { - podStateManager.setBasalSchedule(schedule); - } else { - if (!wasSuspended) { - throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but setting the new basal schedule did not", ex); - } - ex.setCertainFailure(true); - throw ex; + } else { + if (!wasSuspended) { + throw new CommandFailedAfterChangingDeliveryStatusException("Suspending delivery succeeded but setting the new basal schedule did not", ex); } + ex.setCertainFailure(true); + throw ex; } - - - } finally { - logCommandExecutionFinished("setBasalSchedule"); } } @@ -271,70 +207,64 @@ public class OmnipodManager { public synchronized void setTemporaryBasal(double rate, Duration duration, boolean acknowledgementBeep, boolean completionBeep) { assertReadyForDelivery(); - logStartingCommandExecution("setTemporaryBasal [rate=" + rate + ", duration=" + duration + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]"); - boolean cancelCurrentTbr = podStateManager.isTempBasalRunning(); - try { - if (cancelCurrentTbr) { - try { - cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), acknowledgementBeep); - } catch (OmnipodException ex) { - if (ex.isCertainFailure()) { - throw ex; - } - - try { - if (!verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) { - ex.setCertainFailure(true); - throw ex; - } - } catch (DeliveryStatusVerificationFailedException ex2) { - podStateManager.setTempBasalCertain(false); - throw ex2; - } - } - } - + if (cancelCurrentTbr) { try { - executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction( - podStateManager, rate, duration, acknowledgementBeep, completionBeep))); - podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, true); + cancelDelivery(EnumSet.of(DeliveryType.TEMP_BASAL), acknowledgementBeep); } catch (OmnipodException ex) { if (ex.isCertainFailure()) { - if (cancelCurrentTbr) { - throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex); - } throw ex; } - // verifyDeliveryStatus will throw an exception if verification fails try { - if (verifyDeliveryStatus(DeliveryStatus.TEMP_BASAL_RUNNING, ex)) { - podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, true); - } else { - if (cancelCurrentTbr) { - throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex); - } - + if (!verifyDeliveryStatus(DeliveryStatus.NORMAL, ex)) { ex.setCertainFailure(true); throw ex; } - } catch (CommandFailedAfterChangingDeliveryStatusException ex2) { - // Don't set temp basal in Pod State for this Exception - throw ex2; - } catch (OmnipodException ex2) { - if (!ex2.isCertainFailure()) { - // We're not sure that setting the new TBR failed, so we assume that it succeeded - // If it didn't, PodStateManager.updateFromResponse() will fix the state - // upon receiving the next StatusResponse - podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, false); - } + } catch (DeliveryStatusVerificationFailedException ex2) { + podStateManager.setTempBasalCertain(false); throw ex2; } } - } finally { - logCommandExecutionFinished("setTemporaryBasal"); + } + + try { + executeAndVerify(() -> communicationService.executeAction(new SetTempBasalAction( + podStateManager, rate, duration, acknowledgementBeep, completionBeep))); + podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, true); + } catch (OmnipodException ex) { + if (ex.isCertainFailure()) { + if (cancelCurrentTbr) { + throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex); + } + throw ex; + } + + // verifyDeliveryStatus will throw an exception if verification fails + try { + if (verifyDeliveryStatus(DeliveryStatus.TEMP_BASAL_RUNNING, ex)) { + podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, true); + } else { + if (cancelCurrentTbr) { + throw new CommandFailedAfterChangingDeliveryStatusException("Failed to set new TBR while cancelling old TBR succeeded", ex); + } + + ex.setCertainFailure(true); + throw ex; + } + } catch (CommandFailedAfterChangingDeliveryStatusException ex2) { + // Don't set temp basal in Pod State for this Exception + throw ex2; + } catch (OmnipodException ex2) { + if (!ex2.isCertainFailure()) { + // We're not sure that setting the new TBR failed, so we assume that it succeeded + // If it didn't, PodStateManager.updateFromResponse() will fix the state + // upon receiving the next StatusResponse + podStateManager.setTempBasal(DateTime.now().minus(OmnipodConstants.AVERAGE_TEMP_BASAL_COMMAND_COMMUNICATION_DURATION), rate, duration, false); + } + throw ex2; + } } } @@ -361,17 +291,11 @@ public class OmnipodManager { private synchronized StatusResponse cancelDelivery(EnumSet deliveryTypes, boolean acknowledgementBeep) { assertReadyForDelivery(); - logStartingCommandExecution("cancelDelivery [deliveryTypes=" + deliveryTypes + ", acknowledgementBeep=" + acknowledgementBeep + "]"); - - try { - return executeAndVerify(() -> { - StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep)); - aapsLogger.info(LTag.PUMPCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString()); - return statusResponse; - }); - } finally { - logCommandExecutionFinished("cancelDelivery"); - } + return executeAndVerify(() -> { + StatusResponse statusResponse = communicationService.executeAction(new CancelDeliveryAction(podStateManager, deliveryTypes, acknowledgementBeep)); + aapsLogger.info(LTag.PUMPCOMM, "Status response after cancel delivery[types={}]: {}", deliveryTypes.toString(), statusResponse.toString()); + return statusResponse; + }); } // Returns a SingleSubject that returns when the bolus has finished. @@ -380,8 +304,6 @@ public class OmnipodManager { public synchronized BolusCommandResult bolus(Double units, boolean acknowledgementBeep, boolean completionBeep, BiConsumer progressIndicationConsumer) { assertReadyForDelivery(); - logStartingCommandExecution("bolus [units=" + units + ", acknowledgementBeep=" + acknowledgementBeep + ", completionBeep=" + completionBeep + "]"); - bolusCommandExecutionSubject = SingleSubject.create(); CommandDeliveryStatus commandDeliveryStatus = CommandDeliveryStatus.SUCCESS; @@ -467,8 +389,6 @@ public class OmnipodManager { }) .subscribe()); - logCommandExecutionFinished("bolus"); - return new BolusCommandResult(commandDeliveryStatus, bolusCompletionSubject); } @@ -480,16 +400,12 @@ public class OmnipodManager { throw new IllegalDeliveryStatusException(DeliveryStatus.BOLUS_IN_PROGRESS, podStateManager.getLastDeliveryStatus()); } - logStartingCommandExecution("cancelBolus [acknowledgementBeep=" + acknowledgementBeep + "]"); - try { StatusResponse statusResponse = cancelDelivery(EnumSet.of(DeliveryType.BOLUS), acknowledgementBeep); discardActiveBolusData(statusResponse.getBolusNotDelivered()); } catch (PodFaultException ex) { discardActiveBolusData(ex.getDetailedStatus().getBolusNotDelivered()); throw ex; - } finally { - logCommandExecutionFinished("cancelBolus"); } } } @@ -507,7 +423,6 @@ public class OmnipodManager { public synchronized void suspendDelivery(boolean acknowledgementBeep) { assertReadyForDelivery(); - logStartingCommandExecution("suspendDelivery"); try { cancelDelivery(EnumSet.allOf(DeliveryType.class), acknowledgementBeep); @@ -521,8 +436,6 @@ public class OmnipodManager { ex.setCertainFailure(true); throw ex; } - } finally { - logCommandExecutionFinished("suspendDelivery"); } } @@ -531,26 +444,20 @@ public class OmnipodManager { public synchronized void setTime(boolean acknowledgementBeeps) { assertReadyForDelivery(); - logStartingCommandExecution("setTime [acknowledgementBeeps=" + acknowledgementBeeps + "]"); + DateTimeZone oldTimeZone = podStateManager.getTimeZone(); try { - DateTimeZone oldTimeZone = podStateManager.getTimeZone(); + // Joda seems to cache the default time zone, so we use the JVM's + DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault())); + podStateManager.setTimeZone(DateTimeZone.getDefault()); - try { - // Joda seems to cache the default time zone, so we use the JVM's - DateTimeZone.setDefault(DateTimeZone.forTimeZone(TimeZone.getDefault())); - podStateManager.setTimeZone(DateTimeZone.getDefault()); - - setBasalSchedule(podStateManager.getBasalSchedule(), acknowledgementBeeps); - } catch (OmnipodException ex) { - podStateManager.setTimeZone(oldTimeZone); - throw ex; - } - - podStateManager.updateActivatedAt(); - } finally { - logCommandExecutionFinished("setTime"); + setBasalSchedule(podStateManager.getBasalSchedule(), acknowledgementBeeps); + } catch (OmnipodException ex) { + podStateManager.setTimeZone(oldTimeZone); + throw ex; } + + podStateManager.updateActivatedAt(); } public synchronized void deactivatePod() { @@ -558,8 +465,6 @@ public class OmnipodManager { throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, null); } - logStartingCommandExecution("deactivatePod"); - // Try to get pulse log for diagnostics try { PodInfoResponse podInfoResponse = communicationService.executeAction(new GetPodInfoAction(podStateManager, PodInfoType.RECENT_PULSE_LOG)); @@ -574,8 +479,6 @@ public class OmnipodManager { communicationService.executeAction(new DeactivatePodAction(podStateManager, true)); } catch (PodFaultException ex) { aapsLogger.info(LTag.PUMPCOMM, "Ignoring PodFaultException in deactivatePod", ex); - } finally { - logCommandExecutionFinished("deactivatePod"); } podStateManager.discardState(); @@ -605,7 +508,6 @@ public class OmnipodManager { // Only works for commands with nonce resyncable message blocks private StatusResponse executeAndVerify(Supplier supplier) { - logStartingCommandExecution("verifyCommand"); try { return supplier.get(); } catch (OmnipodException originalException) { @@ -629,8 +531,6 @@ public class OmnipodManager { throw originalException; } } - } finally { - logCommandExecutionFinished("verifyCommand"); } } @@ -645,7 +545,7 @@ public class OmnipodManager { * @return true if the Pod's progress status matches the expected status, otherwise false * @throws PodProgressStatusVerificationFailedException in case reading the Pod status fails */ - private boolean verifyPodProgressStatus(PodProgressStatus expectedPodProgressStatus) { + private boolean verifyPodProgressStatus(PodProgressStatus expectedPodProgressStatus, SetupProgress setupProgress) { Boolean result = null; Throwable lastException = null; @@ -654,6 +554,7 @@ public class OmnipodManager { StatusResponse statusResponse = getPodStatus(); if (statusResponse.getPodProgressStatus().equals(expectedPodProgressStatus)) { + podStateManager.setSetupProgress(setupProgress); return true; } else { result = false; @@ -694,14 +595,6 @@ public class OmnipodManager { throw new DeliveryStatusVerificationFailedException(expectedStatus, verificationCause); } - private void logStartingCommandExecution(String action) { - aapsLogger.debug(LTag.PUMPCOMM, "Starting command execution for action: " + action); - } - - private void logCommandExecutionFinished(String action) { - aapsLogger.debug(LTag.PUMPCOMM, "Command execution finished for action: " + action); - } - private Duration calculateEstimatedBolusDuration(DateTime startTime, double units, double deliveryRateInUnitsPerSecond) { if (!podStateManager.isPodActivationCompleted()) { // No basal or temp basal is active yet diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java index 91ab82edfe..38dbeccc8a 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java @@ -16,6 +16,7 @@ import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.function.Supplier; import info.nightscout.androidaps.logging.AAPSLogger; @@ -31,6 +32,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.Firmwar import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodCrc; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; // TODO add nullchecks on some setters @@ -80,7 +82,7 @@ public abstract class PodStateManager { * @return true if we have a Pod state and the Pod activation has been completed. The pod could also be dead at this point */ public final boolean isPodActivationCompleted() { - return isPodInitialized() && podState.getPodProgressStatus().isAtLeast(PodProgressStatus.ABOVE_FIFTY_UNITS) && !isPodActivationTimeExceeded(); + return getSetupProgress().isCompleted(); } /** @@ -335,6 +337,17 @@ public abstract class PodStateManager { return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone())).plus(OmnipodConstants.NOMINAL_POD_LIFE); } + public final SetupProgress getSetupProgress() { + if (hasPodState()) { + return Optional.ofNullable(podState.getSetupProgress()).orElse(SetupProgress.NONE); + } + return SetupProgress.NONE; + } + + public final void setSetupProgress(SetupProgress setupProgress) { + setAndStore(() -> podState.setSetupProgress(setupProgress)); + } + public final PodProgressStatus getPodProgressStatus() { return getSafe(() -> podState.getPodProgressStatus()); } @@ -642,6 +655,7 @@ public abstract class PodStateManager { private Integer totalTicksDelivered; private boolean suspended; private NonceState nonceState; + private SetupProgress setupProgress = SetupProgress.NONE; private PodProgressStatus podProgressStatus; private DeliveryStatus lastDeliveryStatus; private AlertSet activeAlerts; @@ -810,6 +824,14 @@ public abstract class PodStateManager { this.nonceState = nonceState; } + SetupProgress getSetupProgress() { + return setupProgress; + } + + void setSetupProgress(SetupProgress setupProgress) { + this.setupProgress = setupProgress; + } + PodProgressStatus getPodProgressStatus() { return podProgressStatus; } @@ -941,11 +963,12 @@ public abstract class PodStateManager { ", timeZone=" + timeZone + ", activatedAt=" + activatedAt + ", timeActive=" + timeActive + - ", faultEvent=" + faultEventCode + + ", faultEventCode=" + faultEventCode + ", reservoirLevel=" + reservoirLevel + ", totalTicksDelivered=" + totalTicksDelivered + ", suspended=" + suspended + ", nonceState=" + nonceState + + ", setupProgress=" + setupProgress + ", podProgressStatus=" + podProgressStatus + ", lastDeliveryStatus=" + lastDeliveryStatus + ", activeAlerts=" + activeAlerts + diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java index f50c09edcf..bbec85241d 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java @@ -62,6 +62,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalM import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalResponseException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.MessageDecodingException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException; @@ -770,7 +771,8 @@ public class AapsOmnipodManager { comment = getStringResource(R.string.omnipod_error_crc_mismatch); } else if (ex instanceof IllegalPacketTypeException) { comment = getStringResource(R.string.omnipod_error_invalid_packet_type); - } else if (ex instanceof IllegalPodProgressException || ex instanceof IllegalDeliveryStatusException) { + } else if (ex instanceof IllegalPodProgressException || ex instanceof IllegalSetupProgressException || + ex instanceof IllegalDeliveryStatusException) { comment = getStringResource(R.string.omnipod_error_invalid_progress_state); } else if (ex instanceof IllegalVersionResponseTypeException) { comment = getStringResource(R.string.omnipod_error_invalid_response); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt index 168f96180f..3a8326e3fe 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt @@ -25,6 +25,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin import info.nightscout.androidaps.plugins.pump.omnipod.R import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager @@ -345,9 +346,7 @@ class OmnipodOverviewFragment : DaggerFragment() { if (!podStateManager.isPodInitialized) { resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation) } else { - if (podStateManager.isPodActivationTimeExceeded) { - resourceHelper.gs(R.string.omnipod_pod_status_activation_time_exceeded) - } else if (podStateManager.podProgressStatus.isBefore(PodProgressStatus.PRIMING_COMPLETED)) { + if (podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_COMPLETED)) { resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation) } else { resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_cannula_insertion) @@ -454,7 +453,7 @@ class OmnipodOverviewFragment : DaggerFragment() { } private fun updateRefreshStatusButton() { - omnipod_overview_button_refresh_status.isEnabled = podStateManager.isPodInitialized && podStateManager.podProgressStatus.isAtLeast(PodProgressStatus.PAIRING_COMPLETED) + omnipod_overview_button_refresh_status.isEnabled = podStateManager.isPodInitialized && podStateManager.setupProgress.isAtLeast(SetupProgress.PAIRING_COMPLETED) && rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty() } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt index 1732c6e204..c47b2b3912 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt @@ -9,6 +9,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.omnipod.R +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager @@ -93,8 +94,8 @@ class PodManagementActivity : NoSplashAppCompatActivity() { omnipod_pod_management_waiting_for_rl_layout.visibility = (!rileyLinkServiceData.rileyLinkServiceState.isReady).toVisibility() if (rileyLinkServiceData.rileyLinkServiceState.isReady) { - omnipod_pod_management_button_activate_pod.isEnabled = !podStateManager.isPodActivationCompleted && !podStateManager.isPodActivationTimeExceeded - omnipod_pod_management_button_deactivate_pod.isEnabled = podStateManager.isPodInitialized + omnipod_pod_management_button_activate_pod.isEnabled = !podStateManager.isPodActivationCompleted + omnipod_pod_management_button_deactivate_pod.isEnabled = podStateManager.setupProgress.isAtLeast(SetupProgress.PAIRING_COMPLETED) if (discardButtonEnabled) { omnipod_pod_management_button_discard_pod.isEnabled = true } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt index 183c3c239c..31ad021fef 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt @@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation import android.os.Bundle import androidx.annotation.IdRes import info.nightscout.androidaps.plugins.pump.omnipod.R -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.activity.OmnipodWizardActivityBase import javax.inject.Inject @@ -25,7 +25,7 @@ class PodActivationWizardActivity : OmnipodWizardActivityBase() { setContentView(R.layout.omnipod_pod_activation_wizard_activity) startDestination = savedInstanceState?.getInt(KEY_START_DESTINATION, R.id.fillPodInfoFragment) - ?: if (!podStateManager.isPodInitialized || podStateManager.podProgressStatus.isBefore(PodProgressStatus.PRIMING_COMPLETED)) { + ?: if (!podStateManager.isPodInitialized || podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_COMPLETED)) { R.id.fillPodInfoFragment } else { R.id.attachPodInfoFragment diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt index cb064bebcf..c58888242f 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt @@ -3,6 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation.fra import android.content.Intent import android.os.Bundle import android.view.View +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.fragment.ActionFragmentBase import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.deactivation.PodDeactivationWizardActivity @@ -25,7 +26,7 @@ abstract class PodActivationActionFragmentBase : ActionFragmentBase() { } override fun onActionFailure() { - if (podStateManager.isPodActivationTimeExceeded) { + if (podStateManager.isPodActivationTimeExceeded && podStateManager.setupProgress.isAtLeast(SetupProgress.PAIRING_COMPLETED)) { omnipod_wizard_button_retry.visibility = View.GONE omnipod_wizard_button_deactivate_pod.visibility = View.VISIBLE } From b4813ad708ffd141aa56634a3cc25804ce9f2000 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 17 Oct 2020 17:08:47 +0200 Subject: [PATCH 11/15] Rename SetupProgress to ActivationProgress --- .../pump/omnipod/OmnipodPumpPlugin.java | 8 ++--- .../action/AssignAddressAction.java | 2 +- .../action/InsertCannulaAction.java | 20 ++++++------- .../communication/action/PrimeAction.java | 20 ++++++------- .../communication/action/SetupPodAction.java | 6 ++-- ...pProgress.java => ActivationProgress.java} | 8 ++--- ...> IllegalActivationProgressException.java} | 14 ++++----- .../driver/manager/OmnipodManager.java | 30 +++++++++---------- .../driver/manager/PodStateManager.java | 26 ++++++++-------- .../omnipod/manager/AapsOmnipodManager.java | 4 +-- .../omnipod/ui/OmnipodOverviewFragment.kt | 6 ++-- .../pump/omnipod/ui/PodManagementActivity.kt | 4 +-- .../activation/PodActivationWizardActivity.kt | 4 +-- .../PodActivationActionFragmentBase.kt | 4 +-- 14 files changed, 78 insertions(+), 78 deletions(-) rename omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/{SetupProgress.java => ActivationProgress.java} (87%) rename omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/{IllegalSetupProgressException.java => IllegalActivationProgressException.java} (51%) 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 6ce16cb71f..e714253b71 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 @@ -72,9 +72,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodCustomA import info.nightscout.androidaps.plugins.pump.omnipod.definition.OmnipodStorageKeys; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.ExpirationReminderBuilder; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged; import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodTbrChanged; @@ -257,9 +257,9 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface, // BS @ 2020-10-17 FIXME: for backwards compatibility; remove before release if (podStateManager.isPodInitialized() && - podStateManager.getSetupProgress() == SetupProgress.NONE && + podStateManager.getActivationProgress() == ActivationProgress.NONE && podStateManager.getPodProgressStatus().isAtLeast(PodProgressStatus.ABOVE_FIFTY_UNITS)) { - podStateManager.setSetupProgress(SetupProgress.COMPLETED); + podStateManager.setActivationProgress(ActivationProgress.COMPLETED); } lastConnectionTimeMillis = sp.getLong( @@ -930,7 +930,7 @@ public class OmnipodPumpPlugin extends PumpPluginBase implements PumpInterface, } private void initializeAfterRileyLinkConnection() { - if (podStateManager.getSetupProgress().isAtLeast(SetupProgress.PAIRING_COMPLETED)) { + if (podStateManager.getActivationProgress().isAtLeast(ActivationProgress.PAIRING_COMPLETED)) { for (int i = 0; STARTUP_STATUS_REQUEST_TRIES > i; i++) { PumpEnactResult result = executeCommand(OmnipodCommandType.GET_POD_STATUS, aapsOmnipodManager::getPodStatus); if (result.success) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java index a16c69163a..fb1127cecc 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/AssignAddressAction.java @@ -38,7 +38,7 @@ public class AssignAddressAction implements OmnipodAction { podStateManager.initState(generateRandomAddress()); } - if (podStateManager.getSetupProgress().needsPairing()) { + if (podStateManager.getActivationProgress().needsPairing()) { AssignAddressCommand assignAddress = new AssignAddressCommand(podStateManager.getAddress()); OmnipodMessage assignAddressMessage = new OmnipodMessage(OmnipodConstants.DEFAULT_ADDRESS, Collections.singletonList(assignAddress), podStateManager.getMessageNumber()); diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java index b1adbc1f68..ff47b1b900 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/InsertCannulaAction.java @@ -6,11 +6,11 @@ import java.util.List; import java.util.Optional; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.ExpirationReminderBuilder; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; @@ -37,29 +37,29 @@ public class InsertCannulaAction implements OmnipodAction { @Override public Void execute(OmnipodRileyLinkCommunicationManager communicationService) { - if (podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_COMPLETED)) { - throw new IllegalSetupProgressException(SetupProgress.PRIMING_COMPLETED, podStateManager.getSetupProgress()); + if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PRIMING_COMPLETED)) { + throw new IllegalActivationProgressException(ActivationProgress.PRIMING_COMPLETED, podStateManager.getActivationProgress()); } - if (podStateManager.getSetupProgress().needsBasalSchedule()) { + if (podStateManager.getActivationProgress().needsBasalSchedule()) { podStateManager.setBasalSchedule(initialBasalSchedule); communicationService.executeAction(new SetBasalScheduleAction(podStateManager, initialBasalSchedule, true, podStateManager.getScheduleOffset(), false)); - podStateManager.setSetupProgress(SetupProgress.BASAL_INITIALIZED); + podStateManager.setActivationProgress(ActivationProgress.BASAL_INITIALIZED); } - if (podStateManager.getSetupProgress().needsExpirationReminders()) { + if (podStateManager.getActivationProgress().needsExpirationReminders()) { communicationService.executeAction(new ConfigureAlertsAction(podStateManager, buildAlertConfigurations())); podStateManager.setExpirationAlertTimeBeforeShutdown(expirationReminderTimeBeforeShutdown); podStateManager.setLowReservoirAlertUnits(lowReservoirAlertUnits); - podStateManager.setSetupProgress(SetupProgress.EXPIRATION_REMINDERS_SET); + podStateManager.setActivationProgress(ActivationProgress.EXPIRATION_REMINDERS_SET); } - if (podStateManager.getSetupProgress().needsCannulaInsertion()) { + if (podStateManager.getActivationProgress().needsCannulaInsertion()) { communicationService.executeAction(new BolusAction(podStateManager, OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, Duration.standardSeconds(1), false, false)); - podStateManager.setSetupProgress(SetupProgress.INSERTING_CANNULA); + podStateManager.setActivationProgress(ActivationProgress.INSERTING_CANNULA); } return null; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java index 6f748e9962..c1269e3e39 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/PrimeAction.java @@ -1,8 +1,8 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.action.service.PrimeService; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager; import info.nightscout.androidaps.plugins.pump.omnipod.rileylink.manager.OmnipodRileyLinkCommunicationManager; @@ -24,24 +24,24 @@ public class PrimeAction implements OmnipodAction { @Override public Void execute(OmnipodRileyLinkCommunicationManager communicationService) { - if (podStateManager.getSetupProgress().isBefore(SetupProgress.PAIRING_COMPLETED)) { - throw new IllegalSetupProgressException(SetupProgress.PAIRING_COMPLETED, podStateManager.getSetupProgress()); + if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PAIRING_COMPLETED)) { + throw new IllegalActivationProgressException(ActivationProgress.PAIRING_COMPLETED, podStateManager.getActivationProgress()); } - if (podStateManager.getSetupProgress().needsDisableTab5Sub16And17()) { + if (podStateManager.getActivationProgress().needsDisableTab5Sub16And17()) { // FaultConfigCommand sets internal pod variables to effectively disable $6x faults which occur more often with a 0 TBR service.executeDisableTab5Sub16And17FaultConfigCommand(communicationService, podStateManager); - podStateManager.setSetupProgress(SetupProgress.TAB_5_SUB_16_AND_17_DISABLED); + podStateManager.setActivationProgress(ActivationProgress.TAB_5_SUB_16_AND_17_DISABLED); } - if (podStateManager.getSetupProgress().needsSetupReminders()) { + if (podStateManager.getActivationProgress().needsSetupReminders()) { service.executeFinishSetupReminderAlertCommand(communicationService, podStateManager); - podStateManager.setSetupProgress(SetupProgress.SETUP_REMINDERS_SET); + podStateManager.setActivationProgress(ActivationProgress.SETUP_REMINDERS_SET); } - if (podStateManager.getSetupProgress().needsPriming()) { + if (podStateManager.getActivationProgress().needsPriming()) { service.executePrimeBolusCommand(communicationService, podStateManager); - podStateManager.setSetupProgress(SetupProgress.PRIMING); + podStateManager.setActivationProgress(ActivationProgress.PRIMING); } return null; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java index 498e285b0b..8cb2a1ddde 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/action/SetupPodAction.java @@ -8,10 +8,10 @@ import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.OmnipodMessage; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.command.SetupPodCommand; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.VersionResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PacketType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalMessageAddressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; @@ -40,7 +40,7 @@ public class SetupPodAction implements OmnipodAction { throw new IllegalPodProgressException(PodProgressStatus.REMINDER_INITIALIZED, podStateManager.isPodInitialized() ? podStateManager.getPodProgressStatus() : null); } - if (podStateManager.getSetupProgress().needsPairing()) { + if (podStateManager.getActivationProgress().needsPairing()) { DateTime activationDate = DateTime.now(podStateManager.getTimeZone()); SetupPodCommand setupPodCommand = new SetupPodCommand(podStateManager.getAddress(), activationDate, @@ -67,7 +67,7 @@ public class SetupPodAction implements OmnipodAction { } } - podStateManager.setSetupProgress(SetupProgress.PAIRING_COMPLETED); + podStateManager.setActivationProgress(ActivationProgress.PAIRING_COMPLETED); } return null; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/SetupProgress.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/ActivationProgress.java similarity index 87% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/SetupProgress.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/ActivationProgress.java index 874b9a2d3e..9db21f5e59 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/SetupProgress.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/definition/ActivationProgress.java @@ -1,6 +1,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.definition; -public enum SetupProgress { +public enum ActivationProgress { NONE, PAIRING_COMPLETED, TAB_5_SUB_16_AND_17_DISABLED, @@ -52,15 +52,15 @@ public enum SetupProgress { return this == COMPLETED; } - public boolean isBefore(SetupProgress other) { + public boolean isBefore(ActivationProgress other) { return ordinal() < other.ordinal(); } - public boolean isAtLeast(SetupProgress other) { + public boolean isAtLeast(ActivationProgress other) { return ordinal() >= other.ordinal(); } - public boolean isAfter(SetupProgress other) { + public boolean isAfter(ActivationProgress other) { return ordinal() > other.ordinal(); } } \ No newline at end of file diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalSetupProgressException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalActivationProgressException.java similarity index 51% rename from omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalSetupProgressException.java rename to omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalActivationProgressException.java index 42744496ea..e202ceefd8 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalSetupProgressException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalActivationProgressException.java @@ -2,23 +2,23 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.exception; import java.util.Locale; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress; -public class IllegalSetupProgressException extends OmnipodException { - private final SetupProgress expected; - private final SetupProgress actual; +public class IllegalActivationProgressException extends OmnipodException { + private final ActivationProgress expected; + private final ActivationProgress actual; - public IllegalSetupProgressException(SetupProgress expected, SetupProgress actual) { + public IllegalActivationProgressException(ActivationProgress expected, ActivationProgress actual) { super(String.format(Locale.getDefault(), "Illegal setup progress: %s, expected: %s", actual, expected), true); this.expected = expected; this.actual = actual; } - public SetupProgress getExpected() { + public ActivationProgress getExpected() { return expected; } - public SetupProgress getActual() { + public ActivationProgress getActual() { return actual; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java index 1f8593eb67..cc59a21ad7 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java @@ -31,6 +31,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mess import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoRecentPulseLog; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoResponse; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertConfiguration; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.BeepType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.DeliveryStatus; @@ -38,13 +39,12 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.Deliver import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodInfoType; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodFaultException; @@ -89,16 +89,16 @@ public class OmnipodManager { public synchronized Single pairAndPrime() { if (podStateManager.isPodInitialized()) { - if (podStateManager.getSetupProgress().isAfter(SetupProgress.PRIMING)) { + if (podStateManager.getActivationProgress().isAfter(ActivationProgress.PRIMING)) { return Single.just(true); } - if (podStateManager.getSetupProgress().needsPrimingVerification()) { - return Single.fromCallable(() -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, SetupProgress.PRIMING_COMPLETED)); + if (podStateManager.getActivationProgress().needsPrimingVerification()) { + return Single.fromCallable(() -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, ActivationProgress.PRIMING_COMPLETED)); } } // Always send both 0x07 and 0x03 on retries - if (podStateManager.getSetupProgress().isBefore(SetupProgress.PAIRING_COMPLETED)) { + if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PAIRING_COMPLETED)) { communicationService.executeAction( new AssignAddressAction(podStateManager, aapsLogger)); @@ -110,22 +110,22 @@ public class OmnipodManager { long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_PRIME_BOLUS_UNITS, OmnipodConstants.POD_PRIMING_DELIVERY_RATE).getMillis(); return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // - .map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, SetupProgress.PRIMING_COMPLETED)) // + .map(o -> verifyPodProgressStatus(PodProgressStatus.PRIMING_COMPLETED, ActivationProgress.PRIMING_COMPLETED)) // .subscribeOn(Schedulers.io()); } public synchronized Single insertCannula( BasalSchedule basalSchedule, Duration expirationReminderTimeBeforeShutdown, Integer lowReservoirAlertUnits) { - if (podStateManager.getSetupProgress().isBefore(SetupProgress.PRIMING_COMPLETED)) { - throw new IllegalSetupProgressException(SetupProgress.PRIMING_COMPLETED, podStateManager.getSetupProgress()); + if (podStateManager.getActivationProgress().isBefore(ActivationProgress.PRIMING_COMPLETED)) { + throw new IllegalActivationProgressException(ActivationProgress.PRIMING_COMPLETED, podStateManager.getActivationProgress()); } if (podStateManager.isPodInitialized()) { - if (podStateManager.getSetupProgress().isCompleted()) { + if (podStateManager.getActivationProgress().isCompleted()) { return Single.just(true); } - if (podStateManager.getSetupProgress().needsCannulaInsertionVerification()) { - return Single.fromCallable(() -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS, SetupProgress.COMPLETED)); + if (podStateManager.getActivationProgress().needsCannulaInsertionVerification()) { + return Single.fromCallable(() -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS, ActivationProgress.COMPLETED)); } } @@ -134,7 +134,7 @@ public class OmnipodManager { long delayInMillis = calculateEstimatedBolusDuration(DateTime.now().minus(OmnipodConstants.AVERAGE_BOLUS_COMMAND_COMMUNICATION_DURATION), OmnipodConstants.POD_CANNULA_INSERTION_BOLUS_UNITS, OmnipodConstants.POD_CANNULA_INSERTION_DELIVERY_RATE).getMillis(); return Single.timer(delayInMillis, TimeUnit.MILLISECONDS) // - .map(o -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS, SetupProgress.COMPLETED)) // + .map(o -> verifyPodProgressStatus(PodProgressStatus.ABOVE_FIFTY_UNITS, ActivationProgress.COMPLETED)) // .subscribeOn(Schedulers.io()); } @@ -545,7 +545,7 @@ public class OmnipodManager { * @return true if the Pod's progress status matches the expected status, otherwise false * @throws PodProgressStatusVerificationFailedException in case reading the Pod status fails */ - private boolean verifyPodProgressStatus(PodProgressStatus expectedPodProgressStatus, SetupProgress setupProgress) { + private boolean verifyPodProgressStatus(PodProgressStatus expectedPodProgressStatus, ActivationProgress activationProgress) { Boolean result = null; Throwable lastException = null; @@ -554,7 +554,7 @@ public class OmnipodManager { StatusResponse statusResponse = getPodStatus(); if (statusResponse.getPodProgressStatus().equals(expectedPodProgressStatus)) { - podStateManager.setSetupProgress(setupProgress); + podStateManager.setActivationProgress(activationProgress); return true; } else { result = false; diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java index 38dbeccc8a..764467e15e 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/PodStateManager.java @@ -23,6 +23,7 @@ import info.nightscout.androidaps.logging.AAPSLogger; import info.nightscout.androidaps.logging.LTag; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.podinfo.PodInfoDetailedStatus; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSlot; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertType; @@ -32,7 +33,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.Firmwar import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodCrc; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; // TODO add nullchecks on some setters @@ -82,7 +82,7 @@ public abstract class PodStateManager { * @return true if we have a Pod state and the Pod activation has been completed. The pod could also be dead at this point */ public final boolean isPodActivationCompleted() { - return getSetupProgress().isCompleted(); + return getActivationProgress().isCompleted(); } /** @@ -337,15 +337,15 @@ public abstract class PodStateManager { return activatedAt == null ? null : activatedAt.withZone(getSafe(() -> podState.getTimeZone())).plus(OmnipodConstants.NOMINAL_POD_LIFE); } - public final SetupProgress getSetupProgress() { + public final ActivationProgress getActivationProgress() { if (hasPodState()) { - return Optional.ofNullable(podState.getSetupProgress()).orElse(SetupProgress.NONE); + return Optional.ofNullable(podState.getActivationProgress()).orElse(ActivationProgress.NONE); } - return SetupProgress.NONE; + return ActivationProgress.NONE; } - public final void setSetupProgress(SetupProgress setupProgress) { - setAndStore(() -> podState.setSetupProgress(setupProgress)); + public final void setActivationProgress(ActivationProgress activationProgress) { + setAndStore(() -> podState.setActivationProgress(activationProgress)); } public final PodProgressStatus getPodProgressStatus() { @@ -655,7 +655,7 @@ public abstract class PodStateManager { private Integer totalTicksDelivered; private boolean suspended; private NonceState nonceState; - private SetupProgress setupProgress = SetupProgress.NONE; + private ActivationProgress activationProgress = ActivationProgress.NONE; private PodProgressStatus podProgressStatus; private DeliveryStatus lastDeliveryStatus; private AlertSet activeAlerts; @@ -824,12 +824,12 @@ public abstract class PodStateManager { this.nonceState = nonceState; } - SetupProgress getSetupProgress() { - return setupProgress; + ActivationProgress getActivationProgress() { + return activationProgress; } - void setSetupProgress(SetupProgress setupProgress) { - this.setupProgress = setupProgress; + void setActivationProgress(ActivationProgress activationProgress) { + this.activationProgress = activationProgress; } PodProgressStatus getPodProgressStatus() { @@ -968,7 +968,7 @@ public abstract class PodStateManager { ", totalTicksDelivered=" + totalTicksDelivered + ", suspended=" + suspended + ", nonceState=" + nonceState + - ", setupProgress=" + setupProgress + + ", activationProgress=" + activationProgress + ", podProgressStatus=" + podProgressStatus + ", lastDeliveryStatus=" + lastDeliveryStatus + ", activeAlerts=" + activeAlerts + diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java index c6b4f9a82f..9a2956792d 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/manager/AapsOmnipodManager.java @@ -62,7 +62,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalM import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPacketTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalResponseException; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalSetupProgressException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalVersionResponseTypeException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.MessageDecodingException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException; @@ -774,7 +774,7 @@ public class AapsOmnipodManager { comment = getStringResource(R.string.omnipod_error_crc_mismatch); } else if (ex instanceof IllegalPacketTypeException) { comment = getStringResource(R.string.omnipod_error_invalid_packet_type); - } else if (ex instanceof IllegalPodProgressException || ex instanceof IllegalSetupProgressException || + } else if (ex instanceof IllegalPodProgressException || ex instanceof IllegalActivationProgressException || ex instanceof IllegalDeliveryStatusException) { comment = getStringResource(R.string.omnipod_error_invalid_progress_state); } else if (ex instanceof IllegalVersionResponseTypeException) { diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt index 3a8326e3fe..de8f029bff 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/OmnipodOverviewFragment.kt @@ -23,9 +23,9 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.dialog.RileyL import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin import info.nightscout.androidaps.plugins.pump.omnipod.R +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.OmnipodConstants import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProgressStatus -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager @@ -346,7 +346,7 @@ class OmnipodOverviewFragment : DaggerFragment() { if (!podStateManager.isPodInitialized) { resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation) } else { - if (podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_COMPLETED)) { + if (podStateManager.activationProgress.isBefore(ActivationProgress.PRIMING_COMPLETED)) { resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_activation) } else { resourceHelper.gs(R.string.omnipod_pod_status_waiting_for_cannula_insertion) @@ -453,7 +453,7 @@ class OmnipodOverviewFragment : DaggerFragment() { } private fun updateRefreshStatusButton() { - omnipod_overview_button_refresh_status.isEnabled = podStateManager.isPodInitialized && podStateManager.setupProgress.isAtLeast(SetupProgress.PAIRING_COMPLETED) + omnipod_overview_button_refresh_status.isEnabled = podStateManager.isPodInitialized && podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED) && rileyLinkServiceData.rileyLinkServiceState.isReady && isQueueEmpty() } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt index c47b2b3912..fa1de1ef5c 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/PodManagementActivity.kt @@ -9,7 +9,7 @@ import info.nightscout.androidaps.plugins.bus.RxBusWrapper import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.RileyLinkServiceData import info.nightscout.androidaps.plugins.pump.omnipod.R -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.event.EventOmnipodPumpValuesChanged import info.nightscout.androidaps.plugins.pump.omnipod.manager.AapsOmnipodManager @@ -95,7 +95,7 @@ class PodManagementActivity : NoSplashAppCompatActivity() { if (rileyLinkServiceData.rileyLinkServiceState.isReady) { omnipod_pod_management_button_activate_pod.isEnabled = !podStateManager.isPodActivationCompleted - omnipod_pod_management_button_deactivate_pod.isEnabled = podStateManager.setupProgress.isAtLeast(SetupProgress.PAIRING_COMPLETED) + omnipod_pod_management_button_deactivate_pod.isEnabled = podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED) if (discardButtonEnabled) { omnipod_pod_management_button_discard_pod.isEnabled = true } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt index 31ad021fef..0d67bf2709 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt @@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation import android.os.Bundle import androidx.annotation.IdRes import info.nightscout.androidaps.plugins.pump.omnipod.R -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.activity.OmnipodWizardActivityBase import javax.inject.Inject @@ -25,7 +25,7 @@ class PodActivationWizardActivity : OmnipodWizardActivityBase() { setContentView(R.layout.omnipod_pod_activation_wizard_activity) startDestination = savedInstanceState?.getInt(KEY_START_DESTINATION, R.id.fillPodInfoFragment) - ?: if (!podStateManager.isPodInitialized || podStateManager.setupProgress.isBefore(SetupProgress.PRIMING_COMPLETED)) { + ?: if (!podStateManager.isPodInitialized || podStateManager.activationProgress.isBefore(ActivationProgress.PRIMING_COMPLETED)) { R.id.fillPodInfoFragment } else { R.id.attachPodInfoFragment diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt index c58888242f..54df2de98e 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/fragment/PodActivationActionFragmentBase.kt @@ -3,7 +3,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.activation.fra import android.content.Intent import android.os.Bundle import android.view.View -import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.SetupProgress +import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.ActivationProgress import info.nightscout.androidaps.plugins.pump.omnipod.driver.manager.PodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.common.fragment.ActionFragmentBase import info.nightscout.androidaps.plugins.pump.omnipod.ui.wizard.deactivation.PodDeactivationWizardActivity @@ -26,7 +26,7 @@ abstract class PodActivationActionFragmentBase : ActionFragmentBase() { } override fun onActionFailure() { - if (podStateManager.isPodActivationTimeExceeded && podStateManager.setupProgress.isAtLeast(SetupProgress.PAIRING_COMPLETED)) { + if (podStateManager.isPodActivationTimeExceeded && podStateManager.activationProgress.isAtLeast(ActivationProgress.PAIRING_COMPLETED)) { omnipod_wizard_button_retry.visibility = View.GONE omnipod_wizard_button_deactivate_pod.visibility = View.VISIBLE } From e58fa0aff6f39fda8011354fa69e6f2f54430eb9 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 17 Oct 2020 18:32:58 +0200 Subject: [PATCH 12/15] Decrease action verification tries to 1 --- .../plugins/pump/omnipod/driver/manager/OmnipodManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java index cc59a21ad7..e4601e2a68 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/manager/OmnipodManager.java @@ -42,9 +42,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.PodProg import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.schedule.BasalSchedule; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.CommandFailedAfterChangingDeliveryStatusException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.DeliveryStatusVerificationFailedException; +import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalDeliveryStatusException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalPodProgressException; -import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.IllegalActivationProgressException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.NonceOutOfSyncException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.OmnipodException; import info.nightscout.androidaps.plugins.pump.omnipod.driver.exception.PodFaultException; @@ -59,7 +59,7 @@ import io.reactivex.schedulers.Schedulers; import io.reactivex.subjects.SingleSubject; public class OmnipodManager { - private static final int ACTION_VERIFICATION_TRIES = 2; + private static final int ACTION_VERIFICATION_TRIES = 1; private final OmnipodRileyLinkCommunicationManager communicationService; private PodStateManager podStateManager; From f64cc6629849ecda29b6119095219fbc3682a25d Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 17 Oct 2020 19:47:39 +0200 Subject: [PATCH 13/15] Improve Setup Wizard for Omnipod --- .../androidaps/setupwizard/SWDefinition.kt | 10 +++++++++- .../androidaps/setupwizard/SWEventListener.kt | 12 ++++++++++- app/src/main/res/values/strings.xml | 1 + .../EventRileyLinkDeviceStatusChange.kt | 20 +++++++++++++++---- .../rileylink/service/RileyLinkService.java | 6 ++++-- 5 files changed, 41 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt index 1d7c37929f..eb6e39d0ac 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWDefinition.kt @@ -30,6 +30,7 @@ import info.nightscout.androidaps.plugins.profile.local.LocalProfileFragment import info.nightscout.androidaps.plugins.profile.local.LocalProfilePlugin import info.nightscout.androidaps.plugins.profile.ns.NSProfileFragment import info.nightscout.androidaps.plugins.profile.ns.NSProfilePlugin +import info.nightscout.androidaps.plugins.pump.common.events.EventRileyLinkDeviceStatusChange import info.nightscout.androidaps.plugins.pump.omnipod.OmnipodPumpPlugin import info.nightscout.androidaps.setupwizard.elements.* import info.nightscout.androidaps.setupwizard.events.EventSWUpdate @@ -324,6 +325,12 @@ class SWDefinition @Inject constructor( val activePump = activePlugin.activePump activePump is OmnipodPumpPlugin && !activePump.isRileyLinkReady })) + .add( // Omnipod only + SWEventListener(injector, EventRileyLinkDeviceStatusChange::class.java) + .label(R.string.setupwizard_pump_riley_link_status) + .visibility(SWValidator { + activePlugin.activePump is OmnipodPumpPlugin + })) .add(SWButton(injector) .text(R.string.readstatus) .action(Runnable { commandQueue.readStatus("Clicked connect to pump", null) }) @@ -332,7 +339,8 @@ class SWDefinition @Inject constructor( // Getting the status might not be possible activePlugin.activePump !is OmnipodPumpPlugin })) - .add(SWEventListener(injector, EventPumpStatusChanged::class.java)) + .add(SWEventListener(injector, EventPumpStatusChanged::class.java) + .visibility(SWValidator { activePlugin.activePump !is OmnipodPumpPlugin })) .validator(SWValidator { isPumpInitialized() }) diff --git a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.kt b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.kt index 9757cbca32..5a7806b9a7 100644 --- a/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.kt +++ b/app/src/main/java/info/nightscout/androidaps/setupwizard/SWEventListener.kt @@ -11,7 +11,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.disposables.CompositeDisposable class SWEventListener constructor( - injector:HasAndroidInjector, + injector: HasAndroidInjector, clazz: Class ) : SWItem(injector, Type.LISTENER) { @@ -19,6 +19,7 @@ class SWEventListener constructor( private var textLabel = 0 private var status = "" private var textView: TextView? = null + private var visibilityValidator: SWValidator? = null // TODO: Adrian how to clear disposable in this case? init { @@ -43,6 +44,11 @@ class SWEventListener constructor( return this } + fun visibility(visibilityValidator: SWValidator): SWEventListener { + this.visibilityValidator = visibilityValidator + return this + } + @SuppressLint("SetTextI18n") override fun generateDialog(layout: LinearLayout) { val context = layout.context @@ -51,4 +57,8 @@ class SWEventListener constructor( textView?.text = (if (textLabel != 0) resourceHelper.gs(textLabel) else "") + " " + status layout.addView(textView) } + + override fun processVisibility() { + if (visibilityValidator != null && !visibilityValidator!!.isValid) textView?.visibility = View.GONE else textView?.visibility = View.VISIBLE + } } \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2b6e4788aa..e8fecced88 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1443,4 +1443,5 @@ Worker State: %s Uploaded Data The following data will be uploaded to your Open Humans account: Glucose values, boluses, carbs, careportal events (except notes), extended boluses, profile switches, total daily doses, temporary basals, temp targets, preferences, application version, device model and screen dimensions. Secret or private information such as your Nightscout URL or API secret will not be uploaded. + RileyLink status: diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt index b3425d14a5..59c084eb1f 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt @@ -1,11 +1,13 @@ package info.nightscout.androidaps.plugins.pump.common.events -import info.nightscout.androidaps.events.Event +import info.nightscout.androidaps.events.EventStatus import info.nightscout.androidaps.plugins.pump.common.defs.PumpDeviceState import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState +import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice +import info.nightscout.androidaps.utils.resources.ResourceHelper -open class EventRileyLinkDeviceStatusChange : Event { +open class EventRileyLinkDeviceStatusChange : EventStatus { var rileyLinkServiceState: RileyLinkServiceState? = null var rileyLinkError: RileyLinkError? = null @@ -14,10 +16,8 @@ open class EventRileyLinkDeviceStatusChange : Event { var errorDescription: String? = null constructor() { - } - constructor(rileyLinkServiceState: RileyLinkServiceState?, rileyLinkError: RileyLinkError?) { this.rileyLinkServiceState = rileyLinkServiceState this.rileyLinkError = rileyLinkError @@ -31,4 +31,16 @@ open class EventRileyLinkDeviceStatusChange : Event { this.pumpDeviceState = pumpDeviceState this.errorDescription = errorDescription } + + override fun getStatus(resourceHelper: ResourceHelper): String { + val rileyLinkServiceState = this.rileyLinkServiceState ?: return "" + val resourceId = rileyLinkServiceState.resourceId + val rileyLinkError = this.rileyLinkError + + if (rileyLinkServiceState.isError && rileyLinkError != null) { + return resourceHelper.gs(rileyLinkError.getResourceId(RileyLinkTargetDevice.Omnipod)) + } + + return resourceHelper.gs(resourceId) + } } diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.java index b4fb23d65f..b039e49c59 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.java +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkService.java @@ -24,8 +24,6 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.Rile import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkError; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkServiceState; import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.defs.RileyLinkTargetDevice; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceResult; -import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.service.data.ServiceTransport; import info.nightscout.androidaps.utils.resources.ResourceHelper; import info.nightscout.androidaps.utils.sharedPreferences.SP; @@ -114,6 +112,10 @@ public abstract class RileyLinkService extends DaggerService { public abstract RileyLinkCommunicationManager getDeviceCommunicationManager(); + public RileyLinkServiceState getRileyLinkServiceState() { + return rileyLinkServiceData == null ? null : rileyLinkServiceData.rileyLinkServiceState; + } + // Here is where the wake-lock begins: // We've received a service startCommand, we grab the lock. @Override From eb5fb334c96ee41907c7bbc4e82fc6ec5640629b Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Sat, 17 Oct 2020 20:20:48 +0200 Subject: [PATCH 14/15] Small fixes --- .../message/response/podinfo/PodInfoDetailedStatus.java | 4 +--- .../exception/IllegalActivationProgressException.java | 2 +- .../ui/wizard/activation/PodActivationWizardActivity.kt | 2 +- .../pump/common/events/EventRileyLinkDeviceStatusChange.kt | 7 +++++-- .../common/hw/rileylink/service/RileyLinkServiceData.java | 7 +++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java index 123a352f03..0db5ed2b53 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/communication/message/response/podinfo/PodInfoDetailedStatus.java @@ -2,8 +2,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.mes import org.joda.time.Duration; -import java.util.Arrays; - import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil; import info.nightscout.androidaps.plugins.pump.omnipod.driver.communication.message.response.StatusUpdatableResponse; import info.nightscout.androidaps.plugins.pump.omnipod.driver.definition.AlertSet; @@ -185,7 +183,7 @@ public class PodInfoDetailedStatus extends PodInfo implements StatusUpdatableRes ", receiverLowGain=" + receiverLowGain + ", radioRSSI=" + radioRSSI + ", previousPodProgressStatus=" + previousPodProgressStatus + - ", unknownValue=" + Arrays.toString(unknownValue) + + ", unknownValue=" + ByteUtil.shortHexString(unknownValue) + '}'; } } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalActivationProgressException.java b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalActivationProgressException.java index e202ceefd8..0dffb93517 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalActivationProgressException.java +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/driver/exception/IllegalActivationProgressException.java @@ -9,7 +9,7 @@ public class IllegalActivationProgressException extends OmnipodException { private final ActivationProgress actual; public IllegalActivationProgressException(ActivationProgress expected, ActivationProgress actual) { - super(String.format(Locale.getDefault(), "Illegal setup progress: %s, expected: %s", actual, expected), true); + super(String.format(Locale.getDefault(), "Illegal activation progress: %s, expected: %s", actual, expected), true); this.expected = expected; this.actual = actual; } diff --git a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt index 0d67bf2709..eccc00eb94 100644 --- a/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt +++ b/omnipod/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/ui/wizard/activation/PodActivationWizardActivity.kt @@ -25,7 +25,7 @@ class PodActivationWizardActivity : OmnipodWizardActivityBase() { setContentView(R.layout.omnipod_pod_activation_wizard_activity) startDestination = savedInstanceState?.getInt(KEY_START_DESTINATION, R.id.fillPodInfoFragment) - ?: if (!podStateManager.isPodInitialized || podStateManager.activationProgress.isBefore(ActivationProgress.PRIMING_COMPLETED)) { + ?: if (podStateManager.activationProgress.isBefore(ActivationProgress.PRIMING_COMPLETED)) { R.id.fillPodInfoFragment } else { R.id.attachPodInfoFragment diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt index 59c084eb1f..b2ece2d419 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/events/EventRileyLinkDeviceStatusChange.kt @@ -9,6 +9,7 @@ import info.nightscout.androidaps.utils.resources.ResourceHelper open class EventRileyLinkDeviceStatusChange : EventStatus { + var rileyLinkTargetDevice: RileyLinkTargetDevice? = null var rileyLinkServiceState: RileyLinkServiceState? = null var rileyLinkError: RileyLinkError? = null @@ -18,7 +19,8 @@ open class EventRileyLinkDeviceStatusChange : EventStatus { constructor() { } - constructor(rileyLinkServiceState: RileyLinkServiceState?, rileyLinkError: RileyLinkError?) { + constructor(rileyLinkTargetDevice: RileyLinkTargetDevice, rileyLinkServiceState: RileyLinkServiceState?, rileyLinkError: RileyLinkError?) { + this.rileyLinkTargetDevice = rileyLinkTargetDevice this.rileyLinkServiceState = rileyLinkServiceState this.rileyLinkError = rileyLinkError } @@ -38,7 +40,8 @@ open class EventRileyLinkDeviceStatusChange : EventStatus { val rileyLinkError = this.rileyLinkError if (rileyLinkServiceState.isError && rileyLinkError != null) { - return resourceHelper.gs(rileyLinkError.getResourceId(RileyLinkTargetDevice.Omnipod)) + val rileyLinkTargetDevice = this.rileyLinkTargetDevice ?: return "" + return resourceHelper.gs(rileyLinkError.getResourceId(rileyLinkTargetDevice)) } return resourceHelper.gs(resourceId) diff --git a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java index 13bebc22b8..02b27846bc 100644 --- a/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java +++ b/rileylink/src/main/java/info/nightscout/androidaps/plugins/pump/common/hw/rileylink/service/RileyLinkServiceData.java @@ -33,8 +33,7 @@ public class RileyLinkServiceData { public RileyLinkServiceState rileyLinkServiceState = RileyLinkServiceState.NotStarted; private long lastServiceStateChange = 0L; public RileyLinkFirmwareVersion firmwareVersion; - public RileyLinkTargetFrequency rileyLinkTargetFrequency; // TODO this might not be correct place - + public RileyLinkTargetFrequency rileyLinkTargetFrequency; public String rileylinkAddress; long lastTuneUpTime = 0L; public Double lastGoodFrequency; @@ -44,7 +43,7 @@ public class RileyLinkServiceData { // radio version public RileyLinkFirmwareVersion versionCC110; - public RileyLinkTargetDevice targetDevice; // TODO this might not be correct place + public RileyLinkTargetDevice targetDevice; // Medtronic Pump public String pumpID; @@ -86,7 +85,7 @@ public class RileyLinkServiceData { aapsLogger.info(LTag.PUMP, "RileyLink State Changed: {} {}", newState, errorCode == null ? "" : " - Error State: " + errorCode.name()); rileyLinkUtil.getRileyLinkHistory().add(new RLHistoryItem(rileyLinkServiceState, errorCode, targetDevice)); - rxBus.send(new EventRileyLinkDeviceStatusChange(newState, errorCode)); + rxBus.send(new EventRileyLinkDeviceStatusChange(targetDevice, newState, errorCode)); return null; } else { From 3aec6465bef1e8e3bc41f040a3b9c06d33e65ac8 Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Wed, 21 Oct 2020 14:43:57 +0200 Subject: [PATCH 15/15] Improve Omnipod translation --- omnipod/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/omnipod/src/main/res/values/strings.xml b/omnipod/src/main/res/values/strings.xml index 62ab50b16c..7be906aae4 100644 --- a/omnipod/src/main/res/values/strings.xml +++ b/omnipod/src/main/res/values/strings.xml @@ -93,7 +93,7 @@ Communication failed: nonce resync failed Communication failed: nonce out of sync Communication failed: not enough data received from the Pod - A Pod fault (%1$03d %2$s) has been detected. Please deactivate your Pod and start a new one + A Pod fault (%1$03d %2$s) has been detected. Please deactivate your Pod and activate a new one Communication failed: the Pod returned an error response No response from RileyLink RileyLink interrupted