Properly decode pod info response type 02

This commit is contained in:
Bart Sopers 2020-10-02 02:51:16 +02:00
parent 6fa01f88e3
commit e93a9eb34e
4 changed files with 72 additions and 60 deletions

View file

@ -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) +
'}';
}
}

View file

@ -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);
}
}

View file

@ -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());
}
}

View file

@ -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