From e93a9eb34e8967b789c2ecc6445004744a3d6f5f Mon Sep 17 00:00:00 2001 From: Bart Sopers Date: Fri, 2 Oct 2020 02:51:16 +0200 Subject: [PATCH] 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