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